From 3572f0e6324e35a8143026e20355ae08ae0dd1e6 Mon Sep 17 00:00:00 2001 From: johnman Date: Mon, 14 Oct 2024 20:05:06 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20built-on?= =?UTF-8?q?-openfin/container-starter@37cf2ee0e48d27f218c49990ed2a84de989f?= =?UTF-8?q?f9e5=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-logging-apis/html/app.html | 41 +- .../use-logging-apis/html/provider.html | 73 + .../use-logging-apis/js/app.bundle.js | 133 +- .../use-logging-apis/js/provider.bundle.js | 22885 ++++++++++++++++ .../use-logging-apis/manifest.fin.json | 47 +- .../uploads/applogs/AppLogs.md | 4 + .../uploads/opfslogs/OPFSLogs.md | 3 + .../uploads/runtimelogs/SystemLogs.md | 3 + 8 files changed, 23075 insertions(+), 114 deletions(-) create mode 100644 dev/john/update-logging-example/use-logging-apis/html/provider.html create mode 100644 dev/john/update-logging-example/use-logging-apis/js/provider.bundle.js create mode 100644 dev/john/update-logging-example/use-logging-apis/uploads/applogs/AppLogs.md create mode 100644 dev/john/update-logging-example/use-logging-apis/uploads/opfslogs/OPFSLogs.md create mode 100644 dev/john/update-logging-example/use-logging-apis/uploads/runtimelogs/SystemLogs.md diff --git a/dev/john/update-logging-example/use-logging-apis/html/app.html b/dev/john/update-logging-example/use-logging-apis/html/app.html index ff7839df..1269f5a1 100644 --- a/dev/john/update-logging-example/use-logging-apis/html/app.html +++ b/dev/john/update-logging-example/use-logging-apis/html/app.html @@ -2,7 +2,7 @@ - How to collect debug logs + Client that generates logs @@ -12,8 +12,8 @@
-

How to collect logs.

-

Demonstrate how to use logging APIs

+

A client that generates logs

+

Log via Channel API vs console log

OpenFin @@ -22,41 +22,18 @@

Demonstrate how to use logging APIs

-
-
-

Select a debug log.

-
- -
- -
-
-

Upload your applications log.

- +

Console Log A Message

+ +

Channel API Log A Message

+

Preview


+				
 			
- +
diff --git a/dev/john/update-logging-example/use-logging-apis/html/provider.html b/dev/john/update-logging-example/use-logging-apis/html/provider.html new file mode 100644 index 00000000..c351559c --- /dev/null +++ b/dev/john/update-logging-example/use-logging-apis/html/provider.html @@ -0,0 +1,73 @@ + + + + + How to collect debug logs + + + + + + + +
+
+

How to collect logs.

+

Demonstrate how to use logging related APIs

+
+
+ OpenFin +
+
+
+
+
+
+
+

Select a debug log.

+
+ +
+ +
+
+

Upload your applications log (console messages).

+ +

Upload your OPFS log (Channel API Messages).

+ +

Console Log A Message

+ +

Channel API Log A Message

+ +
+
+
+

Preview

+

+				
+			
+
+ + + diff --git a/dev/john/update-logging-example/use-logging-apis/js/app.bundle.js b/dev/john/update-logging-example/use-logging-apis/js/app.bundle.js index 19bf6c9a..3733c795 100644 --- a/dev/john/update-logging-example/use-logging-apis/js/app.bundle.js +++ b/dev/john/update-logging-example/use-logging-apis/js/app.bundle.js @@ -22537,101 +22537,78 @@ var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _openfin_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @openfin/core */ "../../node_modules/@openfin/core/out/mock.js"); -let fileName; -let debugLogStr; -let debugLogFile; -document.addEventListener("DOMContentLoaded", async () => { - try { - await initDom(); - } - catch (error) { - console.error(error); - } +const channelName = `${_openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.identity.uuid}-logger`; +let channelClient; +window.addEventListener("DOMContentLoaded", async () => { + const consoleLogBtn = document.querySelector("#console-app-log"); + if (consoleLogBtn) { + consoleLogBtn.addEventListener("click", consoleLogMessage); + } + const channelLogBtn = document.querySelector("#channel-app-log"); + if (channelLogBtn) { + channelLogBtn.addEventListener("click", channelLogMessage); + } + const clearPreviewBtn = document.querySelector("#clear-preview"); + if (clearPreviewBtn) { + clearPreviewBtn.addEventListener("click", clearPreview); + } + await setupChannelClient(); }); /** - * Populates DOM with the UI elements and adds listeners obtaining selected/submitted options. + * Sends a message to console log. */ -async function initDom() { - const logListElement = document.querySelector("#log-list"); - if (logListElement) { - await createLogDropDown(logListElement); - logListElement.addEventListener("change", async (selectionChangeEvent) => { - fileName = selectionChangeEvent.target.value; - }); - } - const upload = document.querySelector("#upload-form"); - if (upload) { - upload.addEventListener("submit", uploadHandler); +async function consoleLogMessage() { + const logPreview = document.querySelector("#preview"); + try { + const message = `Sending view console log message: ${Date.now()}`; + console.log(message); + if (logPreview) { + logPreview.textContent += ` +Console Logged the following message: +"${message}"`; + } } - const sendAppLogBtn = document.querySelector("#send-app-log"); - if (sendAppLogBtn) { - sendAppLogBtn.addEventListener("click", sendApplicationLogs); + catch (err) { + if (logPreview) { + logPreview.textContent += `Error console logging message: ${err.message}`; + } } } /** - * Handle uploads. - * 1. Creates a FormData object. - * 2. Creates a File object from the string of the Runtime debug log file contents. - * 3. Populates the FormData object with necessary parameters to be read by the server. - * 4. Uploads the created runtime debug log file to a server endpoint. - * @param submitEvent The event to handle. + * Sends a message to console log through the Channel API. */ -async function uploadHandler(submitEvent) { - submitEvent.preventDefault(); - if (!fileName) { - fileName = "debug.log"; - } - const formData = new FormData(); - debugLogStr = await getLogFromName(fileName); - debugLogFile = new File([debugLogStr], fileName, { type: "text/plain" }); - formData.append("file", debugLogFile); - formData.append("filename", fileName); - formData.append("uuid", _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.uuid); - const uploadState = await fetch("https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/uploads", { - method: "POST", - body: formData - }); - const uploadStateJson = await uploadState.json(); - const uploadStateJsonString = JSON.stringify(uploadStateJson, null, 5); - const logs = `${new Date().toLocaleTimeString()}: ${uploadStateJsonString}\n`; +async function channelLogMessage() { const logPreview = document.querySelector("#preview"); - if (logPreview) { - logPreview.textContent += logs; - } -} -/** - * Sends a message to the OpenFin RVM to send the application logs. - */ -async function sendApplicationLogs() { try { - const appLogResponse = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.Application.getCurrentSync().sendApplicationLog(); - console.log(`Log ID: ${appLogResponse.logId}`); + const message = `Sending view channel log message: ${Date.now()}`; + if (logPreview) { + logPreview.textContent += ` +Sending the following message through the Channel API: +"${message}"`; + } + await channelClient.dispatch("log", message); } - catch { - // swallow unnecessary errors. + catch (err) { + if (logPreview) { + logPreview.textContent += `Error sending message through Channel API: ${err.message}`; + } } } /** - * Retrieves the runtime debug log from a filename. - * @param name file name of the runtime debug log to retrieve. - * @returns the log content. + * Sets up the Channel Client. */ -async function getLogFromName(name) { - const log = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.System.getLog({ name }); - return log; +async function setupChannelClient() { + if (channelClient === undefined) { + channelClient = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.InterApplicationBus.Channel.connect(channelName); + } } /** - * Creates an HTMLOptionElement for each of the Runtime debug logs. - * @param parentElement HTML Element to append the log filename HTMLOptionElement to. + * Clears the preview log. */ -async function createLogDropDown(parentElement) { - const logList = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.System.getLogList(); - for (const log of logList) { - const logElement = document.createElement("option"); - logElement.id = log.date; - logElement.textContent = log.name; - logElement.value = log.name; - parentElement.append(logElement); +function clearPreview() { + const logPreview = document.querySelector("#preview"); + if (logPreview) { + logPreview.textContent = ""; } } @@ -22639,4 +22616,4 @@ async function createLogDropDown(parentElement) { /******/ })() ; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRUFBbUU7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxzQkFBc0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxzQkFBc0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxzQkFBc0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELHNCQUFzQjtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEVBQThFLFNBQVM7QUFDdkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLFNBQVM7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RCx5QkFBeUI7QUFDaEY7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRkFBb0YsU0FBUztBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsMENBQTBDO0FBQ25FO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qix5Q0FBeUM7QUFDbEU7QUFDQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRUFBK0UsU0FBUztBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRixTQUFTO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0ZBQWdGLFNBQVM7QUFDekY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELFdBQVc7QUFDM0Q7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxXQUFXO0FBQ3JEO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxpQ0FBaUM7QUFDMUU7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlGQUFpRixTQUFTO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRSxTQUFTO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLFNBQVM7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RCxTQUFTO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsU0FBUztBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxTQUFTO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxnQkFBZ0I7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0QsS0FBSztBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDRFQUE0RTtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSw4RUFBOEUsU0FBUztBQUN2RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFdBQVcsU0FBUztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQsa0NBQWtDO0FBQzlGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsa0RBQWtELGFBQWE7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSwrQ0FBK0MsYUFBYTtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsTUFBTTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsK0VBQStFLGtDQUFrQztBQUNqSDtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRCwwQkFBMEIsaURBQWlELE9BQU87QUFDckk7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCwwQkFBMEIsaURBQWlELE9BQU87QUFDdkk7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSx1REFBdUQsYUFBYTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJGQUEyRiwyQ0FBMkM7QUFDdEk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJGQUEyRiwyQ0FBMkM7QUFDdEk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGdEQUFnRCxhQUFhO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0EseURBQXlELGFBQWE7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsK0NBQStDO0FBQ3ZGO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMseUJBQXlCO0FBQ3pCO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxtSUFBbUkseUJBQXlCO0FBQzVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0VBQStFO0FBQy9FO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFJQUFxSSx5QkFBeUI7QUFDOUo7QUFDQSxnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7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O0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7O0FBRUEsa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7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ekIsVUFBVSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ2xDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQztRQUM1QixhQUFhLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7QUFDRixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvQG9wZW5maW4vY29yZS9vdXQvbW9jay5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fRGF0YVZpZXcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19IYXNoLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fTGlzdENhY2hlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fTWFwQ2FjaGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19Qcm9taXNlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fU2V0Q2FjaGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19TdGFjay5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX1N5bWJvbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX1VpbnQ4QXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19XZWFrTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlFYWNoLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlGaWx0ZXIuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheUxpa2VLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlQdXNoLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlTb21lLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXNzaWduVmFsdWUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19hc3NvY0luZGV4T2YuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlQXNzaWduLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnbkluLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnblZhbHVlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUNsb25lLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUNyZWF0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VHZXRBbGxLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUdldFRhZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0FyZ3VtZW50cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0VxdWFsLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzRXF1YWxEZWVwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTmF0aXZlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzVHlwZWRBcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUtleXNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VUaW1lcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VVbmFyeS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2NhY2hlSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVBcnJheUJ1ZmZlci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lQnVmZmVyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVEYXRhVmlldy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lUmVnRXhwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVTeW1ib2wuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jbG9uZVR5cGVkQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jb3B5QXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jb3B5T2JqZWN0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weVN5bWJvbHMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jb3B5U3ltYm9sc0luLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29yZUpzRGF0YS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2RlZmluZVByb3BlcnR5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxBcnJheXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19lcXVhbEJ5VGFnLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxPYmplY3RzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZnJlZUdsb2JhbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldEFsbEtleXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRBbGxLZXlzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRNYXBEYXRhLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TmF0aXZlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UHJvdG90eXBlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UmF3VGFnLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0U3ltYm9scy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFN5bWJvbHNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFRhZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFZhbHVlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaENsZWFyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaERlbGV0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hHZXQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19oYXNoSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaFNldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2luaXRDbG9uZUFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faW5pdENsb25lQnlUYWcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pbml0Q2xvbmVPYmplY3QuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pc0luZGV4LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faXNLZXlhYmxlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faXNNYXNrZWQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pc1Byb3RvdHlwZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUNsZWFyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlRGVsZXRlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlR2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVDbGVhci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlRGVsZXRlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVHZXQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZUhhcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwVG9BcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX25hdGl2ZUNyZWF0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX25hdGl2ZUtleXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19uYXRpdmVLZXlzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19ub2RlVXRpbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX29iamVjdFRvU3RyaW5nLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fb3ZlckFyZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3Jvb3QuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zZXRDYWNoZUFkZC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3NldENhY2hlSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0VG9BcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrQ2xlYXIuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja0RlbGV0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrR2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc3RhY2tIYXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja1NldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3RvU291cmNlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9jbG9uZURlZXAuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2VxLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0FyZ3VtZW50cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcnJheUxpa2UuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzQnVmZmVyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0VxdWFsLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0Z1bmN0aW9uLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0xlbmd0aC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNNYXAuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzT2JqZWN0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc09iamVjdExpa2UuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc1R5cGVkQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2tleXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2tleXNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvc3R1YkFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9zdHViRmFsc2UuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzL3dlYnBhY2svcnVudGltZS9nbG9iYWwiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvd2VicGFjay9ydW50aW1lL25vZGUgbW9kdWxlIGRlY29yYXRvciIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4vY2xpZW50L3NyYy9hcHAudHMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgcmVxdWlyZSQkMCA9IHJlcXVpcmUoJ2V2ZW50cycpO1xudmFyIHJlcXVpcmUkJDAkMSA9IHJlcXVpcmUoJ2xvZGFzaC9jbG9uZURlZXAnKTtcbnZhciByZXF1aXJlJCQzID0gcmVxdWlyZSgnbG9kYXNoL2lzRXF1YWwnKTtcblxuZnVuY3Rpb24gX21lcmdlTmFtZXNwYWNlcyhuLCBtKSB7XG5cdG0uZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuXHRcdGUgJiYgdHlwZW9mIGUgIT09ICdzdHJpbmcnICYmICFBcnJheS5pc0FycmF5KGUpICYmIE9iamVjdC5rZXlzKGUpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0XHRcdGlmIChrICE9PSAnZGVmYXVsdCcgJiYgIShrIGluIG4pKSB7XG5cdFx0XHRcdHZhciBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLCBrKTtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG4sIGssIGQuZ2V0ID8gZCA6IHtcblx0XHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZVtrXTsgfVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSk7XG5cdHJldHVybiBPYmplY3QuZnJlZXplKG4pO1xufVxuXG52YXIgY29tbW9uanNHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fTtcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHtcblx0cmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDtcbn1cblxudmFyIE9wZW5GaW4kMiA9IHt9O1xuXG52YXIgZXZlbnRzID0ge307XG5cbnZhciBhcHBsaWNhdGlvbiQxID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgdGhhdCBjYW4gYmUgZW1pdHRlZCBieSBhbiB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbn0uICBJbmNsdWRlcyBldmVudHNcbiAqIHJlLXByb3BhZ2F0ZWQgZnJvbSB0aGUge0BsaW5rIE9wZW5GaW4uV2luZG93fSAoYW5kLCB0cmFuc2l0aXZlbHksIHtAbGluayBPcGVuRmluLlZpZXd9KSBsZXZlbCwgcHJlZml4ZWQgd2l0aCBgd2luZG93LWAgKGFuZCBhbHNvLCBpZiBhcHBsaWNhYmxlLCBgdmlldy1gKS5cbiAqIEZvciBleGFtcGxlLCBhIHZpZXcncyBcImF0dGFjaGVkXCIgZXZlbnQgd2lsbCBmaXJlIGFzICd3aW5kb3ctdmlldy1hdHRhY2hlZCcgYXQgdGhlIGFwcGxpY2F0aW9uIGxldmVsLlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhpcyBuYW1lc3BhY2UgY29udGFpbnMgb25seSBwYXlsb2FkIHNoYXBlcyBmb3IgZXZlbnRzIHRoYXQgYXJlIHVuaXF1ZSB0byBgQXBwbGljYXRpb25gLiAgRXZlbnRzIHRoYXQgcHJvcGFnYXRlIHRvIGBBcHBsaWNhdGlvbmAgZnJvbVxuICogY2hpbGQge0BsaW5rIE9wZW5GaW4uV2luZG93IHdpbmRvd3N9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3IHZpZXdzfSBhcmUgZGVmaW5lZCBpbiB0aGUge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfSBhbmRcbiAqIHtAbGluayBPcGVuRmluLlZpZXdFdmVudHN9IG5hbWVzcGFjZXMuICBGb3IgYSBsaXN0IG9mIHZhbGlkIHN0cmluZyBrZXlzIGZvciAqYWxsKiBhcHBsaWNhdGlvbiBldmVudHMsIHNlZSB7QGxpbmsgQXBwbGljYXRpb24ub24gQXBwbGljYXRpb24ub259LlxuICpcbiAqIHtAbGluayBBcHBsaWNhdGlvblNvdXJjZWRFdmVudCBBcHBsaWNhdGlvbi1zb3VyY2VkIGV2ZW50c30gKGkuZS4gdGhvc2UgdGhhdCBoYXZlIG5vdCBwcm9wYWdhdGVkIGZyb20ge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3c31cbiAqIG9yIHtAbGluayBPcGVuRmluLldpbmRvd0V2ZW50cyBXaW5kb3dzfSByZS1wcm9wYWdhdGUgdG8ge0BsaW5rIE9wZW5GaW4uU3lzdGVtRXZlbnRzIFN5c3RlbX0gd2l0aCB0aGVpciB0eXBlIHN0cmluZyBwcmVmaXhlZCB3aXRoIGBhcHBsaWNhdGlvbi1gLlxuICoge0BsaW5rIEFwcGxpY2F0aW9uV2luZG93RXZlbnQgQXBwbGljYXRpb24gZXZlbnRzIHRoYXQgYXJlIHRpZWQgdG8gV2luZG93cyBidXQgZG8gbm90IHByb3BhZ2F0ZSBmcm9tIHRoZW19XG4gKiBhcmUgcHJvcGFnYXRlZCB0byBgU3lzdGVtYCB3aXRob3V0IGFueSB0eXBlIHN0cmluZyBwcmVmaXhpbmcuXG4gKlxuICogXCJSZXF1ZXN0ZWRcIiBldmVudHMgKGUuZy4ge0BsaW5rIFJ1blJlcXVlc3RlZEV2ZW50fSkgZG8gbm90IHByb3BhZ2F0ZS5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcGxpY2F0aW9uJDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgYmFzZSQxID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBzaGFyZWQgZXZlbnQgcGF5bG9hZHMgYW5kIHV0aWxpdHkgdHlwZXMgY29tbW9uIHRvIGFsbCBldmVudCBlbWl0dGVycy5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGJhc2UkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBleHRlcm5hbEFwcGxpY2F0aW9uJDEgPSB7fTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBiZSB0cmFuc21pdHRlZCBieSBhbiB7QGxpbmsgT3BlbkZpbi5FeHRlcm5hbEFwcGxpY2F0aW9ufS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yIGV4dGVybmFsIGFwcGxpY2F0aW9uIGV2ZW50cywgc2VlIHtAbGluayBFeHRlcm5hbEFwcGxpY2F0aW9uLm9uIEV4dGVybmFsQXBwbGljYXRpb24ub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXh0ZXJuYWxBcHBsaWNhdGlvbiQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIGZyYW1lJDEgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGZyYW1lJDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgZ2xvYmFsSG90a2V5JDEgPSB7fTtcblxuLyoqXG4gKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgdGhhdCBjYW4gYmUgdHJhbnNtaXR0ZWQgYnkge0BsaW5rIEdsb2JhbEhvdGtleS5HbG9iYWxIb3RrZXl9LlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogRm9yIGEgbGlzdCBvZiB2YWxpZCBzdHJpbmcga2V5cyBmb3IgZ2xvYmFsIGhvdGtleSBldmVudHMsIHNlZSB7QGxpbmsgR2xvYmFsSG90a2V5Lkdsb2JhbEhvdGtleS5vbiBHbG9iYWxIb3RrZXkub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsSG90a2V5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgcGxhdGZvcm0kMSA9IHt9O1xuXG4vKipcbiAqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBlbWl0dGVkIGJ5IGEge0BsaW5rIE9wZW5GaW4uUGxhdGZvcm19LlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhlIFBsYXRmb3JtIGBFdmVudEVtaXR0ZXJgIGlzIGEgc3VwZXJzZXQgb2YgdGhlIHtAbGluayBPcGVuRmluLkFwcGxpY2F0aW9ufSBgRXZlbnRFbWl0dGVyYCxcbiAqIG1lYW5pbmcgaXQgY2FuIGxpc3RlbiB0byBhbGwge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb25FdmVudHMgQXBwbGljYXRpb24gZXZlbnRzfSBpbiBhZGRpdGlvbiB0byB0aGVcbiAqIFBsYXRmb3JtLXNwZWNpZmljIGV2ZW50cyBsaXN0ZWQgaGVyZS4gIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIHBsYXRmb3JtIGV2ZW50cywgc2VlXG4gKiB7QGxpbmsgUGxhdGZvcm0ub24gUGxhdGZvcm0ub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkocGxhdGZvcm0kMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBzeXN0ZW0kMSA9IHt9O1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgcnVudGltZS13aWRlIE9wZW5GaW4gZXZlbnRzIGVtaXR0ZWQgYnkge0BsaW5rIFN5c3RlbS5TeXN0ZW19LiAgSW5jbHVkZXMgZXZlbnRzXG4gKiByZS1wcm9wYWdhdGVkIGZyb20ge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259LCB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9LCBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30gKHByZWZpeGVkIHdpdGggYGFwcGxpY2F0aW9uLWAsIGB3aW5kb3ctYCwgYW5kIGB2aWV3LWApLiAgQWxsXG4gKiBldmVudCBwcm9wYWdhdGlvbnMgYXJlIHZpc2libGUgYXQgdGhlIFN5c3RlbSBsZXZlbC4gUHJvcGFnYXRlZCBldmVudHMgZnJvbSBXZWJDb250ZW50cyAod2luZG93cywgdmlld3MsIGZyYW1lcykgdG8gdGhlIEFwcGxpY2F0aW9uIGxldmVsIHdpbGwgKm5vdCpcbiAqIHRyYW5zaXRpdmVseSByZS1wcm9wYWdhdGUgdG8gdGhlIFN5c3RlbSBsZXZlbCwgYmVjYXVzZSB0aGV5IGFyZSBhbHJlYWR5IHZpc2libGUgYXQgdGhlIHN5c3RlbSBsZXZlbCBhbmQgY29udGFpbiB0aGUgaWRlbnRpdHlcbiAqIG9mIHRoZSBhcHBsaWNhdGlvbi4gIEZvciBleGFtcGxlLCBhbiBhcHBsaWNhdGlvbidzIFwiY2xvc2VkXCIgZXZlbnQgd2lsbCBmaXJlIGFzICdhcHBsaWNhdGlvbi1jbG9zZWQnIGF0IHRoZSBzeXN0ZW0gbGV2ZWwuICBBIHZpZXcncyAnc2hvd24nIGV2ZW50XG4gKiB3aWxsIGJlIHZpc2libGUgYXMgJ3ZpZXctc2hvd24nIGF0IHRoZSBzeXN0ZW0gbGV2ZWwsIGJ1dCAqbm90KiBhcyBgYXBwbGljYXRpb24td2luZG93LXZpZXctc2hvd25gLlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhpcyBuYW1lc3BhY2UgY29udGFpbnMgb25seSBwYXlsb2FkIHNoYXBlcyBmb3IgZXZlbnRzIHRoYXQgYXJlIHVuaXF1ZSB0byBgU3lzdGVtYC4gIEV2ZW50cyB0aGF0IHByb3BhZ2F0ZSB0byBgU3lzdGVtYCBmcm9tXG4gKiBjaGlsZCB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbiBhcHBsaWNhdGlvbnN9LCB7QGxpbmsgT3BlbkZpbi5XaW5kb3cgd2luZG93c30sIGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3IHZpZXdzfSBhcmUgZGVmaW5lZCBpbiB0aGVcbiAqIHtAbGluayBPcGVuRmluLkFwcGxpY2F0aW9uRXZlbnRzfSwge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfSwgYW5kIHtAbGluayBPcGVuRmluLlZpZXdFdmVudHN9IG5hbWVzcGFjZXMuICBGb3IgYSBsaXN0IG9mIHZhbGlkIHN0cmluZyBrZXlzIGZvciAqYWxsKlxuICogc3lzdGVtIGV2ZW50cywgc2VlIHtAbGluayBTeXN0ZW0ub24gU3lzdGVtLm9ufS5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN5c3RlbSQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIHZpZXckMSA9IHt9O1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgZXZlbnRzIHRoYXQgY2FuIGJlIGVtaXR0ZWQgYnkgYSB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIFRoaXMgbmFtZXNwYWNlIGNvbnRhaW5zIG9ubHkgcGF5bG9hZCBzaGFwZXMgZm9yIGV2ZW50cyB0aGF0IGFyZSB1bmlxdWUgdG8gYFZpZXdgLiAgRXZlbnRzIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIGFsbCBgV2ViQ29udGVudHNgXG4gKiAoaS5lLiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9LCB7QGxpbmsgT3BlbkZpbi5WaWV3fSkgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHN9LiAgRm9yIGEgbGlzdFxuICogb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIFZpZXcgZXZlbnRzLCBzZWUge0BsaW5rIFZpZXcub24gVmlldy5vbn0uXG4gKlxuICogVmlldyBldmVudHMgcHJvcGFnYXRlIHRvIHRoZWlyIHBhcmVudCB7QGxpbmsgT3BlbkZpbi5XaW5kb3dFdmVudHMgV2luZG93fSwge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb25FdmVudHMgQXBwbGljYXRpb259LFxuICogYW5kIHtAbGluayBPcGVuRmluLlN5c3RlbUV2ZW50cyBTeXN0ZW19IHdpdGggYW4gYWRkZWQgYHZpZXdJZGVudGl0eWAgcHJvcGVydHkgYW5kIHRoZWlyIGV2ZW50IHR5cGVzIHByZWZpeGVkIHdpdGggYCd2aWV3LSdgLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodmlldyQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIHdlYmNvbnRlbnRzID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgc2hhcmVkIGJ5IGFsbCBPcGVuRmluIFdlYkNvbnRlbnRzIGVsZW1lbnRzIChpLmUuIHtAbGluayBPcGVuRmluLldpbmRvd30sXG4gKiB7QGxpbmsgT3BlbkZpbi5WaWV3fSkuXG4gKlxuICogV2ViQ29udGVudHMgZXZlbnRzIHdpbGwgcmUtZW1pdCBvbiBwYXJlbnQgZW50aXRpZXMgLSBlLmcuLCBhIHByb3BhZ2F0aW5nIGV2ZW50IGluIGEgdmlldyB3aWxsIGFsc28gYmUgZW1pdHRlZCBvbiB0aGUgdmlldydzXG4gKiBwYXJlbnQgd2luZG93LCBhbmQgcHJvcGFnYXRpbmcgZXZlbnRzIGluIGEgd2luZG93IHdpbGwgYWxzbyBiZSBlbWl0dGVkIG9uIHRoZSB3aW5kb3cncyBwYXJlbnQge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2ViY29udGVudHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgd2luZG93JDIgPSB7fTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBiZSBlbWl0dGVkIGJ5IGEge0BsaW5rIE9wZW5GaW4uV2luZG93fS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIFRoaXMgbmFtZXNwYWNlIGNvbnRhaW5zIG9ubHkgcGF5bG9hZCBzaGFwZXMgZm9yIGV2ZW50cyB0aGF0IGFyZSB1bmlxdWUgdG8gYFdpbmRvd2AuICBFdmVudHMgdGhhdCBhcmUgc2hhcmVkIGJldHdlZW4gYWxsIGBXZWJDb250ZW50c2BcbiAqIChpLmUuIHtAbGluayBPcGVuRmluLldpbmRvd30sIHtAbGluayBPcGVuRmluLlZpZXd9KSBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50c30uIEV2ZW50cyB0aGF0XG4gKiBwcm9wYWdhdGUgZnJvbSBgVmlld2AgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50c30uIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIFdpbmRvdyBldmVudHMsIHNlZVxuICoge0BsaW5rIFdpbmRvdy5vbiBXaW5kb3cub259XG4gKlxuICoge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzLldpbmRvd1NvdXJjZWRFdmVudCBXaW5kb3ctc291cmNlZCBldmVudHN9IChpLmUuIHRob3NlIHRoYXQgYXJlIG5vdCBwcm9wYWdhdGVkIGZyb20gYVxuICoge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3fSkgcHJvcGFnYXRlIHRvIHRoZWlyIHBhcmVudCB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50cyBBcHBsaWNhdGlvbn0gYW5kXG4gKiB7QGxpbmsgT3BlbkZpbi5TeXN0ZW1FdmVudHMgU3lzdGVtfSB3aXRoIHRoZWlyIGV2ZW50IHR5cGVzIHByZWZpeGVkIHdpdGggYCd3aW5kb3ctJ2ApLlxuICpcbiAqIFwiUmVxdWVzdGVkXCIgZXZlbnRzIChlLmcuIHtAbGluayBBdXRoUmVxdWVzdGVkRXZlbnR9KSBkbyBub3QgcHJvcGFnYXRlIHRvIGBTeXN0ZW0uICBUaGUge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzLldpbmRvd0Nsb3NlUmVxdWVzdGVkRXZlbnR9XG4gKiBkb2VzIG5vdCBwcm9wYWdhdGUgYXQgYWxsLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgT3BlbkZpbiBldmVudCB0eXBlcy4gRWFjaCBlbnRpdHkgdGhhdCBlbWl0cyBPcGVuRmluIGV2ZW50cyBoYXMgaXRzIG93biBzdWItbmFtZXNwYWNlLiBFdmVudCBwYXlsb2Fkc1xuICogdGhlbXNlbHZlcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqXG4gKiAjIyMjIEV2ZW50IGVtaXR0ZXJzXG4gKlxuICogVGhlIGZvbGxvd2luZyBlbnRpdGllcyBlbWl0IE9wZW5GaW4gZXZlbnRzLCBhbmQgaGF2ZSBjb3JyZXNwb25kaW5nIHN1Yi1uYW1lc3BhY2VzOlxuICpcbiAqICoge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259OiB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbn06IHtAbGluayBPcGVuRmluLkV4dGVybmFsQXBwbGljYXRpb25FdmVudHN9XG4gKiAqIHtAbGluayBPcGVuRmluLkZyYW1lfToge0BsaW5rIE9wZW5GaW4uRnJhbWVFdmVudHN9XG4gKiAqIHtAbGluayBPcGVuRmluLkdsb2JhbEhvdGtleX06IHtAbGluayBPcGVuRmluLkdsb2JhbEhvdGtleUV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uUGxhdGZvcm19OiB7QGxpbmsgT3BlbkZpbi5QbGF0Zm9ybUV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uU3lzdGVtfToge0BsaW5rIE9wZW5GaW4uU3lzdGVtRXZlbnRzfVxuICogKiB7QGxpbmsgT3BlbkZpbi5WaWV3fToge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uV2luZG93fToge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfVxuICpcbiAqIFRoZXNlIGBFdmVudEVtaXR0ZXJgIGVudGl0aWVzIHNoYXJlIGEgY29tbW9uIHNldCBvZiBtZXRob2RzIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBPcGVuRmluIGV2ZW50IGJ1cywgd2hpY2ggY2FuIGJlXG4gKiBzZWVuIG9uIHRoZSBpbmRpdmlkdWFsIGRvY3VtZW50YXRpb24gcGFnZXMgZm9yIGVhY2ggZW50aXR5IHR5cGUuXG4gKlxuICogUmVnaXN0ZXJpbmcgZXZlbnQgaGFuZGxlcnMgaXMgYW4gYXN5bmNocm9ub3VzIG9wZXJhdGlvbi4gSXQgaXMgaW1wb3J0YW50IHRvIGVuc3VyZSB0aGF0IHRoZSByZXR1cm5lZCBQcm9taXNlcyBhcmUgYXdhaXRlZCB0byByZWR1Y2UgdGhlXG4gKiByaXNrIG9mIHJhY2UgY29uZGl0aW9ucy5cbiAqXG4gKiBXaGVuIHRoZSBgRXZlbnRFbWl0dGVyYCByZWNlaXZlcyBhbiBldmVudCBmcm9tIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIGVtaXRzIG9uIHRoZSByZW5kZXJlciwgYWxsIG9mIHRoZSBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhhdFxuICogc3BlY2lmaWMgZXZlbnQgYXJlIGNhbGxlZCBzeW5jaHJvbm91c2x5LiBBbnkgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsZWQgbGlzdGVuZXJzIGFyZSBpZ25vcmVkIGFuZCB3aWxsIGJlIGRpc2NhcmRlZC4gIElmIHRoZSB3aW5kb3cgZG9jdW1lbnRcbiAqIGlzIGRlc3Ryb3llZCBieSBwYWdlIG5hdmlnYXRpb24gb3IgcmVsb2FkLCBpdHMgcmVnaXN0ZXJlZCBldmVudCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICpcbiAqIFdlIHJlY29tbWVuZCB1c2luZyBBcnJvdyBGdW5jdGlvbnMgZm9yIGV2ZW50IGxpc3RlbmVycyB0byBlbnN1cmUgdGhlIHRoaXMgc2NvcGUgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBjb250ZXh0LlxuICpcbiAqIEV2ZW50cyByZS1wcm9wYWdhdGUgZnJvbSBzbWFsbGVyL21vcmUtbG9jYWwgc2NvcGVzIHRvIGxhcmdlci9tb3JlLWdsb2JhbCBzY29wZXMuICBGb3IgZXhhbXBsZSwgYW4gZXZlbnQgZW1pdHRlZCBvbiBhIHNwZWNpZmljXG4gKiB2aWV3IHdpbGwgcHJvcGFnYXRlIHRvIHRoZSB3aW5kb3cgaW4gd2hpY2ggdGhlIHZpZXcgaXMgZW1iZWRkZWQsIGFuZCB0aGVuIHRvIHRoZSBhcHBsaWNhdGlvbiBpbiB3aGljaCB0aGUgd2luZG93IGlzIHJ1bm5pbmcsIGFuZFxuICogZmluYWxseSB0byB0aGUgT3BlbkZpbiBydW50aW1lIGl0c2VsZiBhdCB0aGUgXCJzeXN0ZW1cIiBsZXZlbC4gIEZvciBkZXRhaWxzIG9uIHByb3BhZ2F0aW9uIHNlbWFudGljcywgc2VlIHRoZSBuYW1lc3BhY2UgZm9yXG4gKiB0aGUgcHJvcGFnYXRpbmcgKG9yIHByb3BhZ2F0ZWQtdG8pIGVudGl0eS5cbiAqXG4gKiBJZiB5b3UgbmVlZCB0aGUgcGF5bG9hZCB0eXBlIGZvciBhIHNwZWNpZmljIHR5cGUgb2YgZXZlbnQgKGVzcGVjaWFsbHkgcHJvcGFnYXRlZCBldmVudHMpLCB1c2UgdGhlIGVtaXR0aW5nIHRvcGljJ3MgYFBheWxvYWRgIGdlbmVyaWNcbiAqIChlLmcuIHtAbGluayBXaW5kb3dFdmVudHMuUGF5bG9hZH0pIHdpdGggdGhlIGV2ZW50J3MgYHR5cGVgIHN0cmluZy4gIEZvciBleGFtcGxlLCB0aGUgcGF5bG9hZCBvZlxuICogYSB7QGxpbmsgVmlld0V2ZW50cy5DcmVhdGVkRXZlbnR9IGFmdGVyIGl0IGhhcyBwcm9wYWdhdGVkIHRvIGl0cyBwYXJlbnQge0BsaW5rIFdpbmRvd0V2ZW50cyBXaW5kb3d9IGNhbiBiZSBmb3VuZCB3aXRoXG4gKiBgV2luZG93RXZlbnRzLlBheWxvYWQ8J3ZpZXctY3JlYXRlZCc+YC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xudmFyIF9fY3JlYXRlQmluZGluZyQxID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19zZXRNb2R1bGVEZWZhdWx0JDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xufSkgOiBmdW5jdGlvbihvLCB2KSB7XG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xufSk7XG52YXIgX19pbXBvcnRTdGFyJDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnRTdGFyKSB8fCBmdW5jdGlvbiAobW9kKSB7XG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmckMShyZXN1bHQsIG1vZCwgayk7XG4gICAgX19zZXRNb2R1bGVEZWZhdWx0JDEocmVzdWx0LCBtb2QpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV2ZW50cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5ldmVudHMuV2luZG93RXZlbnRzID0gZXZlbnRzLldlYkNvbnRlbnRzRXZlbnRzID0gZXZlbnRzLlZpZXdFdmVudHMgPSBldmVudHMuU3lzdGVtRXZlbnRzID0gZXZlbnRzLlBsYXRmb3JtRXZlbnRzID0gZXZlbnRzLkdsb2JhbEhvdGtleUV2ZW50cyA9IGV2ZW50cy5GcmFtZUV2ZW50cyA9IGV2ZW50cy5FeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzID0gZXZlbnRzLkJhc2VFdmVudHMgPSBldmVudHMuQXBwbGljYXRpb25FdmVudHMgPSB2b2lkIDA7XG5jb25zdCBBcHBsaWNhdGlvbkV2ZW50cyA9IF9faW1wb3J0U3RhciQxKGFwcGxpY2F0aW9uJDEpO1xuZXZlbnRzLkFwcGxpY2F0aW9uRXZlbnRzID0gQXBwbGljYXRpb25FdmVudHM7XG5jb25zdCBCYXNlRXZlbnRzID0gX19pbXBvcnRTdGFyJDEoYmFzZSQxKTtcbmV2ZW50cy5CYXNlRXZlbnRzID0gQmFzZUV2ZW50cztcbmNvbnN0IEV4dGVybmFsQXBwbGljYXRpb25FdmVudHMgPSBfX2ltcG9ydFN0YXIkMShleHRlcm5hbEFwcGxpY2F0aW9uJDEpO1xuZXZlbnRzLkV4dGVybmFsQXBwbGljYXRpb25FdmVudHMgPSBFeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzO1xuY29uc3QgRnJhbWVFdmVudHMgPSBfX2ltcG9ydFN0YXIkMShmcmFtZSQxKTtcbmV2ZW50cy5GcmFtZUV2ZW50cyA9IEZyYW1lRXZlbnRzO1xuY29uc3QgR2xvYmFsSG90a2V5RXZlbnRzID0gX19pbXBvcnRTdGFyJDEoZ2xvYmFsSG90a2V5JDEpO1xuZXZlbnRzLkdsb2JhbEhvdGtleUV2ZW50cyA9IEdsb2JhbEhvdGtleUV2ZW50cztcbmNvbnN0IFBsYXRmb3JtRXZlbnRzID0gX19pbXBvcnRTdGFyJDEocGxhdGZvcm0kMSk7XG5ldmVudHMuUGxhdGZvcm1FdmVudHMgPSBQbGF0Zm9ybUV2ZW50cztcbmNvbnN0IFN5c3RlbUV2ZW50cyA9IF9faW1wb3J0U3RhciQxKHN5c3RlbSQxKTtcbmV2ZW50cy5TeXN0ZW1FdmVudHMgPSBTeXN0ZW1FdmVudHM7XG5jb25zdCBWaWV3RXZlbnRzID0gX19pbXBvcnRTdGFyJDEodmlldyQxKTtcbmV2ZW50cy5WaWV3RXZlbnRzID0gVmlld0V2ZW50cztcbmNvbnN0IFdlYkNvbnRlbnRzRXZlbnRzID0gX19pbXBvcnRTdGFyJDEod2ViY29udGVudHMpO1xuZXZlbnRzLldlYkNvbnRlbnRzRXZlbnRzID0gV2ViQ29udGVudHNFdmVudHM7XG5jb25zdCBXaW5kb3dFdmVudHMgPSBfX2ltcG9ydFN0YXIkMSh3aW5kb3ckMik7XG5ldmVudHMuV2luZG93RXZlbnRzID0gV2luZG93RXZlbnRzO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0LyoqXG5cdCAqIFRvcC1sZXZlbCBuYW1lc3BhY2UgZm9yIHR5cGVzIHJlZmVyZW5jZWQgYnkgdGhlIE9wZW5GaW4gQVBJLiAgQ29udGFpbnM6XG5cdCAqXG5cdCAqICogVGhlIHR5cGUgb2YgdGhlIGdsb2JhbCBgZmluYCBlbnRyeSBwb2ludCAoe0BsaW5rIEZpbkFwaX0pXG5cdCAqICogQ2xhc3NlcyB0aGF0IGFjdCBhcyBzdGF0aWMgbmFtZXNwYWNlcyByZXR1cm5lZCBmcm9tIHRoZSBgZmluYCBnbG9iYWwgKGUuZy4ge0BsaW5rIEFwcGxpY2F0aW9uTW9kdWxlfSwgYWNjZXNzaWJsZSB2aWEgYGZpbi5BcHBsaWNhdGlvbmApXG5cdCAqICogSW5zdGFuY2UgY2xhc3NlcyB0aGF0IGFyZSByZXR1cm5lZCBmcm9tIEFQSSBjYWxscyAoZS5nLiB7QGxpbmsgQXBwbGljYXRpb259LCBhY2Nlc3NpYmxlIHZpYSBgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKClgKVxuXHQgKiAqIFBhcmFtZXRlciBzaGFwZXMgZm9yIEFQSSBtZXRob2RzIChlLmcuIHtAbGluayBBcHBsaWNhdGlvbk9wdGlvbnN9LCB1c2VkIGluIGBmaW4uQXBwbGljYXRpb24uc3RhcnQoKWApXG5cdCAqICogRXZlbnQgbmFtZXNwYWNlcyBhbmQgcGF5bG9hZCB1bmlvbiB0eXBlcyAoZS5nLiB7QGxpbmsgQXBwbGljYXRpb25FdmVudHN9IGFuZCB7QGxpbmsgQXBwbGljYXRpb25FdmVudH0pXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0Ly8gRGVwcmVjYXRlZCBzaGltIHRvIHByZXNlcnZlIHYzMCBuYW1lc3BhY2UgbmFtZXNcblx0X19leHBvcnRTdGFyKGV2ZW50cywgZXhwb3J0cyk7IFxufSAoT3BlbkZpbiQyKSk7XG5cbnZhciBPcGVuRmluID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKE9wZW5GaW4kMik7XG5cbnZhciBPcGVuRmluJDEgPSAvKiNfX1BVUkVfXyovX21lcmdlTmFtZXNwYWNlcyh7XG5cdF9fcHJvdG9fXzogbnVsbCxcblx0ZGVmYXVsdDogT3BlbkZpblxufSwgW09wZW5GaW4kMl0pO1xuXG52YXIgZmluJDIgPSB7fTtcblxudmFyIHN5c3RlbSA9IHt9O1xuXG52YXIgYmFzZSA9IHt9O1xuXG52YXIgcHJvbWlzZXMgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2VzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnByb21pc2VzLnByb21pc2VNYXBTZXJpYWwgPSBwcm9taXNlcy5zZXJpYWwgPSBwcm9taXNlcy5wcm9taXNlTWFwID0gcHJvbWlzZXMucHJvbWlzaWZ5ID0gdm9pZCAwO1xuZnVuY3Rpb24gcHJvbWlzaWZ5KGZ1bmMpIHtcbiAgICByZXR1cm4gKC4uLmFyZ3MpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgZnVuYyguLi5hcmdzLCAoZXJyLCB2YWwpID0+IChlcnIgPyByZWplY3QoZXJyKSA6IHJlc29sdmUodmFsKSkpO1xuICAgIH0pO1xufVxucHJvbWlzZXMucHJvbWlzaWZ5ID0gcHJvbWlzaWZ5O1xuYXN5bmMgZnVuY3Rpb24gcHJvbWlzZU1hcChhcnIsIGFzeW5jRikge1xuICAgIHJldHVybiBQcm9taXNlLmFsbChhcnIubWFwKGFzeW5jRikpO1xufVxucHJvbWlzZXMucHJvbWlzZU1hcCA9IHByb21pc2VNYXA7XG5hc3luYyBmdW5jdGlvbiBzZXJpYWwoYXJyKSB7XG4gICAgY29uc3QgcmV0ID0gW107XG4gICAgZm9yIChjb25zdCBmdW5jIG9mIGFycikge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgICAgICBjb25zdCBuZXh0ID0gYXdhaXQgZnVuYygpO1xuICAgICAgICByZXQucHVzaChuZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cbnByb21pc2VzLnNlcmlhbCA9IHNlcmlhbDtcbmFzeW5jIGZ1bmN0aW9uIHByb21pc2VNYXBTZXJpYWwoYXJyLCBmdW5jKSB7XG4gICAgcmV0dXJuIHNlcmlhbChhcnIubWFwKCh2YWx1ZSwgaW5kZXgsIGFycmF5KSA9PiAoKSA9PiBmdW5jKHZhbHVlLCBpbmRleCwgYXJyYXkpKSk7XG59XG5wcm9taXNlcy5wcm9taXNlTWFwU2VyaWFsID0gcHJvbWlzZU1hcFNlcmlhbDtcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRlID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX0VtaXR0ZXJCYXNlX2VtaXR0ZXJBY2Nlc3Nvcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShiYXNlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmJhc2UuUmVwbHkgPSBiYXNlLkVtaXR0ZXJCYXNlID0gYmFzZS5CYXNlID0gdm9pZCAwO1xuY29uc3QgcHJvbWlzZXNfMSA9IHByb21pc2VzO1xuY2xhc3MgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEBkZXByZWNhdGVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzTm9kZUVudmlyb25tZW50ID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5lbnZpcm9ubWVudC50eXBlID09PSAnbm9kZSc7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAaW50ZXJuYWxcbiAgICAgICAgICogQGRlcHJlY2F0ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNPcGVuRmluRW52aXJvbm1lbnQgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgPT09ICdvcGVuZmluJztcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc0Jyb3dzZXJFbnZpcm9ubWVudCA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQudHlwZSA9PT0gJ290aGVyJztcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy53aXJlID0gd2lyZTtcbiAgICB9XG4gICAgZ2V0IGZpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5nZXRGaW4oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBPcGVuRmluIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IGNvZGUgY29udGV4dCAodXN1YWxseSBhIGRvY3VtZW50XG4gICAgICogc3VjaCBhcyBhIHtAbGluayBPcGVuRmluLlZpZXd9IG9yIHtAbGluayBPcGVuRmluLldpbmRvd30pLCBhcyB3ZWxsIGFzIHRvIHRoZSBjdXJyZW50IGBJbnRlcm9wYCBjb250ZXh0LlxuICAgICAqXG4gICAgICogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgaW4gdGhlIGRldnRvb2xzIGNvbnNvbGUsIHdoZXJlIHRoaXMgd2lsbCBpbnRlbGxpZ2VudGx5IHR5cGUgaXRzZWxmIGJhc2VkXG4gICAgICogb24gdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlIGRldnRvb2xzIHBhbmVsIHdhcyBvcGVuZWQuXG4gICAgICovXG4gICAgZ2V0IG1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLm1lO1xuICAgIH1cbn1cbmJhc2UuQmFzZSA9IEJhc2U7XG4vKipcbiAqIEFuIGVudGl0eSB0aGF0IGVtaXRzIE9wZW5GaW4gZXZlbnRzLlxuICpcbiAqIEByZW1hcmtzIEV2ZW50LWJpbmRpbmcgbWV0aG9kcyBhcmUgYXN5bmNocm9ub3VzIGFzIHRoZXkgbXVzdCBjcm9zcyBwcm9jZXNzIGJvdW5kYXJpZXNcbiAqIGFuZCBzZXR1cCB0aGUgbGlzdGVuZXIgaW4gdGhlIGJyb3dzZXIgcHJvY2Vzcy4gIFdoZW4gdGhlIGBFdmVudEVtaXR0ZXJgIHJlY2VpdmVzIGFuIGV2ZW50IGZyb20gdGhlIGJyb3dzZXIgcHJvY2Vzc1xuICogYW5kIGVtaXRzIG9uIHRoZSByZW5kZXJlciwgYWxsIG9mIHRoZSBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhhdCBzcGVjaWZpYyBldmVudCBhcmUgY2FsbGVkIHN5bmNocm9ub3VzbHkuICBBbnkgdmFsdWVzXG4gKiByZXR1cm5lZCBieSB0aGUgY2FsbGVkIGxpc3RlbmVycyBhcmUgaWdub3JlZCBhbmQgd2lsbCBiZSBkaXNjYXJkZWQuICBJZiB0aGUgZXhlY3V0aW9uIGNvbnRleHQgb2YgdGhlIHdpbmRvdyBpcyBkZXN0cm95ZWRcbiAqIGJ5IHBhZ2UgbmF2aWdhdGlvbiBvciByZWxvYWQsIGFueSBldmVudHMgdGhhdCBoYXZlIGJlZW4gc2V0dXAgaW4gdGhhdCBjb250ZXh0IHdpbGwgYmUgZGVzdHJveWVkLlxuICpcbiAqIEl0IGlzIGltcG9ydGFudCB0byBrZWVwIGluIG1pbmQgdGhhdCB3aGVuIGFuIG9yZGluYXJ5IGxpc3RlbmVyIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhlIHN0YW5kYXJkIGB0aGlzYCBrZXl3b3JkIGlzIGludGVudGlvbmFsbHlcbiAqIHNldCB0byByZWZlcmVuY2UgdGhlIGBFdmVudEVtaXR0ZXJgIGluc3RhbmNlIHRvIHdoaWNoIHRoZSBsaXN0ZW5lciBpcyBhdHRhY2hlZC4gIEl0IGlzIHBvc3NpYmxlIHRvIHVzZSBFUzYgQXJyb3cgRnVuY3Rpb25zIGFzXG4gKiBsaXN0ZW5lcnMsIGhvd2V2ZXIsIHdoZW4gZG9pbmcgc28sIHRoZSBgdGhpc2Aga2V5d29yZCB3aWxsIG5vIGxvbmdlciByZWZlcmVuY2UgdGhlIGBFdmVudEVtaXR0ZXJgIGluc3RhbmNlLlxuICpcbiAqIEV2ZW50cyByZS1wcm9wYWdhdGUgZnJvbSBzbWFsbGVyL21vcmUtbG9jYWwgc2NvcGVzIHRvIGxhcmdlci9tb3JlLWdsb2JhbCBzY29wZXMuICBGb3IgZXhhbXBsZSwgYW4gZXZlbnQgZW1pdHRlZCBvbiBhIHNwZWNpZmljXG4gKiB2aWV3IHdpbGwgcHJvcGFnYXRlIHRvIHRoZSB3aW5kb3cgaW4gd2hpY2ggdGhlIHZpZXcgaXMgZW1iZWRkZWQsIGFuZCB0aGVuIHRvIHRoZSBhcHBsaWNhdGlvbiBpbiB3aGljaCB0aGUgd2luZG93IGlzIHJ1bm5pbmcsIGFuZFxuICogZmluYWxseSB0byB0aGUgT3BlbkZpbiBydW50aW1lIGl0c2VsZiBhdCB0aGUgXCJzeXN0ZW1cIiBsZXZlbC4gIFJlLXByb3BhZ2F0ZWQgZXZlbnRzIGFyZSBwcmVmaXhlZCB3aXRoIHRoZSBuYW1lIG9mIHRoZSBzY29wZSBpbiB3aGljaFxuICogdGhleSBvcmlnaW5hdGVkIC0gZm9yIGV4YW1wbGUsIGEgXCJzaG93blwiIGV2ZW50IGVtaXR0ZWQgb24gYSB2aWV3IHdpbGwgYmUgcmUtcHJvcGFnYXRlZCBhdCB0aGUgd2luZG93IGxldmVsIGFzIFwidmlldy1zaG93blwiLCBhbmRcbiAqIHRoZW4gdG8gdGhlIGFwcGxpY2F0aW9uIGFzIFwid2luZG93LXZpZXctc2hvd25cIiwgYW5kIGZpbmFsbHkgYXQgdGhlIHN5c3RlbSBsZXZlbCBhcyBcImFwcGxpY2F0aW9uLXdpbmRvdy12aWV3LXNob3duXCIuXG4gKlxuICogQWxsIGV2ZW50IHByb3BhZ2F0aW9ucyBhcmUgdmlzaWJsZSBhdCB0aGUgU3lzdGVtIGxldmVsLCByZWdhcmRsZXNzIG9mIHNvdXJjZSwgc28gdHJhbnNpdGl2ZSByZS1wcm9wYWdhdGlvbnMgKGUuZy4gZnJvbSB2aWV3IHRvIHdpbmRvd1xuICogdG8gYXBwbGljYXRpb24pIGFyZSB2aXNpYmxlIGluIHRoZWlyIGVudGlyZXR5IGF0IHRoZSBzeXN0ZW0gbGV2ZWwuICBTbywgd2UgY2FuIGxpc3RlbiB0byB0aGUgYWJvdmUgZXZlbnQgYXMgXCJzaG93blwiLCBcInZpZXctc2hvd25cIixcbiAqIFwid2luZG93LXZpZXctc2hvd25cIiwgb3IgXCJhcHBsaWNhdGlvbi13aW5kb3ctdmlldy1zaG93bi5cIlxuICovXG5jbGFzcyBFbWl0dGVyQmFzZSBleHRlbmRzIEJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIHRvcGljLCAuLi5hZGRpdGlvbmFsQWNjZXNzb3JzKSB7XG4gICAgICAgIHN1cGVyKHdpcmUpO1xuICAgICAgICB0aGlzLnRvcGljID0gdG9waWM7XG4gICAgICAgIF9FbWl0dGVyQmFzZV9lbWl0dGVyQWNjZXNzb3Iuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIHRoaXMuZXZlbnROYW1lcyA9ICgpID0+ICh0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkuZXZlbnROYW1lcygpIDogW10pO1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVtaXQgPSAoZXZlbnRUeXBlLCBwYXlsb2FkLCAuLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYXNFbWl0dGVyKCkgPyB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpLmVtaXQoZXZlbnRUeXBlLCBwYXlsb2FkLCAuLi5hcmdzKSA6IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhc0VtaXR0ZXIgPSAoKSA9PiB0aGlzLndpcmUuZXZlbnRBZ2dyZWdhdG9yLmhhcyhfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGUodGhpcywgX0VtaXR0ZXJCYXNlX2VtaXR0ZXJBY2Nlc3NvciwgXCJmXCIpKTtcbiAgICAgICAgdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIgPSAoKSA9PiB0aGlzLndpcmUuZXZlbnRBZ2dyZWdhdG9yLmdldE9yQ3JlYXRlKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZSh0aGlzLCBfRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yLCBcImZcIikpO1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9ICh0eXBlKSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJzKHR5cGUpIDogW107XG4gICAgICAgIHRoaXMubGlzdGVuZXJDb3VudCA9ICh0eXBlKSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJDb3VudCh0eXBlKSA6IDA7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyID0gYXN5bmMgKGV2ZW50VHlwZSwgb3B0aW9ucyA9IHt9LCBhcHBseVN1YnNjcmlwdGlvbiwgdW5kb1N1YnNjcmlwdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgcnVudGltZUV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBvcHRpb25zLnRpbWVzdGFtcCB8fCBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIHRvcGljOiB0aGlzLnRvcGljLFxuICAgICAgICAgICAgICAgIHR5cGU6IGV2ZW50VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpO1xuICAgICAgICAgICAgLy8gV2UgYXBwbHkgdGhlIHN1YnNjcmlwdGlvbiBhbmQgdGhlbiB1bmRvIGlmIHRoZSBhc3luYyBjYWxsIGZhaWxzIHRvIGF2b2lkXG4gICAgICAgICAgICAvLyBpbmRldGVybWluYWN5IGluIHN1YnNjcmlwdGlvbiBhcHBsaWNhdGlvbiBvcmRlciwgd2hpY2ggY2FuIGJyZWFrIHRoaW5ncyBlbHNld2hlcmVcbiAgICAgICAgICAgIGFwcGx5U3Vic2NyaXB0aW9uKGVtaXR0ZXIpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3Vic2NyaWJlLXRvLWRlc2t0b3AtZXZlbnQnLCBydW50aW1lRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB1bmRvU3Vic2NyaXB0aW9uKGVtaXR0ZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlRW1pdHRlcklmTm90aGluZ1JlZ2lzdGVyZWQoZW1pdHRlcik7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kZXJlZ2lzdGVyRXZlbnRMaXN0ZW5lciA9IGFzeW5jIChldmVudFR5cGUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcnVudGltZUV2ZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IG9wdGlvbnMudGltZXN0YW1wIHx8IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIHRvcGljOiB0aGlzLnRvcGljLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBldmVudFR5cGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCd1bnN1YnNjcmliZS10by1kZXNrdG9wLWV2ZW50JywgcnVudGltZUV2ZW50KS5jYXRjaCgoKSA9PiBudWxsKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZW1pdHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBvbmx5IGJlIHJlYWNoZWQgaWYgdW5zdWJzY3JpYmUgZnJvbSBldmVudCB0aGF0IGRvZXMgbm90IGV4aXN0IGJ1dCBkbyBub3Qgd2FudCB0byBlcnJvciBoZXJlXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYyh0aGlzLCBfRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yLCBbdG9waWMsIC4uLmFkZGl0aW9uYWxBY2Nlc3NvcnNdLCBcImZcIik7XG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gKGV2ZW50KSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJzKGV2ZW50KSA6IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRXZlbnQgcGF5bG9hZHMgYXJlIGRvY3VtZW50ZWQgaW4gdGhlIHtAbGluayBPcGVuRmluLkV2ZW50c30gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIGFzeW5jIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zLCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5vbihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSwgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RlbmVycyBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKi9cbiAgICBhc3luYyBhZGRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudC4gVGhlIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGUgZmlyc3QgdGltZSB0aGUgZXZlbnQgaXMgZmlyZWQsIGFmdGVyIHdoaWNoIGl0IGlzIHJlbW92ZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBpbiB0aGUge0BsaW5rIE9wZW5GaW4uRXZlbnRzfSBuYW1lc3BhY2UuXG4gICAgICovXG4gICAgYXN5bmMgb25jZShldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRlcmVnaXN0ZXIgPSAoKSA9PiB0aGlzLmRlcmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgb3B0aW9ucywgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIub25jZShldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5vbmNlKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9LCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRXZlbnQgcGF5bG9hZHMgYXJlIGRvY3VtZW50ZWQgaW4gdGhlIHtAbGluayBPcGVuRmluLkV2ZW50c30gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIGFzeW5jIHByZXBlbmRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgb3B0aW9ucywgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9LCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudC4gVGhlIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGUgZmlyc3QgdGltZSB0aGUgZXZlbnQgaXMgZmlyZWQsXG4gICAgICogYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC4gVGhlIGxpc3RlbmVyIGlzIGFkZGVkIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3RlbmVycyBhcnJheS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGluIHRoZSB7QGxpbmsgT3BlbkZpbi5FdmVudHN9IG5hbWVzcGFjZS5cbiAgICAgKi9cbiAgICBhc3luYyBwcmVwZW5kT25jZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZGVyZWdpc3RlciA9ICgpID0+IHRoaXMuZGVyZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zLCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5wcmVwZW5kT25jZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5vbmNlKGV2ZW50VHlwZSwgZGVyZWdpc3Rlcik7XG4gICAgICAgIH0sIChlbWl0dGVyKSA9PiB7XG4gICAgICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGxpc3RlbmVyIGZyb20gdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2F1dGlvbjogQ2FsbGluZyB0aGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSBhcnJheSBpbmRpY2VzIGluIHRoZSBsaXN0ZW5lciBhcnJheSBiZWhpbmQgdGhlIGxpc3RlbmVyLlxuICAgICAqL1xuICAgIGFzeW5jIHJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IGF3YWl0IHRoaXMuZGVyZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGVtaXR0ZXIpIHtcbiAgICAgICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLmRlbGV0ZUVtaXR0ZXJJZk5vdGhpbmdSZWdpc3RlcmVkKGVtaXR0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBhc3luYyBkZXJlZ2lzdGVyQWxsTGlzdGVuZXJzKGV2ZW50VHlwZSkge1xuICAgICAgICBjb25zdCBydW50aW1lRXZlbnQgPSB7IC4uLnRoaXMuaWRlbnRpdHksIHR5cGU6IGV2ZW50VHlwZSwgdG9waWM6IHRoaXMudG9waWMgfTtcbiAgICAgICAgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlZkNvdW50ID0gZW1pdHRlci5saXN0ZW5lckNvdW50KHJ1bnRpbWVFdmVudC50eXBlKTtcbiAgICAgICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlUHJvbWlzZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVmQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvbWlzZXMucHVzaCh0aGlzLndpcmUuc2VuZEFjdGlvbigndW5zdWJzY3JpYmUtdG8tZGVza3RvcC1ldmVudCcsIHJ1bnRpbWVFdmVudCkuY2F0Y2goKCkgPT4gbnVsbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodW5zdWJzY3JpYmVQcm9taXNlcyk7XG4gICAgICAgICAgICByZXR1cm4gZW1pdHRlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICpcbiAgICAgKi9cbiAgICBhc3luYyByZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnRUeXBlKSB7XG4gICAgICAgIGNvbnN0IHJlbW92ZUJ5RXZlbnQgPSBhc3luYyAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSBhd2FpdCB0aGlzLmRlcmVnaXN0ZXJBbGxMaXN0ZW5lcnMoZXZlbnQpO1xuICAgICAgICAgICAgaWYgKGVtaXR0ZXIpIHtcbiAgICAgICAgICAgICAgICBlbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycyhldmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVFbWl0dGVySWZOb3RoaW5nUmVnaXN0ZXJlZChlbWl0dGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgYXdhaXQgcmVtb3ZlQnlFdmVudChldmVudFR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpLmV2ZW50TmFtZXMoKTtcbiAgICAgICAgICAgIGF3YWl0ICgwLCBwcm9taXNlc18xLnByb21pc2VNYXApKGV2ZW50cywgcmVtb3ZlQnlFdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRlbGV0ZUVtaXR0ZXJJZk5vdGhpbmdSZWdpc3RlcmVkKGVtaXR0ZXIpIHtcbiAgICAgICAgaWYgKGVtaXR0ZXIuZXZlbnROYW1lcygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy53aXJlLmV2ZW50QWdncmVnYXRvci5kZWxldGUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCRlKHRoaXMsIF9FbWl0dGVyQmFzZV9lbWl0dGVyQWNjZXNzb3IsIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5iYXNlLkVtaXR0ZXJCYXNlID0gRW1pdHRlckJhc2U7XG5fRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yID0gbmV3IFdlYWtNYXAoKTtcbmNsYXNzIFJlcGx5IHtcbn1cbmJhc2UuUmVwbHkgPSBSZXBseTtcblxudmFyIHRyYW5zcG9ydEVycm9ycyA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodHJhbnNwb3J0RXJyb3JzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnRyYW5zcG9ydEVycm9ycy5SdW50aW1lRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuTm90U3VwcG9ydGVkRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuTm90SW1wbGVtZW50ZWRFcnJvciA9IHRyYW5zcG9ydEVycm9ycy5Ob0Fja0Vycm9yID0gdHJhbnNwb3J0RXJyb3JzLkR1cGxpY2F0ZUNvcnJlbGF0aW9uRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuVW5leHBlY3RlZEFjdGlvbkVycm9yID0gdHJhbnNwb3J0RXJyb3JzLkRpc2Nvbm5lY3RlZEVycm9yID0gdm9pZCAwO1xuY2xhc3MgRGlzY29ubmVjdGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocmVhZHlTdGF0ZSkge1xuICAgICAgICBzdXBlcihgRXhwZWN0ZWQgd2Vic29ja2V0IHN0YXRlIE9QRU4gYnV0IGZvdW5kICR7cmVhZHlTdGF0ZX1gKTtcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gcmVhZHlTdGF0ZTtcbiAgICB9XG59XG50cmFuc3BvcnRFcnJvcnMuRGlzY29ubmVjdGVkRXJyb3IgPSBEaXNjb25uZWN0ZWRFcnJvcjtcbmNsYXNzIFVuZXhwZWN0ZWRBY3Rpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5VbmV4cGVjdGVkQWN0aW9uRXJyb3IgPSBVbmV4cGVjdGVkQWN0aW9uRXJyb3I7XG5jbGFzcyBEdXBsaWNhdGVDb3JyZWxhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxudHJhbnNwb3J0RXJyb3JzLkR1cGxpY2F0ZUNvcnJlbGF0aW9uRXJyb3IgPSBEdXBsaWNhdGVDb3JyZWxhdGlvbkVycm9yO1xuY2xhc3MgTm9BY2tFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5Ob0Fja0Vycm9yID0gTm9BY2tFcnJvcjtcbmNsYXNzIE5vdEltcGxlbWVudGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG50cmFuc3BvcnRFcnJvcnMuTm90SW1wbGVtZW50ZWRFcnJvciA9IE5vdEltcGxlbWVudGVkRXJyb3I7XG5jbGFzcyBOb3RTdXBwb3J0ZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5Ob3RTdXBwb3J0ZWRFcnJvciA9IE5vdFN1cHBvcnRlZEVycm9yO1xuY2xhc3MgSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihlcnIpIHtcbiAgICAgICAgY29uc3QgeyBtZXNzYWdlLCBuYW1lLCBzdGFjaywgLi4ucmVzdCB9ID0gZXJyO1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZSB8fCAnRXJyb3InO1xuICAgICAgICB0aGlzLnN0YWNrID0gc3RhY2sgPz8gdGhpcy50b1N0cmluZygpO1xuICAgICAgICBPYmplY3Qua2V5cyhyZXN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSByZXN0W2tleV07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vIEZvciBkb2N1bWVudGF0aW9uIG9mIHRoZSBlcnJvciBtZXRob2RzIGJlaW5nIHVzZWQgc2VlIGhlcmU6IGh0dHBzOi8vdjguZGV2L2RvY3Mvc3RhY2stdHJhY2UtYXBpXG5jbGFzcyBSdW50aW1lRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgc3RhdGljIGdldENhbGxTaXRlKGNhbGxzVG9SZW1vdmUgPSAwKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IEVycm9yLnN0YWNrVHJhY2VMaW1pdDtcbiAgICAgICAgY29uc3QgcmVhbENhbGxzVG9SZW1vdmUgPSBjYWxsc1RvUmVtb3ZlICsgMTsgLy8gcmVtb3ZlIHRoaXMgY2FsbDtcbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gbGVuZ3RoICsgcmVhbENhbGxzVG9SZW1vdmU7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgICAgICBjb25zdCBfcHJlcGFyZVN0YWNrVHJhY2UgPSBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZTtcbiAgICAgICAgLy8gVGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIHdlIGFjY2VzcyB0aGUgYHN0YWNrYCBwcm9wZXJ0eVxuICAgICAgICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IChfLCBzdGFjaykgPT4gc3RhY2s7XG4gICAgICAgIC8vIHN0YWNrIGlzIG9wdGlvbmFsIGluIG5vbiBjaHJvbWl1bSBjb250ZXh0c1xuICAgICAgICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrPy5zbGljZShyZWFsQ2FsbHNUb1JlbW92ZSkgPz8gW107XG4gICAgICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gX3ByZXBhcmVTdGFja1RyYWNlO1xuICAgICAgICBFcnJvci5zdGFja1RyYWNlTGltaXQgPSBsZW5ndGg7XG4gICAgICAgIHJldHVybiBzdGFjaztcbiAgICB9XG4gICAgc3RhdGljIHByZXBhcmVTdGFja1RyYWNlKGVyciwgY2FsbFNpdGVzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZShlcnIsIGNhbGxTaXRlcyk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0cmluZyA9IFwiXCI7XG4gICAgICAgIHN0cmluZyArPSBlcnIubmFtZSB8fCBcIkVycm9yXCI7XG4gICAgICAgIHN0cmluZyArPSBgOiAke2Vyci5tZXNzYWdlIHx8IFwiXCJ9YDtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsU2l0ZSBvZiBjYWxsU2l0ZXMpIHtcbiAgICAgICAgICAgIHN0cmluZyArPSBgXFxuICAgIGF0ICR7Y2FsbFNpdGUudG9TdHJpbmcoKX1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgfVxuICAgIDtcbiAgICBjb25zdHJ1Y3RvcihwYXlsb2FkLCBjYWxsU2l0ZXMpIHtcbiAgICAgICAgY29uc3QgeyByZWFzb24sIGVycm9yIH0gPSBwYXlsb2FkO1xuICAgICAgICBzdXBlcihyZWFzb24pO1xuICAgICAgICB0aGlzLm5hbWUgPSAnUnVudGltZUVycm9yJztcbiAgICAgICAgaWYgKGVycm9yPy5zdGFjaykge1xuICAgICAgICAgICAgdGhpcy5jYXVzZSA9IG5ldyBJbnRlcm5hbEVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsbFNpdGVzKSB7XG4gICAgICAgICAgICB0aGlzLnN0YWNrID0gUnVudGltZUVycm9yLnByZXBhcmVTdGFja1RyYWNlKHRoaXMsIGNhbGxTaXRlcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG50cmFuc3BvcnRFcnJvcnMuUnVudGltZUVycm9yID0gUnVudGltZUVycm9yO1xuXG52YXIgd2luZG93JDEgPSB7fTtcblxudmFyIEZhY3RvcnkkOCA9IHt9O1xuXG52YXIgdmFsaWRhdGUgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkYXRlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhbGlkYXRlLnZhbGlkYXRlSWRlbnRpdHkgPSB2b2lkIDA7XG5mdW5jdGlvbiB2YWxpZGF0ZUlkZW50aXR5KGlkZW50aXR5KSB7XG4gICAgbGV0IGVycm9yTXNnO1xuICAgIGlmICh0eXBlb2YgaWRlbnRpdHkgIT09ICdvYmplY3QnIHx8IHR5cGVvZiBpZGVudGl0eS51dWlkICE9PSAnc3RyaW5nJykge1xuICAgICAgICBlcnJvck1zZyA9ICdOb3QgYSB2YWxpZCBpZGVudGl0eSBvYmplY3QnO1xuICAgIH1cbiAgICByZXR1cm4gZXJyb3JNc2c7XG59XG52YWxpZGF0ZS52YWxpZGF0ZUlkZW50aXR5ID0gdmFsaWRhdGVJZGVudGl0eTtcblxudmFyIEluc3RhbmNlJDcgPSB7fTtcblxudmFyIGFwcGxpY2F0aW9uID0ge307XG5cbnZhciBGYWN0b3J5JDcgPSB7fTtcblxudmFyIEluc3RhbmNlJDYgPSB7fTtcblxudmFyIHZpZXcgPSB7fTtcblxudmFyIEZhY3RvcnkkNiA9IHt9O1xuXG52YXIgd2FybmluZ3MgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHdhcm5pbmdzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbndhcm5pbmdzLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IHZvaWQgMDtcbmNvbnN0IGhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IChvcHRpb25zKSA9PiB7XG4gICAgaWYgKG9wdGlvbnMuY29udGVudE5hdmlnYXRpb24/LndoaXRlbGlzdCB8fFxuICAgICAgICBvcHRpb25zLmNvbnRlbnROYXZpZ2F0aW9uPy5ibGFja2xpc3QgfHxcbiAgICAgICAgb3B0aW9ucy5jb250ZW50UmVkaXJlY3Q/LndoaXRlbGlzdCB8fFxuICAgICAgICBvcHRpb25zLmNvbnRlbnRSZWRpcmVjdD8uYmxhY2tsaXN0KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgVGhlIHByb3BlcnRpZXMgJ3doaXRlbGlzdCcgYW5kICdibGFja2xpc3QnIGhhdmUgYmVlbiBtYXJrZWQgYXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uIFBsZWFzZSB1c2UgJ2FsbG93bGlzdCcgYW5kICdkZW55bGlzdCcuYCk7XG4gICAgfVxufTtcbndhcm5pbmdzLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IGhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncztcblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeSQzO1xuXG5mdW5jdGlvbiByZXF1aXJlRmFjdG9yeSQzICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkRmFjdG9yeSQzKSByZXR1cm4gRmFjdG9yeSQ2O1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkkMyA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDYsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDYuVmlld01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgYmFzZV8xID0gYmFzZTtcblx0Y29uc3QgdmFsaWRhdGVfMSA9IHZhbGlkYXRlO1xuXHRjb25zdCBpbmRleF8xID0gcmVxdWlyZVZpZXcoKTtcblx0Y29uc3Qgd2FybmluZ3NfMSA9IHdhcm5pbmdzO1xuXHQvKipcblx0ICogU3RhdGljIG5hbWVzcGFjZSBmb3IgT3BlbkZpbiBBUEkgbWV0aG9kcyB0aGF0IGludGVyYWN0IHdpdGggdGhlIHtAbGluayBWaWV3fSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uVmlld2AuXG5cdCAqL1xuXHRjbGFzcyBWaWV3TW9kdWxlIGV4dGVuZHMgYmFzZV8xLkJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBDcmVhdGVzIGEgbmV3IFZpZXcuXG5cdCAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIFZpZXcgY3JlYXRpb24gb3B0aW9uc1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogbGV0IHZpZXc7XG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICogICAgIGNvbnN0IG1lID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUNyZWF0ZScsXG5cdCAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjcmVhdGVWaWV3KClcblx0ICAgICAqICAgICAudGhlbigoY3JlYXRlZFZpZXcpID0+IHtcblx0ICAgICAqICAgICAgICAgdmlldyA9IGNyZWF0ZWRWaWV3O1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZygnVmlldyBjcmVhdGVkLicsIHZpZXcpO1xuXHQgICAgICogICAgICAgICB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIE5vdGUgdGhhdCBjcmVhdGVkIHZpZXdzIG5lZWRzIHRvIG5hdmlnYXRlIHNvbWV3aGVyZSBmb3IgdGhlbSB0byBhY3R1YWxseSByZW5kZXIgYSB3ZWJzaXRlLlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjcmVhdGUob3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IHsgdXVpZCB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIGlmICghb3B0aW9ucy5uYW1lIHx8IHR5cGVvZiBvcHRpb25zLm5hbWUgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgYSBuYW1lIHByb3BlcnR5IGFzIGEgc3RyaW5nIGluIG9yZGVyIHRvIGNyZWF0ZSBhIFZpZXcuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgICgwLCB3YXJuaW5nc18xLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncykob3B0aW9ucyk7XG5cdCAgICAgICAgaWYgKHRoaXMud2lyZS5lbnZpcm9ubWVudC5jaGlsZFZpZXdzKSB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5jcmVhdGVDaGlsZENvbnRlbnQoe1xuXHQgICAgICAgICAgICAgICAgZW50aXR5VHlwZTogJ3ZpZXcnLFxuXHQgICAgICAgICAgICAgICAgb3B0aW9uczogeyAuLi5vcHRpb25zLCB1dWlkIH1cblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLXZpZXcnLCB7IC4uLm9wdGlvbnMsIHV1aWQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLndyYXBTeW5jKHsgdXVpZCwgbmFtZTogb3B0aW9ucy5uYW1lIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBWaWV3IGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGEgVmlldyBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuXHQgICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuXHQgICAgICogZm9yIGEgVmlldyB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlZpZXcud3JhcCh7IHV1aWQ6ICd0ZXN0Vmlld1V1aWQnLCBuYW1lOiAndGVzdFZpZXdOYW1lJyB9KSlcblx0ICAgICAqICAgICAudGhlbih2aWV3ID0+IGNvbnNvbGUubG9nKCd3cmFwcGVkIHZpZXcnLCB2aWV3KSlcblx0ICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHdyYXAoaWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigndmlldy13cmFwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMS52YWxpZGF0ZUlkZW50aXR5KShpZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGVycm9yTXNnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgaW5kZXhfMS5WaWV3KHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIFZpZXcgaWRlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBWaWV3IGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYSBWaWV3IHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcud3JhcFN5bmMoeyB1dWlkOiAndGVzdFZpZXcnLCBuYW1lOiAndGVzdFZpZXdOYW1lJyB9KTtcblx0ICAgICAqIGF3YWl0IHZpZXcuaGlkZSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMS52YWxpZGF0ZUlkZW50aXR5KShpZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGVycm9yTXNnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgaW5kZXhfMS5WaWV3KHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgVmlldyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5WaWV3LmdldEN1cnJlbnQoKVxuXHQgICAgICogICAgIC50aGVuKHZpZXcgPT4gY29uc29sZS5sb2coJ2N1cnJlbnQgdmlldycsIHZpZXcpKVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnQoKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctZ2V0LWN1cnJlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoIXRoaXMud2lyZS5tZS5pc1ZpZXcpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFZpZXcgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwKHsgdXVpZCwgbmFtZSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgVmlldyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogY29uc29sZS5sb2codmlldyk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd2aWV3LWdldC1jdXJyZW50LXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoIXRoaXMud2lyZS5tZS5pc1ZpZXcpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFZpZXcgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQ2LlZpZXdNb2R1bGUgPSBWaWV3TW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQ2O1xufVxuXG52YXIgSW5zdGFuY2UkNSA9IHt9O1xuXG52YXIgbGF6eSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5sYXp5LkFzeW5jUmV0cnlhYmxlTGF6eSA9IGxhenkuTGF6eSA9IHZvaWQgMDtcbi8qKlxuICogSGFuZHkgY2xhc3MgZm9yIG1hbmFnaW5nIGFzeW5jaHJvbm91cyBkZXBlbmRlbmNpZXMgb2YgY2xhc3Nlcy5cbiAqXG4gKiBXaWxsIGNhbGwgdGhlIHByb2R1Y2VyIGZ1bmN0aW9uIG9uY2UgYW5kIG9ubHkgb25jZSB3aGVuIGdldFZhbHVlIGlzIGNhbGxlZCxcbiAqIHJldHVybmluZyB0aGUgcmVzdWx0YW50IHZhbHVlIGZvciBldmVyeSBzdWJzZXF1ZW50IGNhbGwuXG4gKi9cbmNsYXNzIExhenkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHByb2R1Y2VyRm4pIHtcbiAgICAgICAgdGhpcy5wcm9kdWNlckZuID0gcHJvZHVjZXJGbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF6aWx5IGdldCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIHByb2R1Y2VyLlxuICAgICAqIEByZXR1cm5zIFRoZSB2YWx1ZSByZXR1cm5lZCBmcm9tIHRoZSBwcm9kdWNlciBmdW5jdGlvblxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBpZiAoIXRoaXMudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnByb2R1Y2VyRm4oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5sYXp5LkxhenkgPSBMYXp5O1xuLyoqXG4gKiBIYW5keSBjbGFzcyBmb3IgbWFuYWdpbmcgYXN5bmNocm9ub3VzIGRlcGVuZGVuY2llcyBvZiBjbGFzc2VzLlxuICpcbiAqIFdpbGwgY2FsbCBhc3luY2hyb25vdXMgcHJvZHVjZXIgb25seSBhZnRlciBgZ2V0VmFsdWVgIGlzIGNhbGxlZC4gIElmIHRoZVxuICogZGVmZXJyZWQgY29kZSBlcnJvcnMsIHdlIGNhbiB0cnkgaXQgYWdhaW4gYnkgcmUtY2FsbGluZyBgZ2V0VmFsdWVgIGFmdGVyXG4gKiB0aGUgcHJvbWlzZSByZWplY3RzLlxuICovXG5jbGFzcyBBc3luY1JldHJ5YWJsZUxhenkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHByb2R1Y2VyRm4pIHtcbiAgICAgICAgdGhpcy5wcm9kdWNlckZuID0gcHJvZHVjZXJGbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF6aWx5IGdldCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGFzeW5jIHByb2R1Y2VyLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIHZhbHVlIHJldHVybmVkIGZyb20gdGhlIHByb2R1Y2VyIGZ1bmN0aW9uXG4gICAgICovXG4gICAgYXN5bmMgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9taXNlKSB7XG4gICAgICAgICAgICB0aGlzLnByb21pc2UgPSB0aGlzLnByb2R1Y2VyRm4oKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnByb21pc2U7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XG4gICAgfVxufVxubGF6eS5Bc3luY1JldHJ5YWJsZUxhenkgPSBBc3luY1JldHJ5YWJsZUxhenk7XG5cbnZhciBsYXlvdXRFbnRpdGllcyA9IHt9O1xuXG52YXIgYXBpRXhwb3NlciQxID0ge307XG5cbnZhciBhcGlDb25zdW1lciA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoYXBpQ29uc3VtZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuYXBpQ29uc3VtZXIuQXBpQ29uc3VtZXIgPSB2b2lkIDA7XG4vKipcbiAqIENvbnN1bWVyIGZvciBhcGlzIGV4cG9zZWQgd2l0aCB7QHNlZSBBcGlFeHBvc2VyfS5cbiAqXG4gKiBBIHN0cmF0ZWd5IHRoYXQgbWF0Y2hlcyB0aGUgc3RyYXRlZ3kgdXNlZCB0byBleHBvc2UgYSB0YXJnZXQgQVBJIG11c3QgYmUgcHJvdmlkZWQuXG4gKi9cbmNsYXNzIEFwaUNvbnN1bWVyIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBjb25zdHJ1Y3RvcihzdHJhdGVneSkge1xuICAgICAgICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdW1lcyBhbiBhcGkgZXhwb3NlZCB1c2luZyBhIGdpdmVuIHRyYW5zcG9ydCBzdHJhdGVneSwgYW5kIGdlbmVyYXRlcyBhIGNsaWVudFxuICAgICAgICAgKiBmb3IgZWFzeSwgdHlwZSBzYWZlIGNvbnN1bXB0aW9uIG9mIHRoYXQgY2xpZW50LlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBTdHJhdGVneSBzcGVjaWZpYyBjb25zdW1wdGlvbiBvcHRpb25zLlxuICAgICAgICAgKiBAcmV0dXJucyBBbiBhcGkgY2xpZW50IG1hdGNoaW5nIHRoZSBnaXZlbiB0eXBlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb25zdW1lID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV4cG9zZWRQcm9wZXJ0aWVzID0gYXdhaXQgdGhpcy5zdHJhdGVneS5nZXRFeHBvc2VkRnVuY3Rpb25zKG9wdGlvbnMpO1xuICAgICAgICAgICAgcmV0dXJuIGV4cG9zZWRQcm9wZXJ0aWVzLnJlZHVjZSgoY2xpZW50LCBwcm9wKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLmNsaWVudCxcbiAgICAgICAgICAgICAgICBbcHJvcC5rZXldOiB0aGlzLnN0cmF0ZWd5LmNyZWF0ZUZ1bmN0aW9uKHByb3AsIG9wdGlvbnMpXG4gICAgICAgICAgICB9KSwge30pO1xuICAgICAgICB9O1xuICAgIH1cbn1cbmFwaUNvbnN1bWVyLkFwaUNvbnN1bWVyID0gQXBpQ29uc3VtZXI7XG5cbnZhciBhcGlFeHBvc2VyID0ge307XG5cbnZhciBkZWNvcmF0b3JzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWNvcmF0b3JzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmRlY29yYXRvcnMuZXhwb3NlID0gZGVjb3JhdG9ycy5nZXRFeHBvc2VkUHJvcGVydGllcyA9IHZvaWQgMDtcbmNvbnN0IGV4cG9zZWRQcm9wZXJ0aWVzID0gU3ltYm9sKCdleHBvc2VkUHJvcGVydGllcycpO1xuY29uc3QgZ2V0RXhwb3NlZFByb3BlcnRpZXMgPSAodGFyZ2V0KSA9PiB7XG4gICAgcmV0dXJuIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10gfHwgdGFyZ2V0LnByb3RvdHlwZVtleHBvc2VkUHJvcGVydGllc10gfHwgW107XG59O1xuZGVjb3JhdG9ycy5nZXRFeHBvc2VkUHJvcGVydGllcyA9IGdldEV4cG9zZWRQcm9wZXJ0aWVzO1xuLyoqXG4gKiBJbmRpY2F0ZXMgdGhhdCBhIGNsYXNzIG1lbWJlciBmdW5jdGlvbiBjYW4gYmUgZXhwb3NlZCB1c2luZyB7QGxpbmsgQXBpRXhwb3Nlcn0uXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIHNwZWNpZmljIHRvIHRoZSBzdHJhdGVneSB1c2VkIGluIHtAbGluayBBcGlFeHBvc2VyfVxuICovXG4vLyBSZXR1cm5zIGFueSBhcyBkZWNvcmF0b3IgdHlwaW5nIGlzIHdlaXJkLlxuY29uc3QgZXhwb3NlID0gKG9wdGlvbnMpID0+ICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikgPT4ge1xuICAgIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10gPSB0YXJnZXRbZXhwb3NlZFByb3BlcnRpZXNdIHx8IFtdO1xuICAgIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10ucHVzaCh7IGtleSwgZGVzY3JpcHRvciwgb3B0aW9ucyB9KTtcbn07XG5kZWNvcmF0b3JzLmV4cG9zZSA9IGV4cG9zZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwaUV4cG9zZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuYXBpRXhwb3Nlci5BcGlFeHBvc2VyID0gdm9pZCAwO1xuY29uc3QgZGVjb3JhdG9yc18xID0gZGVjb3JhdG9ycztcbi8qKlxuICogRXhwb3NlcyBhcGkgc2VydmljZXMgb24gdGhlIHRyYW5zcG9ydCBvZiBjaG9pY2UuXG4gKi9cbmNsYXNzIEFwaUV4cG9zZXIge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBzdHJhdGVneSBUaGUgZXhwb3NlIHN0cmF0ZWd5IHRvIHVzZSB0byBleHBvc2UgaW5zdGFuY2VzLlxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHN0cmF0ZWd5KSB7XG4gICAgICAgIHRoaXMuc3RyYXRlZ3kgPSBzdHJhdGVneTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV4cG9zZXMgYW4gaW5zdGFuY2Ugb2YgYSBnaXZlbiBhcGkgb25cbiAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIEluc3RhbmNlIG9mIGEgY2xhc3Mgd2hpY2ggaGFzIGJlZW4gZGVjb3JhdGVkIHRvIGluZGljYXRlIHdoaWNoIGZ1bmN0aW9ucyBjYW4gYmUgZXhwb3NlZC5cbiAgICAgICAgICogQHBhcmFtIGluc3RhbmNlT3B0aW9ucyBUcmFuc3BvcnQgc3RyYXRlZ3kgc3BlY2lmaWMgb3B0aW9ucyB0byB1c2Ugd2hlbiBleHBvc2luZy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXhwb3NlSW5zdGFuY2UgPSBhc3luYyAoaW5zdGFuY2UsIGluc3RhbmNlT3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhwb3NhYmxlUHJvcHMgPSAoMCwgZGVjb3JhdG9yc18xLmdldEV4cG9zZWRQcm9wZXJ0aWVzKShpbnN0YW5jZSk7XG4gICAgICAgICAgICBjb25zdCBleHBvc2VkUHJvcHMgPSBhd2FpdCBQcm9taXNlLmFsbChleHBvc2FibGVQcm9wcy5tYXAoYXN5bmMgKHsga2V5LCBvcHRpb25zIH0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXN0b21Db25zdW1wdGlvbk9wdGlvbnMgPSBhd2FpdCB0aGlzLnN0cmF0ZWd5LmV4cG9zZUZ1bmN0aW9uKGluc3RhbmNlW2tleV0uYmluZChpbnN0YW5jZSksIHtcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBtZXRhOiBpbnN0YW5jZU9wdGlvbnNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IGN1c3RvbUNvbnN1bXB0aW9uT3B0aW9uc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnN0cmF0ZWd5LmV4cG9zZU1ldGEoaW5zdGFuY2VPcHRpb25zLCBleHBvc2VkUHJvcHMpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICA7XG59XG5hcGlFeHBvc2VyLkFwaUV4cG9zZXIgPSBBcGlFeHBvc2VyO1xuXG52YXIgc3RyYXRlZ2llcyA9IHt9O1xuXG52YXIgb3BlbmZpbkNoYW5uZWxzID0ge307XG5cbnZhciBjaGFubmVsc0NvbnN1bWVyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsc0NvbnN1bWVyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWxzQ29uc3VtZXIuQ2hhbm5lbHNDb25zdW1lciA9IHZvaWQgMDtcbmNsYXNzIENoYW5uZWxzQ29uc3VtZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKGNoYW5uZWwpIHtcbiAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcbiAgICAgICAgdGhpcy5nZXRFeHBvc2VkRnVuY3Rpb25zID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgaWQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHByb3BzIH0gPSBhd2FpdCB0aGlzLmNoYW5uZWwuZGlzcGF0Y2goYGFwaS1tZXRhOiR7aWR9YCk7XG4gICAgICAgICAgICByZXR1cm4gcHJvcHM7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY3JlYXRlRnVuY3Rpb24gPSAocHJvcCkgPT4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgYWN0aW9uIH0gPSBwcm9wLm9wdGlvbnM7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGFubmVsLmRpc3BhdGNoKGFjdGlvbiwgeyBhcmdzIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICA7XG59XG5jaGFubmVsc0NvbnN1bWVyLkNoYW5uZWxzQ29uc3VtZXIgPSBDaGFubmVsc0NvbnN1bWVyO1xuXG52YXIgY2hhbm5lbHNFeHBvc2VyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsc0V4cG9zZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY2hhbm5lbHNFeHBvc2VyLkNoYW5uZWxzRXhwb3NlciA9IHZvaWQgMDtcbmNsYXNzIENoYW5uZWxzRXhwb3NlciB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgY29uc3RydWN0b3IoY2hhbm5lbFByb3ZpZGVyT3JDbGllbnQpIHtcbiAgICAgICAgdGhpcy5jaGFubmVsUHJvdmlkZXJPckNsaWVudCA9IGNoYW5uZWxQcm92aWRlck9yQ2xpZW50O1xuICAgICAgICB0aGlzLmV4cG9zZUZ1bmN0aW9uID0gYXN5bmMgKHRhcmdldCwgY29uZmlnKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGtleSwgb3B0aW9ucywgbWV0YSB9ID0gY29uZmlnO1xuICAgICAgICAgICAgY29uc3QgeyBpZCB9ID0gbWV0YTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGAke2lkfS4ke29wdGlvbnM/LmFjdGlvbiB8fCBrZXl9YDtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2hhbm5lbFByb3ZpZGVyT3JDbGllbnQucmVnaXN0ZXIoYWN0aW9uLCBhc3luYyAoeyBhcmdzIH0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0KC4uLmFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4geyBhY3Rpb24gfTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5leHBvc2VNZXRhID0gYXN5bmMgKHsgaWQgfSwgcHJvcHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGBhcGktbWV0YToke2lkfWA7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNoYW5uZWxQcm92aWRlck9yQ2xpZW50LnJlZ2lzdGVyKGFjdGlvbiwgKCkgPT4gKHsgcHJvcHMgfSkpO1xuICAgICAgICB9O1xuICAgIH1cbn1cbmNoYW5uZWxzRXhwb3Nlci5DaGFubmVsc0V4cG9zZXIgPSBDaGFubmVsc0V4cG9zZXI7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRfX2V4cG9ydFN0YXIoY2hhbm5lbHNDb25zdW1lciwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihjaGFubmVsc0V4cG9zZXIsIGV4cG9ydHMpOyBcbn0gKG9wZW5maW5DaGFubmVscykpO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKG9wZW5maW5DaGFubmVscywgZXhwb3J0cyk7IFxufSAoc3RyYXRlZ2llcykpO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKGFwaUNvbnN1bWVyLCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKGFwaUV4cG9zZXIsIGV4cG9ydHMpO1xuXHRfX2V4cG9ydFN0YXIoc3RyYXRlZ2llcywgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihkZWNvcmF0b3JzLCBleHBvcnRzKTsgXG59IChhcGlFeHBvc2VyJDEpKTtcblxudmFyIGNoYW5uZWxBcGlSZWxheSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbEFwaVJlbGF5LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWxBcGlSZWxheS5jcmVhdGVSZWxheWVkRGlzcGF0Y2ggPSBjaGFubmVsQXBpUmVsYXkucmVsYXlDaGFubmVsQ2xpZW50QXBpID0gdm9pZCAwO1xuY29uc3QgRVhQRUNURURfRVJST1JTID0gW1xuICAgICdubyBsb25nZXIgY29ubmVjdGVkJyxcbiAgICAnUlRDRGF0YUNoYW5uZWwgY2xvc2VkIHVuZXhwZWN0ZWRseScsXG4gICAgJ1RoZSBjbGllbnQgeW91IGFyZSB0cnlpbmcgdG8gZGlzcGF0Y2ggZnJvbSBpcyBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgdGFyZ2V0IHByb3ZpZGVyJyxcbl07XG4vLyBDaGVja3MgcG9zc2libGUgZXJyb3IgbWVzc2FnZXMgdGhhdCB3ZSB3YW50IHRvIHRyYXAsIGNsaWVudCBlcnJvciBtZXNzYWdlIGNhbiBvcmlnaW5hdGVcbi8vIGZyb20gQ2hhbm5lbFByb3ZpZGVyOjpkaXNwYXRjaCBPUiBDbGFzc2ljU3RyYXRlZ3k6OmNsb3NlRW5kcG9pbnQgT1IgUlRDRW5kUG9pbnQ6OmRhdGFDaGFubmVsOjpvbmNsb3NlXG5jb25zdCBpc0Rpc2Nvbm5lY3RlZEVycm9yID0gKGVycm9yTXNnKSA9PiB7XG4gICAgcmV0dXJuIEVYUEVDVEVEX0VSUk9SUy5zb21lKGUgPT4gZXJyb3JNc2cuaW5jbHVkZXMoZSkpO1xufTtcbi8qKlxuICogQGludGVybmFsXG4gKiBDcmVhdGUgYSBjaGFubmVsIHJlbGF5IGZvciBhIGdpdmVuIGNoYW5uZWwgZXhwb3NpdGlvbiwgYWxsb3dpbmcgYSBzaW5nbGUgcHJvdmlkZXIgdG8gcm91dGVcbiAqIGFjdGlvbnMgdG8gdGhlIGRlc2lnbmF0ZWQgY2xpZW50cy5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggQGV4cG9zZVxuICpcbiAqIEBwYXJhbSBjaGFubmVsUHJvdmlkZXIgVGhlIGNoYW5uZWwgcHJvdmlkZXIgdG8gcmVsYXkgdGhlIGFjdGlvbnMgb24uXG4gKiBAcGFyYW0gY29uZmlnIERldGVybWluZXMgd2hpY2ggYWN0aW9ucyB0byByZWxheS4gUGxlYXNlIGVuc3VyZSBhY3Rpb24gcHJlZml4IG1hdGNoZXMgdGhlIGV4cG9zZWQgYXBpLlxuICovXG5jb25zdCByZWxheUNoYW5uZWxDbGllbnRBcGkgPSBhc3luYyAoY2hhbm5lbFByb3ZpZGVyLCByZWxheUlkKSA9PiB7XG4gICAgY2hhbm5lbFByb3ZpZGVyLnJlZ2lzdGVyKGByZWxheToke3JlbGF5SWR9YCwgKHsgYWN0aW9uLCB0YXJnZXQsIHBheWxvYWQgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY2hhbm5lbFByb3ZpZGVyLmRpc3BhdGNoKHRhcmdldCwgYWN0aW9uLCBwYXlsb2FkKTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5jaGFubmVsQXBpUmVsYXkucmVsYXlDaGFubmVsQ2xpZW50QXBpID0gcmVsYXlDaGFubmVsQ2xpZW50QXBpO1xuY29uc3QgY3JlYXRlUmVsYXllZERpc3BhdGNoID0gKGNsaWVudCwgdGFyZ2V0LCByZWxheUlkLCByZWxheUVycm9yTXNnKSA9PiBhc3luYyAoYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kaXNwYXRjaChgcmVsYXk6JHtyZWxheUlkfWAsIHtcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICB0YXJnZXRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc0Rpc2Nvbm5lY3RlZEVycm9yKGUubWVzc2FnZSkgJiYgcmVsYXlFcnJvck1zZykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlbGF5RXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgfVxufTtcbmNoYW5uZWxBcGlSZWxheS5jcmVhdGVSZWxheWVkRGlzcGF0Y2ggPSBjcmVhdGVSZWxheWVkRGlzcGF0Y2g7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JGIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9MYXlvdXROb2RlX2NsaWVudCwgX1RhYlN0YWNrX2NsaWVudCwgX0NvbHVtbk9yUm93X2NsaWVudDtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShsYXlvdXRFbnRpdGllcywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5sYXlvdXRFbnRpdGllcy5Db2x1bW5PclJvdyA9IGxheW91dEVudGl0aWVzLlRhYlN0YWNrID0gbGF5b3V0RW50aXRpZXMuTGF5b3V0Tm9kZSA9IHZvaWQgMDtcbmNvbnN0IGFwaV9leHBvc2VyXzEgPSBhcGlFeHBvc2VyJDE7XG5jb25zdCBjaGFubmVsX2FwaV9yZWxheV8xID0gY2hhbm5lbEFwaVJlbGF5O1xuLypcbiAgICBUaGlzIGZpbGUgaW5jbHVkZXMgTGF5b3V0Tm9kZSwgQ29sdW1uT3JSb3cgYW5kIFRhYlN0YWNrIGNsYXNzZXMsIHdoaWNoIGFyZSBhbGwgY2xvc2VseVxuICAgIGludGVydHdpbmVkLCBhbmQgc2hhcmUgbWVtYmVycyB2aWEgcGFyZW50IGFic3RyYWN0IGNsYXNzIExheW91dE5vZGUuIFRvIHByZXZlbnQgY2lyY3VsYXJcbiAgICByZWZzLCB3ZSBkZWZpbmUgYW5kIGV4cG9ydCBhbGwgdGhlIGNsYXNzZXMgaGVyZS5cbiovXG4vKipcbiAqIEBpZ25vcmVcbiAqIEBpbnRlcm5hbFxuICogU3VwcGxpZXMgYW4gQXBpQ2xpZW50IGZvciB7QGxpbmsgTGF5b3V0RW50aXRpZXNDb250cm9sbGVyfSBhbmQgaGVscGVyIG1ldGhvZHNcbiAqIGZvciB0aGUgZW50aXRpZXMge0BsaW5rIFRhYlN0YWNrfSBBTkQge0BsaW5rIENvbHVtbk9yUm93fSB0byB1c2UuXG4gKi9cbmNsYXNzIExheW91dE5vZGUge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjbGllbnQsIGVudGl0eUlkKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAaWdub3JlXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBBcGlDbGllbnQgZm9yIHtAbGluayBMYXlvdXRFbnRpdGllc0NvbnRyb2xsZXJ9XG4gICAgICAgICAqL1xuICAgICAgICBfTGF5b3V0Tm9kZV9jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgdGhlIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93IGlzIHRoZSByb290IGNvbnRlbnQgaXRlbVxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBpc1Jvb3QgPSBhd2FpdCBzdGFjay5pc1Jvb3QoKTtcbiAgICAgICAgICogLy8gVGhlIFRhYlN0YWNrIGlzIHJvb3Q6IGZhbHNlXG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgVGFiU3RhY2sgaXMgcm9vdDogJHtpc1Jvb3R9YCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIFJldHJpZXZlcyB0aGUgcGFyZW50IENvbHVtbk9yUm93XG4gICAgICAgICAqIGNvbnN0IHBhcmVudCA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBjb25zdCBwYXJlbnRJc1Jvb3QgPSBhd2FpdCBwYXJlbnQuaXNSb290KCk7XG4gICAgICAgICAqIC8vIFRoZSBwYXJlbnQgQ29sdW1uT3JSb3cgaXMgcm9vdDogdHJ1ZVxuICAgICAgICAgKiBjb25zb2xlLmxvZyhgVGhlIHBhcmVudCBDb2x1bW5PclJvdyBpcyByb290OiAke3BhcmVudElzUm9vdH1gKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzUm9vdCA9ICgpID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5pc1Jvb3QodGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgdGhlIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93IGV4aXN0c1xuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiAvLyBSZXRyaWV2ZXMgdGhlIHBhcmVudCBDb2x1bW5PclJvd1xuICAgICAgICAgKiBjb25zdCBjb2x1bW5PclJvdyA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBsZXQgZXhpc3RzID0gYXdhaXQgc3RhY2suZXhpc3RzKCk7XG4gICAgICAgICAqIC8vIG9yXG4gICAgICAgICAqIGxldCBleGlzdHMgPSBhd2FpdCBjb2x1bW5PclJvdy5leGlzdHMoKTtcbiAgICAgICAgICogLy8gVGhlIGVudGl0eSBleGlzdHM6IHRydWVcbiAgICAgICAgICogY29uc29sZS5sb2coYFRoZSBlbnRpdHkgZXhpc3RzOiAke2V4aXN0c31gKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmV4aXN0cyA9ICgpID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5leGlzdHModGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIHBhcmVudCBvZiB0aGUgVGFiU3RhY2sgb3IgQ29sdW1uT3JSb3dcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogaWYgKCFmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluIGEgcGxhdGZvcm0gVmlldy4nKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKlxuICAgICAgICAgKiBjb25zdCBzdGFjayA9IGF3YWl0IGZpbi5tZS5nZXRDdXJyZW50U3RhY2soKTtcbiAgICAgICAgICogLy8gUmV0cmlldmVzIHRoZSBwYXJlbnQgQ29sdW1uT3JSb3dcbiAgICAgICAgICogY29uc3QgY29sdW1uT3JSb3cgPSBhd2FpdCBzdGFjay5nZXRQYXJlbnQoKTtcbiAgICAgICAgICpcbiAgICAgICAgICogLy8gdW5kZWZpbmVkIGlmIGVudGl0eSBpcyB0aGUgcm9vdCBpdGVtXG4gICAgICAgICAqIGxldCBwYXJlbnQgPSBhd2FpdCBjb2x1bW5PclJvdy5nZXRQYXJlbnQoKTtcbiAgICAgICAgICogLy8gb3JcbiAgICAgICAgICogbGV0IHBhcmVudCA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0UGFyZW50ID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRkKHRoaXMsIF9MYXlvdXROb2RlX2NsaWVudCwgXCJmXCIpLmdldFBhcmVudCh0aGlzLmVudGl0eUlkKTtcbiAgICAgICAgICAgIGlmICghcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBMYXlvdXROb2RlLmdldEVudGl0eShwYXJlbnQsIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFRhYlN0YWNrIGFkamFjZW50IHRvIHRoZSBnaXZlbiBUYWJTdGFjayBvciBDb2x1bW5PclJvdy4gSW5wdXRzIGNhbiBiZSBuZXcgdmlld3MgdG8gY3JlYXRlLCBvciBleGlzdGluZyB2aWV3cy5cbiAgICAgICAgICpcbiAgICAgICAgICogS25vd24gSXNzdWU6IElmIHRoZSBudW1iZXIgb2Ygdmlld3MgdG8gYWRkIG92ZXJmbG93cyB0aGUgdGFiLWNvbnRhaW5lciwgdGhlIGFkZGVkIHZpZXdzIHdpbGwgYmUgc2V0IGFzIGFjdGl2ZVxuICAgICAgICAgKiBkdXJpbmcgZWFjaCByZW5kZXIsIGFuZCB0aGVuIHBsYWNlZCBhdCB0aGUgZnJvbnQgb2YgdGhlIHRhYi1zdGFjaywgd2hpbGUgdGhlIHVuZGVybHlpbmcgb3JkZXIgb2YgdGFicyB3aWxsIHJlbWFpbiB1bmNoYW5nZWQuXG4gICAgICAgICAqIFRoaXMgbWVhbnMgdGhlIHZpZXdzIHlvdSBwYXNzIHRvIGNyZWF0ZUFkamFjZW50U3RhY2soKSBtYXkgbm90IHJlbmRlciBpbiB0aGUgb3JkZXIgZ2l2ZW4gYnkgdGhlIGFycmF5LlxuICAgICAgICAgKiBVbnRpbCBmaXhlZCwgdGhpcyBwcm9ibGVtIGNhbiBiZSBhdm9pZGVkIG9ubHkgaWYgeW91ciB3aW5kb3cgaXMgd2lkZSBlbm91Z2ggdG8gZml0IGNyZWF0aW5nIGFsbCB0aGUgdmlld3MgaW4gdGhlIHRhYnN0YWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gdmlld3MgVGhlIHZpZXdzIHRoYXQgd2lsbCBwb3B1bGF0ZSB0aGUgbmV3IFRhYlN0YWNrLlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBjb250cm9sIG5ldyBUYWJTdGFjayBjcmVhdGlvbi5cbiAgICAgICAgICogQHJldHVybnMgVGhlIG5ld2x5LWNyZWF0ZWQgVGFiU3RhY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIGNvbnN0IGNvbHVtbk9yUm93ID0gYXdhaXQgc3RhY2suZ2V0UGFyZW50KCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIENyZWF0ZSB2aWV3IHJlZmVyZW5jZXMgYnkgc3VwcGx5aW5nIGEgJ25hbWUnIGFuZCAndXJsJ1xuICAgICAgICAgKiBjb25zdCB2aWV3cyA9IFtcbiAgICAgICAgICogICAgIC8vIGlmICduYW1lJyBpcyB1bmRlZmluZWQsIG9uZSB3aWxsIGJlIGdlbmVyYXRlZFxuICAgICAgICAgKiAgICAgLy8gaWYgJ3VybCcgaXMgdW5kZWZpbmVkLCBpdCB3aWxsIGRlZmF1bHQgdGhlIHZpZXcgVVJMIHRvICdhYm91dDpibGFuaydcbiAgICAgICAgICogICAgIHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJ30sXG4gICAgICAgICAqICAgICB7IG5hbWU6ICdvZi1kZXZlbG9wZXJzLXZpZXcnLCB1cmw6ICdodHRwOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvLyd9LFxuICAgICAgICAgKiBdO1xuICAgICAgICAgKlxuICAgICAgICAgKiAvLyBDcmVhdGUgYSB2aWV3IGJlZm9yZWhhbmQgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIG5ldyB0YWIgc3RhY2tcbiAgICAgICAgICogY29uc3Qgb3V0c2lkZVZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuICAgICAgICAgKiAgICAgbmFtZTogJ291dHNpZGUtYmxvb21iZXJnLXZpZXcnLFxuICAgICAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly9ibG9vbWJlcmcuY29tLycsXG4gICAgICAgICAqICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgICAgICogfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIFZpZXdzIHRvIGFkZCBjYW4gYmUgaWRlbnRpdGllcywgb3IgdGhlIHJlZmVyZW5jZSB2aWV3cyBtZW50aW9uZWQgYWJvdmVcbiAgICAgICAgICogY29uc3Qgdmlld3NUb0FkZCA9IFtvdXRzaWRlVmlldy5pZGVudGl0eSwgLi4udmlld3NdO1xuICAgICAgICAgKlxuICAgICAgICAgKiAvLyBQb3NzaWJsZSBwb3NpdGlvbiBpbnB1dHM6ICdyaWdodCcgfCAnbGVmdCcgfCAndG9wJyB8ICdib3R0b20nXG4gICAgICAgICAqIGxldCBzdGFja0Zyb20gPSBhd2FpdCBjb2x1bW5PclJvdy5jcmVhdGVBZGphY2VudFN0YWNrKHZpZXdzVG9BZGQsIHsgcG9zaXRpb246ICdyaWdodCcgfSk7XG4gICAgICAgICAqIC8vIE9yXG4gICAgICAgICAqIGxldCBuZXdTdGFjayA9IGF3YWl0IHN0YWNrLmNyZWF0ZUFkamFjZW50U3RhY2sodmlld3NUb0FkZCwgeyBwb3NpdGlvbjogJ3JpZ2h0JyB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coYEEgbmV3IFRhYlN0YWNrIGNyZWF0ZWQgdG8gdGhlIHJpZ2h0IGhhcyAke25ld1N0YWNrLmxlbmd0aH0gdmlld3MgaW4gaXRgKTtcbiAgICAgICAgICpcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY3JlYXRlQWRqYWNlbnRTdGFjayA9IGFzeW5jICh2aWV3cywgb3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5SWQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikuY3JlYXRlQWRqYWNlbnRTdGFjayh0aGlzLmVudGl0eUlkLCB2aWV3cywgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoeyBlbnRpdHlJZCwgdHlwZTogJ3N0YWNrJyB9LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogUmV0cmlldmVzIHRoZSBhZGphY2VudCBUYWJTdGFja3Mgb2YgdGhlIGdpdmVuIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZWRnZSBFZGdlIHdob3NlIGFkamFjZW50IFRhYlN0YWNrcyB3aWxsIGJlIHJldHVybmVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBjb2x1bW5PclJvdyA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiAvLyBQb3NzaWJsZSBwb3NpdGlvbiBpbnB1dHM6ICdyaWdodCcgfCAnbGVmdCcgfCAndG9wJyB8ICdib3R0b20nXG4gICAgICAgICAqIGxldCByaWdodFN0YWNrcyA9IGF3YWl0IGNvbHVtbk9yUm93LmdldEFkamFjZW50U3RhY2tzKCdyaWdodCcpO1xuICAgICAgICAgKiBsZXQgbGVmdFN0YWNrcyA9IGF3YWl0IGNvbHVtbk9yUm93LmdldEFkamFjZW50U3RhY2tzKCdsZWZ0Jyk7XG4gICAgICAgICAqIC8vIG9yXG4gICAgICAgICAqIGxldCByaWdodFN0YWNrcyA9IGF3YWl0IHN0YWNrLmdldEFkamFjZW50U3RhY2tzKCdyaWdodCcpO1xuICAgICAgICAgKiBsZXQgbGVmdFN0YWNrcyA9IGF3YWl0IHN0YWNrLmdldEFkamFjZW50U3RhY2tzKCdsZWZ0Jyk7XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgZW50aXR5IGhhcyAke3JpZ2h0U3RhY2tzLmxlbmd0aH0gc3RhY2tzIHRvIHRoZSByaWdodCwgYW5kICR7bGVmdFN0YWNrcy5sZW5ndGh9IHN0YWNrcyB0byB0aGUgbGVmdGApO1xuICAgICAgICAgKlxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5nZXRBZGphY2VudFN0YWNrcyA9IGFzeW5jIChlZGdlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhZGphY2VudFN0YWNrcyA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5nZXRBZGphY2VudFN0YWNrcyh7XG4gICAgICAgICAgICAgICAgdGFyZ2V0SWQ6IHRoaXMuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZWRnZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gYWRqYWNlbnRTdGFja3MubWFwKChzdGFjaykgPT4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IHN0YWNrLmVudGl0eUlkXG4gICAgICAgICAgICB9LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikpKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCRiKHRoaXMsIF9MYXlvdXROb2RlX2NsaWVudCwgY2xpZW50LCBcImZcIik7XG4gICAgICAgIHRoaXMuZW50aXR5SWQgPSBlbnRpdHlJZDtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5MYXlvdXROb2RlID0gTGF5b3V0Tm9kZTtcbl9MYXlvdXROb2RlX2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIEBpbnRlcm5hbFxuICogRW5jYXBzdWxhdGVzIEFwaSBjb25zdW1wdGlvbiBvZiB7QGxpbmsgTGF5b3V0RW50aXRpZXNDbGllbnR9IHdpdGggYSByZWxheWVkIGRpc3BhdGNoXG4gKiBAcGFyYW0gY2xpZW50XG4gKiBAcGFyYW0gY29udHJvbGxlcklkXG4gKiBAcGFyYW0gaWRlbnRpdHlcbiAqIEByZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAbGluayBMYXlvdXRFbnRpdGllc0NsaWVudH0gd2l0aCBib3VuZCB0byB0aGUgY29udHJvbGxlcklkXG4gKi9cbkxheW91dE5vZGUubmV3TGF5b3V0RW50aXRpZXNDbGllbnQgPSBhc3luYyAoY2xpZW50LCBjb250cm9sbGVySWQsIGlkZW50aXR5KSA9PiB7XG4gICAgY29uc3QgZGlzcGF0Y2ggPSAoMCwgY2hhbm5lbF9hcGlfcmVsYXlfMS5jcmVhdGVSZWxheWVkRGlzcGF0Y2gpKGNsaWVudCwgaWRlbnRpdHksICdsYXlvdXQtcmVsYXknLCAnWW91IGFyZSB0cnlpbmcgdG8gaW50ZXJhY3Qgd2l0aCBhIGxheW91dCBjb21wb25lbnQgb24gYSB3aW5kb3cgdGhhdCBkb2VzIG5vdCBleGlzdCBvciBoYXMgYmVlbiBkZXN0cm95ZWQuJyk7XG4gICAgY29uc3QgY29uc3VtZXIgPSBuZXcgYXBpX2V4cG9zZXJfMS5BcGlDb25zdW1lcihuZXcgYXBpX2V4cG9zZXJfMS5DaGFubmVsc0NvbnN1bWVyKHsgZGlzcGF0Y2ggfSkpO1xuICAgIHJldHVybiBjb25zdW1lci5jb25zdW1lKHsgaWQ6IGNvbnRyb2xsZXJJZCB9KTtcbn07XG5MYXlvdXROb2RlLmdldEVudGl0eSA9IChkZWZpbml0aW9uLCBjbGllbnQpID0+IHtcbiAgICBjb25zdCB7IGVudGl0eUlkLCB0eXBlIH0gPSBkZWZpbml0aW9uO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdjb2x1bW4nOlxuICAgICAgICBjYXNlICdyb3cnOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2x1bW5PclJvdyhjbGllbnQsIGVudGl0eUlkLCB0eXBlKTtcbiAgICAgICAgY2FzZSAnc3RhY2snOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBUYWJTdGFjayhjbGllbnQsIGVudGl0eUlkKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pc2VkIExheW91dCBFbnRpdHkgZW5jb3VudGVyZWQgKCcke0pTT04uc3RyaW5naWZ5KGRlZmluaXRpb24pfSlgKTtcbiAgICB9XG59O1xuLyoqXG4gKiBBIFRhYlN0YWNrIGlzIHVzZWQgdG8gbWFuYWdlIHRoZSBzdGF0ZSBvZiBhIHN0YWNrIG9mIHRhYnMgd2l0aGluIGFuIE9wZW5GaW4gTGF5b3V0LlxuICovXG5jbGFzcyBUYWJTdGFjayBleHRlbmRzIExheW91dE5vZGUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBjb25zdHJ1Y3RvcihjbGllbnQsIGVudGl0eUlkKSB7XG4gICAgICAgIHN1cGVyKGNsaWVudCwgZW50aXR5SWQpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEFwaUNsaWVudCBmb3Ige0BsaW5rIExheW91dEVudGl0aWVzQ29udHJvbGxlcn1cbiAgICAgICAgICovXG4gICAgICAgIF9UYWJTdGFja19jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUeXBlIG9mIHRoZSBjb250ZW50IGl0ZW0uIEFsd2F5cyBzdGFjaywgYnV0IHVzZWZ1bCBmb3IgZGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBhIHtAbGluayBUYWJTdGFja30gYW5kIHtAbGluayBDb2x1bW5PclJvd30uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnR5cGUgPSAnc3RhY2snO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmV0cmlldmVzIGEgbGlzdCBvZiBhbGwgdmlld3MgYmVsb25naW5nIHRvIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogS25vd24gSXNzdWU6IElmIGFkZGluZyBhIHZpZXcgb3ZlcmZsb3dzIHRoZSB0YWItY29udGFpbmVyIHdpZHRoLCB0aGUgYWRkZWQgdmlldyB3aWxsIGJlIHNldCBhcyBhY3RpdmVcbiAgICAgICAgICogYW5kIHJlbmRlcmVkIGF0IHRoZSBmcm9udCBvZiB0aGUgdGFiLXN0YWNrLCB3aGlsZSB0aGUgdW5kZXJseWluZyBvcmRlciBvZiB0YWJzIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgICAgICogSWYgdGhhdCBoYXBwZW5zIGFuZCB0aGVuIGdldFZpZXdzKCkgaXMgY2FsbGVkLCBpdCB3aWxsIHJldHVybiB0aGUgaWRlbnRpdGllcyBpbiBhIGRpZmZlcmVudCBvcmRlciB0aGFuXG4gICAgICAgICAqIHRoYW4gdGhlIGN1cnJlbnRseSByZW5kZXJlZCB0YWIgb3JkZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHtAbGluayBUYWJTdGFja30gaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiAvLyBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIHdyYXAgYW55IHZpZXcgYW5kIGdldCB0aGUgc3RhY2sgZnJvbSB0aGVyZVxuICAgICAgICAgKiAvLyBjb25zdCB2aWV3RnJvbVNvbWV3aGVyZSA9IGZpbi5WaWV3LndyYXBTeW5jKHNvbWVWaWV3LmlkZW50aXR5KTtcbiAgICAgICAgICogLy8gY29uc3Qgc3RhY2sgPSBhd2FpdCB2aWV3RnJvbVNvbWV3aGVyZS5nZXRDdXJyZW50U3RhY2soKTtcbiAgICAgICAgICogY29uc3Qgdmlld3MgPSBhd2FpdCBzdGFjay5nZXRWaWV3cygpO1xuICAgICAgICAgKiBjb25zb2xlLmxvZyhgU3RhY2sgY29udGFpbnMgJHt2aWV3cy5sZW5ndGh9IHZpZXcocylgKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0Vmlld3MgPSAoKSA9PiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX1RhYlN0YWNrX2NsaWVudCwgXCJmXCIpLmdldFN0YWNrVmlld3ModGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBZGRzIG9yIGNyZWF0ZXMgYSB2aWV3IGluIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgS25vd24gSXNzdWU6IElmIGFkZGluZyBhIHZpZXcgb3ZlcmZsb3dzIHRoZSB0YWItY29udGFpbmVyLCB0aGUgYWRkZWQgdmlldyB3aWxsIGJlIHNldCBhcyBhY3RpdmVcbiAgICAgICAgICogYW5kIHJlbmRlcmVkIGF0IHRoZSBmcm9udCBvZiB0aGUgdGFiLXN0YWNrLCB3aGlsZSB0aGUgdW5kZXJseWluZyBvcmRlciBvZiB0YWJzIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHZpZXcgVGhlIGlkZW50aXR5IG9mIGFuIGV4aXN0aW5nIHZpZXcgdG8gYWRkLCBvciBvcHRpb25zIHRvIGNyZWF0ZSBhIHZpZXcuXG4gICAgICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIHZpZXcgb3B0aW9uczogaW5kZXggbnVtYmVyIHVzZWQgdG8gaW5zZXJ0IHRoZSB2aWV3IGludG8gdGhlIHN0YWNrIGF0IHRoYXQgaW5kZXguIERlZmF1bHRzIHRvIDAgKGZyb250IG9mIHRoZSBzdGFjaylcbiAgICAgICAgICogQHJldHVybnMgUmVzb2x2ZXMgd2l0aCB0aGUge0BsaW5rIE9wZW5GaW4uSWRlbnRpdHkgaWRlbnRpdHl9IG9mIHRoZSBhZGRlZCB2aWV3LlxuICAgICAgICAgKiBAdGhyb3dzIElmIHRoZSB2aWV3IGRvZXMgbm90IGV4aXN0IG9yIGZhaWxzIHRvIGNyZWF0ZS5cbiAgICAgICAgICogQHRocm93cyBJZiB0aGUge0BsaW5rIFRhYlN0YWNrfSBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIC8vIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gd3JhcCBhbnkgdmlldyBhbmQgZ2V0IHRoZSBzdGFjayBmcm9tIHRoZXJlXG4gICAgICAgICAqIC8vIGNvbnN0IHZpZXdGcm9tU29tZXdoZXJlID0gZmluLlZpZXcud3JhcFN5bmMoc29tZVZpZXcuaWRlbnRpdHkpO1xuICAgICAgICAgKiAvLyBjb25zdCBzdGFjayA9IGF3YWl0IHZpZXdGcm9tU29tZXdoZXJlLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBnb29nbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJyB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coJ0lkZW50aXR5IG9mIHRoZSBnb29nbGUgdmlldyBqdXN0IGFkZGVkJywgeyBnb29nbGVWaWV3SWRlbnRpdHkgfSk7XG4gICAgICAgICAqIC8vIHBhc3MgaW4geyBpbmRleDogbnVtYmVyIH0gdG8gc2V0IHRoZSBpbmRleCBpbiB0aGUgc3RhY2suIEhlcmUgMSBtZWFucywgZW5kIG9mIHRoZSBzdGFjayAoZGVmYXVsdHMgdG8gMClcbiAgICAgICAgICogY29uc3QgYXBwbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2FwcGxlLXZpZXcnLCB1cmw6ICdodHRwOi8vYXBwbGUuY29tLycgfSwgeyBpbmRleDogMSB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coJ0lkZW50aXR5IG9mIHRoZSBhcHBsZSB2aWV3IGp1c3QgYWRkZWQnLCB7IGFwcGxlVmlld0lkZW50aXR5IH0pO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hZGRWaWV3ID0gYXN5bmMgKHZpZXcsIG9wdGlvbnMgPSB7IGluZGV4OiAwIH0pID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfVGFiU3RhY2tfY2xpZW50LCBcImZcIikuYWRkVmlld1RvU3RhY2sodGhpcy5lbnRpdHlJZCwgdmlldywgb3B0aW9ucyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZW1vdmVzIGEgdmlldyBmcm9tIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgdmlldyBpZGVudGl0eSBkb2VzIG5vdCBleGlzdCBvciB3YXMgYWxyZWFkeSBkZXN0cm95ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB2aWV3IC0gSWRlbnRpdHkgb2YgdGhlIHZpZXcgdG8gcmVtb3ZlLlxuICAgICAgICAgKiBAdGhyb3dzIElmIHRoZSB2aWV3IGRvZXMgbm90IGV4aXN0IG9yIGRvZXMgbm90IGJlbG9uZyB0byB0aGUgc3RhY2suXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHtAbGluayBUYWJTdGFja30gaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBnb29nbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJyB9KTtcbiAgICAgICAgICpcbiAgICAgICAgICogYXdhaXQgc3RhY2sucmVtb3ZlVmlldyhnb29nbGVWaWV3SWRlbnRpdHkpO1xuICAgICAgICAgKlxuICAgICAgICAgKiB0cnkge1xuICAgICAgICAgKiAgICAgYXdhaXQgc3RhY2sucmVtb3ZlVmlldyhnb29nbGVWaWV3SWRlbnRpdHkpO1xuICAgICAgICAgKiB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgKiAgICAgLy8gVHJpZWQgdG8gcmVtb3ZlIGEgdmlldyAoJ2dvb2dsZS12aWV3Jykgd2hpY2ggZG9lcyBub3QgYmVsb25nIHRvIHRoZSBzdGFjay5cbiAgICAgICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVtb3ZlVmlldyA9IGFzeW5jICh2aWV3KSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX1RhYlN0YWNrX2NsaWVudCwgXCJmXCIpLnJlbW92ZVZpZXdGcm9tU3RhY2sodGhpcy5lbnRpdHlJZCwgdmlldyk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBhY3RpdmUgdmlldyBvZiB0aGUge0BsaW5rIFRhYlN0YWNrfSB3aXRob3V0IGZvY3VzaW5nIGl0LlxuICAgICAgICAgKiBAcGFyYW0gdmlldyAtIElkZW50aXR5IG9mIHRoZSB2aWV3IHRvIGFjdGl2YXRlLlxuICAgICAgICAgKiBAcmV0dXJucyBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdm9pZCBvbmNlIHRoZSB2aWV3IGhhcyBiZWVuIGFjdGl2YXRlZC5cbiAgICAgICAgICogQHRocm93cyBJZiB0aGUge0BsaW5rIFRhYlN0YWNrfSBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHZpZXcgZG9lcyBub3QgZXhpc3QuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIENoYW5nZSB0aGUgYWN0aXZlIHRhYiBvZiBhIGtub3duIFZpZXcncyBUYWJTdGFjazpcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogY29uc3QgdGFyZ2V0VmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogJ3V1aWQnLCBuYW1lOiAndmlldy1uYW1lJyB9KTtcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCB0YXJnZXRWaWV3LmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBhd2FpdCBzdGFjay5zZXRBY3RpdmVWaWV3KHRhcmdldFZpZXcuaWRlbnRpdHkpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICpcbiAgICAgICAgICogU2V0IHRoZSBjdXJyZW50IFZpZXcgYXMgYWN0aXZlIHdpdGhpbiBpdHMgVGFiU3RhY2s6XG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBhd2FpdCBzdGFjay5zZXRBY3RpdmVWaWV3KGZpbi5tZS5pZGVudGl0eSk7XG4gICAgICAgICAqIGBgYFxuICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnNldEFjdGl2ZVZpZXcgPSBhc3luYyAodmlldykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRkKHRoaXMsIF9UYWJTdGFja19jbGllbnQsIFwiZlwiKS5zZXRTdGFja0FjdGl2ZVZpZXcodGhpcy5lbnRpdHlJZCwgdmlldyk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYih0aGlzLCBfVGFiU3RhY2tfY2xpZW50LCBjbGllbnQsIFwiZlwiKTtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5UYWJTdGFjayA9IFRhYlN0YWNrO1xuX1RhYlN0YWNrX2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEEgQ29sdW1uT3JSb3cgaXMgdXNlZCB0byBtYW5hZ2UgdGhlIHN0YXRlIG9mIENvbHVtbiBhbmQgUm93cyB3aXRoaW4gYW4gT3BlbkZpbiBMYXlvdXQuXG4gKi9cbmNsYXNzIENvbHVtbk9yUm93IGV4dGVuZHMgTGF5b3V0Tm9kZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2xpZW50LCBlbnRpdHlJZCwgdHlwZSkge1xuICAgICAgICBzdXBlcihjbGllbnQsIGVudGl0eUlkKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpZ25vcmVcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEFwaUNsaWVudCBmb3Ige0BsaW5rIExheW91dEVudGl0aWVzQ29udHJvbGxlcn1cbiAgICAgICAgICovXG4gICAgICAgIF9Db2x1bW5PclJvd19jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbnRlbnQgYXJyYXkgb2YgdGhlIENvbHVtbk9yUm93XG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIC8vIFJldHJpZXZlcyB0aGUgcGFyZW50IENvbHVtbk9yUm93XG4gICAgICAgICAqIGNvbnN0IGNvbHVtbk9yUm93ID0gYXdhaXQgc3RhY2suZ2V0UGFyZW50KCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIHJldHVybnMgW1RhYlN0YWNrXVxuICAgICAgICAgKiBjb25zdCBjb250ZW50QXJyYXkgPSBhd2FpdCBjb2x1bW5PclJvdy5nZXRDb250ZW50KCk7XG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgQ29sdW1uT3JSb3cgaGFzICR7Y29udGVudEFycmF5Lmxlbmd0aH0gaXRlbShzKWApO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0Q29udGVudCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRJdGVtRW50aXRpZXMgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0NvbHVtbk9yUm93X2NsaWVudCwgXCJmXCIpLmdldENvbnRlbnQodGhpcy5lbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gY29udGVudEl0ZW1FbnRpdGllcy5tYXAoKGVudGl0eSkgPT4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoZW50aXR5LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0NvbHVtbk9yUm93X2NsaWVudCwgXCJmXCIpKSk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYih0aGlzLCBfQ29sdW1uT3JSb3dfY2xpZW50LCBjbGllbnQsIFwiZlwiKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5Db2x1bW5PclJvdyA9IENvbHVtbk9yUm93O1xuX0NvbHVtbk9yUm93X2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBsYXlvdXRfY29uc3RhbnRzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShsYXlvdXRfY29uc3RhbnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmxheW91dF9jb25zdGFudHMuREVGQVVMVF9MQVlPVVRfS0VZID0gbGF5b3V0X2NvbnN0YW50cy5MQVlPVVRfQ09OVFJPTExFUl9JRCA9IHZvaWQgMDtcbmxheW91dF9jb25zdGFudHMuTEFZT1VUX0NPTlRST0xMRVJfSUQgPSAnbGF5b3V0LWVudGl0aWVzJztcbi8vIFRPRE86IGV2ZW50dWFsbHkgZXhwb3J0IHRoaXMgc29tZWhvd1xubGF5b3V0X2NvbnN0YW50cy5ERUZBVUxUX0xBWU9VVF9LRVkgPSAnX19kZWZhdWx0X18nO1xuXG52YXIgbWFpbiA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobWFpbiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5tYWluLldlYkNvbnRlbnRzID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJGogPSBiYXNlO1xuY2xhc3MgV2ViQ29udGVudHMgZXh0ZW5kcyBiYXNlXzEkai5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBpZGVudGl0eSBvZiB0aGUge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgV2ViQ29udGVudHN9LlxuICAgICAqIEBwYXJhbSBlbnRpdHlUeXBlIFRoZSB0eXBlIG9mIHRoZSB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBXZWJDb250ZW50c30uXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHksIGVudGl0eVR5cGUpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgZW50aXR5VHlwZSwgaWRlbnRpdHkudXVpZCwgaWRlbnRpdHkubmFtZSk7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyBhIGJhc2U2NCBlbmNvZGVkIGltYWdlIG9mIGFsbCBvciBwYXJ0IG9mIHRoZSBXZWJDb250ZW50cy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgY2FwdHVyZVBhZ2UgY2FsbC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiAvLyBQTkcgaW1hZ2Ugb2YgYSBmdWxsIHZpc2libGUgVmlld1xuICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHZpZXcuY2FwdHVyZVBhZ2UoKSk7XG4gICAgICpcbiAgICAgKiAvLyBMb3ctcXVhbGl0eSBKUEVHIGltYWdlIG9mIGEgZGVmaW5lZCB2aXNpYmxlIGFyZWEgb2YgdGhlIHZpZXdcbiAgICAgKiBjb25zdCBvcHRpb25zID0ge1xuICAgICAqICAgICBhcmVhOiB7XG4gICAgICogICAgICAgICBoZWlnaHQ6IDEwMCxcbiAgICAgKiAgICAgICAgIHdpZHRoOiAxMDAsXG4gICAgICogICAgICAgICB4OiAxMCxcbiAgICAgKiAgICAgICAgIHk6IDEwLFxuICAgICAqICAgICB9LFxuICAgICAqICAgICBmb3JtYXQ6ICdqcGcnLFxuICAgICAqICAgICBxdWFsaXR5OiAyMFxuICAgICAqIH1cbiAgICAgKiBjb25zb2xlLmxvZyhhd2FpdCB2aWV3LmNhcHR1cmVQYWdlKG9wdGlvbnMpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHduZCA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogLy8gUE5HIGltYWdlIG9mIGEgZnVsbCB2aXNpYmxlIHdpbmRvd1xuICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHduZC5jYXB0dXJlUGFnZSgpKTtcbiAgICAgKlxuICAgICAqIC8vIExvdy1xdWFsaXR5IEpQRUcgaW1hZ2Ugb2YgYSBkZWZpbmVkIHZpc2libGUgYXJlYSBvZiB0aGUgd2luZG93XG4gICAgICogY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgKiAgICAgYXJlYToge1xuICAgICAqICAgICAgICAgaGVpZ2h0OiAxMDAsXG4gICAgICogICAgICAgICB3aWR0aDogMTAwLFxuICAgICAqICAgICAgICAgeDogMTAsXG4gICAgICogICAgICAgICB5OiAxMCxcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgZm9ybWF0OiAnanBnJyxcbiAgICAgKiAgICAgcXVhbGl0eTogMjBcbiAgICAgKiB9XG4gICAgICogY29uc29sZS5sb2coYXdhaXQgd25kLmNhcHR1cmVQYWdlKG9wdGlvbnMpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBjYXB0dXJlUGFnZShvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignY2FwdHVyZS1wYWdlJywgeyBvcHRpb25zLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBKYXZhc2NyaXB0IG9uIHRoZSBXZWJDb250ZW50cywgcmVzdHJpY3RlZCB0byBjb250ZW50cyB5b3Ugb3duIG9yIGNvbnRlbnRzIG93bmVkIGJ5XG4gICAgICogYXBwbGljYXRpb25zIHlvdSBoYXZlIGNyZWF0ZWQuXG4gICAgICogQHBhcmFtIGNvZGUgSmF2YVNjcmlwdCBjb2RlIHRvIGJlIGV4ZWN1dGVkIG9uIHRoZSB2aWV3LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUphdmFTY3JpcHQoY29kZSkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7dXVpZDogJ3V1aWQnLCBuYW1lOiAndmlldyBuYW1lJ30pO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5leGVjdXRlSmF2YVNjcmlwdChjb2RlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBleGVjdXRlSmF2YVNjcmlwdChgY29uc29sZS5sb2coJ0hlbGxvLCBPcGVuZmluJylgKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdKYXZhc2NyaXB0IGV4Y3V0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUphdmFTY3JpcHQoY29kZSkge1xuICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcbiAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmV4ZWN1dGVKYXZhU2NyaXB0Lmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5leGVjdXRlSmF2YVNjcmlwdChjb2RlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBleGVjdXRlSmF2YVNjcmlwdChgY29uc29sZS5sb2coJ0hlbGxvLCBPcGVuZmluJylgKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdKYXZhc2NyaXB0IGV4Y3V0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBleGVjdXRlSmF2YVNjcmlwdChjb2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdleGVjdXRlLWphdmFzY3JpcHQtaW4td2luZG93JywgeyAuLi50aGlzLmlkZW50aXR5LCBjb2RlIH0pXG4gICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIFdlYkNvbnRlbnRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5nZXRab29tTGV2ZWwoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0Wm9vbUxldmVsLmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRab29tTGV2ZWwoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGdldFpvb21MZXZlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtem9vbS1sZXZlbCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB6b29tIGxldmVsIG9mIHRoZSBXZWJDb250ZW50cy5cbiAgICAgKiBAcGFyYW0gbGV2ZWwgVGhlIHpvb20gbGV2ZWxcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFpvb21MZXZlbChudW1iZXIpIHtcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcuc2V0Wm9vbUxldmVsKG51bWJlcik7XG4gICAgICogfVxuICAgICAqXG4gICAgICogc2V0Wm9vbUxldmVsKDQpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1NldHRpbmcgYSAgem9vbSBsZXZlbCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2V0Wm9vbUxldmVsLmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogYXN5bmMgZnVuY3Rpb24gc2V0Wm9vbUxldmVsKG51bWJlcikge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zZXRab29tTGV2ZWwobnVtYmVyKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBzZXRab29tTGV2ZWwoNCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2V0dGluZyBhICB6b29tIGxldmVsJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgc2V0Wm9vbUxldmVsKGxldmVsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2V0LXpvb20tbGV2ZWwnLCB7IC4uLnRoaXMuaWRlbnRpdHksIGxldmVsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRoZSBXZWJDb250ZW50cyB0byBhIHNwZWNpZmllZCBVUkwuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGUgdXJsIG11c3QgY29udGFpbiB0aGUgcHJvdG9jb2wgcHJlZml4IHN1Y2ggYXMgaHR0cDovLyBvciBodHRwczovLy5cbiAgICAgKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCB0byBuYXZpZ2F0ZSB0aGUgV2ViQ29udGVudHMgdG8uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IG1lLmlkZW50aXR5LFxuICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuICAgICAqICAgICB9KTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBjcmVhdGVWaWV3KClcbiAgICAgKiAgICAgLnRoZW4odmlldyA9PiB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2V4YW1wbGUuY29tJykpXG4gICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCduYXZpZ2F0aW9uIGNvbXBsZXRlJykpXG4gICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBuYXZpZ2F0ZSgpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubmF2aWdhdGUoJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cubmF2aWdhdGUuaHRtbCcpO1xuICAgICAqIH1cbiAgICAgKiBuYXZpZ2F0ZSgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ05hdmlnYXRlIHRvIHR1dG9yaWFsJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIG5hdmlnYXRlKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ25hdmlnYXRlLXdpbmRvdycsIHsgLi4udGhpcy5pZGVudGl0eSwgdXJsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRoZSBXZWJDb250ZW50cyBiYWNrIG9uZSBwYWdlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGVCYWNrKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7IG5hbWU6ICd0ZXN0YXBwLXZpZXcnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHZpZXcubmF2aWdhdGUoJ2h0dHBzOi8vd3d3Lmdvb2dsZS5jb20nKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcubmF2aWdhdGVCYWNrKCk7XG4gICAgICogfVxuICAgICAqIG5hdmlnYXRlQmFjaygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ05hdmlnYXRlZCBiYWNrJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIG5hdmlnYXRlQmFjaygpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy53cmFwKHsgbmFtZTogJ3Rlc3RhcHAnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHdpbi5uYXZpZ2F0ZSgnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbScpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLm5hdmlnYXRlQmFjaygpO1xuICAgICAqIH1cbiAgICAgKiBuYXZpZ2F0ZUJhY2soKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdOYXZpZ2F0ZWQgYmFjaycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIG5hdmlnYXRlQmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCduYXZpZ2F0ZS13aW5kb3ctYmFjaycsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5hdmlnYXRlcyB0aGUgV2ViQ29udGVudHMgZm9yd2FyZCBvbmUgcGFnZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIG5hdmlnYXRlRm9yd2FyZCgpIHtcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbScpO1xuICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlQmFjaygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5uYXZpZ2F0ZUZvcndhcmQoKTtcbiAgICAgKiB9XG4gICAgICogbmF2aWdhdGVGb3J3YXJkKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTmF2aWdhdGVkIGZvcndhcmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGVGb3J3YXJkKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLm5hdmlnYXRlKCdodHRwczovL3d3dy5nb29nbGUuY29tJyk7XG4gICAgICogICAgIGF3YWl0IHdpbi5uYXZpZ2F0ZUJhY2soKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5uYXZpZ2F0ZUZvcndhcmQoKTtcbiAgICAgKiB9XG4gICAgICogbmF2aWdhdGVGb3J3YXJkKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTmF2aWdhdGVkIGZvcndhcmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBhc3luYyBuYXZpZ2F0ZUZvcndhcmQoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCduYXZpZ2F0ZS13aW5kb3ctZm9yd2FyZCcsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcHMgYW55IGN1cnJlbnQgbmF2aWdhdGlvbiB0aGUgV2ViQ29udGVudHMgaXMgcGVyZm9ybWluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BOYXZpZ2F0aW9uKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7IG5hbWU6ICd0ZXN0YXBwLXZpZXcnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHZpZXcubmF2aWdhdGUoJ2h0dHBzOi8vd3d3Lmdvb2dsZS5jb20nKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcuc3RvcE5hdmlnYXRpb24oKTtcbiAgICAgKiB9XG4gICAgICogc3RvcE5hdmlnYXRpb24oKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCd5b3Ugc2hhbGwgbm90IG5hdmlnYXRlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BOYXZpZ2F0aW9uKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LndyYXAoeyBuYW1lOiAndGVzdGFwcCcsIHV1aWQ6ICd0ZXN0YXBwJyB9KTtcbiAgICAgKiAgICAgYXdhaXQgd2luLm5hdmlnYXRlKCdodHRwczovL3d3dy5nb29nbGUuY29tJyk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc3RvcE5hdmlnYXRpb24oKTtcbiAgICAgKiB9XG4gICAgICogc3RvcE5hdmlnYXRpb24oKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCd5b3Ugc2hhbGwgbm90IG5hdmlnYXRlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgc3RvcE5hdmlnYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc3RvcC13aW5kb3ctbmF2aWdhdGlvbicsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbG9hZHMgdGhlIFdlYkNvbnRlbnRzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWxvYWQoKSB7XG4gICAgICogXHRjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5yZWxvYWQoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiByZWxvYWQoKS50aGVuKCgpID0+IHtcbiAgICAgKiBcdFx0Y29uc29sZS5sb2coJ1JlbG9hZGVkIHZpZXcnKVxuICAgICAqIH0pLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlbG9hZFdpbmRvdygpIHtcbiAgICAgKiBcdFx0Y29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcbiAgICAgKiBcdFx0XHRcdG5hbWU6ICdteUFwcCcsXG4gICAgICogXHRcdFx0XHR1dWlkOiAnYXBwLTEnLFxuICAgICAqIFx0XHRcdFx0dXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5yZWxvYWQuaHRtbCcsXG4gICAgICogXHRcdFx0XHRhdXRvU2hvdzogdHJ1ZVxuICAgICAqIFx0XHR9KTtcbiAgICAgKiBcdFx0Y29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnJlbG9hZCgpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHJlbG9hZFdpbmRvdygpLnRoZW4oKCkgPT4ge1xuICAgICAqIFx0XHRjb25zb2xlLmxvZygnUmVsb2FkZWQgd2luZG93JylcbiAgICAgKiB9KS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHJlbG9hZChpZ25vcmVDYWNoZSA9IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdyZWxvYWQtd2luZG93Jywge1xuICAgICAgICAgICAgaWdub3JlQ2FjaGUsXG4gICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG4gICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQcmludHMgdGhlIFdlYkNvbnRlbnRzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIFByaW50ZXIgT3B0aW9uc1xuICAgICAqXG4gICAgICogTm90ZTogV2hlbiBgc2lsZW50YCBpcyBzZXQgdG8gYHRydWVgLCB0aGUgQVBJIHdpbGwgcGljayB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBwcmludGVyIGlmIGRldmljZU5hbWVcbiAgICAgKiBpcyBlbXB0eSBhbmQgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIHByaW50aW5nLlxuICAgICAqXG4gICAgICogVXNlIHRoZSBDU1Mgc3R5bGUgYHBhZ2UtYnJlYWstYmVmb3JlOiBhbHdheXM7YCB0byBmb3JjZSBwcmludCB0byBhIG5ldyBwYWdlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogdmlldy5wcmludCh7IHNpbGVudDogZmFsc2UsIGRldmljZU5hbWU6ICdzeXN0ZW0tcHJpbnRlci1uYW1lJyB9KS50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ3ByaW50IGNhbGwgaGFzIGJlZW4gc2VudCB0byB0aGUgc3lzdGVtJyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHByaW50KG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ByaW50JywgeyAuLi50aGlzLmlkZW50aXR5LCBvcHRpb25zIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZCBhbmQgaGlnaGxpZ2h0IHRleHQgb24gYSBwYWdlLlxuICAgICAqIEBwYXJhbSBzZWFyY2hUZXJtIFRlcm0gdG8gZmluZCBpbiBwYWdlXG4gICAgICogQHBhcmFtIG9wdGlvbnMgU2VhcmNoIG9wdGlvbnNcbiAgICAgKlxuICAgICAqIE5vdGU6IEJ5IGRlZmF1bHQsIGVhY2ggc3Vic2VxdWVudCBjYWxsIHdpbGwgaGlnaGxpZ2h0IHRoZSBuZXh0IHRleHQgdGhhdCBtYXRjaGVzIHRoZSBzZWFyY2ggdGVybS5cbiAgICAgKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdHMgZm9yIHRoZSByZXF1ZXN0LiBCeSBzdWJzY3JpYmluZyB0byB0aGVcbiAgICAgKiBmb3VuZC1pbi1wYWdlIGV2ZW50LCB5b3UgY2FuIGdldCB0aGUgcmVzdWx0cyBvZiB0aGlzIGNhbGwgYXMgd2VsbC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogLy9CeSBzdWJzY3JpYmluZyB0byB0aGUgJ2ZvdW5kIGluIHBhZ2UnIGV2ZW50IHdlIGNhbiBnZXQgdGhlIHJlc3VsdHMgb2YgZWFjaCBmaW5kSW5QYWdlIGNhbGwgbWFkZS5cbiAgICAgKiB2aWV3LmFkZExpc3RlbmVyKCdmb3VuZC1pbi1wYWdlJywgKGV2ZW50KSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGV2ZW50KTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBwcm9taXNlIGFsc28gcmV0dXJucyB0aGUgcmVzdWx0cyBmb3IgdGhlIHJlcXVlc3RcbiAgICAgKiB2aWV3LmZpbmRJblBhZ2UoJ2EnKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocmVzdWx0KVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogLy9CeSBzdWJzY3JpYmluZyB0byB0aGUgJ2ZvdW5kIGluIHBhZ2UnIGV2ZW50IHdlIGNhbiBnZXQgdGhlIHJlc3VsdHMgb2YgZWFjaCBmaW5kSW5QYWdlIGNhbGwgbWFkZS5cbiAgICAgKiB3aW4uYWRkTGlzdGVuZXIoJ2ZvdW5kLWluLXBhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXZlbnQpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gVGhlIHByb21pc2UgYWxzbyByZXR1cm5zIHRoZSByZXN1bHRzIGZvciB0aGUgcmVxdWVzdFxuICAgICAqIHdpbi5maW5kSW5QYWdlKCdhJykudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdClcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgZmluZEluUGFnZShzZWFyY2hUZXJtLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdmaW5kLWluLXBhZ2UnLCB7IC4uLnRoaXMuaWRlbnRpdHksIHNlYXJjaFRlcm0sIG9wdGlvbnMgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhIHtAbGluayBWaWV3I2ZpbmRJblBhZ2UgZmluZEluUGFnZX0gY2FsbCBieSBzcGVjaWZ5aW5nIGFueSBvZiB0aGVzZSBhY3Rpb25zOlxuICAgICAqXG4gICAgICogKiBjbGVhclNlbGVjdGlvbiAtIENsZWFyIHRoZSBzZWxlY3Rpb24uXG4gICAgICogKiBrZWVwU2VsZWN0aW9uIC0gVHJhbnNsYXRlIHRoZSBzZWxlY3Rpb24gaW50byBhIG5vcm1hbCBzZWxlY3Rpb24uXG4gICAgICogKiBhY3RpdmF0ZVNlbGVjdGlvbiAtIEZvY3VzIGFuZCBjbGljayB0aGUgc2VsZWN0aW9uIG5vZGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcuZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKlxuICAgICAqIHZpZXcuYWRkTGlzdGVuZXIoJ2ZvdW5kLWluLXBhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICogICAgICAgICB2aWV3LnN0b3BGaW5kSW5QYWdlKCdjbGVhclNlbGVjdGlvbicpO1xuICAgICAqICAgICB9LCA1MDAwKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHZpZXcuZmluZEluUGFnZSgnYScpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogd2luLmFkZExpc3RlbmVyKCdmb3VuZC1pbi1wYWdlJywgKGV2ZW50KSA9PiB7XG4gICAgICogICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAqICAgICAgICAgd2luLnN0b3BGaW5kSW5QYWdlKCdjbGVhclNlbGVjdGlvbicpO1xuICAgICAqICAgICB9LCA1MDAwKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHdpbi5maW5kSW5QYWdlKCdhJykudGhlbihyZXN1bHRzID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHN0b3BGaW5kSW5QYWdlKGFjdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3N0b3AtZmluZC1pbi1wYWdlJywgeyAuLi50aGlzLmlkZW50aXR5LCBhY3Rpb24gfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggYWxsIHN5c3RlbSBwcmludGVyc1xuICAgICAqIEBkZXByZWNhdGVkIHVzZSBTeXN0ZW0uZ2V0UHJpbnRlcnMgaW5zdGVhZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiB2aWV3LmdldFByaW50ZXJzKClcbiAgICAgKiAgICAgLnRoZW4oKHByaW50ZXJzKSA9PiB7XG4gICAgICogICAgICAgICBwcmludGVycy5mb3JFYWNoKChwcmludGVyKSA9PiB7XG4gICAgICogICAgICAgICAgICAgaWYgKHByaW50ZXIuaXNEZWZhdWx0KSB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHByaW50ZXIpO1xuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9KVxuICAgICAqICAgICAuY2F0Y2goKGVycikgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiB3aW4uZ2V0UHJpbnRlcnMoKVxuICAgICAqICAgICAudGhlbigocHJpbnRlcnMpID0+IHtcbiAgICAgKiAgICAgICAgIHByaW50ZXJzLmZvckVhY2goKHByaW50ZXIpID0+IHtcbiAgICAgKiAgICAgICAgICAgICBpZiAocHJpbnRlci5pc0RlZmF1bHQpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocHJpbnRlcik7XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH0pXG4gICAgICogICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgZ2V0UHJpbnRlcnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByaW50ZXJzJywgeyAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlcyBmb2N1cyB0byB0aGUgV2ViQ29udGVudHMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZm9jdXNXaW5kb3coKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZm9jdXMuaHRtbCcsXG4gICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuICAgICAqICAgICB9KTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmZvY3VzKCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZm9jdXNXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgZm9jdXNlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGZvY3VzKHsgZW1pdFN5bnRoRm9jdXNlZCB9ID0geyBlbWl0U3ludGhGb2N1c2VkOiB0cnVlIH0pIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZvY3VzLXdpbmRvdycsIHsgZW1pdFN5bnRoRm9jdXNlZCwgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29sc1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd0RldmVsb3BlclRvb2xzKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gdmlldy5zaG93RGV2ZWxvcGVyVG9vbHMoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBzaG93RGV2ZWxvcGVydG9vbHMoKVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTaG93aW5nIGRldiB0b29scycpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNob3dEZXZlbG9wZXJUb29scygpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIHJldHVybiB3aW4uc2hvd0RldmVsb3BlclRvb2xzKCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogc2hvd0RldmVsb3BlcnRvb2xzKClcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2hvd2luZyBkZXYgdG9vbHMnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIHNob3dEZXZlbG9wZXJUb29scygpIHtcbiAgICAgICAgLy8gTm90ZSB0aGlzIGhpdHMgdGhlIHN5c3RlbSBhY3Rpb24gbWFwIGluIGNvcmUgc3RhdGUgZm9yIGxlZ2FjeSByZWFzb25zLlxuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy1kZXZlbG9wZXItdG9vbHMnLCB0aGlzLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBwcm9jZXNzIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCBhIFdlYkNvbnRlbnRzLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBpbmNsdWRlcyBhbnkgaWZyYW1lcyBhc3NvY2lhdGVkIHdpdGggdGhlIFdlYkNvbnRlbnRzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgY29uc3QgcHJvY2Vzc0luZm8gPSBhd2FpdCB2aWV3LmdldFByb2Nlc3NJbmZvKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgd2luLmdldFByb2Nlc3NJbmZvKCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGdldFByb2Nlc3NJbmZvKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgZGF0YSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByb2Nlc3MtaW5mbycsIHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIG9uIGFsbCBTaGFyZWQgV29ya2Vycy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9tZG4uZ2l0aHViLmlvL2RvbS1leGFtcGxlcy93ZWItd29ya2Vycy9zaW1wbGUtc2hhcmVkLXdvcmtlci8nKTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBzaGFyZWRXb3JrZXJzID0gYXdhaXQgdmlldy5nZXRTaGFyZWRXb3JrZXJzKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luT3B0aW9uID0ge1xuICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuICAgICAqICAgICAgICAgZGVmYXVsdFdpZHRoOiAzMDAsXG4gICAgICogICAgICAgICBkZWZhdWx0SGVpZ2h0OiAzMDAsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycsXG4gICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcbiAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG4gICAgICogICAgIH07XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG4gICAgICogICAgIGNvbnN0IHNoYXJlZFdvcmtlcnMgPSBhd2FpdCB3aW4uZ2V0U2hhcmVkV29ya2VycygpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBhc3luYyBnZXRTaGFyZWRXb3JrZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1zaGFyZWQtd29ya2VycycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZGV2ZWxvcGVyIHRvb2xzIGZvciB0aGUgc2hhcmVkIHdvcmtlciBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lJyxcbiAgICAgKiAgICAgICAgIHRhcmdldDogZmluLm1lLmlkZW50aXR5LFxuICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHZpZXcuaW5zcGVjdFNoYXJlZFdvcmtlcigpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhhbXBsZTpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB3aW5PcHRpb24gPSB7XG4gICAgICogICAgICAgICBuYW1lOidjaGlsZCcsXG4gICAgICogICAgICAgICBkZWZhdWx0V2lkdGg6IDMwMCxcbiAgICAgKiAgICAgICAgIGRlZmF1bHRIZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vbWRuLmdpdGh1Yi5pby9kb20tZXhhbXBsZXMvd2ViLXdvcmtlcnMvc2ltcGxlLXNoYXJlZC13b3JrZXIvJyxcbiAgICAgKiAgICAgICAgIGZyYW1lOiB0cnVlLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLmluc3BlY3RTaGFyZWRXb3JrZXIoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgYXN5bmMgaW5zcGVjdFNoYXJlZFdvcmtlcigpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2luc3BlY3Qtc2hhcmVkLXdvcmtlcicsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zcGVjdHMgdGhlIHNoYXJlZCB3b3JrZXIgYmFzZWQgb24gaXRzIElELlxuICAgICAqIEBwYXJhbSB3b3JrZXJJZCAtIFRoZSBpZCBvZiB0aGUgc2hhcmVkIHdvcmtlci5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9tZG4uZ2l0aHViLmlvL2RvbS1leGFtcGxlcy93ZWItd29ya2Vycy9zaW1wbGUtc2hhcmVkLXdvcmtlci8nKTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBzaGFyZWRXb3JrZXJzID0gYXdhaXQgdmlldy5nZXRTaGFyZWRXb3JrZXJzKCk7XG4gICAgICogICAgIGF3YWl0IHZpZXcuaW5zcGVjdFNoYXJlZFdvcmtlckJ5SWQoc2hhcmVkV29ya2Vyc1swXS5pZCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luT3B0aW9uID0ge1xuICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuICAgICAqICAgICAgICAgZGVmYXVsdFdpZHRoOiAzMDAsXG4gICAgICogICAgICAgICBkZWZhdWx0SGVpZ2h0OiAzMDAsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycsXG4gICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcbiAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG4gICAgICogICAgIH07XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG4gICAgICogICAgIGNvbnN0IHNoYXJlZFdvcmtlcnMgPSBhd2FpdCB3aW4uZ2V0U2hhcmVkV29ya2VycygpO1xuICAgICAqICAgICBhd2FpdCB3aW4uaW5zcGVjdFNoYXJlZFdvcmtlckJ5SWQoc2hhcmVkV29ya2Vyc1swXS5pZCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGluc3BlY3RTaGFyZWRXb3JrZXJCeUlkKHdvcmtlcklkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnNwZWN0LXNoYXJlZC13b3JrZXItYnktaWQnLCB7IC4uLnRoaXMuaWRlbnRpdHksIHdvcmtlcklkIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZGV2ZWxvcGVyIHRvb2xzIGZvciB0aGUgc2VydmljZSB3b3JrZXIgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cDovL2dvb2dsZWNocm9tZS5naXRodWIuaW8vc2FtcGxlcy9zZXJ2aWNlLXdvcmtlci9iYXNpYy9pbmRleC5odG1sJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5pbnNwZWN0U2VydmljZVdvcmtlcigpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIGNvbnN0IHdpbk9wdGlvbiA9IHtcbiAgICAgKiAgICAgICAgIG5hbWU6J2NoaWxkJyxcbiAgICAgKiAgICAgICAgIGRlZmF1bHRXaWR0aDogMzAwLFxuICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuICAgICAqICAgICAgICAgdXJsOiAnaHR0cDovL2dvb2dsZWNocm9tZS5naXRodWIuaW8vc2FtcGxlcy9zZXJ2aWNlLXdvcmtlci9iYXNpYy9pbmRleC5odG1sJyxcbiAgICAgKiAgICAgICAgIGZyYW1lOiB0cnVlLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLmluc3BlY3RTZXJ2aWNlV29ya2VyKCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGluc3BlY3RTZXJ2aWNlV29ya2VyKCkge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignaW5zcGVjdC1zZXJ2aWNlLXdvcmtlcicsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgYSBwb3B1cCB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBOb3RlOiBJZiB0aGlzIFdlYkNvbnRlbnRzIGlzIGEgdmlldyBhbmQgaXRzIGF0dGFjaGVkIHdpbmRvdyBoYXMgYSBwb3B1cCBvcGVuLCB0aGlzIHdpbGwgY2xvc2UgaXQuXG4gICAgICpcbiAgICAgKiBTaG93cyBhIHBvcHVwIHdpbmRvdy4gSW5jbHVkaW5nIGEgYG5hbWVgIGluIGBvcHRpb25zYCB3aWxsIGF0dGVtcHQgdG8gc2hvdyBhbiBleGlzdGluZyB3aW5kb3cgYXMgYSBwb3B1cCwgaWZcbiAgICAgKiB0aGF0IHdpbmRvdyBkb2Vzbid0IGV4aXN0IG9yIG5vIGBuYW1lYCBpcyBpbmNsdWRlZCBhIHdpbmRvdyB3aWxsIGJlIGNyZWF0ZWQuIElmIHRoZSBjYWxsZXIgdmlldyBvciB0aGUgY2FsbGVyXG4gICAgICogdmlldydzIHBhcmVudCB3aW5kb3cgY3VycmVudGx5IGhhcyBhIHBvcHVwIHdpbmRvdyBvcGVuLCBjYWxsaW5nIGBzaG93UG9wdXBXaW5kb3dgIGFnYWluIHdpbGwgZGlzbWlzcyB0aGUgY3VycmVudGx5XG4gICAgICogb3BlbiBwb3B1cCB3aW5kb3cgYmVmb3JlIHNob3dpbmcgdGhlIG5ldyBwb3B1cCB3aW5kb3cuIEFsc28sIGlmIHRoZSBjYWxsZXIgdmlldyBpcyBkZXN0cm95ZWQgb3IgZGV0YWNoZWQsIHRoZSBwb3B1cFxuICAgICAqIHdpbGwgYmUgZGlzbWlzc2VkLlxuICAgICAqXG4gICAgICogTm90ZTogaW4gdGhlIGNhc2Ugd2hlcmUgdGhlIHdpbmRvdyBiZWluZyBzaG93biBhcyBhIHBvcHVwIG5lZWRzIHRvIGJlIGNyZWF0ZWQsIGl0IGlzIGEgY2hpbGQgb2YgdGhlIGNhbGxlciB2aWV3J3MgcGFyZW50IHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYW5kIHNob3cgYSBzaW5nbGUtdXNlIHBvcHVwIHdpbmRvdyB0aGF0IHJldHVybnMgYSBzaW5nbGUgcmVzdWx0IHRvIHRoZSBjYWxsZXIuIGBpbml0aWFsT3B0aW9uc2AgYWxsb3dzXG4gICAgICogdXMgdG8gcGFzcyB3aW5kb3cgb3B0aW9ucyB0byB0aGUgcG9wdXAgd2luZG93IHRoYXQgd2lsbCBiZSBjcmVhdGVkLiBgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJ2AgZW5zdXJlc1xuICAgICAqIHRoYXQgb25jZSB0aGUgcG9wdXAgd2luZG93IGNhbGxzIGBkaXNwYXRjaFBvcHVwUmVzdWx0YCBpdCBpcyBjbG9zZWQuIGBibHVyQmVoYXZpb3I6ICdjbG9zZSdgIHdpbGwgeWllbGQgYSBkaXNtaXNzZWRcbiAgICAgKiByZXN1bHQgc2hvdWxkIHRoZSBwb3B1cCB3aW5kb3cgbG9zZSBmb2N1cy5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIGluaXRpYWxPcHRpb25zOiB7XG4gICAgICogICAgICAgICBmcmFtZTogZmFsc2VcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdjbG9zZScsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogU2FtZSBhcyBhYm92ZSBidXQgdXNpbmcgYW4gZXhpc3Rpbmcgd2luZG93IGFzIGEgcG9wdXAgYnkgcmVmZXJlbmNpbmcgaXRzIGBuYW1lYDpcbiAgICAgKlxuICAgICAqIE5vdGU6IGlmIGEgd2luZG93IHdpdGggdGhlIGBuYW1lYCBwcm92aWRlZCBkb2Vzbid0IGV4aXN0LCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBpbml0aWFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgZnJhbWU6IHRydWVcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbmFtZTogJ215LXBvcHVwJywgLy8gc2hvd3MgdGhlICdteS1wb3B1cCcgd2luZG93IGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGNyZWF0ZXMgaXRcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLCAvLyBuYXZpZ2F0ZXMgdG8gdGhpcyB1cmwgaWYgaXQgZG9lc24ndCBtYXRjaCB0aGUgbG9jYXRpb24uaHJlZiBvZiB0aGUgJ215LXBvcHVwJyB3aW5kb3dcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIHBlcnNpc3Qgd2luZG93IG9uICdkaXNtaXNzZWQnIHJlc3VsdCwgYWx0ZXJuYXRpdmVseSBjaGFuZ2Ugb25SZXN1bHREaXNwYXRjaCBhbmQgYmx1ckJlaGF2aW9yIHRvICdoaWRlJ1xuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIGFuZCBzaG93IGEgcG9wdXAgd2luZG93IHRoYXQgaXMgYWJsZSB0byByZXR1cm4gbXVsdGlwbGUgcmVzdWx0cyB0byB0aGUgY2FsbGVyIHZpYSBhbiBgb25Qb3B1cFJlc3VsdGAgY2FsbGJhY2suIEVhY2hcbiAgICAgKiB0aW1lIHRoZSBwb3B1cCB3aW5kb3cgY2FsbHMgYGRpc3BhdGNoUG9wdXBSZXN1bHRgLCB0aGUgY2FsbGJhY2sgd2lsbCBiZSBleGVjdXRlZCBvbiB0aGUgcmVzdWx0LiBPbmNlIHRoZSBwb3B1cCB3aW5kb3cgaXNcbiAgICAgKiBjbG9zZWQgb3IgaGlkZGVuLCB0aGUgYHNob3dQb3B1cFdpbmRvd2AgcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhIGBkaXNtaXNzZWRgIHJlc3VsdCB0aGF0IHdpbGwgaW5jbHVkZSB0aGUgbW9zdCByZWNlbnRseVxuICAgICAqIGRpc3BhdGNoZWQgcmVzdWx0IGFzIGBsYXN0RGlzcGF0Y2hSZXN1bHRgOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFJlc3VsdENhbGxiYWNrID0gKHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgaWYgKHBheWxvYWQucmVzdWx0ID09PSAnY2xpY2tlZCcpIHtcbiAgICAgKiAgICAgICAgICAgIGlmIChwYXlsb2FkLmRhdGEudG9waWMgPT09ICdjb2xvci1jaGFuZ2VkJykge1xuICAgICAqICAgICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBsaWtlXG4gICAgICogICAgICAgICAgICAgICAgLy8gc2V0Q29sb3IocGF5bG9hZC5kYXRhLnZhbHVlKTtcbiAgICAgKiAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4ubWUuc2hvd1BvcHVwV2luZG93KHtcbiAgICAgKiAgICAgaW5pdGlhbE9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGZyYW1lOiBmYWxzZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICB1cmw6ICc8bXlfcG9wdXBfdXJsPicsXG4gICAgICogICAgIHJlc3VsdERpc3BhdGNoQmVoYXZpb3I6ICdub25lJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDAsXG4gICAgICogICAgIG9uUG9wdXBSZXN1bHQ6IHBvcHVwUmVzdWx0Q2FsbGJhY2tcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFNhbWUgYXMgYWJvdmUgYnV0IHVzaW5nIGFuIGV4aXN0aW5nIHdpbmRvdyBhcyBhIHBvcHVwOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFJlc3VsdENhbGxiYWNrID0gKHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgaWYgKHBheWxvYWQucmVzdWx0ID09PSAnY2xpY2tlZCcpIHtcbiAgICAgKiAgICAgICAgICAgIGlmIChwYXlsb2FkLmRhdGEudG9waWMgPT09ICdjb2xvci1jaGFuZ2VkJykge1xuICAgICAqICAgICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBsaWtlXG4gICAgICogICAgICAgICAgICAgICAgLy8gc2V0Q29sb3IocGF5bG9hZC5kYXRhLnZhbHVlKTtcbiAgICAgKiAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4ubWUuc2hvd1BvcHVwV2luZG93KHtcbiAgICAgKiAgICAgaW5pdGlhbE9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGZyYW1lOiBmYWxzZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICBuYW1lOiAnbXktcG9wdXAnLCAvLyBzaG93cyB0aGUgJ215LXBvcHVwJyB3aW5kb3cgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgY3JlYXRlcyBpdFxuICAgICAqICAgICB1cmw6ICc8bXlfcG9wdXBfdXJsPicsIC8vIG5hdmlnYXRlcyB0byB0aGlzIHVybCBpZiBpdCBkb2Vzbid0IG1hdGNoIHRoZSBsb2NhdGlvbi5ocmVmIG9mIHRoZSAnbXktcG9wdXAnIHdpbmRvd1xuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnbm9uZScsXG4gICAgICogICAgIGJsdXJCZWhhdmlvcjogJ2hpZGUnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIHdlIGNhbiBqdXN0IHVzZSB0aGlzIG9yIHdlIGNhbiBjaGFuZ2UgYmx1ckJlaGF2aW9yIHRvICdoaWRlJ1xuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMCxcbiAgICAgKiAgICAgb25Qb3B1cFJlc3VsdDogcG9wdXBSZXN1bHRDYWxsYmFja1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIG9yIHNob3cgYSBwb3B1cCB3aW5kb3cgdGhhdCBkaXNhYmxlcyB1c2VyIG1vdmVtZW50IChwb3NpdGlvbmluZyBhbmQgcmVzaXppbmcpIGluIHRoZSBjYWxsZXJcbiAgICAgKiB2aWV3J3MgcGFyZW50IHdpbmRvdyBieSB1c2luZyBgYmx1ckJlaGF2aW9yOiAnbW9kYWwnYDpcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIGluaXRpYWxPcHRpb25zOiB7XG4gICAgICogICAgICAgICBmcmFtZTogZmFsc2VcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdtb2RhbCcsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIGEgcG9wdXAgd2luZG93IGFzIGEgbW9kYWw6XG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGUgb25seSB3YXkgdG8gZW5zdXJlIHRydWUgbW9kYWwgYmVoYXZpb3IgaXMgdG8gY3JlYXRlIHRoZSB3aW5kb3cgYmVpbmcgc2hvd24gYXMgYSBwb3B1cCB3aXRoIGFcbiAgICAgKiBgbW9kYWxQYXJlbnRJZGVudGl0eWAgdGhhdCB1c2VzIHRoZSBjYWxsZXIgdmlldydzIHBhcmVudCB3aW5kb3cgaWRlbnRpdHkuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBpbml0aWFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgZnJhbWU6IGZhbHNlLFxuICAgICAqICAgICAgICAgbW9kYWxQYXJlbnRJZGVudGl0eTogZmluLm1lLmlkZW50aXR5XG4gICAgICogICAgIH0sXG4gICAgICogICAgIHVybDogJzxteV9wb3B1cF91cmw+JyxcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnbW9kYWwnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDBcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFBhc3MgZGF0YSB0byBhIHBvcHVwIHdpbmRvdyB0aGF0IGlzIGF2YWlsYWJsZSB3aGVuIHRoZSBwb3B1cCBpcyBzaG93bi5cbiAgICAgKlxuICAgICAqIE5vdGU6IHRoaXMgaXMganVzdCBvbmUgZXhhbXBsZSBmb3IgYSB1c2Ugb2YgYGFkZGl0aW9uYWxPcHRpb25zYCwgaXQgY2FuIGJlIHVzZWQgdG8gdXBkYXRlIGFueSB1cGRhdGFibGVcbiAgICAgKiB3aW5kb3cgb3B0aW9ucyB3aGVuIGNyZWF0aW5nIG9yIHNob3dpbmcgYW4gZXhpc3Rpbmcgd2luZG93IGFzIGEgcG9wdXAuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBhZGRpdGlvbmFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgY3VzdG9tRGF0YToge1xuICAgICAqICAgICAgICAgICAgIGZvbzogJ2JhcidcbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdjbG9zZScsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gQWNjZXNzIGZyb20gdGhlIHBvcHVwIHdpbmRvdyBjb250ZXh0IGxpa2Ugc286XG4gICAgICogY29uc3QgeyBjdXN0b21EYXRhIH0gPSBhd2FpdCBmaW4ubWUuZ2V0T3B0aW9ucygpO1xuICAgICAqIGNvbnN0IHsgZm9vIH0gPSBjdXN0b21EYXRhO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhlY3V0ZSBhIGNhbGxiYWNrIG9uIHRoZSBwb3B1cCdzIE9wZW5GaW4gd2luZG93IHdoZW4gdGhlIHBvcHVwIGlzIHNob3duOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFdpbmRvd0NhbGxiYWNrID0gYXN5bmMgKHdpbikgPT4ge1xuICAgICAqICAgICBhd2FpdCB3aW4uZmxhc2goKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIHVybDogJzxteV9wb3B1cF91cmw+JyxcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDAsXG4gICAgICogICAgIG9uUG9wdXBSZWFkeTogcG9wdXBXaW5kb3dDYWxsYmFjaztcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgYXN5bmMgc2hvd1BvcHVwV2luZG93KG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oYCR7dGhpcy5lbnRpdHlUeXBlfS1zaG93LXBvcHVwLXdpbmRvd2AsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9wdGlvbnM/Lm9uUG9wdXBSZWFkeSkge1xuICAgICAgICAgICAgY29uc3QgcmVhZHlMaXN0ZW5lciA9IGFzeW5jICh7IHBvcHVwTmFtZSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9wdXBXaW5kb3cgPSB0aGlzLmZpbi5XaW5kb3cud3JhcFN5bmMoeyB1dWlkOiB0aGlzLmZpbi5tZS51dWlkLCBuYW1lOiBwb3B1cE5hbWUgfSk7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG9wdGlvbnMub25Qb3B1cFJlYWR5KHBvcHVwV2luZG93KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU29tZXRoaW5nIHdlbnQgd3JvbmcgZHVyaW5nIG9uUG9wdXBSZWFkeSBleGVjdXRpb246ICR7ZXJyb3J9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGludGVybmFsKVxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbmNlKCdwb3B1cC1yZWFkeScsIHJlYWR5TGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogdHJ5Q3JlYXRlUGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3RyeS1jcmVhdGUtcG9wdXAtd2luZG93Jywge1xuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgLy8gSW50ZXJuYWwgdXNlIG9ubHkuXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIGhhc1Jlc3VsdENhbGxiYWNrOiAhIW9wdGlvbnM/Lm9uUG9wdXBSZXN1bHQsXG4gICAgICAgICAgICAgICAgaGFzUmVhZHlDYWxsYmFjazogISFvcHRpb25zPy5vblBvcHVwUmVhZHlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IGRhdGE6IHsgd2lsbE9wZW4sIG9wdGlvbnM6IHBvcHVwT3B0aW9ucyB9IH0gPSB0cnlDcmVhdGVQYXlsb2FkO1xuICAgICAgICBpZiAod2lsbE9wZW4pIHtcbiAgICAgICAgICAgIC8vIFNvbHZlIHRoZSBpc3N1ZSB3aGVyZSBJbnRlcm9wIGluIGEgcG9wdXAgd2luZG93IHdpdGggbm9uIGNyb3NzLW9yaWdpbiB1cmwgaXMgbm90IHdvcmtpbmcoY29yZS0xMDc2KS5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZmluLldpbmRvdy5jcmVhdGUocG9wdXBPcHRpb25zLmluaXRpYWxPcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBub3JtYWxpemVQb3B1cFJlc3VsdCA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IG5hbWUsIHV1aWQsIHJlc3VsdCwgZGF0YSB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgIGNvbnN0IHBvcHVwUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIGlkZW50aXR5OiB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHV1aWRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcG9wdXBSZXN1bHQuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcG9wdXBSZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICAgIGlmIChvcHRpb25zPy5vblBvcHVwUmVzdWx0KSB7XG4gICAgICAgICAgICBjb25zdCBkaXNwYXRjaFJlc3VsdExpc3RlbmVyID0gYXN5bmMgKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBvcHRpb25zLm9uUG9wdXBSZXN1bHQobm9ybWFsaXplUG9wdXBSZXN1bHQocGF5bG9hZCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHRlYXJkb3duTGlzdGVuZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogZml4IHR5cGluZyAoaW50ZXJuYWwpXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3BvcHVwLXJlc3VsdCcsIGRpc3BhdGNoUmVzdWx0TGlzdGVuZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGludGVybmFsKVxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbigncG9wdXAtcmVzdWx0JywgZGlzcGF0Y2hSZXN1bHRMaXN0ZW5lcik7XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgIC8vIGhpbGFyaW91c2x5IHRoaXMgZG9lcyBub3QgbmVlZCBhIHRzLWV4cGVjdC1lcnJvciAtIHRoaXMgaXMgZ2FwIGluIHR5cGUgc291bmRuZXNzXG4gICAgICAgICAgICAvLyBzaG91bGQgaW52ZXN0aWdhdGUgLSBwcm9iYWJseSBkdWUgdG8gYHRlYXJkb3duTGlzdGVuZXJgIHRha2luZyBhIHZvaWQgYXJndW1lbnRcbiAgICAgICAgICAgIC8vIHdoaWNoIG1pZ2h0IHBsYXkgbmljZWx5IHdpdGggdGhlIGBuZXZlcmAgdHlwZT8gIGh1aC4uLlxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbmNlKCdwb3B1cC10ZWFyZG93bicsIHRlYXJkb3duTGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctcG9wdXAtd2luZG93Jywge1xuICAgICAgICAgICAgb3B0aW9uczogcG9wdXBPcHRpb25zLFxuICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG59XG5tYWluLldlYkNvbnRlbnRzID0gV2ViQ29udGVudHM7XG5cbnZhciBoYXNSZXF1aXJlZEluc3RhbmNlJDI7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSQyICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkSW5zdGFuY2UkMikgcmV0dXJuIEluc3RhbmNlJDU7XG5cdGhhc1JlcXVpcmVkSW5zdGFuY2UkMiA9IDE7XG5cdHZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcblx0ICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcblx0ICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuXHQgICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcblx0fTtcblx0dmFyIF9WaWV3X3Byb3ZpZGVyQ2hhbm5lbENsaWVudDtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDUsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRJbnN0YW5jZSQ1LlZpZXcgPSB2b2lkIDA7XG5cdGNvbnN0IHRyYW5zcG9ydF9lcnJvcnNfMSA9IHRyYW5zcG9ydEVycm9ycztcblx0Y29uc3QgbGF6eV8xID0gbGF6eTtcblx0Y29uc3QgbGF5b3V0X2VudGl0aWVzXzEgPSBsYXlvdXRFbnRpdGllcztcblx0Y29uc3QgbGF5b3V0X2NvbnN0YW50c18xID0gbGF5b3V0X2NvbnN0YW50cztcblx0Y29uc3QgbWFpbl8xID0gbWFpbjtcblx0Y29uc3Qgd2luZG93XzEgPSByZXF1aXJlV2luZG93KCk7XG5cdC8qKlxuXHQgKiBBIFZpZXcgY2FuIGJlIHVzZWQgdG8gZW1iZWQgYWRkaXRpb25hbCB3ZWIgY29udGVudCBpbnRvIGEgV2luZG93LlxuXHQgKiBJdCBpcyBsaWtlIGEgY2hpbGQgd2luZG93LCBleGNlcHQgaXQgaXMgcG9zaXRpb25lZCByZWxhdGl2ZSB0byBpdHMgb3duaW5nIHdpbmRvdy5cblx0ICogSXQgaGFzIHRoZSBhYmlsaXR5IHRvIGxpc3RlbiBmb3Ige0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3LXNwZWNpZmljIGV2ZW50c30uXG5cdCAqXG5cdCAqIEJ5IGRlZmF1bHQsIGEgVmlldyB3aWxsIHRyeSB0byBzaGFyZSB0aGUgc2FtZSByZW5kZXJlciBwcm9jZXNzIGFzIG90aGVyIFZpZXdzIG93bmVkIGJ5IGl0cyBwYXJlbnQgQXBwbGljYXRpb24uXG5cdCAqIFRvIGNoYW5nZSB0aGF0IGJlaGF2aW9yLCBzZWUgdGhlIHByb2Nlc3NBZmZpbml0eSB7QGxpbmsgT3BlbkZpbi5WaWV3T3B0aW9ucyB2aWV3IG9wdGlvbn0uXG5cdCAqXG5cdCAqIEEgVmlldydzIGxpZmVjeWNsZSBpcyB0aWVkIHRvIGl0cyBvd25pbmcgd2luZG93IGFuZCBjYW4gYmUgcmUtYXR0YWNoZWQgdG8gYSBkaWZmZXJlbnQgd2luZG93IGF0IGFueSBwb2ludCBkdXJpbmcgaXRzIGxpZmVjeWNsZS5cblx0ICovXG5cdGNsYXNzIFZpZXcgZXh0ZW5kcyBtYWluXzEuV2ViQ29udGVudHMge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCBpZGVudGl0eSwgJ3ZpZXcnKTtcblx0ICAgICAgICB0aGlzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5cdCAgICAgICAgX1ZpZXdfcHJvdmlkZXJDaGFubmVsQ2xpZW50LnNldCh0aGlzLCBuZXcgbGF6eV8xLkxhenkoKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IHRoaXMuZmluLlBsYXRmb3JtLndyYXBTeW5jKHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgICAgICAgICByZXR1cm4gcGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG5cdCAgICAgICAgfSkpO1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEF0dGFjaGVzIHRoZSBjdXJyZW50IHZpZXcgdG8gdGhlIGdpdmVuIHdpbmRvdyBpZGVudGl0eS5cblx0ICAgICAgICAgKiBJZGVudGl0eSBtdXN0IGJlIHRoZSBpZGVudGl0eSBvZiBhIHdpbmRvdyBpbiB0aGUgc2FtZSBhcHBsaWNhdGlvbi5cblx0ICAgICAgICAgKiBUaGlzIGRldGFjaGVzIHRoZSB2aWV3IGZyb20gaXRzIGN1cnJlbnQgd2luZG93LCBhbmQgc2V0cyB0aGUgdmlldyB0byBiZSBkZXN0cm95ZWQgd2hlbiBpdHMgbmV3IHdpbmRvdyBjbG9zZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVBdHRhY2gnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gYXR0YWNoVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBjb25zdCB3aW5PcHRpb24gPSB7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOid3aW5PcHRpb25OYW1lJyxcblx0ICAgICAgICAgKiAgICAgICAgIGRlZmF1bHRXaWR0aDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5jcmVhdGUuaHRtbCcsXG5cdCAgICAgICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcblx0ICAgICAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgICAgICogICAgIH07XG5cdCAgICAgICAgICogICAgIGNvbnN0IG5ld1dpbmRvdyA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG5cdCAgICAgICAgICogICAgIHZpZXcuYXR0YWNoKG5ld1dpbmRvdy5pZGVudGl0eSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXR0YWNoVmlldygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IGF0dGFjaGVkIHRvIG5ldyB3aW5kb3cuJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuYXR0YWNoID0gYXN5bmMgKHRhcmdldCkgPT4ge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignYXR0YWNoLXZpZXcnLCB7IHRhcmdldCwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlc3Ryb3lzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcud3JhcFN5bmMoeyB1dWlkOiAndmlld1V1aWQnLCBuYW1lOiAndmlld05hbWUnIH0pO1xuXHQgICAgICAgICAqIHZpZXcuZGVzdHJveSgpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmRlc3Ryb3kgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdkZXN0cm95LXZpZXcnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBTaG93cyB0aGUgY3VycmVudCB2aWV3IGlmIGl0IGlzIGN1cnJlbnRseSBoaWRkZW4uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVTaG93Jyxcblx0ICAgICAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgICAgICogICAgICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIGhpZGVBbmRTaG93VmlldygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybCBvcHRpb24uJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5oaWRlKCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKFwiVmlldyBoaWRkZW4uXCIpO1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZpZXcuc2hvdygpO1xuXHQgICAgICAgICAqICAgICBjb25zb2xlLmxvZyhcIlZpZXcgc2hvd24uXCIpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGhpZGVBbmRTaG93VmlldygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IGhpZGRlbiBhbmQgc2hvd24uJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuc2hvdyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctdmlldycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFNldHMgdGhlIGJvdW5kcyAodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgdmlldyByZWxhdGl2ZSB0byBpdHMgd2luZG93IGFuZCBzaG93cyBpdCBpZiBpdCBpcyBoaWRkZW4uXG5cdCAgICAgICAgICogVGhpcyBtZXRob2QgZW5zdXJlcyB0aGUgdmlldyBpcyBib3RoIHBvc2l0aW9uZWQgYW5kIHNob3dpbmcuIEl0IHdpbGwgcmVwb3NpdGlvbiBhIHZpc2libGUgdmlldyBhbmQgYm90aCBzaG93IGFuZCByZXBvc2l0aW9uIGEgaGlkZGVuIHZpZXcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmVtYXJrcyBWaWV3IHBvc2l0aW9uIGlzIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAgICAgKiAoe3RvcDogMCwgbGVmdDogMH0gcmVwcmVzZW50cyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cpXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVTZXRCb3VuZHMnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd1ZpZXdBdCgpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3LnNob3dBdCh7XG5cdCAgICAgICAgICogICAgICAgICB0b3A6IDEwMCxcblx0ICAgICAgICAgKiAgICAgICAgIGxlZnQ6IDEwMCxcblx0ICAgICAgICAgKiAgICAgICAgIHdpZHRoOiAzMDAsXG5cdCAgICAgICAgICogICAgICAgICBoZWlnaHQ6IDMwMFxuXHQgICAgICAgICAqICAgICB9LCB7XG5cdCAgICAgICAgICogICAgICAgYnJpbmdUb0Zyb250IDogdHJ1ZVxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBzaG93Vmlld0F0KClcblx0ICAgICAgICAgKiAgICAgLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1ZpZXcgc2V0IHRvIG5ldyBib3VuZHMgYW5kIHNob3duLicpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnNob3dBdCA9IGFzeW5jIChib3VuZHMsIG9wdGlvbnMgPSB7fSkgPT4ge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy12aWV3LWF0JywgeyBib3VuZHMsIC4uLnRoaXMuaWRlbnRpdHksIG9wdGlvbnMgfSk7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBCcmluZ3MgdGhlIHNwZWNpZmllZCB2aWV3IHRvIHRoZSBmcm9udCBvZiBpdHMgY3VycmVudCB3aW5kb3cuIFRoaXMgZW5zdXJlcyB0aGUgdmlldyB3aWxsIGJlIHZpc2libGUgb24gdG9wIG9mIGFueSBvdGhlciB2aWV3c1xuXHQgICAgICAgICAqIHdoaWNoIGhhdmUgb3ZlcmxhcHBpbmcgYm91bmRzIHdpdGggaXQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBQbGVhc2Ugbm90ZSwgdGhpcyBpcyBub3QgYSBwZXJtYW5lbnQgYWN0aW9uIC0gd2hlbiBhIG5ldyB2aWV3IGlzIGNyZWF0ZWQgb3IgYXR0YWNoZWQgdG8gdGhlIHdpbmRvdywgaXQgd2lsbCBkaXNwbGF5IG9uIHRvcCBvZiBhbGwgb3RoZXIgdmlld3Ncblx0ICAgICAgICAgKiBpbiB0aGUgd2luZG93IHRoYXQgc2hhcmUgYm91bmRzIHdpdGggaXQuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdicmluZy12aWV3LXRvLWZyb250JywgeyAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSGlkZXMgdGhlIGN1cnJlbnQgdmlldyBpZiBpdCBpcyBjdXJyZW50bHkgdmlzaWJsZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUhpZGUnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gaGlkZVZpZXcoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5oaWRlKCk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogaGlkZVZpZXcoKVxuXHQgICAgICAgICAqICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnVmlldyBoaWRkZW4uJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuaGlkZSA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hpZGUtdmlldycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFNldHMgdGhlIGJvdW5kcyAodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgdmlldyByZWxhdGl2ZSB0byBpdHMgd2luZG93LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJlbWFya3MgVmlldyBwb3NpdGlvbiBpcyByZWxhdGl2ZSB0byB0aGUgYm91bmRzIG9mIHRoZSB3aW5kb3cuXG5cdCAgICAgICAgICogKHt0b3A6IDAsIGxlZnQ6IDB9IHJlcHJlc2VudHMgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93KVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBqc1xuXHQgICAgICAgICAqIGxldCB2aWV3O1xuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVZpZXcoKSB7XG5cdCAgICAgICAgICogICAgIGNvbnN0IG1lID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG5cdCAgICAgICAgICogICAgIHJldHVybiBmaW4uVmlldy5jcmVhdGUoe1xuXHQgICAgICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lU2V0Qm91bmRzJyxcblx0ICAgICAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgICAgICogICAgICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFZpZXdCb3VuZHMoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5zZXRCb3VuZHMoe1xuXHQgICAgICAgICAqICAgICAgICAgdG9wOiAxMDAsXG5cdCAgICAgICAgICogICAgICAgICBsZWZ0OiAxMDAsXG5cdCAgICAgICAgICogICAgICAgICB3aWR0aDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgaGVpZ2h0OiAzMDBcblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogc2V0Vmlld0JvdW5kcygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IHNldCB0byBuZXcgYm91bmRzLicpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnNldEJvdW5kcyA9IGFzeW5jIChib3VuZHMpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC12aWV3LWJvdW5kcycsIHsgYm91bmRzLCAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogR2V0cyB0aGUgYm91bmRzICh0b3AsIGxlZnQsIHdpZHRoLCBoZWlnaHQpIG9mIHRoZSB2aWV3IHJlbGF0aXZlIHRvIGl0cyB3aW5kb3cuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmVtYXJrcyBWaWV3IHBvc2l0aW9uIGlzIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAgICAgKiAoe3RvcDogMCwgbGVmdDogMH0gcmVwcmVzZW50cyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cpXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgIG5hbWU6ICd2aWV3TmFtZVNldEJvdW5kcycsXG5cdCAgICAgICAgICogICAgIHRhcmdldDogZmluLm1lLmlkZW50aXR5LFxuXHQgICAgICAgICAqICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogfSk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGF3YWl0IHZpZXcuc2V0Qm91bmRzKHtcblx0ICAgICAgICAgKiAgICAgdG9wOiAxMDAsXG5cdCAgICAgICAgICogICAgIGxlZnQ6IDEwMCxcblx0ICAgICAgICAgKiAgICAgd2lkdGg6IDMwMCxcblx0ICAgICAgICAgKiAgICAgaGVpZ2h0OiAzMDBcblx0ICAgICAgICAgKiB9KTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHZpZXcuZ2V0Qm91bmRzKCkpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldEJvdW5kcyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgYWNrID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC12aWV3LWJvdW5kcycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFjay5wYXlsb2FkLmRhdGE7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBHZXRzIHRoZSBWaWV3J3MgaW5mby5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUdldEluZm8nLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Vmlld0luZm8oKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIHZpZXcuZ2V0SW5mbygpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGdldFZpZXdJbmZvKClcblx0ICAgICAgICAgKiAgICAgLnRoZW4oKGluZm8pID0+IGNvbnNvbGUubG9nKCdWaWV3IGluZm8gZmV0Y2hlZC4nLCBpbmZvKSlcblx0ICAgICAgICAgKiAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAgICAgKiBgYGBcblx0ICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5nZXRJbmZvID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBhY2sgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXZpZXctaW5mbycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFjay5wYXlsb2FkLmRhdGE7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGxheW91dCBmb3IgdGhlIHdpbmRvdyB0aGUgdmlldyBpcyBhdHRhY2hlZCB0by5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiAgICAgLy9nZXQgdGhlIGN1cnJlbnQgVmlld1xuXHQgICAgICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIC8vZ2V0IGEgcmVmZXJlbmNlIHRvIHRoZSBMYXlvdXQgZm9yIHRoZSBXaW5kb3cgdGhlIHZpZXcgaXMgcGFydCBvZlxuXHQgICAgICAgICAqICAgICBjb25zdCBsYXlvdXQgPSBhd2FpdCB2aWV3LmdldFBhcmVudExheW91dCgpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldFBhcmVudExheW91dCA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctZ2V0LXBhcmVudC1sYXlvdXQnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSkuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBjb25zdCBsYXlvdXRXaW5kb3cgPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRXaW5kb3coKTtcblx0ICAgICAgICAgICAgbGV0IGxheW91dFdpbmRvd0lkZW50aXR5ID0gbGF5b3V0V2luZG93LmlkZW50aXR5O1xuXHQgICAgICAgICAgICAvLyBUT0RPOiBDT1JFLTE4NTcgLSB3aGVuIHdlIHRlYXJvdXQgYWN0aXZlIGxheW91dCBvciBkcmFnIGEgdmlldyBvdXQgb2YgYSB3aW5kb3csIHRoZSBhYm92ZSBpZGVudGl0eSBpbmNsdWRlcyB0aGUgd2hvbGUgd2luZG93IGluZm8uXG5cdCAgICAgICAgICAgIGlmIChsYXlvdXRXaW5kb3dJZGVudGl0eS5pZGVudGl0eSkge1xuXHQgICAgICAgICAgICAgICAgbGF5b3V0V2luZG93SWRlbnRpdHkgPSBsYXlvdXRXaW5kb3dJZGVudGl0eS5pZGVudGl0eTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJDaGFubmVsQ2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVmlld19wcm92aWRlckNoYW5uZWxDbGllbnQsIFwiZlwiKS5nZXRWYWx1ZSgpO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgbGF5b3V0X2VudGl0aWVzXzEuTGF5b3V0Tm9kZS5uZXdMYXlvdXRFbnRpdGllc0NsaWVudChwcm92aWRlckNoYW5uZWxDbGllbnQsIGxheW91dF9jb25zdGFudHNfMS5MQVlPVVRfQ09OVFJPTExFUl9JRCwgbGF5b3V0V2luZG93SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0SWRlbnRpdHkgPSBhd2FpdCBjbGllbnQuZ2V0TGF5b3V0SWRlbnRpdHlGb3JWaWV3T3JUaHJvdyh0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcChsYXlvdXRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IGFsbG93ZWRFcnJvcnMgPSBbXG5cdCAgICAgICAgICAgICAgICAgICAgJ05vIGFjdGlvbiByZWdpc3RlcmVkIGF0IHRhcmdldCBmb3InLFxuXHQgICAgICAgICAgICAgICAgICAgICdnZXRMYXlvdXRJZGVudGl0eUZvclZpZXdPclRocm93IGlzIG5vdCBhIGZ1bmN0aW9uJ1xuXHQgICAgICAgICAgICAgICAgXTtcblx0ICAgICAgICAgICAgICAgIGlmICghYWxsb3dlZEVycm9ycy5zb21lKChtKSA9PiBlLm1lc3NhZ2UuaW5jbHVkZXMobSkpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIGxvZ2ljIGZvciBtaXNzaW5nIGVuZHBvaW50XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5maW4uUGxhdGZvcm0uTGF5b3V0LndyYXAobGF5b3V0V2luZG93SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBHZXRzIHRoZSBWaWV3J3Mgb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUdldE9wdGlvbnMnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Vmlld09wdGlvbnMoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogbWUuaWRlbnRpdHkudXVpZCwgbmFtZTogJ3ZpZXdOYW1lR2V0T3B0aW9ucycgfSk7XG5cdCAgICAgICAgICogICAgIHJldHVybiB2aWV3LmdldE9wdGlvbnMoKTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBnZXRWaWV3T3B0aW9ucygpXG5cdCAgICAgICAgICogICAgIC50aGVuKChpbmZvKSA9PiBjb25zb2xlLmxvZygnVmlldyBvcHRpb25zIGZldGNoZWQuJywgaW5mbykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuZ2V0T3B0aW9ucyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtdmlldy1vcHRpb25zJywgeyAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogVXBkYXRlcyB0aGUgdmlldydzIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2dvb2dsZS5jb20nLFxuXHQgICAgICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lVXBkYXRlT3B0aW9ucycsXG5cdCAgICAgICAgICogICAgICAgICB0YXJnZXQ6IG1lLmlkZW50aXR5LFxuXHQgICAgICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiB1cGRhdGVWaWV3T3B0aW9ucygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybCBvcHRpb24uJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHsgYXV0b1Jlc2l6ZToge1xuXHQgICAgICAgICAqICAgICAgICAgd2lkdGg6IHRydWUsXG5cdCAgICAgICAgICogICAgICAgICBob3Jpem9udGFsOiB0cnVlXG5cdCAgICAgICAgICogICAgIH19O1xuXHQgICAgICAgICAqICAgICByZXR1cm4gdmlldy51cGRhdGVPcHRpb25zKG5ld09wdGlvbnMpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIHVwZGF0ZVZpZXdPcHRpb25zKClcblx0ICAgICAgICAgKiAgICAgLnRoZW4ocGF5bG9hZCA9PiBjb25zb2xlLmxvZygnVmlldyBvcHRpb25zIHVwZGF0ZWQ6ICcsIHBheWxvYWQpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnVwZGF0ZU9wdGlvbnMgPSBhc3luYyAob3B0aW9ucykgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3VwZGF0ZS12aWV3LW9wdGlvbnMnLCB7IG9wdGlvbnMsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmV0cmlldmVzIHRoZSB3aW5kb3cgdGhlIHZpZXcgaXMgY3VycmVudGx5IGF0dGFjaGVkIHRvLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBqc1xuXHQgICAgICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy53cmFwU3luYyh7IHV1aWQ6ICd2aWV3VXVpZCcsIG5hbWU6ICd2aWV3TmFtZScgfSk7XG5cdCAgICAgICAgICogdmlldy5nZXRDdXJyZW50V2luZG93KClcblx0ICAgICAgICAgKiAgICAgLnRoZW4od2luID0+IGNvbnNvbGUubG9nKCdjdXJyZW50IHdpbmRvdycsIHdpbikpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7KVxuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldEN1cnJlbnRXaW5kb3cgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtdmlldy13aW5kb3cnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgd2luZG93XzEuX1dpbmRvdyh0aGlzLndpcmUsIGRhdGEpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmV0cmlldmVzIHRoZSBjdXJyZW50IHtAbGluayBPcGVuRmluLlRhYlN0YWNrfSBvZiB0aGUgdmlldyBpZiBpdCBiZWxvbmdzIHRvIG9uZS5cblx0ICAgICAgICAgKiBAcmV0dXJucyB0aGlzIHZpZXcgYmVsb25ncyB0by5cblx0ICAgICAgICAgKiBAdGhyb3dzIGlmIHRoaXMgdmlldyBkb2VzIG5vdCBiZWxvbmcgdG8gYSBUYWJTdGFjayBvciBpZiB0aGUgd2luZG93IGhhcyBiZWVuIGRlc3Ryb3llZC5cblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogaWYgKCFmaW4ubWUuaXNWaWV3KSB7XG5cdCAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuXHQgICAgICAgICAqIC8vIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gd3JhcCBhbnkgdmlldyBhbmQgZ2V0IHRoZSBzdGFjayBmcm9tIHRoZXJlXG5cdCAgICAgICAgICogLy8gY29uc3Qgdmlld0Zyb21Tb21ld2hlcmUgPSBmaW4uVmlldy53cmFwU3luYyhzb21lVmlldy5pZGVudGl0eSk7XG5cdCAgICAgICAgICogLy8gY29uc3Qgc3RhY2sgPSBhd2FpdCB2aWV3RnJvbVNvbWV3aGVyZS5nZXRDdXJyZW50U3RhY2soKTtcblx0ICAgICAgICAgKiBjb25zdCB2aWV3cyA9IGF3YWl0IHN0YWNrLmdldFZpZXdzKCk7XG5cdCAgICAgICAgICogY29uc29sZS5sb2coYFN0YWNrIGNvbnRhaW5zICR7dmlld3MubGVuZ3RofSB2aWV3KHMpYCk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5nZXRDdXJyZW50U3RhY2sgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd2aWV3LWdldC1jdXJyZW50LXN0YWNrJykuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0V2luZG93ID0gYXdhaXQgdGhpcy5nZXRDdXJyZW50V2luZG93KCk7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwcm92aWRlckNoYW5uZWxDbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9WaWV3X3Byb3ZpZGVyQ2hhbm5lbENsaWVudCwgXCJmXCIpLmdldFZhbHVlKCk7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBsYXlvdXRfZW50aXRpZXNfMS5MYXlvdXROb2RlLm5ld0xheW91dEVudGl0aWVzQ2xpZW50KHByb3ZpZGVyQ2hhbm5lbENsaWVudCwgbGF5b3V0X2NvbnN0YW50c18xLkxBWU9VVF9DT05UUk9MTEVSX0lELCBsYXlvdXRXaW5kb3cuaWRlbnRpdHkpO1xuXHQgICAgICAgICAgICAgICAgY29uc3Qgc3RhY2tEZWZpbml0aW9uID0gKGF3YWl0IGNsaWVudC5nZXRTdGFja0J5Vmlldyh0aGlzLmlkZW50aXR5KSk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbGF5b3V0X2VudGl0aWVzXzEuTGF5b3V0Tm9kZS5nZXRFbnRpdHkoc3RhY2tEZWZpbml0aW9uLCBjbGllbnQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5SdW50aW1lRXJyb3IoeyByZWFzb246ICdUaGlzIHZpZXcgZG9lcyBub3QgYmVsb25nIHRvIGEgc3RhY2suJywgZXJyb3IgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFRyaWdnZXJzIHRoZSBiZWZvcmUtdW5sb2FkIGhhbmRsZXIgZm9yIHRoZSBWaWV3LCBpZiBvbmUgaXMgc2V0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJlbWFya3MgUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGhhbmRsZXIgaXMgdHJ5aW5nIHRvIHByZXZlbnQgdGhlIFZpZXcgZnJvbSB1bmxvYWRpbmcsIGFuZCBgZmFsc2VgIGlmIGl0IGlzbid0LlxuXHQgICAgICAgICAqIE9ubHkgZW5hYmxlZCB3aGVuIHNldHRpbmcgZW5hYmxlQmVmb3JlVW5sb2FkOiB0cnVlIGluIHlvdXIgVmlldyBvcHRpb25zLiBJZiB0aGlzIG9wdGlvbiBpcyBub3QgZW5hYmxlZCBpdCB3aWxsXG5cdCAgICAgICAgICogYWx3YXlzIHJldHVybiBmYWxzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgUGxhdGZvcm0gUHJvdmlkZXIgdG8gZGV0ZXJtaW5lIHRoZSBzdGF0dXMgb2YgZWFjaCBiZWZvcmUgdW5sb2FkIGhhbmRsZXIgaW4gVmlld3Mgd2hlbiBjbG9zaW5nIHRoZSBXaW5kb3cuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiAvLyBmcm9tIGluc2lkZSBhIFZpZXcgY29udGV4dFxuXHQgICAgICAgICAqIGNvbnN0IHVubG9hZFByZXZlbnRlZCA9IGF3YWl0IGZpbi5tZS50cmlnZ2VyQmVmb3JlVW5sb2FkKCk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy50cmlnZ2VyQmVmb3JlVW5sb2FkID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3RyaWdnZXItYmVmb3JlLXVubG9hZCcsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UucGF5bG9hZC5kYXRhO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogKipOT1RFKio6IEludGVybmFsIHVzZSBvbmx5LlxuXHQgICAgICAgICAqIEF0dGFjaGVzIHRoaXMgdmlldyB0byBhbiBIVE1MIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgY29udGV4dC4gVGhlIHZpZXcgd2lsbCByZXNpemUgcmVzcG9uc2l2ZWx5IHdoZW4gdGhlIGVsZW1lbnQgYm91bmRzIGNoYW5nZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICoqS25vd24gaXNzdWUqKjogVmlldy5iaW5kVG9FbGVtZW50IGRvZXMgbm90IHRyYWNrIHBvc2l0aW9uIGNoYW5nZXMsIGlmIHRoZSBlbGVtZW50IGhhcyBmaXhlZCBweCB3aWR0aCBhbmQgaGVpZ2h0IHZhbHVlcyBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIHZpZXcgdG8gbm90IHVwZGF0ZSByZXNwb25zaXZlbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAqKktub3duIGlzc3VlKio6IFdoZW4gVmlldy5iaW5kVG9FbGVtZW50IGlzIHVzZWQgb24gYSBlbGVtZW50IHRoYXQgdGFrZXMgdXAgdGhlIGVudGlyZSBwYWdlIGluIGEgcGxhdGZvcm0gd2luZG93LCB0aGUgYm91bmQgdmlldyB3aWxsIG5vdCByZXNwb25kIHJlc3BvbnNpdmVseSB3aGVuIHRoZSB3aW5kb3cgaXMgcmVzaXplZCB0byBiZSBzbWFsbGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgLSBIVE1MIGVsZW1lbnQgdG8gYXR0YWNoIHRoZSB2aWV3IHRvLlxuXHQgICAgICAgICAqIEByZXR1cm5zIC0gQ2xlYW51cCBmdW5jdGlvbiB0aGF0IHdpbGwgZGlzY29ubmVjdCB0aGUgZWxlbWVudCByZXNpemUgb2JzZXJ2ZXIuXG5cdCAgICAgICAgICogQGludGVybmFsXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqIEByZW1hcmtzIFZpZXcgd2lsbCByZXNpemUgYWNjb3JkaW5nbHkgd2hlbiB0aGUgZWxlbWVudCBpcyByZXNpemVkLiBJZiB0aGUgZWxlbWVudCBpcyByZXBvc2l0aW9uZWQgaW4gdGhlIERPTSB0aGUgdmlldyB3aWxsIG5vdCBiZSByZXBvc2l0aW9uZWQsIHRvIGhhbmRsZSB0aGlzIGNhc2UgY2FsbCBgYmluZFRvRWxlbWVudGAgYWdhaW4gb25jZSB0aGUgZWxlbWVudCBjaGFuZ2VzIHBvc2l0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBodG1sXG5cdCAgICAgICAgICogPGRpdiBpZD1cInZpZXctY29udGFpbmVyXCI+PC9kaXY+XG5cdCAgICAgICAgICogPHNjcmlwdD5cblx0ICAgICAgICAgKiAgICAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQW5kQXR0YWNoVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IHVybCA9ICdodHRwczovL2V4YW1wbGUuY29tJztcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IGVsZW1lbnRJZCA9ICd2aWV3LWNvbnRhaW5lcic7XG5cdCAgICAgICAgICogICAgICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuXHQgICAgICAgICAqICAgICAgICAgICAgIG5hbWU6ICdteS12aWV3Jyxcblx0ICAgICAgICAgKiAgICAgICAgICAgICB1cmwsXG5cdCAgICAgICAgICogICAgICAgICAgICAgdGFyZ2V0OiBmaW4ubWUuaWRlbnRpdHlcblx0ICAgICAgICAgKiAgICAgICAgIH0pO1xuXHQgICAgICAgICAqICAgICAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSh1cmwpO1xuXHQgICAgICAgICAqICAgICAgICAgYXdhaXQgdmlldy5iaW5kVG9FbGVtZW50KGVsZW1lbnQpO1xuXHQgICAgICAgICAqICAgICB9XG5cdCAgICAgICAgICogICAgIGNyZWF0ZUFuZEF0dGFjaFZpZXcoKS5jYXRjaChjb25zb2xlLmVycm9yKTtcblx0ICAgICAgICAgKiA8L3NjcmlwdD5cblx0ICAgICAgICAgKiBgYGBcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmJpbmRUb0VsZW1lbnQgPSBhc3luYyAoZWxlbWVudCkgPT4ge1xuXHQgICAgICAgICAgICBpZiAoIWVsZW1lbnQpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxlbWVudCBub3QgZm91bmQuJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3Qgb25DaGFuZ2UgPSBhc3luYyAoYm91bmRzKSA9PiB0aGlzLnNldEJvdW5kcyhib3VuZHMpO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50Lm9ic2VydmVCb3VuZHMoZWxlbWVudCwgb25DaGFuZ2UpO1xuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZvY3VzZXMgdGhlIHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy53cmFwU3luYyh7IHV1aWQ6ICd2aWV3VXVpZCcsIG5hbWU6ICd2aWV3TmFtZScgfSk7XG5cdCAgICAgKiBhd2FpdCB2aWV3LmZvY3VzKCk7XG5cdCAgICAgKiAvLyBkbyB0aGluZ3Mgd2l0aCB0aGUgZm9jdXNlZCB2aWV3XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZm9jdXMoeyBlbWl0U3ludGhGb2N1c2VkIH0gPSB7IGVtaXRTeW50aEZvY3VzZWQ6IHRydWUgfSkge1xuXHQgICAgICAgIGNvbnN0IHdpbiA9IGF3YWl0IHRoaXMuZ2V0Q3VycmVudFdpbmRvdygpO1xuXHQgICAgICAgIGF3YWl0IHdpbi5mb2N1c2VkV2ViVmlld1dhc0NoYW5nZWQoKTtcblx0ICAgICAgICBhd2FpdCBzdXBlci5mb2N1cyh7IGVtaXRTeW50aEZvY3VzZWQgfSk7XG5cdCAgICB9XG5cdH1cblx0SW5zdGFuY2UkNS5WaWV3ID0gVmlldztcblx0X1ZpZXdfcHJvdmlkZXJDaGFubmVsQ2xpZW50ID0gbmV3IFdlYWtNYXAoKTtcblx0cmV0dXJuIEluc3RhbmNlJDU7XG59XG5cbnZhciBoYXNSZXF1aXJlZFZpZXc7XG5cbmZ1bmN0aW9uIHJlcXVpcmVWaWV3ICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkVmlldykgcmV0dXJuIHZpZXc7XG5cdGhhc1JlcXVpcmVkVmlldyA9IDE7XG5cdChmdW5jdGlvbiAoZXhwb3J0cykge1xuXHRcdHZhciBfX2NyZWF0ZUJpbmRpbmcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jcmVhdGVCaW5kaW5nKSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdFx0ICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG5cdFx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0XHQgICAgfVxuXHRcdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xuXHRcdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdFx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdFx0ICAgIG9bazJdID0gbVtrXTtcblx0XHR9KSk7XG5cdFx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0XHQgICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChleHBvcnRzLCBwKSkgX19jcmVhdGVCaW5kaW5nKGV4cG9ydHMsIG0sIHApO1xuXHRcdH07XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRcdC8qKlxuXHRcdCAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIE9wZW5GaW4gYFZpZXdgIEFQSSAoYGZpbi5WaWV3YCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBWaWV3TW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYFZpZXdgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uVmlld2AuXG5cdFx0ICogKiB7QGxpbmsgVmlld30gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gVmlldywgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlZpZXcuZ2V0Q3VycmVudGAuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdFx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQzKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UkMigpLCBleHBvcnRzKTsgXG5cdH0gKHZpZXcpKTtcblx0cmV0dXJuIHZpZXc7XG59XG5cbnZhciBoYXNSZXF1aXJlZEluc3RhbmNlJDE7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSQxICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkSW5zdGFuY2UkMSkgcmV0dXJuIEluc3RhbmNlJDY7XG5cdGhhc1JlcXVpcmVkSW5zdGFuY2UkMSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSQ2LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW5zdGFuY2UkNi5BcHBsaWNhdGlvbiA9IHZvaWQgMDtcblx0LyogZXNsaW50LWRpc2FibGUgaW1wb3J0L3ByZWZlci1kZWZhdWx0LWV4cG9ydCAqL1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCB3aW5kb3dfMSA9IHJlcXVpcmVXaW5kb3coKTtcblx0Y29uc3Qgdmlld18xID0gcmVxdWlyZVZpZXcoKTtcblx0LyoqXG5cdCAqIEFuIG9iamVjdCByZXByZXNlbnRpbmcgYW4gYXBwbGljYXRpb24uIEFsbG93cyB0aGUgZGV2ZWxvcGVyIHRvIGNyZWF0ZSxcblx0ICogZXhlY3V0ZSwgc2hvdy9jbG9zZSBhbiBhcHBsaWNhdGlvbiBhcyB3ZWxsIGFzIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50cyBhcHBsaWNhdGlvbiBldmVudHN9LlxuXHQgKi9cblx0Y2xhc3MgQXBwbGljYXRpb24gZXh0ZW5kcyBiYXNlXzEuRW1pdHRlckJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCAnYXBwbGljYXRpb24nLCBpZGVudGl0eS51dWlkKTtcblx0ICAgICAgICB0aGlzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5cdCAgICAgICAgdGhpcy53aW5kb3cgPSBuZXcgd2luZG93XzEuX1dpbmRvdyh0aGlzLndpcmUsIHtcblx0ICAgICAgICAgICAgdXVpZDogdGhpcy5pZGVudGl0eS51dWlkLFxuXHQgICAgICAgICAgICBuYW1lOiB0aGlzLmlkZW50aXR5LnV1aWRcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIHdpbmRvd0xpc3RGcm9tSWRlbnRpdHlMaXN0KGlkZW50aXR5TGlzdCkge1xuXHQgICAgICAgIGNvbnN0IHdpbmRvd0xpc3QgPSBbXTtcblx0ICAgICAgICBpZGVudGl0eUxpc3QuZm9yRWFjaCgoaWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgd2luZG93TGlzdC5wdXNoKG5ldyB3aW5kb3dfMS5fV2luZG93KHRoaXMud2lyZSwge1xuXHQgICAgICAgICAgICAgICAgdXVpZDogaWRlbnRpdHkudXVpZCxcblx0ICAgICAgICAgICAgICAgIG5hbWU6IGlkZW50aXR5Lm5hbWVcblx0ICAgICAgICAgICAgfSkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB3aW5kb3dMaXN0O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBhcHBsaWNhdGlvbiBpcyBjdXJyZW50bHkgcnVubmluZy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc0FwcFJ1bm5pbmcoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmlzUnVubmluZygpO1xuXHQgICAgICogfVxuXHQgICAgICogaXNBcHBSdW5uaW5nKCkudGhlbihydW5uaW5nID0+IGNvbnNvbGUubG9nKGBDdXJyZW50IGFwcCBpcyBydW5uaW5nOiAke3J1bm5pbmd9YCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBpc1J1bm5pbmcoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpcy1hcHBsaWNhdGlvbi1ydW5uaW5nJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENsb3NlcyB0aGUgYXBwbGljYXRpb24gYW5kIGFueSBjaGlsZCB3aW5kb3dzIGNyZWF0ZWQgYnkgdGhlIGFwcGxpY2F0aW9uLlxuXHQgICAgICogQ2xlYW5zIHRoZSBhcHBsaWNhdGlvbiBmcm9tIHN0YXRlIHNvIGl0IGlzIG5vIGxvbmdlciBmb3VuZCBpbiBnZXRBbGxBcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgQ2xvc2Ugd2lsbCBiZSBwcmV2ZW50ZWQgZnJvbSBjbG9zaW5nIHdoZW4gZm9yY2UgaXMgZmFsc2UgYW5kXG5cdCAgICAgKiAg4oCYY2xvc2UtcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjbG9zZUFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhbGxBcHBzMSA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0QWxsQXBwbGljYXRpb25zKCk7IC8vW3t1dWlkOiAnYXBwMScsIGlzUnVubmluZzogdHJ1ZX0sIHt1dWlkOiAnYXBwMicsIGlzUnVubmluZzogdHJ1ZX1dXG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLndyYXAoe3V1aWQ6ICdhcHAyJ30pO1xuXHQgICAgICogICAgIGF3YWl0IGFwcC5xdWl0KCk7XG5cdCAgICAgKiAgICAgY29uc3QgYWxsQXBwczIgPSBhd2FpdCBmaW4uU3lzdGVtLmdldEFsbEFwcGxpY2F0aW9ucygpOyAvL1t7dXVpZDogJ2FwcDEnLCBpc1J1bm5pbmc6IHRydWV9XVxuXHQgICAgICpcblx0ICAgICAqIH1cblx0ICAgICAqIGNsb3NlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gcXVpdCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcXVpdChmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy5fY2xvc2UoZm9yY2UpO1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZGVzdHJveS1hcHBsaWNhdGlvbicsIHsgZm9yY2UsIC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBhY2NlcHRhYmxlRXJyb3JzID0gWydSZW1vdGUgY29ubmVjdGlvbiBoYXMgY2xvc2VkJywgJ0NvdWxkIG5vdCBsb2NhdGUgdGhlIHJlcXVlc3RlZCBhcHBsaWNhdGlvbiddO1xuXHQgICAgICAgICAgICBpZiAoIWFjY2VwdGFibGVFcnJvcnMuc29tZSgobXNnKSA9PiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKG1zZykpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIF9jbG9zZShmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Nsb3NlLWFwcGxpY2F0aW9uJywgeyBmb3JjZSwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGlmICghZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnUmVtb3RlIGNvbm5lY3Rpb24gaGFzIGNsb3NlZCcpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgdXNlIEFwcGxpY2F0aW9uLnF1aXQgaW5zdGVhZFxuXHQgICAgICogQ2xvc2VzIHRoZSBhcHBsaWNhdGlvbiBhbmQgYW55IGNoaWxkIHdpbmRvd3MgY3JlYXRlZCBieSB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgLSBDbG9zZSB3aWxsIGJlIHByZXZlbnRlZCBmcm9tIGNsb3Npbmcgd2hlbiBmb3JjZSBpcyBmYWxzZSBhbmQg4oCYY2xvc2UtcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvdy5cblx0ICAgICAqIEBwYXJhbSBjYWxsYmFjayAtIGNhbGxlZCBpZiB0aGUgbWV0aG9kIHN1Y2NlZWRzLlxuXHQgICAgICogQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBjYWxsZWQgaWYgdGhlIG1ldGhvZCBmYWlscy4gVGhlIHJlYXNvbiBmb3IgZmFpbHVyZSBpcyBwYXNzZWQgYXMgYW4gYXJndW1lbnQuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY2xvc2VBcHAoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmNsb3NlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKiBjbG9zZUFwcCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIGNsb3NlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY2xvc2UoZm9yY2UgPSBmYWxzZSkge1xuXHQgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gV2FybmluZzogQXBwbGljYXRpb24uY2xvc2UgaXMgZGVwcmVjYXRlZCBQbGVhc2UgdXNlIEFwcGxpY2F0aW9uLnF1aXQnKTtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tY2xvc2UnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2UoZm9yY2UpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2Ygd3JhcHBlZCBmaW4uV2luZG93cyBmb3IgZWFjaCBvZiB0aGUgYXBwbGljYXRpb27igJlzIGNoaWxkIHdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Q2hpbGRXaW5kb3dzKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRDaGlsZFdpbmRvd3MoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRDaGlsZFdpbmRvd3MoKS50aGVuKGNoaWxkcmVuID0+IGNvbnNvbGUubG9nKGNoaWxkcmVuKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldENoaWxkV2luZG93cygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jaGlsZC13aW5kb3dzJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgaWRlbnRpdHlMaXN0ID0gW107XG5cdCAgICAgICAgICAgIHBheWxvYWQuZGF0YS5mb3JFYWNoKCh3aW5OYW1lKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZGVudGl0eUxpc3QucHVzaCh7IHV1aWQ6IHRoaXMuaWRlbnRpdHkudXVpZCwgbmFtZTogd2luTmFtZSB9KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLndpbmRvd0xpc3RGcm9tSWRlbnRpdHlMaXN0KGlkZW50aXR5TGlzdCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyB0aGUgSlNPTiBtYW5pZmVzdCB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSB0aGUgYXBwbGljYXRpb24uIEludm9rZXMgdGhlIGVycm9yIGNhbGxiYWNrXG5cdCAgICAgKiBpZiB0aGUgYXBwbGljYXRpb24gd2FzIG5vdCBjcmVhdGVkIGZyb20gYSBtYW5pZmVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRNYW5pZmVzdCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0TWFuaWZlc3QoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRNYW5pZmVzdCgpLnRoZW4obWFuaWZlc3QgPT4gY29uc29sZS5sb2cobWFuaWZlc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0TWFuaWZlc3QoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYXBwbGljYXRpb24tbWFuaWZlc3QnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIFVVSUQgb2YgdGhlIGFwcGxpY2F0aW9uIHRoYXQgbGF1bmNoZXMgdGhpcyBhcHBsaWNhdGlvbi4gSW52b2tlcyB0aGUgZXJyb3IgY2FsbGJhY2tcblx0ICAgICAqIGlmIHRoZSBhcHBsaWNhdGlvbiB3YXMgY3JlYXRlZCBmcm9tIGEgbWFuaWZlc3QuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50VXVpZCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtQXBwbGljYXRpb24uZ2V0UGFyZW50VXVpZC5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFBhcmVudFV1aWQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRQYXJlbnRVdWlkKCkudGhlbihwYXJlbnRVdWlkID0+IGNvbnNvbGUubG9nKHBhcmVudFV1aWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0UGFyZW50VXVpZCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1wYXJlbnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGN1cnJlbnQgYXBwbGljYXRpb24ncyBzaG9ydGN1dCBjb25maWd1cmF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFNob3J0Y3V0cygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24ud3JhcCh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFNob3J0Y3V0cygpO1xuXHQgICAgICogfVxuXHQgICAgICogZ2V0U2hvcnRjdXRzKCkudGhlbihjb25maWcgPT4gY29uc29sZS5sb2coY29uZmlnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldFNob3J0Y3V0cygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1zaG9ydGN1dHMnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGN1cnJlbnQgYXBwbGljYXRpb24ncyB2aWV3cy5cblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRWaWV3cygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0Vmlld3MoKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGdldFZpZXdzKCkudGhlbih2aWV3cyA9PiBjb25zb2xlLmxvZyh2aWV3cykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRWaWV3cygpIHtcblx0ICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdhcHBsaWNhdGlvbi1nZXQtdmlld3MnLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhLm1hcCgoaWQpID0+IG5ldyB2aWV3XzEuVmlldyh0aGlzLndpcmUsIGlkKSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgem9vbSBsZXZlbCBvZiB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRab29tTGV2ZWwoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0Wm9vbUxldmVsKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWFwcGxpY2F0aW9uLXpvb20tbGV2ZWwnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB0aGUgbWFpbiBXaW5kb3cgb2YgdGhlIGFwcGxpY2F0aW9uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0V2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1BcHBsaWNhdGlvbi5nZXRXaW5kb3cuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3coKS50aGVuKHdpbiA9PiB7XG5cdCAgICAgKiAgICAgd2luLnNob3dBdCgwLCA0MDApO1xuXHQgICAgICogICAgIHdpbi5mbGFzaCgpO1xuXHQgICAgICogfSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldFdpbmRvdygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tZ2V0LXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy53aW5kb3cpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBNYW51YWxseSByZWdpc3RlcnMgYSB1c2VyIHdpdGggdGhlIGxpY2Vuc2luZyBzZXJ2aWNlLiBUaGUgb25seSBkYXRhIHNlbnQgYnkgdGhpcyBjYWxsIGlzIHVzZXJOYW1lIGFuZCBhcHBOYW1lLlxuXHQgICAgICogQHBhcmFtIHVzZXJOYW1lIC0gdXNlcm5hbWUgdG8gYmUgcGFzc2VkIHRvIHRoZSBSVk0uXG5cdCAgICAgKiBAcGFyYW0gYXBwTmFtZSAtIGFwcCBuYW1lIHRvIGJlIHBhc3NlZCB0byB0aGUgUlZNLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlZ2lzdGVyVXNlcigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAucmVnaXN0ZXJVc2VyKCd1c2VyJywgJ215QXBwJyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogcmVnaXN0ZXJVc2VyKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQgdGhlIHVzZXInKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHJlZ2lzdGVyVXNlcih1c2VyTmFtZSwgYXBwTmFtZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVnaXN0ZXItdXNlcicsIHsgdXNlck5hbWUsIGFwcE5hbWUsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZW1vdmVzIHRoZSBhcHBsaWNhdGlvbuKAmXMgaWNvbiBmcm9tIHRoZSB0cmF5LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlbW92ZVRyYXlJY29uKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5yZW1vdmVUcmF5SWNvbigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlbW92ZVRyYXlJY29uKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnUmVtb3ZlZCB0aGUgdHJheSBpY29uLicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVtb3ZlVHJheUljb24oKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdyZW1vdmUtdHJheS1pY29uJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXN0YXJ0cyB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcmVzdGFydEFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAucmVzdGFydCgpO1xuXHQgICAgICogfVxuXHQgICAgICogcmVzdGFydEFwcCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIHJlc3RhcnRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVzdGFydCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Jlc3RhcnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIERFUFJFQ0FURUQgbWV0aG9kIHRvIHJ1biB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKiBOZWVkZWQgd2hlbiBzdGFydGluZyBhcHBsaWNhdGlvbiB2aWEge0BsaW5rIEFwcGxpY2F0aW9uLmNyZWF0ZX0sIGJ1dCBOT1QgbmVlZGVkIHdoZW4gc3RhcnRpbmcgdmlhIHtAbGluayBBcHBsaWNhdGlvbi5zdGFydH0uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcnVuKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5jcmVhdGUoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtQXBwbGljYXRpb24ucnVuLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGF3YWl0IGFwcC5ydW4oKTtcblx0ICAgICAqIH1cblx0ICAgICAqIHJ1bigpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIGlzIHJ1bm5pbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICBydW4oKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiBXYXJuaW5nOiBBcHBsaWNhdGlvbi5ydW4gaXMgZGVwcmVjYXRlZCBQbGVhc2UgdXNlIGZpbi5BcHBsaWNhdGlvbi5zdGFydCcpO1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdhcHBsaWNhdGlvbi1ydW4nLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fcnVuKCk7XG5cdCAgICB9XG5cdCAgICBfcnVuKG9wdHMgPSB7fSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3J1bi1hcHBsaWNhdGlvbicsIHtcblx0ICAgICAgICAgICAgbWFuaWZlc3RVcmw6IHRoaXMuX21hbmlmZXN0VXJsLFxuXHQgICAgICAgICAgICBvcHRzLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSW5zdHJ1Y3RzIHRoZSBSVk0gdG8gc2NoZWR1bGUgb25lIHJlc3RhcnQgb2YgdGhlIGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNjaGVkdWxlUmVzdGFydCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2NoZWR1bGVSZXN0YXJ0KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2NoZWR1bGVSZXN0YXJ0KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gaXMgc2NoZWR1bGVkIHRvIHJlc3RhcnQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNjaGVkdWxlUmVzdGFydCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlbGF1bmNoLW9uLWNsb3NlJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIFJWTSB0byB1cGxvYWQgdGhlIGFwcGxpY2F0aW9uJ3MgbG9ncy4gT24gc3VjY2Vzcyxcblx0ICAgICAqIGFuIG9iamVjdCBjb250YWluaW5nIGxvZ0lkIGlzIHJldHVybmVkLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNlbmRMb2coKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnNlbmRBcHBsaWNhdGlvbkxvZygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHNlbmRMb2coKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mby5sb2dJZCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZW5kQXBwbGljYXRpb25Mb2coKSB7XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2VuZC1hcHBsaWNhdGlvbi1sb2cnLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIG9yIHJlbW92ZXMgYSBjdXN0b20gSnVtcExpc3QgZm9yIHRoZSBhcHBsaWNhdGlvbi4gT25seSBhcHBsaWNhYmxlIGluIFdpbmRvd3MgT1MuXG5cdCAgICAgKiBJZiBjYXRlZ29yaWVzIGlzIG51bGwgdGhlIHByZXZpb3VzbHkgc2V0IGN1c3RvbSBKdW1wTGlzdCAoaWYgYW55KSB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBzdGFuZGFyZCBKdW1wTGlzdCBmb3IgdGhlIGFwcCAobWFuYWdlZCBieSBXaW5kb3dzKS5cblx0ICAgICAqXG5cdCAgICAgKiBOb3RlOiBJZiB0aGUgXCJuYW1lXCIgcHJvcGVydHkgaXMgb21pdHRlZCBpdCBkZWZhdWx0cyB0byBcInRhc2tzXCIuXG5cdCAgICAgKiBAcGFyYW0ganVtcExpc3RDYXRlZ29yaWVzIEFuIGFycmF5IG9mIEp1bXBMaXN0IENhdGVnb3JpZXMgdG8gcG9wdWxhdGUuIElmIG51bGwsIHJlbW92ZSBhbnkgZXhpc3RpbmcgSnVtcExpc3QgY29uZmlndXJhdGlvbiBhbmQgc2V0IHRvIFdpbmRvd3MgZGVmYXVsdC5cblx0ICAgICAqXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSWYgY2F0ZWdvcmllcyBpcyBudWxsIHRoZSBwcmV2aW91c2x5IHNldCBjdXN0b20gSnVtcExpc3QgKGlmIGFueSkgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgc3RhbmRhcmQgSnVtcExpc3QgZm9yIHRoZSBhcHAgKG1hbmFnZWQgYnkgV2luZG93cykuXG5cdCAgICAgKlxuXHQgICAgICogVGhlIGJvdHRvbW1vc3QgaXRlbSBpbiB0aGUganVtcGxpc3Qgd2lsbCBhbHdheXMgYmUgYW4gaXRlbSBwb2ludGluZyB0byB0aGUgY3VycmVudCBhcHAuIEl0cyBuYW1lIGlzIHRha2VuIGZyb20gdGhlIG1hbmlmZXN0J3Ncblx0ICAgICAqICoqYCBzaG9ydGN1dC5uYW1lIGAqKiBhbmQgdXNlcyAqKmAgc2hvcnRjdXQuY29tcGFueSBgKiogYXMgYSBmYWxsYmFjay4gQ2xpY2tpbmcgdGhhdCBpdGVtIHdpbGwgbGF1bmNoIHRoZSBhcHAgZnJvbSBpdHMgY3VycmVudCBtYW5pZmVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBOb3RlOiBJZiB0aGUgXCJuYW1lXCIgcHJvcGVydHkgaXMgb21pdHRlZCBpdCBkZWZhdWx0cyB0byBcInRhc2tzXCIuXG5cdCAgICAgKlxuXHQgICAgICogTm90ZTogV2luZG93IE9TIGNhY2hlcyBqdW1wbGlzdHMgaWNvbnMsIHRoZXJlZm9yZSBhbiBpY29uIGNoYW5nZSBtaWdodCBvbmx5IGJlIHZpc2libGUgYWZ0ZXIgdGhlIGNhY2hlIGlzIHJlbW92ZWQgb3IgdGhlXG5cdCAgICAgKiB1dWlkIG9yIHNob3J0Y3V0Lm5hbWUgaXMgY2hhbmdlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwTmFtZSA9ICdNeSBBcHAnO1xuXHQgICAgICogICAgIGNvbnN0IGp1bXBMaXN0Q29uZmlnID0gWyAvLyBhcnJheSBvZiBKdW1wTGlzdCBjYXRlZ29yaWVzXG5cdCAgICAgKiAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgIC8vIGhhcyBubyBuYW1lIGFuZCBubyB0eXBlIHNvIGB0eXBlYCBpcyBhc3N1bWVkIHRvIGJlIFwidGFza3NcIlxuXHQgICAgICogICAgICAgICAgICAgaXRlbXM6IFsgLy8gYXJyYXkgb2YgSnVtcExpc3QgaXRlbXNcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6IGBMYXVuY2ggJHthcHBOYW1lfWAsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBSdW5zICR7YXBwTmFtZX0gd2l0aCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uYCxcblx0ICAgICAqICAgICAgICAgICAgICAgICBkZWVwTGluazogJ2ZpbnM6Ly9wYXRoLnRvL2FwcC9tYW5pZmVzdC5qc29uJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICBpY29uUGF0aDogJ2h0dHBzOi8vcGF0aC50by9hcHAvaWNvbi5pY28nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25JbmRleDogMFxuXHQgICAgICogICAgICAgICAgICAgfSxcblx0ICAgICAqICAgICAgICAgICAgIHsgdHlwZTogJ3NlcGFyYXRvcicgfSxcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6IGBSZXN0b3JlICR7YXBwTmFtZX1gLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVzdG9yZSB0byBsYXN0IGNvbmZpZ3VyYXRpb24nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlZXBMaW5rOiAnZmluczovL3BhdGgudG8vYXBwL21hbmlmZXN0Lmpzb24/JCR1c2UtbGFzdC1jb25maWd1cmF0aW9uPXRydWUnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25QYXRoOiAnaHR0cHM6Ly9wYXRoLnRvL2FwcC9pY29uLmljbycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvbkluZGV4OiAwXG5cdCAgICAgKiAgICAgICAgICAgICB9LFxuXHQgICAgICogICAgICAgICAgICAgXVxuXHQgICAgICogICAgICAgICB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBuYW1lOiAnVG9vbHMnLFxuXHQgICAgICogICAgICAgICAgICAgaXRlbXM6IFsgLy8gYXJyYXkgb2YgSnVtcExpc3QgaXRlbXNcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6ICdUb29sIEEnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUnVucyBUb29sIEEnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlZXBMaW5rOiAnZmluczovL3BhdGgudG8vdG9vbC1hL21hbmlmZXN0Lmpzb24nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25QYXRoOiAnaHR0cHM6Ly9wYXRoLnRvL3Rvb2wtYS9pY29uLmljbycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvbkluZGV4OiAwXG5cdCAgICAgKiAgICAgICAgICAgICB9LFxuXHQgICAgICogICAgICAgICAgICAge1xuXHQgICAgICogICAgICAgICAgICAgICAgIHR5cGU6ICd0YXNrJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICB0aXRsZTogJ1Rvb2wgQicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSdW5zIFRvb2wgQicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVlcExpbms6ICdmaW5zOi8vcGF0aC50by90b29sLWIvbWFuaWZlc3QuanNvbicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvblBhdGg6ICdodHRwczovL3BhdGgudG8vdG9vbC1iL2ljb24uaWNvJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICBpY29uSW5kZXg6IDBcblx0ICAgICAqICAgICAgICAgICAgIH1dXG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICBdO1xuXHQgICAgICpcblx0ICAgICAqICAgICBhcHAuc2V0SnVtcExpc3QoanVtcExpc3RDb25maWcpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0p1bXBMaXN0IGFwcGxpZWQnKSkuY2F0Y2goZSA9PiBjb25zb2xlLmxvZyhgSnVtcExpc3QgZmFpbGVkIHRvIGFwcGx5OiAke2UudG9TdHJpbmcoKX1gKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBUbyBoYW5kbGUgZGVlcGxpbmsgYXJnczpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgZnVuY3Rpb24gaGFuZGxlVXNlTGFzdENvbmZpZ3VyYXRpb24oKSB7XG5cdCAgICAgKiAgICAgICAgIC8vIHRoaXMgaGFuZGxlciBpcyBjYWxsZWQgd2hlbiB0aGUgYXBwIGlzIGJlaW5nIGxhdW5jaGVkXG5cdCAgICAgKiAgICAgICAgIGFwcC5vbigncnVuLXJlcXVlc3RlZCcsIGV2ZW50ID0+IHtcblx0ICAgICAqICAgICAgICAgICAgIGlmKGV2ZW50LnVzZXJBcHBDb25maWdBcmdzWyd1c2UtbGFzdC1jb25maWd1cmF0aW9uJ10pIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAvLyB5b3VyIGxvZ2ljIGhlcmVcblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgIC8vIHRoaXMgaGFuZGxlciBpcyBjYWxsZWQgd2hlbiB0aGUgYXBwIHdhcyBhbHJlYWR5IHJ1bm5pbmcgd2hlbiB0aGUgbGF1bmNoIHdhcyByZXF1ZXN0ZWRcblx0ICAgICAqICAgICAgICAgZmluLmRlc2t0b3AubWFpbihmdW5jdGlvbihhcmdzKSB7XG5cdCAgICAgKiAgICAgICAgICAgICBpZihhcmdzICYmIGFyZ3NbJ3VzZS1sYXN0LWNvbmZpZ3VyYXRpb24nXSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIHlvdXIgbG9naWMgaGVyZVxuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9KTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc2V0SnVtcExpc3QoanVtcExpc3RDYXRlZ29yaWVzKSB7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1qdW1wLWxpc3QnLCB7IGNvbmZpZzoganVtcExpc3RDYXRlZ29yaWVzLCAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBZGRzIGEgY3VzdG9taXphYmxlIGljb24gaW4gdGhlIHN5c3RlbSB0cmF5LiAgVG8gbGlzdGVuIGZvciBhIGNsaWNrIG9uIHRoZSBpY29uIHVzZSB0aGUgYHRyYXktaWNvbi1jbGlja2VkYCBldmVudC5cblx0ICAgICAqIEBwYXJhbSBpY29uIEltYWdlIFVSTCBvciBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYmUgdXNlZCBhcyB0aGUgaWNvblxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGltYWdlVXJsID0gXCJodHRwOi8vY2RuLm9wZW5maW4uY28vYXNzZXRzL3Rlc3RpbmcvaWNvbnMvY2lyY2xlZC1kaWdpdC1vbmUucG5nXCI7XG5cdCAgICAgKiBjb25zdCBiYXNlNjRFbmNvZGVkSW1hZ2UgPSBcImlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBZ0FBQUFJQVFNQUFBRCt3U3pJQUFBQUJsQk1WRVhcXFxuXHQgICAgICogLy8vKy92NytqUTNZNUFBQUFEa2xFUVZRSTEyUDRBSVg4RUFnQUxnQUQvYU5wYnRFQUFBQUFTVVZPUks1Q1lJSVwiO1xuXHQgICAgICogY29uc3QgZGF0YVVSTCA9IFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBVUFBQUFGQ0FZQUFBQ05ieWJsQUFBQUhFbEVRVlFJMTJQNC8vOC93MzhHSUFYRElCS0UwREhcXFxuXHQgICAgICogeGdsak5CQUFPOVRYTDBZNE9Id0FBQUFCSlJVNUVya0pnZ2c9PVwiO1xuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFRyYXlJY29uKGljb24pIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2V0VHJheUljb24oaWNvbik7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogLy8gdXNlIGltYWdlIHVybCB0byBzZXQgdHJheSBpY29uXG5cdCAgICAgKiBzZXRUcmF5SWNvbihpbWFnZVVybCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2V0dGluZyB0cmF5IGljb24nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICpcblx0ICAgICAqIC8vIHVzZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gc2V0IHRyYXkgaWNvblxuXHQgICAgICogc2V0VHJheUljb24oYmFzZTY0RW5jb2RlZEltYWdlKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIHRyYXkgaWNvbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKlxuXHQgICAgICogLy8gdXNlIGEgZGF0YVVSTCB0byBzZXQgdHJheSBpY29uXG5cdCAgICAgKiBzZXRUcmF5SWNvbihkYXRhVVJMKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIHRyYXkgaWNvbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgc2V0VHJheUljb24oaWNvbikge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3NldC10cmF5LWljb24nLCB7XG5cdCAgICAgICAgICAgIGVuYWJsZWRJY29uOiBpY29uLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBuZXcgYXBwbGljYXRpb24ncyBzaG9ydGN1dCBjb25maWd1cmF0aW9uLiBXaW5kb3dzIG9ubHkuXG5cdCAgICAgKiBAcGFyYW0gY29uZmlnIE5ldyBhcHBsaWNhdGlvbidzIHNob3J0Y3V0IGNvbmZpZ3VyYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgQXBwbGljYXRpb24gaGFzIHRvIGJlIGxhdW5jaGVkIHdpdGggYSBtYW5pZmVzdCBhbmQgaGFzIHRvIGhhdmUgc2hvcnRjdXQgY29uZmlndXJhdGlvbiAoaWNvbiB1cmwsIG5hbWUsIGV0Yy4pIGluIGl0cyBtYW5pZmVzdFxuXHQgICAgICogdG8gYmUgYWJsZSB0byBjaGFuZ2Ugc2hvcnRjdXQgc3RhdGVzLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFNob3J0Y3V0cyhjb25maWcpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuc2V0U2hvcnRjdXRzKGNvbmZpZyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0U2hvcnRjdXRzKHtcblx0ICAgICAqICAgICBkZXNrdG9wOiB0cnVlLFxuXHQgICAgICogICAgIHN0YXJ0TWVudTogZmFsc2UsXG5cdCAgICAgKiAgICAgc3lzdGVtU3RhcnR1cDogdHJ1ZVxuXHQgICAgICogfSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2hvcnRjdXRzIGFyZSBzZXQuJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBzZXRTaG9ydGN1dHMoY29uZmlnKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtc2hvcnRjdXRzJywgeyBkYXRhOiBjb25maWcsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIHRoZSBxdWVyeSBzdHJpbmcgaW4gYWxsIHNob3J0Y3V0cyBmb3IgdGhpcyBhcHAuIFJlcXVpcmVzIFJWTSA1LjUrLlxuXHQgICAgICogQHBhcmFtIHF1ZXJ5U3RyaW5nIFRoZSBuZXcgcXVlcnkgc3RyaW5nIGZvciB0aGlzIGFwcCdzIHNob3J0Y3V0cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBuZXdRdWVyeUFyZ3MgPSAnYXJnPXRydWUmYXJnMj1mYWxzZSc7XG5cdCAgICAgKiBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogdHJ5IHtcblx0ICAgICAqICAgICBhd2FpdCBhcHAuc2V0U2hvcnRjdXRRdWVyeVBhcmFtcyhuZXdRdWVyeUFyZ3MpO1xuXHQgICAgICogfSBjYXRjaChlcnIpIHtcblx0ICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRTaG9ydGN1dFF1ZXJ5UGFyYW1zKHF1ZXJ5U3RyaW5nKSB7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1zaG9ydGN1dC1xdWVyeS1hcmdzJywgeyBkYXRhOiBxdWVyeVN0cmluZywgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyB0aGUgem9vbSBsZXZlbCBvZiB0aGUgYXBwbGljYXRpb24uIFRoZSBvcmlnaW5hbCBzaXplIGlzIDAgYW5kIGVhY2ggaW5jcmVtZW50IGFib3ZlIG9yIGJlbG93IHJlcHJlc2VudHMgem9vbWluZyAyMCVcblx0ICAgICAqIGxhcmdlciBvciBzbWFsbGVyIHRvIGRlZmF1bHQgbGltaXRzIG9mIDMwMCUgYW5kIDUwJSBvZiBvcmlnaW5hbCBzaXplLCByZXNwZWN0aXZlbHkuXG5cdCAgICAgKiBAcGFyYW0gbGV2ZWwgVGhlIHpvb20gbGV2ZWxcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzZXRab29tTGV2ZWwobnVtYmVyKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnNldFpvb21MZXZlbChudW1iZXIpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHNldFpvb21MZXZlbCg1KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIGEgIHpvb20gbGV2ZWwnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNldFpvb21MZXZlbChsZXZlbCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2V0LWFwcGxpY2F0aW9uLXpvb20tbGV2ZWwnLCB7IGxldmVsLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBhIHVzZXJuYW1lIHRvIGNvcnJlbGF0ZSB3aXRoIEFwcCBMb2cgTWFuYWdlbWVudC5cblx0ICAgICAqIEBwYXJhbSB1c2VybmFtZSBVc2VybmFtZSB0byBjb3JyZWxhdGUgd2l0aCBBcHAncyBMb2cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gc2V0QXBwTG9nVXNlcigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2V0QXBwTG9nVXNlcm5hbWUoJ3VzZXJuYW1lJyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0QXBwTG9nVXNlcigpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1N1Y2Nlc3MnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICpcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRBcHBMb2dVc2VybmFtZSh1c2VybmFtZSkge1xuXHQgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtYXBwLWxvZy11c2VybmFtZScsIHsgZGF0YTogdXNlcm5hbWUsIC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3lzdGVtIHRyYXkuIElmIHRoZSBzeXN0ZW0gdHJheSBpcyBub3Qgc2V0LCBpdCB3aWxsIHRocm93IGFuIGVycm9yIG1lc3NhZ2UuXG5cdCAgICAgKiBAcmVtYXJrcyBUaGUgb25seSBpbmZvcm1hdGlvbiBjdXJyZW50bHkgcmV0dXJuZWQgaXMgdGhlIHBvc2l0aW9uIGFuZCBkaW1lbnNpb25zLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFRyYXlJY29uSW5mbygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24ud3JhcCh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFRyYXlJY29uSW5mbygpO1xuXHQgICAgICogfVxuXHQgICAgICogZ2V0VHJheUljb25JbmZvKCkudGhlbihpbmZvID0+IGNvbnNvbGUubG9nKGluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0VHJheUljb25JbmZvKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXRyYXktaWNvbi1pbmZvJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENoZWNrcyBpZiB0aGUgYXBwbGljYXRpb24gaGFzIGFuIGFzc29jaWF0ZWQgdHJheSBpY29uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi53cmFwKHsgdXVpZDogJ3Rlc3RhcHAnIH0pO1xuXHQgICAgICogY29uc3QgaGFzVHJheUljb24gPSBhd2FpdCBhcHAuaGFzVHJheUljb24oKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKGhhc1RyYXlJY29uKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBoYXNUcmF5SWNvbigpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hhcy10cmF5LWljb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2xvc2VzIHRoZSBhcHBsaWNhdGlvbiBieSB0ZXJtaW5hdGluZyBpdHMgcHJvY2Vzcy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiB0ZXJtaW5hdGVBcHAoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnRlcm1pbmF0ZSgpO1xuXHQgICAgICogfVxuXHQgICAgICogdGVybWluYXRlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gdGVybWluYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgdGVybWluYXRlKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndGVybWluYXRlLWFwcGxpY2F0aW9uJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBXYWl0cyBmb3IgYSBoYW5naW5nIGFwcGxpY2F0aW9uLiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGluIHJlc3BvbnNlIHRvIGFuIGFwcGxpY2F0aW9uXG5cdCAgICAgKiBcIm5vdC1yZXNwb25kaW5nXCIgdG8gYWxsb3cgdGhlIGFwcGxpY2F0aW9uIHRvIGNvbnRpbnVlIGFuZCB0byBnZW5lcmF0ZSBhbm90aGVyIFwibm90LXJlc3BvbmRpbmdcIlxuXHQgICAgICogbWVzc2FnZSBhZnRlciBhIGNlcnRhaW4gcGVyaW9kIG9mIHRpbWUuXG5cdCAgICAgKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICB3YWl0KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignd2FpdC1mb3ItaHVuZy1hcHBsaWNhdGlvbicsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBhcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBJZiB0aGUgYXBwbGljYXRpb24gd2FzIG5vdCBsYXVuY2hlZCBmcm9tIGEgbWFuaWZlc3QsIHRoZSBjYWxsIHdpbGwgcmV0dXJuIHRoZSBjbG9zZXN0IHBhcmVudCBhcHBsaWNhdGlvbiBgbWFuaWZlc3RgXG5cdCAgICAgKiBhbmQgYG1hbmlmZXN0VXJsYC4gIGBpbml0aWFsT3B0aW9uc2Agc2hvd3MgdGhlIHBhcmFtZXRlcnMgdXNlZCB3aGVuIGxhdW5jaGVkIHByb2dyYW1tYXRpY2FsbHksIG9yIHRoZSBgc3RhcnR1cF9hcHBgIG9wdGlvbnNcblx0ICAgICAqIGlmIGxhdW5jaGVkIGZyb20gbWFuaWZlc3QuIFRoZSBgcGFyZW50VXVpZGAgd2lsbCBiZSB0aGUgdXVpZCBvZiB0aGUgaW1tZWRpYXRlIHBhcmVudCAoaWYgYXBwbGljYWJsZSkuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0SW5mbygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0SW5mbygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldEluZm8oKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRJbmZvKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWluZm8nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGFsbCBwcm9jZXNzIGluZm9ybWF0aW9uIGZvciBlbnRpdGllcyAod2luZG93cyBhbmQgdmlld3MpIGFzc29jaWF0ZWQgd2l0aCBhbiBhcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgYXBwLmdldFByb2Nlc3NJbmZvKCk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0UHJvY2Vzc0luZm8oKSB7XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGEgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLWdldC1wcm9jZXNzLWluZm8nLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBmaWxlIGF1dG8gZG93bmxvYWQgbG9jYXRpb24uIEl0J3Mgb25seSBhbGxvd2VkIGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuXHQgICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cblx0ICAgICAqIEBwYXJhbSBkb3dubG9hZExvY2F0aW9uIGZpbGUgYXV0byBkb3dubG9hZCBsb2NhdGlvblxuXHQgICAgICpcblx0ICAgICAqIEB0aHJvd3MgaWYgc2V0dGluZyBmaWxlIGF1dG8gZG93bmxvYWQgbG9jYXRpb24gb24gZGlmZmVyZW50IGFwcGxpY2F0aW9ucy5cblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGRvd25sb2FkTG9jYXRpb24gPSAnQzpcXFxcZGV2XFxcXHRlbXAnO1xuXHQgICAgICogY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqIHRyeSB7XG5cdCAgICAgKiAgICAgYXdhaXQgYXBwLnNldEZpbGVEb3dubG9hZExvY2F0aW9uKGRvd25sb2FkTG9jYXRpb24pO1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKCdGaWxlIGRvd25sb2FkIGxvY2F0aW9uIGlzIHNldCcpO1xuXHQgICAgICogfSBjYXRjaChlcnIpIHtcblx0ICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRGaWxlRG93bmxvYWRMb2NhdGlvbihkb3dubG9hZExvY2F0aW9uKSB7XG5cdCAgICAgICAgY29uc3QgeyBuYW1lIH0gPSB0aGlzLndpcmUubWU7XG5cdCAgICAgICAgY29uc3QgZW50aXR5SWRlbnRpdHkgPSB7IHV1aWQ6IHRoaXMuaWRlbnRpdHkudXVpZCwgbmFtZSB9O1xuXHQgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtZmlsZS1kb3dubG9hZC1sb2NhdGlvbicsIHsgLi4uZW50aXR5SWRlbnRpdHksIGRvd25sb2FkTG9jYXRpb24gfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdldHMgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uLiBJdCdzIG9ubHkgYWxsb3dlZCBpbiB0aGUgc2FtZSBhcHBsaWNhdGlvbi4gSWYgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uIGlzIG5vdCBzZXQsIGl0IHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IGxvY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuXHQgICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cblx0ICAgICAqXG5cdCAgICAgKiBAdGhyb3dzIGlmIGdldHRpbmcgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uIG9uIGRpZmZlcmVudCBhcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogY29uc3QgZmlsZURvd25sb2FkRGlyID0gIGF3YWl0IGFwcC5nZXRGaWxlRG93bmxvYWRMb2NhdGlvbigpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEZpbGVEb3dubG9hZExvY2F0aW9uKCkge1xuXHQgICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZmlsZS1kb3dubG9hZC1sb2NhdGlvbicsIHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgICAgIHJldHVybiBkYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG93cyBhIG1lbnUgb24gdGhlIHRyYXkgaWNvbi4gVXNlIHdpdGggdHJheS1pY29uLWNsaWNrZWQgZXZlbnQuXG5cdCAgICAgKiBAcGFyYW0gb3B0aW9uc1xuXHQgICAgICogQHR5cGVQYXJhbSBEYXRhIFVzZXItZGVmaW5lZCBzaGFwZSBmb3IgZGF0YSByZXR1cm5lZCB1cG9uIG1lbnUgaXRlbSBjbGljay4gU2hvdWxkIGJlIGFcblx0ICAgICAqIFt1bmlvbl0oaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9ldmVyeWRheS10eXBlcy5odG1sI3VuaW9uLXR5cGVzKVxuXHQgICAgICogb2YgYWxsIHBvc3NpYmxlIGRhdGEgc2hhcGVzIGZvciB0aGUgZW50aXJlIG1lbnUsIGFuZCB0aGUgY2xpY2sgaGFuZGxlciBzaG91bGQgcHJvY2Vzc1xuXHQgICAgICogdGhlc2Ugd2l0aCBhIFwicmVkdWNlclwiIHBhdHRlcm4uXG5cdCAgICAgKiBAdGhyb3dzIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gdHJheSBpY29uIHNldFxuXHQgICAgICogQHRocm93cyBpZiB0aGUgc3lzdGVtIHRyYXkgaXMgY3VycmVudGx5IGhpZGRlblxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgaWNvblVybCA9ICdodHRwOi8vY2RuLm9wZW5maW4uY28vYXNzZXRzL3Rlc3RpbmcvaWNvbnMvY2lyY2xlZC1kaWdpdC1vbmUucG5nJztcblx0ICAgICAqIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICpcblx0ICAgICAqIGF3YWl0IGFwcC5zZXRUcmF5SWNvbihpY29uVXJsKTtcblx0ICAgICAqXG5cdCAgICAgKiBjb25zdCB0ZW1wbGF0ZSA9IFtcblx0ICAgICAqICB7XG5cdCAgICAgKiAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgIGRhdGE6ICdoZWxsbyBmcm9tIGl0ZW0gMSdcblx0ICAgICAqICB9LFxuXHQgICAgICogIHsgdHlwZTogJ3NlcGFyYXRvcicgfSxcblx0ICAgICAqICB7XG5cdCAgICAgKiAgICBsYWJlbDogJ01lbnUgSXRlbSAyJyxcblx0ICAgICAqICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICBjaGVja2VkOiB0cnVlLFxuXHQgICAgICogICAgZGF0YTogJ1RoZSB1c2VyIGNsaWNrZWQgdGhlIGNoZWNrYm94J1xuXHQgICAgICogIH0sXG5cdCAgICAgKiAge1xuXHQgICAgICogICAgbGFiZWw6ICdzZWUgbW9yZScsXG5cdCAgICAgKiAgICBlbmFibGVkOiBmYWxzZSxcblx0ICAgICAqICAgIHN1Ym1lbnU6IFtcblx0ICAgICAqICAgICAgeyBsYWJlbDogJ3N1Ym1lbnUgMScsIGRhdGE6ICdoZWxsbyBmcm9tIHN1Ym1lbnUnIH1cblx0ICAgICAqICAgIF1cblx0ICAgICAqICB9XG5cdCAgICAgKiBdO1xuXHQgICAgICpcblx0ICAgICAqIGFwcC5hZGRMaXN0ZW5lcigndHJheS1pY29uLWNsaWNrZWQnLCAoZXZlbnQpID0+IHtcblx0ICAgICAqICAgLy8gcmlnaHQtY2xpY2tcblx0ICAgICAqICAgaWYgKGV2ZW50LmJ1dHRvbiA9PT0gMikge1xuXHQgICAgICogICAgIGFwcC5zaG93VHJheUljb25Qb3B1cE1lbnUoeyB0ZW1wbGF0ZSB9KS50aGVuKHIgPT4ge1xuXHQgICAgICogICAgICAgaWYgKHIucmVzdWx0ID09PSAnY2xvc2VkJykge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZygnbm90aGluZyBoYXBwZW5lZCcpO1xuXHQgICAgICogICAgICAgfSBlbHNlIHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coci5kYXRhKTtcblx0ICAgICAqICAgICAgIH1cblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgfVxuXHQgICAgICogfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc2hvd1RyYXlJY29uUG9wdXBNZW51KG9wdGlvbnMpIHtcblx0ICAgICAgICBjb25zdCB7IG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICBjb25zdCBlbnRpdHlJZGVudGl0eSA9IHsgdXVpZDogdGhpcy5pZGVudGl0eS51dWlkLCBuYW1lIH07XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy10cmF5LWljb24tcG9wdXAtbWVudScsIHsgLi4uZW50aXR5SWRlbnRpdHksIG9wdGlvbnMgfSk7XG5cdCAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2xvc2VzIHRoZSB0cmF5IGljb24gbWVudS5cblx0ICAgICAqXG5cdCAgICAgKiBAdGhyb3dzIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gdHJheSBpY29uIHNldFxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgYXBwID0gZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKlxuXHQgICAgICogYXdhaXQgYXBwLmNsb3NlVHJheUljb25Qb3B1cE1lbnUoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjbG9zZVRyYXlJY29uUG9wdXBNZW51KCkge1xuXHQgICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIGNvbnN0IGVudGl0eUlkZW50aXR5ID0geyB1dWlkOiB0aGlzLmlkZW50aXR5LnV1aWQsIG5hbWUgfTtcblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xvc2UtdHJheS1pY29uLXBvcHVwLW1lbnUnLCB7IC4uLmVudGl0eUlkZW50aXR5IH0pO1xuXHQgICAgfVxuXHR9XG5cdEluc3RhbmNlJDYuQXBwbGljYXRpb24gPSBBcHBsaWNhdGlvbjtcblx0cmV0dXJuIEluc3RhbmNlJDY7XG59XG5cbnZhciBoYXNSZXF1aXJlZEZhY3RvcnkkMjtcblxuZnVuY3Rpb24gcmVxdWlyZUZhY3RvcnkkMiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZhY3RvcnkkMikgcmV0dXJuIEZhY3RvcnkkNztcblx0aGFzUmVxdWlyZWRGYWN0b3J5JDIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoRmFjdG9yeSQ3LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0RmFjdG9yeSQ3LkFwcGxpY2F0aW9uTW9kdWxlID0gdm9pZCAwO1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCB2YWxpZGF0ZV8xID0gdmFsaWRhdGU7XG5cdGNvbnN0IEluc3RhbmNlXzEgPSByZXF1aXJlSW5zdGFuY2UkMSgpO1xuXHQvKipcblx0ICogU3RhdGljIG5hbWVzcGFjZSBmb3IgT3BlbkZpbiBBUEkgbWV0aG9kcyB0aGF0IGludGVyYWN0IHdpdGggdGhlIHtAbGluayBBcHBsaWNhdGlvbn0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkFwcGxpY2F0aW9uYC5cblx0ICovXG5cdGNsYXNzIEFwcGxpY2F0aW9uTW9kdWxlIGV4dGVuZHMgYmFzZV8xLkJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBBcHBsaWNhdGlvbiBpZGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBXcmFwcGluZyBhbiBBcHBsaWNhdGlvbiBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuXHQgICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuXHQgICAgICogZm9yIGFuIEFwcGxpY2F0aW9uIHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLndyYXAoeyB1dWlkOiAndGVzdGFwcCcgfSlcblx0ICAgICAqIC50aGVuKGFwcCA9PiBhcHAuaXNSdW5uaW5nKCkpXG5cdCAgICAgKiAudGhlbihydW5uaW5nID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiBpcyBydW5uaW5nOiAnICsgcnVubmluZykpXG5cdCAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBhc3luYyB3cmFwKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dyYXAtYXBwbGljYXRpb24nKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIEFwcGxpY2F0aW9uIGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGFuIEFwcGxpY2F0aW9uIGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYW4gQXBsaWNhdGlvbiB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi53cmFwU3luYyh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqIGF3YWl0IGFwcC5jbG9zZSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3cmFwLWFwcGxpY2F0aW9uLXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgX2NyZWF0ZShhcHBPcHRpb25zKSB7XG5cdCAgICAgICAgLy8gc2V0IGRlZmF1bHRzOlxuXHQgICAgICAgIGlmIChhcHBPcHRpb25zLndhaXRGb3JQYWdlTG9hZCA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIGFwcE9wdGlvbnMud2FpdEZvclBhZ2VMb2FkID0gZmFsc2U7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhcHBPcHRpb25zLmF1dG9TaG93ID09PSB1bmRlZmluZWQgJiYgYXBwT3B0aW9ucy5pc1BsYXRmb3JtQ29udHJvbGxlciA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIGFwcE9wdGlvbnMuYXV0b1Nob3cgPSB0cnVlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLWFwcGxpY2F0aW9uJywgYXBwT3B0aW9ucyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQ6IGFwcE9wdGlvbnMudXVpZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogREVQUkVDQVRFRCBtZXRob2QgdG8gY3JlYXRlIGEgbmV3IEFwcGxpY2F0aW9uLiBVc2Uge0BsaW5rIEFwcGxpY2F0aW9uLkFwcGxpY2F0aW9uTW9kdWxlLnN0YXJ0IEFwcGxpY2F0aW9uLnN0YXJ0fSBpbnN0ZWFkLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uY3JlYXRlKHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0zJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLUFwcGxpY2F0aW9uLmNyZWF0ZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBhd2FpdCBhcHAucnVuKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogY3JlYXRlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gaXMgY3JlYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblx0ICAgIGNyZWF0ZShhcHBPcHRpb25zKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiBXYXJuaW5nOiBmaW4uQXBwbGljYXRpb24uY3JlYXRlIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgZmluLkFwcGxpY2F0aW9uLnN0YXJ0Jyk7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLWNyZWF0ZScpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9jcmVhdGUoYXBwT3B0aW9ucyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYW5kIHN0YXJ0cyBhIG5ldyBBcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzdGFydCgpIHtcblx0ICAgICAqICAgICByZXR1cm4gZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLUFwcGxpY2F0aW9uLnN0YXJ0Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogfVxuXHQgICAgICogc3RhcnQoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiBpcyBydW5uaW5nJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc3RhcnQoYXBwT3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzdGFydC1hcHBsaWNhdGlvbicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGFwcCA9IGF3YWl0IHRoaXMuX2NyZWF0ZShhcHBPcHRpb25zKTtcblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncnVuLWFwcGxpY2F0aW9uJywgeyB1dWlkOiBhcHBPcHRpb25zLnV1aWQgfSk7XG5cdCAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQXN5bmNocm9ub3VzbHkgc3RhcnRzIGEgYmF0Y2ggb2YgYXBwbGljYXRpb25zIGdpdmVuIGFuIGFycmF5IG9mIGFwcGxpY2F0aW9uIGlkZW50aWZpZXJzIGFuZCBtYW5pZmVzdFVybHMuXG5cdCAgICAgKiBSZXR1cm5zIG9uY2UgdGhlIFJWTSBpcyBmaW5pc2hlZCBhdHRlbXB0aW5nIHRvIGxhdW5jaCB0aGUgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIG9wdHMgLSBQYXJhbWV0ZXJzIHRoYXQgdGhlIFJWTSB3aWxsIHVzZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKlxuXHQgICAgICogY29uc3QgYXBwbGljYXRpb25JbmZvQXJyYXkgPSBbXG5cdCAgICAgKiAgICAge1xuXHQgICAgICogICAgICAgICBcInV1aWRcIjogJ0FwcC0xJyxcblx0ICAgICAqICAgICAgICAgXCJtYW5pZmVzdFVybFwiOiAnaHR0cDovL2xvY2FsaG9zdDo1NTU1L2FwcDEuanNvbicsXG5cdCAgICAgKiAgICAgfSxcblx0ICAgICAqICAgICB7XG5cdCAgICAgKiAgICAgICAgIFwidXVpZFwiOiAnQXBwLTInLFxuXHQgICAgICogICAgICAgICBcIm1hbmlmZXN0VXJsXCI6ICdodHRwOi8vbG9jYWxob3N0OjU1NTUvYXBwMi5qc29uJyxcblx0ICAgICAqICAgICB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgXCJ1dWlkXCI6ICdBcHAtMycsXG5cdCAgICAgKiAgICAgICAgIFwibWFuaWZlc3RVcmxcIjogJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAzLmpzb24nLFxuXHQgICAgICogICAgIH1cblx0ICAgICAqIF1cblx0ICAgICAqXG5cdCAgICAgKiBmaW4uQXBwbGljYXRpb24uc3RhcnRNYW55TWFuaWZlc3RzKGFwcGxpY2F0aW9uSW5mb0FycmF5KVxuXHQgICAgICogICAgIC50aGVuKCgpID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1JWTSBoYXMgZmluaXNoZWQgbGF1bmNoaW5nIHRoZSBhcHBsaWNhdGlvbiBsaXN0LicpO1xuXHQgICAgICogICAgIH0pXG5cdCAgICAgKiAgICAgLmNhdGNoKChlcnIpID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzdGFydE1hbnlNYW5pZmVzdHMoYXBwbGljYXRpb25zLCBvcHRzKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdydW4tYXBwbGljYXRpb25zJywgeyBhcHBsaWNhdGlvbnMsIG9wdHMgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFwcGxpY2F0aW9uIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgYXBwbGljYXRpb25cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc0N1cnJlbnRBcHBSdW5uaW5nICgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuaXNSdW5uaW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNDdXJyZW50QXBwUnVubmluZygpLnRoZW4ocnVubmluZyA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coYEN1cnJlbnQgYXBwIGlzIHJ1bm5pbmc6ICR7cnVubmluZ31gKTtcblx0ICAgICAqIH0pLmNhdGNoKGVyciA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuXHQgICAgICogfSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnQoKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jdXJyZW50LWFwcGxpY2F0aW9uJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQ6IHRoaXMud2lyZS5tZS51dWlkIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQXBwbGljYXRpb24gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBhcHBsaWNhdGlvblxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGlzQ3VycmVudEFwcFJ1bm5pbmcgKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuaXNSdW5uaW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNDdXJyZW50QXBwUnVubmluZygpLnRoZW4ocnVubmluZyA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coYEN1cnJlbnQgYXBwIGlzIHJ1bm5pbmc6ICR7cnVubmluZ31gKTtcblx0ICAgICAqIH0pLmNhdGNoKGVyciA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuXHQgICAgICogfSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY3VycmVudC1hcHBsaWNhdGlvbi1zeW5jJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcFN5bmMoeyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3QgYW5kIHJldHVybnMgYSBydW5uaW5nIGluc3RhbmNlIG9mIHRoZSBhcHBsaWNhdGlvbi5cblx0ICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgYXBwJ3MgbWFuaWZlc3QuXG5cdCAgICAgKiBAcGFyYW0gb3B0cyAtIFBhcmFtZXRlcnMgdGhhdCB0aGUgUlZNIHdpbGwgdXNlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5BcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdCgnaHR0cDovL2xvY2FsaG9zdDo1NTU1L2FwcC5qc29uJykudGhlbihhcHAgPT4gY29uc29sZS5sb2coJ0FwcCBpcyBydW5uaW5nJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBGb3IgYSBsb2NhbCBtYW5pZmVzdCBmaWxlOlxuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLnN0YXJ0RnJvbU1hbmlmZXN0KCdmaWxlOi8vL0M6L3NvbWVmb2xkZXIvYXBwLmpzb24nKS50aGVuKGFwcCA9PiBjb25zb2xlLmxvZygnQXBwIGlzIHJ1bm5pbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHN0YXJ0RnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsLCBvcHRzKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLXN0YXJ0LWZyb20tbWFuaWZlc3QnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLl9jcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpO1xuXHQgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSBtZXRob2Qgd2l0aG91dCB3YXJuaW5nLlxuXHQgICAgICAgIGF3YWl0IGFwcC5fcnVuKG9wdHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBBcHBsaWNhdGlvbi5BcHBsaWNhdGlvbk1vZHVsZS5zdGFydEZyb21NYW5pZmVzdCBBcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdH0gaW5zdGVhZC5cblx0ICAgICAqIFJldHJpZXZlcyBhcHBsaWNhdGlvbidzIG1hbmlmZXN0IGFuZCByZXR1cm5zIGEgd3JhcHBlZCBhcHBsaWNhdGlvbi5cblx0ICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgYXBwJ3MgbWFuaWZlc3QuXG5cdCAgICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBjYWxsZWQgaWYgdGhlIG1ldGhvZCBzdWNjZWVkcy5cblx0ICAgICAqIEBwYXJhbSBlcnJvckNhbGxiYWNrIC0gY2FsbGVkIGlmIHRoZSBtZXRob2QgZmFpbHMuIFRoZSByZWFzb24gZm9yIGZhaWx1cmUgaXMgcGFzc2VkIGFzIGFuIGFyZ3VtZW50LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5BcHBsaWNhdGlvbi5jcmVhdGVGcm9tTWFuaWZlc3QoJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAuanNvbicpLnRoZW4oYXBwID0+IGNvbnNvbGUubG9nKGFwcCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICBjcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ0RlcHJlY2F0aW9uIFdhcm5pbmc6IGZpbi5BcHBsaWNhdGlvbi5jcmVhdGVGcm9tTWFuaWZlc3QgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBmaW4uQXBwbGljYXRpb24uc3RhcnRGcm9tTWFuaWZlc3QnKTtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tY3JlYXRlLWZyb20tbWFuaWZlc3QnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlRnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsKTtcblx0ICAgIH1cblx0ICAgIF9jcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdnZXQtYXBwbGljYXRpb24tbWFuaWZlc3QnLCB7IG1hbmlmZXN0VXJsIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB1dWlkID0gcGF5bG9hZC5kYXRhLnBsYXRmb3JtID8gcGF5bG9hZC5kYXRhLnBsYXRmb3JtLnV1aWQgOiBwYXlsb2FkLmRhdGEuc3RhcnR1cF9hcHAudXVpZDtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQgfSk7XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKGFwcCkgPT4ge1xuXHQgICAgICAgICAgICBhcHAuX21hbmlmZXN0VXJsID0gbWFuaWZlc3RVcmw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZXJzY29yZS1kYW5nbGVcblx0ICAgICAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0fVxuXHRGYWN0b3J5JDcuQXBwbGljYXRpb25Nb2R1bGUgPSBBcHBsaWNhdGlvbk1vZHVsZTtcblx0cmV0dXJuIEZhY3RvcnkkNztcbn1cblxudmFyIGhhc1JlcXVpcmVkQXBwbGljYXRpb247XG5cbmZ1bmN0aW9uIHJlcXVpcmVBcHBsaWNhdGlvbiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEFwcGxpY2F0aW9uKSByZXR1cm4gYXBwbGljYXRpb247XG5cdGhhc1JlcXVpcmVkQXBwbGljYXRpb24gPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHRcdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHRcdCAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG5cdFx0ICAgIH1cblx0XHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0XHR9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICBvW2syXSA9IG1ba107XG5cdFx0fSkpO1xuXHRcdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdFx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0XHR9O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludHMgZm9yIHRoZSBPcGVuRmluIGBBcHBsaWNhdGlvbmAgQVBJIChgZmluLkFwcGxpY2F0aW9uYCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBBcHBsaWNhdGlvbk1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBBcHBsaWNhdGlvbmAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5BcHBsaWNhdGlvbmAuXG5cdFx0ICogKiB7QGxpbmsgQXBwbGljYXRpb259IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIEFwcGxpY2F0aW9uLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudGAuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdFx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQyKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UkMSgpLCBleHBvcnRzKTsgXG5cdH0gKGFwcGxpY2F0aW9uKSk7XG5cdHJldHVybiBhcHBsaWNhdGlvbjtcbn1cblxudmFyIHByb21pc2lmeVN1YnNjcmlwdGlvbiQxID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9taXNpZnlTdWJzY3JpcHRpb24kMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5wcm9taXNpZnlTdWJzY3JpcHRpb24kMS5wcm9taXNpZnlTdWJzY3JpcHRpb24gPSB2b2lkIDA7XG5jb25zdCBwcm9taXNpZnlTdWJzY3JpcHRpb24gPSBhc3luYyAoZW1pdHRlciwgZXZlbnROYW1lLCBwcmVkaWNhdGUgPSAoKSA9PiB0cnVlLCB0aW1lb3V0KSA9PiB7XG4gICAgbGV0IHJlc29sdmU7XG4gICAgbGV0IHJlamVjdDtcbiAgICBsZXQgdGltZXI7XG4gICAgY29uc3QgdmFsdWVQcm9taXNlID0gbmV3IFByb21pc2UoKHksIG4pID0+IHtcbiAgICAgICAgcmVzb2x2ZSA9IHk7XG4gICAgICAgIHJlamVjdCA9IG47XG4gICAgfSk7XG4gICAgY29uc3QgbGlzdGVuZXIgPSAoZSkgPT4ge1xuICAgICAgICBpZiAocHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZShlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgYXdhaXQgZW1pdHRlci5vbihldmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignZXZlbnQgdGltZWQgb3V0JykpLCB0aW1lb3V0KTtcbiAgICB9XG4gICAgdmFsdWVQcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpLmNhdGNoKCgpID0+IG51bGwpO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldFZhbHVlOiAoKSA9PiB2YWx1ZVByb21pc2VcbiAgICB9O1xufTtcbnByb21pc2lmeVN1YnNjcmlwdGlvbiQxLnByb21pc2lmeVN1YnNjcmlwdGlvbiA9IHByb21pc2lmeVN1YnNjcmlwdGlvbjtcblxudmFyIGhhc1JlcXVpcmVkSW5zdGFuY2U7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEluc3RhbmNlKSByZXR1cm4gSW5zdGFuY2UkNztcblx0aGFzUmVxdWlyZWRJbnN0YW5jZSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSQ3LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW5zdGFuY2UkNy5fV2luZG93ID0gdm9pZCAwO1xuXHQvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5cdC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuXHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5cdC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblx0Y29uc3QgYXBwbGljYXRpb25fMSA9IHJlcXVpcmVBcHBsaWNhdGlvbigpO1xuXHRjb25zdCBtYWluXzEgPSBtYWluO1xuXHRjb25zdCB2aWV3XzEgPSByZXF1aXJlVmlldygpO1xuXHRjb25zdCB3YXJuaW5nc18xID0gd2FybmluZ3M7XG5cdGNvbnN0IHByb21pc2lmeVN1YnNjcmlwdGlvbl8xID0gcHJvbWlzaWZ5U3Vic2NyaXB0aW9uJDE7XG5cdC8qKlxuXHQgKiBBIGJhc2ljIHdpbmRvdyB0aGF0IHdyYXBzIGEgbmF0aXZlIEhUTUwgd2luZG93LiBQcm92aWRlcyBtb3JlIGZpbmUtZ3JhaW5lZFxuXHQgKiBjb250cm9sIG92ZXIgdGhlIHdpbmRvdyBzdGF0ZSBzdWNoIGFzIHRoZSBhYmlsaXR5IHRvIG1pbmltaXplLCBtYXhpbWl6ZSwgcmVzdG9yZSwgZXRjLlxuXHQgKiBCeSBkZWZhdWx0IGEgd2luZG93IGRvZXMgbm90IHNob3cgdXBvbiBpbnN0YW50aWF0aW9uOyBpbnN0ZWFkIHRoZSB3aW5kb3cncyBzaG93KCkgbWV0aG9kXG5cdCAqIG11c3QgYmUgaW52b2tlZCBtYW51YWxseS4gVGhlIG5ldyB3aW5kb3cgYXBwZWFycyBpbiB0aGUgc2FtZSBwcm9jZXNzIGFzIHRoZSBwYXJlbnQgd2luZG93LlxuXHQgKiBJdCBoYXMgdGhlIGFiaWxpdHkgdG8gbGlzdGVuIGZvciB7QGxpbmsgT3BlbkZpbi5XaW5kb3dFdmVudHMgd2luZG93IHNwZWNpZmljIGV2ZW50c30uXG5cdCAqL1xuXHQvLyBUaGUgd2luZG93LldpbmRvdyBuYW1lIGlzIHRha2VuXG5cdGNsYXNzIF9XaW5kb3cgZXh0ZW5kcyBtYWluXzEuV2ViQ29udGVudHMge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCBpZGVudGl0eSwgJ3dpbmRvdycpO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgY3JlYXRlV2luZG93KG9wdGlvbnMpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWNyZWF0ZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBDT05TVFJVQ1RPUl9DQl9UT1BJQyA9ICdmaXJlLWNvbnN0cnVjdG9yLWNhbGxiYWNrJztcblx0ICAgICAgICBjb25zdCByZXNwb25zZVN1YnNjcmlwdGlvbiA9IGF3YWl0ICgwLCBwcm9taXNpZnlTdWJzY3JpcHRpb25fMS5wcm9taXNpZnlTdWJzY3JpcHRpb24pKHRoaXMsIENPTlNUUlVDVE9SX0NCX1RPUElDKTtcblx0ICAgICAgICAvLyBzZXQgZGVmYXVsdHM6XG5cdCAgICAgICAgaWYgKG9wdGlvbnMud2FpdEZvclBhZ2VMb2FkID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgb3B0aW9ucy53YWl0Rm9yUGFnZUxvYWQgPSBmYWxzZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKG9wdGlvbnMuYXV0b1Nob3cgPT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICBvcHRpb25zLmF1dG9TaG93ID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgKDAsIHdhcm5pbmdzXzEuaGFuZGxlRGVwcmVjYXRlZFdhcm5pbmdzKShvcHRpb25zKTtcblx0ICAgICAgICBjb25zdCB3aW5kb3dDcmVhdGlvbiA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5jcmVhdGVDaGlsZENvbnRlbnQoeyBlbnRpdHlUeXBlOiAnd2luZG93Jywgb3B0aW9ucyB9KTtcblx0ICAgICAgICBjb25zdCBbcmVzcG9uc2VdID0gYXdhaXQgUHJvbWlzZS5hbGwoW3Jlc3BvbnNlU3Vic2NyaXB0aW9uLmdldFZhbHVlKCksIHdpbmRvd0NyZWF0aW9uXSk7XG5cdCAgICAgICAgbGV0IGNiUGF5bG9hZDtcblx0ICAgICAgICBjb25zdCB7IHN1Y2Nlc3MgfSA9IHJlc3BvbnNlO1xuXHQgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHJlc3BvbnNlLmRhdGE7XG5cdCAgICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSByZXNwb25zZURhdGE7XG5cdCAgICAgICAgaWYgKHN1Y2Nlc3MpIHtcblx0ICAgICAgICAgICAgY2JQYXlsb2FkID0ge1xuXHQgICAgICAgICAgICAgICAgaHR0cFJlc3BvbnNlQ29kZTogcmVzcG9uc2VEYXRhLmh0dHBSZXNwb25zZUNvZGUsXG5cdCAgICAgICAgICAgICAgICBhcGlJbmplY3RlZDogcmVzcG9uc2VEYXRhLmFwaUluamVjdGVkXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICBjYlBheWxvYWQgPSB7XG5cdCAgICAgICAgICAgICAgICBtZXNzYWdlOiByZXNwb25zZURhdGEubWVzc2FnZSxcblx0ICAgICAgICAgICAgICAgIG5ldHdvcmtFcnJvckNvZGU6IHJlc3BvbnNlRGF0YS5uZXR3b3JrRXJyb3JDb2RlLFxuXHQgICAgICAgICAgICAgICAgc3RhY2s6IHJlc3BvbnNlRGF0YS5zdGFja1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCBwYWdlUmVzb2x2ZSA9IHtcblx0ICAgICAgICAgICAgbWVzc2FnZSxcblx0ICAgICAgICAgICAgY2JQYXlsb2FkLFxuXHQgICAgICAgICAgICBzdWNjZXNzXG5cdCAgICAgICAgfTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIGVuZm9yY2UgYSA1LjAgY29udHJhY3QgdGhhdCB0aGUgY2hpbGQncyBtYWluIGZ1bmN0aW9uXG5cdCAgICAgICAgICAgIC8vIHdpbGwgbm90IGZpcmUgYmVmb3JlIHRoZSBwYXJlbnQncyBzdWNjZXNzIGNhbGxiYWNrIG9uIGNyZWF0aW9uLlxuXHQgICAgICAgICAgICAvLyBpZiB0aGUgY2hpbGQgd2luZG93IGlzIG5vdCBhY2Nlc3NpYmxlIChDT1JTKSB0aGlzIGNvbnRyYWN0IGRvZXNcblx0ICAgICAgICAgICAgLy8gbm90IGhvbGQuXG5cdCAgICAgICAgICAgIGNvbnN0IHdlYldpbmRvdyA9IHRoaXMuZ2V0V2ViV2luZG93KCk7XG5cdCAgICAgICAgICAgIHdlYldpbmRvdy5maW4uX19pbnRlcm5hbF8ub3BlbmVyU3VjY2Vzc0NCQ2FsbGVkKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgIC8vIGNvbW1vbiBmb3IgbWFpbiB3aW5kb3dzLCB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvci4gaGVyZSBqdXN0IHRvIGhhdmUgYSBkZWJ1ZyB0YXJnZXQuXG5cdCAgICAgICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChwYWdlUmVzb2x2ZS5zdWNjZXNzKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QocGFnZVJlc29sdmUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2YgZnJhbWUgaW5mbyBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgbWFpbiBmcmFtZSBhbmQgYW55XG5cdCAgICAgKiBpZnJhbWVzIHRoYXQgYXJlIGN1cnJlbnRseSBvbiB0aGUgcGFnZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldEFsbEZyYW1lcygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmdldEFsbEZyYW1lcy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRBbGxGcmFtZXMoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRBbGxGcmFtZXMoKS50aGVuKGZyYW1lc0luZm8gPT4gY29uc29sZS5sb2coZnJhbWVzSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRBbGxGcmFtZXMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWZyYW1lcycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGJvdW5kcyAodG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Qm91bmRzKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMycsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0Qm91bmRzLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldEJvdW5kcygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldEJvdW5kcygpLnRoZW4oYm91bmRzID0+IGNvbnNvbGUubG9nKGJvdW5kcykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRCb3VuZHMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignZ2V0LXdpbmRvdy1ib3VuZHMnLCB0aGlzLmlkZW50aXR5KVxuXHQgICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENlbnRlcnMgdGhlIHdpbmRvdyBvbiBpdHMgY3VycmVudCBzY3JlZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgRG9lcyBub3QgaGF2ZSBhbiBlZmZlY3Qgb24gbWluaW1pemVkIG9yIG1heGltaXplZCB3aW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY2VudGVyV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuY2VudGVyLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmNlbnRlcigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGNlbnRlcldpbmRvdygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBjZW50ZXJlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIGNlbnRlcigpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NlbnRlci13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlbW92ZXMgZm9jdXMgZnJvbSB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gYmx1cldpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmJsdXIuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uYmx1cigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGJsdXJXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdCbHVyZWQgV2luZG93JykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBibHVyKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignYmx1ci13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEJyaW5ncyB0aGUgd2luZG93IHRvIHRoZSBmcm9udCBvZiB0aGUgd2luZG93IHN0YWNrLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gQnJpbmdXaW5kb3dUb0Zyb250KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuYnJpbmdUb0Zyb250Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmJyaW5nVG9Gcm9udCgpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIEJyaW5nV2luZG93VG9Gcm9udCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBpcyBpbiB0aGUgZnJvbnQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGJyaW5nVG9Gcm9udCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2JyaW5nLXdpbmRvdy10by1mcm9udCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUGVyZm9ybXMgdGhlIHNwZWNpZmllZCB3aW5kb3cgdHJhbnNpdGlvbnMuXG5cdCAgICAgKiBAcGFyYW0gdHJhbnNpdGlvbnMgLSBEZXNjcmliZXMgdGhlIGFuaW1hdGlvbnMgdG8gcGVyZm9ybS4gU2VlIHRoZSB0dXRvcmlhbC5cblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIGFuaW1hdGlvbi4gU2VlIHRoZSB0dXRvcmlhbC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBgXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBhbmltYXRlV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHRyYW5zaXRpb25zID0ge1xuXHQgICAgICogICAgICAgICBvcGFjaXR5OiB7XG5cdCAgICAgKiAgICAgICAgICAgICBvcGFjaXR5OiAwLjcsXG5cdCAgICAgKiAgICAgICAgICAgICBkdXJhdGlvbjogNTAwXG5cdCAgICAgKiAgICAgICAgIH0sXG5cdCAgICAgKiAgICAgICAgIHBvc2l0aW9uOiB7XG5cdCAgICAgKiAgICAgICAgICAgICB0b3A6IDEwMCxcblx0ICAgICAqICAgICAgICAgICAgIGxlZnQ6IDEwMCxcblx0ICAgICAqICAgICAgICAgICAgIGR1cmF0aW9uOiA1MDAsXG5cdCAgICAgKiAgICAgICAgICAgICByZWxhdGl2ZTogdHJ1ZVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqICAgICBjb25zdCBvcHRpb25zID0ge1xuXHQgICAgICogICAgICAgICBpbnRlcnJ1cHQ6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIHR3ZWVuOiAnZWFzZS1pbidcblx0ICAgICAqICAgICB9O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gd2luLmFuaW1hdGUodHJhbnNpdGlvbnMsIG9wdGlvbnMpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFuaW1hdGVXaW5kb3coKVxuXHQgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBbmltYXRpb24gZG9uZScpKVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhbmltYXRlKHRyYW5zaXRpb25zLCBvcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignYW5pbWF0ZS13aW5kb3cnLCB7XG5cdCAgICAgICAgICAgIHRyYW5zaXRpb25zLFxuXHQgICAgICAgICAgICBvcHRpb25zLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSGlkZXMgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGhpZGVXaW5kb3coKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5oaWRlLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmhpZGUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBoaWRlV2luZG93KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnV2luZG93IGlzIGhpZGRlbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgaGlkZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hpZGUtd2luZG93JywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBjbG9zZXMgdGhlIHdpbmRvdyBhcHBsaWNhdGlvblxuXHQgICAgICogQHBhcmFtIGZvcmNlIENsb3NlIHdpbGwgYmUgcHJldmVudGVkIGZyb20gY2xvc2luZyB3aGVuIGZvcmNlIGlzIGZhbHNlIGFuZFxuXHQgICAgICogIOKAmGNsb3NlLXJlcXVlc3RlZOKAmSBoYXMgYmVlbiBzdWJzY3JpYmVkIHRvIGZvciBhcHBsaWNhdGlvbuKAmXMgbWFpbiB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjbG9zZVdpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTMnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmNsb3NlLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmNsb3NlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogY2xvc2VXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgY2xvc2VkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBjbG9zZShmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbG9zZS13aW5kb3cnLCB7IGZvcmNlLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4ge1xuXHQgICAgICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbnVsbCk7XG5cdCAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBmb2N1c2VkV2ViVmlld1dhc0NoYW5nZWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmb2N1c2VkLXdlYnZpZXctY2hhbmdlZCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyB0aGUgbmF0aXZlIE9TIGxldmVsIElkLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIEluIFdpbmRvd3MsIGl0IHdpbGwgcmV0dXJuIHRoZSBXaW5kb3dzIFtoYW5kbGVdKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3dpbmRvd3MvZGVza3RvcC9XaW5Qcm9nL3dpbmRvd3MtZGF0YS10eXBlcyNIV05EKS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFdpbmRvd05hdGl2ZUlkKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMycsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0TmF0aXZlSWQuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZ2V0TmF0aXZlSWQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3dOYXRpdmVJZCgpLnRoZW4obmF0aXZlSWQgPT4gY29uc29sZS5sb2cobmF0aXZlSWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0TmF0aXZlSWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LW5hdGl2ZS1pZCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgd2luZG93J3MgYXR0YWNoZWQgdmlld3MuXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKlxuXHQgICAgICogd2luLmdldEN1cnJlbnRWaWV3cygpXG5cdCAgICAgKiAgIC50aGVuKHZpZXdzID0+IGNvbnNvbGUubG9nKHZpZXdzKSlcblx0ICAgICAqICAgLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEN1cnJlbnRWaWV3cygpIHtcblx0ICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZ2V0LXZpZXdzJywgdGhpcy5pZGVudGl0eSk7XG5cdCAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YS5tYXAoKGlkKSA9PiBuZXcgdmlld18xLlZpZXcodGhpcy53aXJlLCBpZCkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFdpbmRvdy5fV2luZG93LmRpc2FibGVVc2VyTW92ZW1lbnR9IGluc3RlYWQuXG5cdCAgICAgKi9cblx0ICAgIGRpc2FibGVGcmFtZSgpIHtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ0Z1bmN0aW9uIGlzIGRlcHJlY2F0ZWQ7IHVzZSBkaXNhYmxlVXNlck1vdmVtZW50IGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdkaXNhYmxlLXdpbmRvdy1mcmFtZScsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJldmVudHMgYSB1c2VyIGZyb20gY2hhbmdpbmcgYSB3aW5kb3cncyBzaXplL3Bvc2l0aW9uIHdoZW4gdXNpbmcgdGhlIHdpbmRvdydzIGZyYW1lLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZGlzYWJsZVVzZXJNb3ZlbWVudCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTMnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmRpc2FibGVGcmFtZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5kaXNhYmxlVXNlck1vdmVtZW50KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZGlzYWJsZVVzZXJNb3ZlbWVudCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBpcyBkaXNhYmxlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZGlzYWJsZVVzZXJNb3ZlbWVudCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rpc2FibGUtd2luZG93LWZyYW1lJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFdpbmRvdy5fV2luZG93LmVuYWJsZVVzZXJNb3ZlbWVudH0gaW5zdGVhZC5cblx0ICAgICAqL1xuXHQgICAgZW5hYmxlRnJhbWUoKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdGdW5jdGlvbiBpcyBkZXByZWNhdGVkOyB1c2UgZW5hYmxlVXNlck1vdmVtZW50IGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdlbmFibGUtd2luZG93LWZyYW1lJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZS1lbmFibGVzIHVzZXIgY2hhbmdlcyB0byBhIHdpbmRvdydzIHNpemUvcG9zaXRpb24gd2hlbiB1c2luZyB0aGUgd2luZG93J3MgZnJhbWUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBlbmFibGVVc2VyTW92ZW1lbnQoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0zJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5lbmFibGVGcmFtZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5lbmFibGVVc2VyTW92ZW1lbnQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBlbmFibGVVc2VyTW92ZW1lbnQoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgaXMgZW5hYmxlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZW5hYmxlVXNlck1vdmVtZW50KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZW5hYmxlLXdpbmRvdy1mcmFtZScsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmxhc2hlcyB0aGUgd2luZG934oCZcyBmcmFtZSBhbmQgdGFza2JhciBpY29uIHVudGlsIHN0b3BGbGFzaGluZyBpcyBjYWxsZWQgb3IgdW50aWwgYSBmb2N1cyBldmVudCBpcyBmaXJlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBPbiBtYWNPUyBmbGFzaCBvbmx5IHdvcmtzIG9uIGluYWN0aXZlIHdpbmRvd3MuXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHdpbmRvd0ZsYXNoKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZmxhc2guaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZmxhc2goKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiB3aW5kb3dGbGFzaCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBmbGFzaGluZycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZmxhc2goKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmbGFzaC13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFN0b3BzIHRoZSB0YXNrYmFyIGljb24gZnJvbSBmbGFzaGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BXaW5kb3dGbGFzaGluZygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnN0b3BGbGFzaGluZy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zdG9wRmxhc2hpbmcoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzdG9wV2luZG93Rmxhc2hpbmcoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiB3aW5kb3cgZmxhc2hpbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHN0b3BGbGFzaGluZygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3N0b3AtZmxhc2gtd2luZG93JywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGFuIGluZm9ybWF0aW9uIG9iamVjdCBmb3IgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldEluZm8oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5nZXRJbmZvLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldEluZm8oKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRJbmZvKCkudGhlbihpbmZvID0+IGNvbnNvbGUubG9nKGluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mbygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC13aW5kb3ctaW5mbycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgdGhlIHdpbmRvdydzIExheW91dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogICAgIC8vZ2V0IHRoZSBjdXJyZW50IHdpbmRvd1xuXHQgICAgICogICAgIGNvbnN0IHdpbmRvdyA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAvL2dldCB0aGUgbGF5b3V0IGZvciB0aGUgd2luZG93XG5cdCAgICAgKiAgICAgY29uc3QgbGF5b3V0ID0gYXdhaXQgd2luZG93LmdldExheW91dCgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldExheW91dChsYXlvdXRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZ2V0LWxheW91dCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IG9wdHMgPSBhd2FpdCB0aGlzLmdldE9wdGlvbnMoKTtcblx0ICAgICAgICBpZiAoIW9wdHMubGF5b3V0ICYmICFvcHRzLmxheW91dFNuYXBzaG90KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2luZG93IGRvZXMgbm90IGhhdmUgYSBMYXlvdXQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuZmluLlBsYXRmb3JtLkxheW91dC53cmFwKGxheW91dElkZW50aXR5ID8/IHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHNldHRpbmdzIG9mIHRoZSB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRXaW5kb3dPcHRpb25zKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0T3B0aW9ucy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRPcHRpb25zKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZ2V0V2luZG93T3B0aW9ucygpLnRoZW4ob3B0cyA9PiBjb25zb2xlLmxvZyhvcHRzKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldE9wdGlvbnMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LW9wdGlvbnMnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgcGFyZW50IGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50QXBwbGljYXRpb24oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5nZXRQYXJlbnRBcHBsaWNhdGlvbi5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRQYXJlbnRBcHBsaWNhdGlvbigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldFBhcmVudEFwcGxpY2F0aW9uKCkudGhlbihwYXJlbnRBcHBsaWNhdGlvbiA9PiBjb25zb2xlLmxvZyhwYXJlbnRBcHBsaWNhdGlvbikpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRQYXJlbnRBcHBsaWNhdGlvbigpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWdldC1wYXJlbnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBhcHBsaWNhdGlvbl8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgdGhpcy5pZGVudGl0eSkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBwYXJlbnQgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50V2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0UGFyZW50V2luZG93Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldFBhcmVudFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldFBhcmVudFdpbmRvdygpLnRoZW4ocGFyZW50V2luZG93ID0+IGNvbnNvbGUubG9nKHBhcmVudFdpbmRvdykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRQYXJlbnRXaW5kb3coKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy1nZXQtcGFyZW50LXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IGFwcGxpY2F0aW9uXzEuQXBwbGljYXRpb24odGhpcy53aXJlLCB0aGlzLmlkZW50aXR5KSkudGhlbigoYXBwKSA9PiBhcHAuZ2V0V2luZG93KCkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiAqKipERVBSRUNBVEVEIC0gcGxlYXNlIHVzZSBXaW5kb3cuY2FwdHVyZVBhZ2UuKioqXG5cdCAgICAgKiBHZXRzIGEgYmFzZTY0IGVuY29kZWQgUE5HIGltYWdlIG9mIHRoZSB3aW5kb3cgb3IganVzdCBwYXJ0IGEgb2YgaXQuXG5cdCAgICAgKiBAcGFyYW0gYXJlYSBUaGUgYXJlYSBvZiB0aGUgd2luZG93IHRvIGJlIGNhcHR1cmVkLlxuXHQgICAgICogT21pdHRpbmcgaXQgd2lsbCBjYXB0dXJlIHRoZSB3aG9sZSB2aXNpYmxlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgV2luZG93LmNhcHR1cmVQYWdlXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldFNuYXBzaG90KGFyZWEpIHtcblx0ICAgICAgICBjb25zdCByZXEgPSB7IGFyZWEsIC4uLnRoaXMuaWRlbnRpdHkgfTtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ1dpbmRvdy5nZXRTbmFwc2hvdCBoYXMgYmVlbiBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIFdpbmRvdy5jYXB0dXJlUGFnZScpO1xuXHQgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LXNuYXBzaG90JywgcmVxKTtcblx0ICAgICAgICByZXR1cm4gcmVzLnBheWxvYWQuZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgY3VycmVudCBzdGF0ZSAoXCJtaW5pbWl6ZWRcIiwgXCJtYXhpbWl6ZWRcIiwgb3IgXCJub3JtYWxcIikgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFdpbmRvd1N0YXRlKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0U3RhdGUuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZ2V0U3RhdGUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3dTdGF0ZSgpLnRoZW4od2luU3RhdGUgPT4gY29uc29sZS5sb2cod2luU3RhdGUpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0U3RhdGUoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LXN0YXRlJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFByZXZpb3VzbHkgY2FsbGVkIGdldE5hdGl2ZVdpbmRvdy5cblx0ICAgICAqIFJldHVybnMgdGhlIFtXaW5kb3cgT2JqZWN0XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93KVxuXHQgICAgICogdGhhdCByZXByZXNlbnRzIHRoZSB3ZWIgY29udGV4dCBvZiB0aGUgdGFyZ2V0IHdpbmRvdy4gVGhpcyBpcyB0aGUgc2FtZSBvYmplY3QgdGhhdFxuXHQgICAgICogeW91IHdvdWxkIGdldCBmcm9tIGNhbGxpbmcgW3dpbmRvdy5vcGVuKCldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvb3BlbikgaW4gYSBzdGFuZGFyZCB3ZWIgY29udGV4dC5cblx0ICAgICAqIFRoZSB0YXJnZXQgd2luZG93IG5lZWRzIHRvIGJlIGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFzIHRoZSByZXF1ZXN0aW5nIHdpbmRvd1xuXHQgICAgICogYXMgd2VsbCBhcyBjb21wbHkgd2l0aCBbc2FtZS1vcmlnaW5dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL1NlY3VyaXR5L1NhbWUtb3JpZ2luX3BvbGljeSkgcG9saWN5IHJlcXVpcmVtZW50cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogSW5qZWN0aW5nIGNvbnRlbnQgaW50byBhbiBlbXB0eSB3aW5kb3c6XG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIChhc3luYyAoKT0+IHtcblx0ICAgICAqICAgICB0cnkge1xuXHQgICAgICogICAgICAgICBjb25zdCB3aW5OYW1lID0gYGNoaWxkLXdpbmRvdy0ke0RhdGUubm93KCl9YDtcblx0ICAgICAqICAgICAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUoe1xuXHQgICAgICogICAgICAgICAgICAgbmFtZTogd2luTmFtZSxcblx0ICAgICAqICAgICAgICAgICAgIHVybDogJ2Fib3V0OmJsYW5rJ1xuXHQgICAgICogICAgICAgICB9KTtcblx0ICAgICAqICAgICAgICAgd2luLmdldFdlYldpbmRvdygpLmRvY3VtZW50LndyaXRlKCc8aDE+SGVsbG8gV29ybGQ8L2gxPicpO1xuXHQgICAgICogICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSkoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIENsb25pbmcgRE9NIGVsZW1lbnRzIGZyb20gdGhlIHBhcmVudCB3aW5kb3cgKGluIHRoaXMgZXhhbXBsZSB3ZSBjbG9uZSBhbiBgaDNgIGVsZW1lbnQgZnJvbSB0aGUgcGFyZW50IHdpbmRvdyk6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogKGFzeW5jICgpPT4ge1xuXHQgICAgICogICAgIHRyeSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IGN1cnJlbnRXaW5kb3cgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICAgICAgY29uc3QgcGFyZW50V2luZG93ID0gYXdhaXQgY3VycmVudFdpbmRvdy5nZXRQYXJlbnRXaW5kb3coKTtcblx0ICAgICAqICAgICAgICAgY29uc3QgY2xvbmVkSDMgPSBwYXJlbnRXaW5kb3cuZ2V0V2ViV2luZG93KCkuZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaDMnKS5jbG9uZU5vZGUodHJ1ZSk7XG5cdCAgICAgKiAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKGNsb25lZEgzKTtcblx0ICAgICAqXG5cdCAgICAgKiAgICAgfSBjYXRjaCAoZXJyKSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogUmVuZGVyaW5nIG9uIGEgY2hpbGQgd2luZG93IHZpYSBhIGxpYnJhcnkgKGluIHRoaXMgZXhhbXBsZSB3ZSBhcmUgdXNpbmcgdGhlIFtsaXQtaHRtbF0oaHR0cHM6Ly9saXQtaHRtbC5wb2x5bWVyLXByb2plY3Qub3JnLylcblx0ICAgICAqIHRlbXBsYXRlIGxpYnJhcnkgdG8gcmVuZGVyIGNvbnRlbnQgb24gYSBibGFuayBjaGlsZCB3aW5kb3cuIFlvdSBhcmUgbm90IGdvaW5nIHRvIGJlIGFibGUgdG8gY29weSBwYXN0ZSB0aGlzIGV4YW1wbGUgd2l0aG91dFxuXHQgICAgICogY29uZmlndXJpbmcgdGhlIHByb2plY3QgY29ycmVjdGx5IGJ1dCB0aGlzIHdvdWxkIGRlbW9uc3RyYXRlIHNvbWUgdGVtcGxhdGluZyBvcHRpb25zIGF2YWlsYWJsZSk6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogKGFzeW5jICgpPT4ge1xuXHQgICAgICogICAgIHRyeSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHtcblx0ICAgICAqICAgICAgICAgICAgIG5hbWU6IGBjaGlsZC13aW5kb3ctJHtEYXRlLm5vdygpfWAsXG5cdCAgICAgKiAgICAgICAgICAgICB1cmw6ICdhYm91dDpibGFuaydcblx0ICAgICAqICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IHRlbXBsYXRlID0gaHRtbGBcblx0ICAgICAqICAgICAgICAgICAgIDxkaXY+XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgPHNwYW4+Q2xpY2sgaGVyZTogPC9zcGFuPlxuXHQgICAgICogICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPSR7KCk9PiBjb25zb2xlLmxvZygnSGVsbG8gV29ybGQhJyl9PmxvZyB0byB0aGUgY29uc29sZTwvYnV0dG9uPlxuXHQgICAgICogICAgICAgICAgICAgPC9kaXY+YDtcblx0ICAgICAqICAgICAgICAgcmVuZGVyKHRlbXBsYXRlLCB3aW4uZ2V0V2ViV2luZG93KCkuZG9jdW1lbnQuYm9keSk7XG5cdCAgICAgKlxuXHQgICAgICogICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSkoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRXZWJXaW5kb3coKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy1nZXQtd2ViLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0V2ViV2luZG93KHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB3aW5kb3cgaXMgYSBtYWluIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHduZCA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqIGNvbnN0IGlzTWFpblduZCA9IHduZC5pc01haW5XaW5kb3coKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKCdJcyB0aGlzIGEgbWFpbiB3aW5kb3c/ICcgKyBpc01haW5XbmQpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGlzTWFpbldpbmRvdygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWlzLW1haW4td2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMubWUudXVpZCA9PT0gdGhpcy5tZS5uYW1lO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IHNob3dpbmcuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc1dpbmRvd1Nob3dpbmcoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5pc1Nob3dpbmcuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uaXNTaG93aW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNXaW5kb3dTaG93aW5nKCkudGhlbihib29sID0+IGNvbnNvbGUubG9nKGJvb2wpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgaXNTaG93aW5nKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignaXMtd2luZG93LXNob3dpbmcnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTWF4aW1pemVzIHRoZSB3aW5kb3dcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIG1heFdpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93Lm1heGltaXplLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLm1heGltaXplKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogbWF4V2luZG93KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTWF4aW1pemVkIHdpbmRvdycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgbWF4aW1pemUoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdtYXhpbWl6ZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIE1pbmltaXplcyB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gbWluV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubWluaW1pemUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtaW5XaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdNaW5pbWl6ZWQgd2luZG93JykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBtaW5pbWl6ZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ21pbmltaXplLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTW92ZXMgdGhlIHdpbmRvdyBieSBhIHNwZWNpZmllZCBhbW91bnQuXG5cdCAgICAgKiBAcGFyYW0gZGVsdGFMZWZ0IFRoZSBjaGFuZ2UgaW4gdGhlIGxlZnQgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGRlbHRhVG9wIFRoZSBjaGFuZ2UgaW4gdGhlIHRvcCBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5tb3ZlQnkuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBtb3ZlQnkobGVmdCwgdG9wKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5tb3ZlQnkobGVmdCwgdG9wKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtb3ZlQnkoNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01vdmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBtb3ZlQnkoZGVsdGFMZWZ0LCBkZWx0YVRvcCwgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignbW92ZS13aW5kb3ctYnknLCB7XG5cdCAgICAgICAgICAgIGRlbHRhTGVmdCxcblx0ICAgICAgICAgICAgZGVsdGFUb3AsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIE1vdmVzIHRoZSB3aW5kb3cgdG8gYSBzcGVjaWZpZWQgbG9jYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gbGVmdCBUaGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG5cdCAgICAgKiBAcGFyYW0gdG9wIFRoZSB0b3AgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cubW92ZVRvLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gbW92ZVRvKGxlZnQsIHRvcCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubW92ZVRvKGxlZnQsIHRvcClcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtb3ZlVG8oNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01vdmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIG1vdmVUbyhsZWZ0LCB0b3AsIHBvc2l0aW9uaW5nT3B0aW9ucykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ21vdmUtd2luZG93Jywge1xuXHQgICAgICAgICAgICBsZWZ0LFxuXHQgICAgICAgICAgICB0b3AsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc2l6ZXMgdGhlIHdpbmRvdyBieSBhIHNwZWNpZmllZCBhbW91bnQuXG5cdCAgICAgKiBAcGFyYW0gZGVsdGFXaWR0aCBUaGUgY2hhbmdlIGluIHRoZSB3aWR0aCBvZiB0aGUgd2luZG93XG5cdCAgICAgKiBAcGFyYW0gZGVsdGFIZWlnaHQgVGhlIGNoYW5nZSBpbiB0aGUgaGVpZ2h0IG9mIHRoZSB3aW5kb3dcblx0ICAgICAqIEBwYXJhbSBhbmNob3IgU3BlY2lmaWVzIGEgY29ybmVyIHRvIHJlbWFpbiBmaXhlZCBkdXJpbmcgdGhlIHJlc2l6ZS5cblx0ICAgICAqIENhbiB0YWtlIHRoZSB2YWx1ZXM6IFwidG9wLWxlZnRcIiwgXCJ0b3AtcmlnaHRcIiwgXCJib3R0b20tbGVmdFwiLCBvciBcImJvdHRvbS1yaWdodFwiLlxuXHQgICAgICogSWYgdW5kZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyBcInRvcC1sZWZ0XCJcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnJlc2l6ZUJ5Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcmVzaXplQnkobGVmdCwgdG9wLCBhbmNob3IpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnJlc2l6ZUJ5KGxlZnQsIHRvcCwgYW5jaG9yKVxuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlc2l6ZUJ5KDU4MCwgMzAwLCAndG9wLXJpZ2h0JykudGhlbigoKSA9PiBjb25zb2xlLmxvZygnUmVzaXplZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVzaXplQnkoZGVsdGFXaWR0aCwgZGVsdGFIZWlnaHQsIGFuY2hvciwgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbigncmVzaXplLXdpbmRvdy1ieScsIHtcblx0ICAgICAgICAgICAgZGVsdGFXaWR0aDogTWF0aC5mbG9vcihkZWx0YVdpZHRoKSxcblx0ICAgICAgICAgICAgZGVsdGFIZWlnaHQ6IE1hdGguZmxvb3IoZGVsdGFIZWlnaHQpLFxuXHQgICAgICAgICAgICBhbmNob3IsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc2l6ZXMgdGhlIHdpbmRvdyB0byB0aGUgc3BlY2lmaWVkIGRpbWVuc2lvbnMuXG5cdCAgICAgKiBAcGFyYW0gd2lkdGggVGhlIGNoYW5nZSBpbiB0aGUgd2lkdGggb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGhlaWdodCBUaGUgY2hhbmdlIGluIHRoZSBoZWlnaHQgb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGFuY2hvciBTcGVjaWZpZXMgYSBjb3JuZXIgdG8gcmVtYWluIGZpeGVkIGR1cmluZyB0aGUgcmVzaXplLlxuXHQgICAgICogQ2FuIHRha2UgdGhlIHZhbHVlczogXCJ0b3AtbGVmdFwiLCBcInRvcC1yaWdodFwiLCBcImJvdHRvbS1sZWZ0XCIsIG9yIFwiYm90dG9tLXJpZ2h0XCIuXG5cdCAgICAgKiBJZiB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IGlzIFwidG9wLWxlZnRcIlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cucmVzaXplVG8uaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiByZXNpemVUbyhsZWZ0LCB0b3AsIGFuY2hvcikge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ucmVzaXplVG8obGVmdCwgdG9wLCBhbmNob3IpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlc2l6ZVRvKDU4MCwgMzAwLCAndG9wLWxlZnQnKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdSZXNpemVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICByZXNpemVUbyh3aWR0aCwgaGVpZ2h0LCBhbmNob3IsIHBvc2l0aW9uaW5nT3B0aW9ucykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3Jlc2l6ZS13aW5kb3cnLCB7XG5cdCAgICAgICAgICAgIHdpZHRoOiBNYXRoLmZsb29yKHdpZHRoKSxcblx0ICAgICAgICAgICAgaGVpZ2h0OiBNYXRoLmZsb29yKGhlaWdodCksXG5cdCAgICAgICAgICAgIGFuY2hvcixcblx0ICAgICAgICAgICAgcG9zaXRpb25pbmdPcHRpb25zLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzdG9yZXMgdGhlIHdpbmRvdyB0byBpdHMgbm9ybWFsIHN0YXRlIChpLmUuLCB1bm1pbmltaXplZCwgdW5tYXhpbWl6ZWQpLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cucmVzdG9yZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlc3RvcmUoKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5yZXN0b3JlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogcmVzdG9yZSgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Jlc3RvcmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICByZXN0b3JlKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVzdG9yZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFdpbGwgYnJpbmcgdGhlIHdpbmRvdyB0byB0aGUgZnJvbnQgb2YgdGhlIGVudGlyZSBzdGFjayBhbmQgZ2l2ZSBpdCBmb2N1cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnNldEFzRm9yZWdyb3VuZC5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldEFzRm9yZWdyb3VuZCgpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnNldEFzRm9yZWdyb3VuZCgpXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0QXNGb3JlZ3JvdW5kKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnSW4gdGhlIGZvcmVncm91bmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNldEFzRm9yZWdyb3VuZCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1mb3JlZ3JvdW5kLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyB0aGUgd2luZG93J3Mgc2l6ZSBhbmQgcG9zaXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5zZXRCb3VuZHMuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzZXRCb3VuZHMoYm91bmRzKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zZXRCb3VuZHMoYm91bmRzKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzZXRCb3VuZHMoe1xuXHQgICAgICogICAgIGhlaWdodDogMTAwLFxuXHQgICAgICogICAgIHdpZHRoOiAyMDAsXG5cdCAgICAgKiAgICAgdG9wOiA0MDAsXG5cdCAgICAgKiAgICAgbGVmdDogNDAwXG5cdCAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdCb3VuZHMgc2V0IHRvIHdpbmRvdycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgc2V0Qm91bmRzKGJvdW5kcywgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignc2V0LXdpbmRvdy1ib3VuZHMnLCB7IC4uLmJvdW5kcywgLi4udGhpcy5pZGVudGl0eSwgcG9zaXRpb25pbmdPcHRpb25zIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNob3dzIHRoZSB3aW5kb3cgaWYgaXQgaXMgaGlkZGVuLlxuXHQgICAgICogQHBhcmFtIGZvcmNlIFNob3cgd2lsbCBiZSBwcmV2ZW50ZWQgZnJvbSBzaG93aW5nIHdoZW4gZm9yY2UgaXMgZmFsc2UgYW5kXG5cdCAgICAgKiAg4oCYc2hvdy1yZXF1ZXN0ZWTigJkgaGFzIGJlZW4gc3Vic2NyaWJlZCB0byBmb3IgYXBwbGljYXRpb27igJlzIG1haW4gd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2hvdy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IGZhbHNlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzaG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc2hvdygpXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2hvdygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Nob3dpbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNob3coZm9yY2UgPSBmYWxzZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy13aW5kb3cnLCB7IGZvcmNlLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgdGhlIHdpbmRvdyBpZiBpdCBpcyBoaWRkZW4gYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gbGVmdCBUaGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgd2luZG93IGluIHBpeGVsc1xuXHQgICAgICogQHBhcmFtIHRvcCBUaGUgdG9wIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cgaW4gcGl4ZWxzXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgU2hvdyB3aWxsIGJlIHByZXZlbnRlZCBmcm9tIGNsb3Npbmcgd2hlbiBmb3JjZSBpcyBmYWxzZSBhbmRcblx0ICAgICAqIOKAmHNob3ctcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvd1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2hvd0F0Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd0F0KGxlZnQsIHRvcCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc2hvd0F0KGxlZnQsIHRvcClcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzaG93QXQoNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Nob3dpbmcgYXQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNob3dBdChsZWZ0LCB0b3AsIGZvcmNlID0gZmFsc2UpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdzaG93LWF0LXdpbmRvdycsIHtcblx0ICAgICAgICAgICAgZm9yY2UsXG5cdCAgICAgICAgICAgIGxlZnQ6IE1hdGguZmxvb3IobGVmdCksXG5cdCAgICAgICAgICAgIHRvcDogTWF0aC5mbG9vcih0b3ApLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29sc1xuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBXaW5kb3cuc2hvd0RldmVsb3BlclRvb2xzXG5cdCAgICAgKi9cblx0ICAgIC8qKlxuXHQgICAgICogVXBkYXRlcyB0aGUgd2luZG93IHVzaW5nIHRoZSBwYXNzZWQgb3B0aW9ucy5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBWYWx1ZXMgdGhhdCBhcmUgb2JqZWN0cyBhcmUgZGVlcC1tZXJnZWQsIG92ZXJ3cml0aW5nIG9ubHkgdGhlIHZhbHVlcyB0aGF0IGFyZSBwcm92aWRlZC5cblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIENoYW5nZXMgYSB3aW5kb3cncyBvcHRpb25zIHRoYXQgd2VyZSBkZWZpbmVkIHVwb24gY3JlYXRpb24uIFNlZSB0dXRvcmlhbFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gdXBkYXRlT3B0aW9ucygpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gd2luLnVwZGF0ZU9wdGlvbnMoe21heFdpZHRoOiAxMDB9KTtcblx0ICAgICAqIH1cblx0ICAgICAqIHVwZGF0ZU9wdGlvbnMoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdvcHRpb25zIGlzIHVwZGF0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgdXBkYXRlT3B0aW9ucyhvcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd1cGRhdGUtd2luZG93LW9wdGlvbnMnLCB7IG9wdGlvbnMsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBQcm92aWRlcyBjcmVkZW50aWFscyB0byBhdXRoZW50aWNhdGlvbiByZXF1ZXN0c1xuXHQgICAgICogQHBhcmFtIHVzZXJOYW1lIHVzZXJOYW1lIHRvIHByb3ZpZGUgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIGNoYWxsZW5nZVxuXHQgICAgICogQHBhcmFtIHBhc3N3b3JkIHBhc3N3b3JkIHRvIHByb3ZpZGUgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIGNoYWxsZW5nZVxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLndyYXAoe3V1aWQ6ICdPcGVuZmluUE9DJ30pLnRoZW4oYXBwID0+IHtcblx0ICAgICAqICAgICBhcHAub24oJ3dpbmRvdy1hdXRoLXJlcXVlc3RlZCcsIGV2dCA9PiB7XG5cdCAgICAgKiAgICAgICAgIGxldCB3aW4gPSBmaW4uV2luZG93LndyYXAoeyB1dWlkOiBldnQudXVpZCwgbmFtZTogZXZ0Lm5hbWV9KTtcblx0ICAgICAqICAgICAgICAgd2luLmF1dGhlbnRpY2F0ZSgndXNlck5hbWUnLCAnUEBhc3N3MHJkJykudGhlbigoKT0+IGNvbnNvbGUubG9nKCdhdXRoZW50aWNhdGVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGF1dGhlbnRpY2F0ZSh1c2VyTmFtZSwgcGFzc3dvcmQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCd3aW5kb3ctYXV0aGVudGljYXRlJywgeyB1c2VyTmFtZSwgcGFzc3dvcmQsIC4uLnRoaXMuaWRlbnRpdHkgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgYSBtZW51IG9uIHRoZSB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSB1c2VyIGhhcyBlaXRoZXIgc2VsZWN0ZWQgYW4gaXRlbSBvciBjbG9zZWQgdGhlIG1lbnUuIChUaGlzIG1heSB0YWtlIGxvbmdlciB0aGFuIG90aGVyIGFwaXMpLlxuXHQgICAgICogUmVzb2x2ZXMgdG8gYW4gb2JqZWN0IHdpdGggYHtyZXN1bHQ6ICdjbGlja2VkJywgZGF0YSB9YCB3aGVyZSBkYXRhIGlzIHRoZSBkYXRhIGZpZWxkIG9uIHRoZSBtZW51IGl0ZW0gY2xpY2tlZCwgb3IgYHtyZXN1bHQgJ2Nsb3NlZCd9YCB3aGVuIHRoZSB1c2VyIGRvZXNuJ3Qgc2VsZWN0IGFueXRoaW5nLlxuXHQgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aWxsIGNsb3NlIHByZXZpb3VzbHkgb3BlbmVkIG1lbnVzLlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICogQHBhcmFtIG9wdGlvbnNcblx0ICAgICAqIEB0eXBlUGFyYW0gRGF0YSBVc2VyLWRlZmluZWQgc2hhcGUgZm9yIGRhdGEgcmV0dXJuZWQgdXBvbiBtZW51IGl0ZW0gY2xpY2suICBTaG91bGQgYmUgYVxuXHQgICAgICogW3VuaW9uXShodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay8yL2V2ZXJ5ZGF5LXR5cGVzLmh0bWwjdW5pb24tdHlwZXMpXG5cdCAgICAgKiBvZiBhbGwgcG9zc2libGUgZGF0YSBzaGFwZXMgZm9yIHRoZSBlbnRpcmUgbWVudSwgYW5kIHRoZSBjbGljayBoYW5kbGVyIHNob3VsZCBwcm9jZXNzXG5cdCAgICAgKiB0aGVzZSB3aXRoIGEgXCJyZWR1Y2VyXCIgcGF0dGVybi5cblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gc2hvdyBhIGRyb3AgZG93biBtZW51IG92ZXIgdmlld3MgaW4gYSBwbGF0Zm9ybSB3aW5kb3c6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgdGVtcGxhdGUgPSBbXG5cdCAgICAgKiAgICAge1xuXHQgICAgICogICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgICAgICAgZGF0YTogJ2hlbGxvIGZyb20gaXRlbSAxJ1xuXHQgICAgICogICAgIH0sXG5cdCAgICAgKiAgICAgeyB0eXBlOiAnc2VwYXJhdG9yJyB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgbGFiZWw6ICdNZW51IEl0ZW0gMicsXG5cdCAgICAgKiAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICAgICAgIGNoZWNrZWQ6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIGRhdGE6ICdUaGUgdXNlciBjbGlja2VkIHRoZSBjaGVja2JveCdcblx0ICAgICAqICAgICB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgbGFiZWw6ICdzZWUgbW9yZScsXG5cdCAgICAgKiAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuXHQgICAgICogICAgICAgICBzdWJtZW51OiBbXG5cdCAgICAgKiAgICAgICAgICAgICB7IGxhYmVsOiAnc3VibWVudSAxJywgZGF0YTogJ2hlbGxvIGZyb20gc3VibWVudScgfVxuXHQgICAgICogICAgICAgICBdXG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogXVxuXHQgICAgICogZmluLm1lLnNob3dQb3B1cE1lbnUoeyB0ZW1wbGF0ZSB9KS50aGVuKHIgPT4ge1xuXHQgICAgICogICAgIGlmIChyLnJlc3VsdCA9PT0gJ2Nsb3NlZCcpIHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ25vdGhpbmcgaGFwcGVuZWQnKTtcblx0ICAgICAqICAgICB9IGVsc2Uge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZyhyLmRhdGEpXG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIE92ZXJyaWRpbmcgdGhlIGJ1aWx0IGluIGNvbnRleHQgbWVudSAobm90ZTogdGhhdCB0aGlzIGNhbiBiZSBkb25lIHBlciBlbGVtZW50IG9yIGRvY3VtZW50IHdpZGUpOlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZSA9PiB7XG5cdCAgICAgKiAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICogICAgIGNvbnN0IHRlbXBsYXRlID0gW1xuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgICAgICAgICAgIGRhdGE6ICdoZWxsbyBmcm9tIGl0ZW0gMSdcblx0ICAgICAqICAgICAgICAgfSxcblx0ICAgICAqICAgICAgICAgeyB0eXBlOiAnc2VwYXJhdG9yJyB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAyJyxcblx0ICAgICAqICAgICAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICAgICAgICAgICBjaGVja2VkOiB0cnVlLFxuXHQgICAgICogICAgICAgICAgICAgZGF0YTogJ1RoZSB1c2VyIGNsaWNrZWQgdGhlIGNoZWNrYm94J1xuXHQgICAgICogICAgICAgICB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ3NlZSBtb3JlJyxcblx0ICAgICAqICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuXHQgICAgICogICAgICAgICAgICAgc3VibWVudTogW1xuXHQgICAgICogICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdzdWJtZW51IDEnLCBkYXRhOiAnaGVsbG8gZnJvbSBzdWJtZW51JyB9XG5cdCAgICAgKiAgICAgICAgICAgICBdXG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICBdXG5cdCAgICAgKiAgICAgZmluLm1lLnNob3dQb3B1cE1lbnUoeyB0ZW1wbGF0ZSwgeDogZS54LCB5OiBlLnkgfSkudGhlbihyID0+IHtcblx0ICAgICAqICAgICAgICAgaWYgKHIucmVzdWx0ID09PSAnY2xvc2VkJykge1xuXHQgICAgICogICAgICAgICAgICAgY29uc29sZS5sb2coJ25vdGhpbmcgaGFwcGVuZWQnKTtcblx0ICAgICAqICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKHIuZGF0YSlcblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgIH0pXG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHNob3dQb3B1cE1lbnUob3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctcG9wdXAtbWVudScsIHsgb3B0aW9ucywgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDbG9zZXMgdGhlIHdpbmRvdydzIHBvcHVwIG1lbnUsIGlmIG9uZSBleGlzdHMuXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgT25seSBvbmUgcG9wdXAgbWVudSB3aWxsIGV2ZXIgYmUgc2hvd2luZyBhdCBhIHRpbWUuIENhbGxpbmcgYHNob3dQb3B1cE1lbnVgIHdpbGwgYXV0b21hdGljYWxseSBjbG9zZVxuXHQgICAgICogYW55IGV4aXN0aW5nIHBvcHVwIG1lbnUuXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gY2xvc2UgYSBwb3B1cCBtZW51IGlmIHRoZSB1c2VyJ3MgbW91c2UgbGVhdmVzIGFuIGVsZW1lbnQgZm9yIGV4YW1wbGUuXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5jbG9zZVBvcHVwTWVudSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGNsb3NlUG9wdXBNZW51KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xvc2UtcG9wdXAtbWVudScsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIERpc3BhdGNoIGEgcmVzdWx0IHRvIHRoZSBjYWxsZXIgb2YgYHNob3dQb3B1cFdpbmRvd2AuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSWYgdGhpcyB3aW5kb3cgaXNuJ3QgY3VycmVudGx5IGJlaW5nIHNob3duIGFzIGEgcG9wdXAsIHRoaXMgY2FsbCB3aWxsIHNpbGVudGx5IGZhaWwuXG5cdCAgICAgKiBAcGFyYW0gZGF0YSBTZXJpYWxpemFibGUgZGF0YSB0byBzZW5kIHRvIHRoZSBjYWxsZXIgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXdhaXQgZmluLm1lLmRpc3BhdGNoUG9wdXBSZXN1bHQoe1xuXHQgICAgICogICAgIGZvbzogJ2Jhcidcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGRpc3BhdGNoUG9wdXBSZXN1bHQoZGF0YSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZGlzcGF0Y2gtcG9wdXAtcmVzdWx0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rpc3BhdGNoLXBvcHVwLXJlc3VsdCcsIHsgZGF0YSwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJpbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBwcmludCB0YXNrLlxuXHQgICAgICogQHJlbWFya3MgV2hlbiBgc2lsZW50YCBpcyBzZXQgdG8gYHRydWVgLCB0aGUgQVBJIHdpbGwgcGljayB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBwcmludGVyIGlmIGRldmljZU5hbWUgaXMgZW1wdHlcblx0ICAgICAqIGFuZCB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgcHJpbnRpbmcuXG5cdCAgICAgKlxuXHQgICAgICogVXNlIHRoZSBDU1Mgc3R5bGUgYHBhZ2UtYnJlYWstYmVmb3JlOiBhbHdheXM7YCB0byBmb3JjZSBwcmludCB0byBhIG5ldyBwYWdlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICpcblx0ICAgICAqIHdpbi5wcmludCh7IHNpbGVudDogZmFsc2UsIGRldmljZU5hbWU6ICdzeXN0ZW0tcHJpbnRlci1uYW1lJyB9KS50aGVuKCgpID0+IHtcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygncHJpbnQgY2FsbCBoYXMgYmVlbiBzZW50IHRvIHRoZSBzeXN0ZW0nKTtcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogSWYgYSB3aW5kb3cgaGFzIGVtYmVkZGVkIHZpZXdzLCB0aG9zZSB2aWV3cyB3aWxsIG5vdCBwcmludCBieSBkZWZhdWx0LiAgVG8gcHJpbnQgYSB3aW5kb3cncyBjb250ZW50cyBpbmNsdWRpbmcgZW1iZWRkZWQgdmlld3MsXG5cdCAgICAgKiB1c2UgdGhlIGBjb250ZW50YCBvcHRpb246XG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBQcmludCBlbWJlZGRlZCB2aWV3c1xuXHQgICAgICogd2luLnByaW50KHsgY29udGVudDogJ3ZpZXdzJyB9KTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBQcmludCBzY3JlZW5zaG90IG9mIGN1cnJlbnQgd2luZG93XG5cdCAgICAgKiB3aW4ucHJpbnQoeyBjb250ZW50OiAnc2NyZWVuc2hvdCcgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIFdoZW4gYGNvbnRlbnRgIGlzIHNldCB0byBgdmlld3NgLCB0aGUgZW1iZWRkZWQgdmlld3MgaW4gdGhlIHBsYXRmb3JtIHdpbmRvdyB3aWxsIGJlIGNvbmNhdGVuYXRlZCBhbmQgcHJpbnRlZCBhc1xuXHQgICAgICogaW5kaXZpZHVhbCBwYWdlcy4gIElmIGBpbmNsdWRlU2VsZmAgaXMgc2V0IHRvIGB0cnVlYCwgdGhlIHBsYXRmb3JtIHdpbmRvdyBpdHNlbGYgd2lsbCBiZSBwcmludGVkIGFzIHRoZSBmaXJzdFxuXHQgICAgICogcGFnZSAtIGJlIGF3YXJlIHRoYXQgdGhpcyBwYWdlIHdpbGwgKm5vdCogaW5jbHVkZSB0aGUgZW1iZWRkZWQgdmlld3MgLSBpdCB3aWxsIG9ubHkgaW5jbHVkZSB0aGUgY29udGVudHMgb2Zcblx0ICAgICAqIHRoZSBwbGF0Zm9ybSB3aW5kb3cgaXRzZWxmIChlLmcuIHRhYiBzdGFja3MpLCB3aXRoIGJsYW5rIHNwYWNlcyB3aGVyZSB0aGUgdmlldyBjb250ZW50cyB3b3VsZCBiZSBlbWJlZGRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBEdWUgdG8gYSBrbm93biBpc3N1ZSwgdmlldyBjb250ZW50cyB0aGF0IGFyZSBub3QgdmlzaWJsZSBhdCB0aGUgdGltZSBgcHJpbnRgIGlzIGNhbGxlZCB3aWxsIG5vdCBhcHBlYXIgd2hlblxuXHQgICAgICogcHJpbnRpbmcgYGNvbnRlbnRzOiB2aWV3c2AuICBUaGlzIGluY2x1ZGVzIHZpZXdzIHRoYXQgYXJlIG9ic2N1cmVkIGJlaGluZCBvdGhlciBhY3RpdmUgVUkgZWxlbWVudHMuXG5cdCAgICAgKlxuXHQgICAgICogVG8gcHJpbnQgdGhlIHZpZXdzIGVtYmVkZGVkIGluIHRoZWlyIHBhZ2UgY29udGV4dCwgc2V0IGBjb250ZW50YCB0byBgc2NyZWVuc2hvdGAuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHByaW50KG9wdGlvbnMgPSB7IGNvbnRlbnQ6ICdzZWxmJyB9KSB7XG5cdCAgICAgICAgc3dpdGNoIChvcHRpb25zLmNvbnRlbnQpIHtcblx0ICAgICAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG5cdCAgICAgICAgICAgIGNhc2UgJ3NlbGYnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnByaW50KG9wdGlvbnMpO1xuXHQgICAgICAgICAgICBjYXNlICdzY3JlZW5zaG90Jzpcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncHJpbnQtc2NyZWVuc2hvdCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgICAgICAgICAgY2FzZSAndmlld3MnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwcmludC12aWV3cycsIHsgLi4udGhpcy5pZGVudGl0eSwgb3B0aW9ucyB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fVxuXHRJbnN0YW5jZSQ3Ll9XaW5kb3cgPSBfV2luZG93O1xuXHRyZXR1cm4gSW5zdGFuY2UkNztcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeSQxO1xuXG5mdW5jdGlvbiByZXF1aXJlRmFjdG9yeSQxICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkRmFjdG9yeSQxKSByZXR1cm4gRmFjdG9yeSQ4O1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkkMSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDgsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDguX1dpbmRvd01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgYmFzZV8xID0gYmFzZTtcblx0Y29uc3QgdmFsaWRhdGVfMSA9IHZhbGlkYXRlO1xuXHRjb25zdCBJbnN0YW5jZV8xID0gcmVxdWlyZUluc3RhbmNlKCk7XG5cdC8qKlxuXHQgKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIF9XaW5kb3d9IGNsYXNzLCBhdmFpbGFibGUgdW5kZXIgYGZpbi5XaW5kb3dgLlxuXHQgKi9cblx0Y2xhc3MgX1dpbmRvd01vZHVsZSBleHRlbmRzIGJhc2VfMS5CYXNlIHtcblx0ICAgIC8qKlxuXHQgICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBBUEkgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gV2luZG93IGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGEgV2luZG93IGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYSBXaW5kb3cgdGhyb3VnaG91dCBpdHMgZW50aXJlIGxpZmVjeWNsZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LndyYXAuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGNyZWF0ZVdpbigpLnRoZW4oKCkgPT4gZmluLldpbmRvdy53cmFwKHsgdXVpZDogJ2FwcC0xJywgbmFtZTogJ215QXBwJyB9KSlcblx0ICAgICAqIC50aGVuKHdpbiA9PiBjb25zb2xlLmxvZygnd3JhcHBlZCB3aW5kb3cnKSlcblx0ICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctd3JhcCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGVycm9yTXNnID0gKDAsIHZhbGlkYXRlXzEudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuXHQgICAgICAgIGlmIChlcnJvck1zZykge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gbmV3IEluc3RhbmNlXzEuX1dpbmRvdyh0aGlzLndpcmUsIGlkZW50aXR5KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBXaW5kb3cgaWRlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBXaW5kb3cgaWRlbnRpdHkgdGhhdCBkb2VzIG5vdCB5ZXQgZXhpc3Qgd2lsbCAqbm90KiB0aHJvdyBhbiBlcnJvciwgYW5kIGluc3RlYWRcblx0ICAgICAqIHJldHVybnMgYSBzdHViIG9iamVjdCB0aGF0IGNhbm5vdCB5ZXQgcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGx1bWJpbmcgZXZlbnRpbmdcblx0ICAgICAqIGZvciBhIFdpbmRvdyB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cud3JhcFN5bmMuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogbGV0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyB1dWlkOiAnYXBwLTEnLCBuYW1lOiAnbXlBcHAnIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy13cmFwLXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLl9XaW5kb3codGhpcy53aXJlLCBpZGVudGl0eSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYSBuZXcgV2luZG93LlxuXHQgICAgICogQHBhcmFtIG9wdGlvbnMgLSBXaW5kb3cgY3JlYXRpb24gb3B0aW9uc1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbk9wdGlvbiA9IHtcblx0ICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuXHQgICAgICogICAgICAgICBkZWZhdWx0V2lkdGg6IDMwMCxcblx0ICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmNyZWF0ZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgZnJhbWU6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjcmVhdGVXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgaXMgY3JlYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY3JlYXRlKG9wdGlvbnMpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLXdpbmRvdycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHdpbiA9IG5ldyBJbnN0YW5jZV8xLl9XaW5kb3codGhpcy53aXJlLCB7IHV1aWQ6IHRoaXMubWUudXVpZCwgbmFtZTogb3B0aW9ucy5uYW1lIH0pO1xuXHQgICAgICAgIHJldHVybiB3aW4uY3JlYXRlV2luZG93KG9wdGlvbnMpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgV2luZG93IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgd2luZG93XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uV2luZG93LmdldEN1cnJlbnQoKVxuXHQgICAgICogLnRoZW4od25kID0+IGNvbnNvbGUubG9nKCdjdXJyZW50IHdpbmRvdycpKVxuXHQgICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqXG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0Q3VycmVudCgpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWN1cnJlbnQtd2luZG93JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKCF0aGlzLndpcmUubWUuaXNXaW5kb3cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFdpbmRvdyBjb250ZXh0Jyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIHJldHVybiB0aGlzLndyYXAoeyB1dWlkLCBuYW1lIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYSBXaW5kb3cgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCB3aW5kb3dcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHduZCA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqIGNvbnN0IGluZm8gPSBhd2FpdCB3bmQuZ2V0SW5mbygpO1xuXHQgICAgICogY29uc29sZS5sb2coaW5mbyk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY3VycmVudC13aW5kb3ctc3luYycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICghdGhpcy53aXJlLm1lLmlzV2luZG93KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgaW4gYSBXaW5kb3cgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQ4Ll9XaW5kb3dNb2R1bGUgPSBfV2luZG93TW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQ4O1xufVxuXG52YXIgaGFzUmVxdWlyZWRXaW5kb3c7XG5cbmZ1bmN0aW9uIHJlcXVpcmVXaW5kb3cgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRXaW5kb3cpIHJldHVybiB3aW5kb3ckMTtcblx0aGFzUmVxdWlyZWRXaW5kb3cgPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHRcdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHRcdCAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG5cdFx0ICAgIH1cblx0XHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0XHR9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICBvW2syXSA9IG1ba107XG5cdFx0fSkpO1xuXHRcdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdFx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0XHR9O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludHMgZm9yIHRoZSBPcGVuRmluIGBXaW5kb3dgIEFQSSAoYGZpbi5XaW5kb3dgKS5cblx0XHQgKlxuXHRcdCAqICoge0BsaW5rIF9XaW5kb3dNb2R1bGV9IGNvbnRhaW5zIHN0YXRpYyBtZW1iZXJzIG9mIHRoZSBgV2luZG93YCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLldpbmRvd2AuXG5cdFx0ICogKiB7QGxpbmsgX1dpbmRvd30gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gV2luZG93LCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uV2luZG93LmdldEN1cnJlbnRgLlxuXHRcdCAqXG5cdFx0ICogVGhlc2UgYXJlIHNlcGFyYXRlIGNvZGUgZW50aXRpZXMsIGFuZCBhcmUgZG9jdW1lbnRlZCBzZXBhcmF0ZWx5LiAgSW4gdGhlIFtwcmV2aW91cyB2ZXJzaW9uIG9mIHRoZSBBUEkgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvMzIuMTE0Ljc2LjEwL2luZGV4Lmh0bWwpLFxuXHRcdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdFx0ICpcblx0XHQgKiBVbmRlcnNjb3JlIHByZWZpeGluZyBvZiBPcGVuRmluIHR5cGVzIHRoYXQgYWxpYXMgRE9NIGVudGl0aWVzIHdpbGwgYmUgZml4ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQxKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UoKSwgZXhwb3J0cyk7IFxuXHR9ICh3aW5kb3ckMSkpO1xuXHRyZXR1cm4gd2luZG93JDE7XG59XG5cbi8qKlxuICogRW50cnkgcG9pbnQgZm9yIHRoZSBPcGVuRmluIGBTeXN0ZW1gIEFQSSAoYGZpbi5TeXN0ZW1gKS5cbiAqXG4gKiAqIHtAbGluayBTeXN0ZW19IGNvbnRhaW5zIHN0YXRpYyBtZW1iZXJzIG9mIHRoZSBgU3lzdGVtYCBBUEkgKGF2YWlsYWJsZSB1bmRlciBgZmluLlN5c3RlbWApXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzeXN0ZW0sIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3lzdGVtLlN5c3RlbSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSRpID0gYmFzZTtcbmNvbnN0IHRyYW5zcG9ydF9lcnJvcnNfMSQxID0gdHJhbnNwb3J0RXJyb3JzO1xuY29uc3Qgd2luZG93XzEgPSByZXF1aXJlV2luZG93KCk7XG5jb25zdCBldmVudHNfMSQ2ID0gcmVxdWlyZSQkMDtcbi8qKlxuICogQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29yZSBvZiBPcGVuRmluIFJ1bnRpbWUuIEFsbG93cyB0aGUgZGV2ZWxvcGVyXG4gKiB0byBwZXJmb3JtIHN5c3RlbS1sZXZlbCBhY3Rpb25zLCBzdWNoIGFzIGFjY2Vzc2luZyBsb2dzLCB2aWV3aW5nIHByb2Nlc3NlcyxcbiAqIGNsZWFyaW5nIHRoZSBjYWNoZSBhbmQgZXhpdGluZyB0aGUgcnVudGltZSBhcyB3ZWxsIGFzIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5TeXN0ZW1FdmVudHMgc3lzdGVtIGV2ZW50c30uXG4gKlxuICovXG5jbGFzcyBTeXN0ZW0gZXh0ZW5kcyBiYXNlXzEkaS5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlLCAnc3lzdGVtJyk7XG4gICAgfVxuICAgIHNlbmRFeHRlcm5hbFByb2Nlc3NSZXF1ZXN0KGFjdGlvbiwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhpdEV2ZW50S2V5ID0gJ2V4dGVybmFsLXByb2Nlc3MtZXhpdGVkJztcbiAgICAgICAgICAgIGxldCBwcm9jZXNzVXVpZDtcbiAgICAgICAgICAgIGxldCBleGl0UGF5bG9hZDtcbiAgICAgICAgICAgIGxldCBleHRlcm5hbFByb2Nlc3NFeGl0SGFuZGxlcjtcbiAgICAgICAgICAgIGxldCBvZldpbmRvdztcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5saXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGV4dGVybmFsUHJvY2Vzc0V4aXRIYW5kbGVyID0gKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHBheWxvYWQgfHwge307XG4gICAgICAgICAgICAgICAgICAgIGV4aXRQYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9waWM6ICdleGl0ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXVpZDogZGF0YS5wcm9jZXNzVXVpZCB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXRDb2RlOiBkYXRhLmV4aXRDb2RlIHx8IDBcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NVdWlkID09PSBwYXlsb2FkLnByb2Nlc3NVdWlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmxpc3RlbmVyKGV4aXRQYXlsb2FkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mV2luZG93LnJlbW92ZUxpc3RlbmVyKGV4aXRFdmVudEtleSwgZXh0ZXJuYWxQcm9jZXNzRXhpdEhhbmRsZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAvLyB3aW5kb3cgY29uc3RydWN0b3IgZXhwZWN0cyB0aGUgbmFtZSBpcyBub3QgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLndpcmUubWUubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpcmUubWUubmFtZSA9IHRoaXMud2lyZS5tZS51dWlkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvZldpbmRvdyA9IG5ldyB3aW5kb3dfMS5fV2luZG93KHRoaXMud2lyZSwgdGhpcy53aXJlLm1lKTtcbiAgICAgICAgICAgICAgICBvZldpbmRvdy5vbihleGl0RXZlbnRLZXksIGV4dGVybmFsUHJvY2Vzc0V4aXRIYW5kbGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2lyZVxuICAgICAgICAgICAgICAgIC5zZW5kQWN0aW9uKGFjdGlvbiwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzVXVpZCA9IHBheWxvYWQuZGF0YS51dWlkO1xuICAgICAgICAgICAgICAgIHJlc29sdmUocGF5bG9hZC5kYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoZXhpdFBheWxvYWQgJiYgcHJvY2Vzc1V1aWQgPT09IGV4aXRQYXlsb2FkLnV1aWQpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5saXN0ZW5lcihleGl0UGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgICAgIG9mV2luZG93LnJlbW92ZUxpc3RlbmVyKGV4aXRFdmVudEtleSwgZXh0ZXJuYWxQcm9jZXNzRXhpdEhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAob2ZXaW5kb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgb2ZXaW5kb3cucmVtb3ZlTGlzdGVuZXIoZXhpdEV2ZW50S2V5LCBleHRlcm5hbFByb2Nlc3NFeGl0SGFuZGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBydW50aW1lLiBUaGUgdmVyc2lvbiBjb250YWlucyB0aGUgbWFqb3IsIG1pbm9yLFxuICAgICAqIGJ1aWxkIGFuZCByZXZpc2lvbiBudW1iZXJzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0VmVyc2lvbigpLnRoZW4odiA9PiBjb25zb2xlLmxvZyh2KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFZlcnNpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXZlcnNpb24nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGNhY2hlZCBkYXRhIGNvbnRhaW5pbmcgYXBwbGljYXRpb24gcmVzb3VyY2VcbiAgICAgKiBmaWxlcyAoaW1hZ2VzLCBIVE1MLCBKYXZhU2NyaXB0IGZpbGVzKSwgY29va2llcywgYW5kIGl0ZW1zIHN0b3JlZCBpbiB0aGVcbiAgICAgKiBMb2NhbCBTdG9yYWdlLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gU2VlIGJlbG93IGZvciBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIGFjY2VwdGVkIG9wdGlvbnMsIHNlZSB0aGUgZm9sbG93aW5nIHBhZ2VzOlxuICAgICAqICogY2FjaGU6IGJyb3dzaW5nIGRhdGEgY2FjaGUgZm9yIGh0bWwgZmlsZXMgYW5kIGltYWdlcyAoW2NhY2hpbmddKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvQ2FjaGluZykpXG4gICAgICogKiBjb29raWVzOiBicm93c2VyIFtjb29raWVzXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Nvb2tpZXMpXG4gICAgICogKiBsb2NhbFN0b3JhZ2U6IGJyb3dzZXIgZGF0YSB0aGF0IGNhbiBiZSB1c2VkIGFjcm9zcyBzZXNzaW9ucyAoW2xvY2FsIHN0b3JhZ2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvbG9jYWxTdG9yYWdlKSlcbiAgICAgKiAqIGFwcGNhY2hlOiBodG1sNSBbYXBwbGljYXRpb24gY2FjaGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvVXNpbmdfdGhlX2FwcGxpY2F0aW9uX2NhY2hlKVxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBjbGVhckNhY2hlT3B0aW9ucyA9IHtcbiAgICAgKiAgICAgYXBwY2FjaGU6IHRydWUsXG4gICAgICogICAgIGNhY2hlOiB0cnVlLFxuICAgICAqICAgICBjb29raWVzOiB0cnVlLFxuICAgICAqICAgICBsb2NhbFN0b3JhZ2U6IHRydWVcbiAgICAgKiB9O1xuICAgICAqIGZpbi5TeXN0ZW0uY2xlYXJDYWNoZShjbGVhckNhY2hlT3B0aW9ucykudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ2FjaGUgY2xlYXJlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKi9cbiAgICBjbGVhckNhY2hlKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGVhci1jYWNoZScsIG9wdGlvbnMpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGFsbCBjYWNoZWQgZGF0YSB3aGVuIE9wZW5GaW4gUnVudGltZSBleGl0cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmRlbGV0ZUNhY2hlT25FeGl0KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnRGVsZXRlZCBDYWNoZScpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGVsZXRlQ2FjaGVPbkV4aXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZGVsZXRlLWNhY2hlLXJlcXVlc3QnKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEV4aXRzIHRoZSBSdW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZXhpdCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ2V4aXQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4aXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZXhpdC1kZXNrdG9wJykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIGEgSlNPTiBtYW5pZmVzdCB1c2luZyB0aGUgYnJvd3NlciBwcm9jZXNzIGFuZCByZXR1cm5zIGEgSmF2YXNjcmlwdCBvYmplY3QuXG4gICAgICogQHBhcmFtIG1hbmlmZXN0VXJsIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRvIGZldGNoLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5mZXRjaE1hbmlmZXN0KCdodHRwczovL3d3dy5wYXRoLXRvLW1hbmlmZXN0LmNvbScpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBmZXRjaE1hbmlmZXN0KG1hbmlmZXN0VXJsKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZXRjaC1tYW5pZmVzdCcsIHsgbWFuaWZlc3RVcmwgfSk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgYW55IHVud3JpdHRlbiBjb29raWVzIGRhdGEgdG8gZGlzay5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmZsdXNoQ29va2llU3RvcmUoKVxuICAgICAqICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnc3VjY2VzcycpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZmx1c2hDb29raWVTdG9yZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmbHVzaC1jb29raWUtc3RvcmUnKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBkYXRhIChuYW1lLCBpZHMsIGJvdW5kcykgZm9yIGFsbCBhcHBsaWNhdGlvbiB3aW5kb3dzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0QWxsV2luZG93cygpLnRoZW4od2lucyA9PiBjb25zb2xlLmxvZyh3aW5zKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEFsbFdpbmRvd3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWFsbC13aW5kb3dzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBkYXRhIGZvciBhbGwgYXBwbGljYXRpb25zLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0QWxsQXBwbGljYXRpb25zKCkudGhlbihhcHBzID0+IGNvbnNvbGUubG9nKGFwcHMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0QWxsQXBwbGljYXRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1hbGwtYXBwbGljYXRpb25zJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50IHN0cmluZyB0aGF0IHN0YXJ0ZWQgT3BlbkZpbiBSdW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0Q29tbWFuZExpbmVBcmd1bWVudHMoKS50aGVuKGFyZ3MgPT4gY29uc29sZS5sb2coYXJncykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRDb21tYW5kTGluZUFyZ3VtZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY29tbWFuZC1saW5lLWFyZ3VtZW50cycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGNyYXNoIHJlcG9ydGVyLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0Q3Jhc2hSZXBvcnRlclN0YXRlKCkudGhlbihzdGF0ZSA9PiBjb25zb2xlLmxvZyhzdGF0ZSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRDcmFzaFJlcG9ydGVyU3RhdGUoKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhOiB7IGRpYWdub3N0aWNNb2RlLCBpc1J1bm5pbmcgfSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWNyYXNoLXJlcG9ydGVyLXN0YXRlJyk7XG4gICAgICAgIGNvbnNvbGUud2FybignZGlhZ25vc3RpY01vZGUgcHJvcGVydHkgaXMgZGVwcmVjYXRlZC4gSXQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24nKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWNNb2RlIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uXG4gICAgICAgICAgICBkaWFnbm9zdGljTW9kZSxcbiAgICAgICAgICAgIGRpYWdub3N0aWNzTW9kZTogZGlhZ25vc3RpY01vZGUsXG4gICAgICAgICAgICBpc1J1bm5pbmdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGNyYXNoIHJlcG9ydGVyIGlmIG5vdCBhbHJlYWR5IHJ1bm5pbmcuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBjb25maWd1cmUgY3Jhc2ggcmVwb3J0ZXJcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFlvdSBjYW4gb3B0aW9uYWxseSBzcGVjaWZ5IGBkaWFnbm9zdGljc01vZGVgIHRvIGhhdmUgdGhlIGxvZ3Mgc2VudCB0b1xuICAgICAqIE9wZW5GaW4gb24gcnVudGltZSBjbG9zZS4gKE5PVEU6IGBkaWFnbm9zdGljc01vZGVgIHdpbGwgdHVybiBvbiB2ZXJib3NlIGxvZ2dpbmcgYW5kIGRpc2FibGUgdGhlIHNhbmRib3hcbiAgICAgKiBmb3IgbmV3bHkgbGF1bmNoZWQgcmVuZGVyZXIgcHJvY2Vzc2VzLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2RlYnVnZ2luZyNkaWFnbm9zdGljcy1tb2RlIGZvclxuICAgICAqIG1vcmUgZGV0YWlscy4pXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5zdGFydENyYXNoUmVwb3J0ZXIoe2RpYWdub3N0aWNzTW9kZTogdHJ1ZX0pLnRoZW4ocmVwb3J0ZXIgPT4gY29uc29sZS5sb2cocmVwb3J0ZXIpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgc3RhcnRDcmFzaFJlcG9ydGVyKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IG5ld09wdHMgPSB7IC4uLm9wdHMsIGRpYWdub3N0aWNNb2RlOiBvcHRzLmRpYWdub3N0aWNzTW9kZSB8fCBvcHRzLmRpYWdub3N0aWNNb2RlIH07XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhOiB7IGRpYWdub3N0aWNNb2RlLCBpc1J1bm5pbmcgfSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3RhcnQtY3Jhc2gtcmVwb3J0ZXInLCBuZXdPcHRzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWNNb2RlIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uXG4gICAgICAgICAgICBkaWFnbm9zdGljTW9kZSxcbiAgICAgICAgICAgIGRpYWdub3N0aWNzTW9kZTogZGlhZ25vc3RpY01vZGUsXG4gICAgICAgICAgICBpc1J1bm5pbmdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGhleCBlbmNvZGVkIGhhc2ggb2YgdGhlIG1hY2hpbmUgaWQgYW5kIHRoZSBjdXJyZW50bHkgbG9nZ2VkIGluIHVzZXIgbmFtZS5cbiAgICAgKiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCB3YXkgdG8gdW5pcXVlbHkgaWRlbnRpZnkgYSB1c2VyIC8gbWFjaGluZSBjb21iaW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEZvciBXaW5kb3dzIHN5c3RlbXMgdGhpcyBpcyBhIHNoYTI1NiBoYXNoIG9mIHRoZSBtYWNoaW5lIElEIHNldCBpbiB0aGUgcmVnaXN0cnkga2V5OlxuICAgICAqIGBIS0VZX0xPQ0FMX01BQ0hJTkVcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXENyeXB0b2dyYXBoeVxcTWFjaGluZUd1aWRgIGFuZCBgVVNFUk5BTUVgLlxuICAgICAqXG4gICAgICogRm9yIE9TWCBzeXN0ZW1zLCBhIG5hdGl2ZS1sZXZlbCBjYWxsIGlzIHVzZWQgdG8gZ2V0IHRoZSBtYWNoaW5lIElELlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0VW5pcXVlVXNlcklkKCkudGhlbihpZCA9PiBjb25zb2xlLmxvZyhpZCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRVbmlxdWVVc2VySWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXVuaXF1ZS11c2VyLWlkJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIGZyYW1lIGluZm8gb2JqZWN0IGZvciB0aGUgdXVpZCBhbmQgbmFtZSBwYXNzZWQgaW5cbiAgICAgKiBAcGFyYW0gdXVpZCAtIFRoZSBVVUlEIG9mIHRoZSB0YXJnZXQuXG4gICAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlIHBvc3NpYmxlIHR5cGVzIGFyZSAnd2luZG93JywgJ2lmcmFtZScsICdleHRlcm5hbCBjb25uZWN0aW9uJyBvciAndW5rbm93bicuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGVudGl0eVV1aWQgPSAnT3BlbmZpblBPQyc7XG4gICAgICogY29uc3QgZW50aXR5TmFtZSA9ICc0MGM3NGI1ZC1lZDk4LTQwZjctODUzZi1lM2QzYzI2OTkxNzUnO1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0RW50aXR5SW5mbyhlbnRpdHlVdWlkLCBlbnRpdHlOYW1lKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIC8vIGV4YW1wbGUgaW5mbyBzaGFwZVxuICAgICAqIHtcbiAgICAgKiAgICAgXCJ1dWlkXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICBcIm5hbWVcIjogXCI0MGM3NGI1ZC1lZDk4LTQwZjctODUzZi1lM2QzYzI2OTkxNzVcIixcbiAgICAgKiAgICAgXCJwYXJlbnRcIjoge1xuICAgICAqICAgICAgICAgXCJ1dWlkXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICAgICAgXCJuYW1lXCI6IFwiT3BlbmZpblBPQ1wiXG4gICAgICogICAgIH0sXG4gICAgICogICAgIFwiZW50aXR5VHlwZVwiOiBcImlmcmFtZVwiXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEVudGl0eUluZm8odXVpZCwgbmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1lbnRpdHktaW5mbycsIHsgdXVpZCwgbmFtZSB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBnaXZlbiBlbnZpcm9ubWVudCB2YXJpYWJsZSBvbiB0aGUgY29tcHV0ZXIgb24gd2hpY2ggdGhlIHJ1bnRpbWUgaXMgaW5zdGFsbGVkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRFbnZpcm9ubWVudFZhcmlhYmxlKCdIT01FJykudGhlbihlbnYgPT4gY29uc29sZS5sb2coZW52KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEVudmlyb25tZW50VmFyaWFibGUoZW52TmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlXG4gICAgICAgICAgICAuc2VuZEFjdGlvbignZ2V0LWVudmlyb25tZW50LXZhcmlhYmxlJywge1xuICAgICAgICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IGVudk5hbWVcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGN1cnJlbnRseSBmb2N1c2VkIFdpbmRvdy5cbiAgICAgKiBJZiBhIFZpZXcgY3VycmVudGx5IGhhcyBmb2N1cywgcmV0dXJucyB0aGUgaWRlbnRpdHkgb2YgVmlldydzIHBhcmVudCBXaW5kb3cuXG4gICAgICogVXNlIHtAbGluayBXaW5kb3cuX1dpbmRvdyNnZXRGb2N1c2VkQ29udGVudCBXaW5kb3cuZ2V0Rm9jdXNlZENvbnRlbnR9IHRvIGRpcmVjdGx5IGFjY2VzcyBjdXJyZW50bHkgZm9jdXNlZCBXaW5kb3cgb3IgVmlldy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldEZvY3VzZWRXaW5kb3coKS50aGVuKHdpbkluZm8gPT4gY29uc29sZS5sb2cod2luSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRGb2N1c2VkV2luZG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1mb2N1c2VkLXdpbmRvdycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY3VycmVudGx5IGZvY3VzZWQgY29udGVudC4gUmV0dXJucyBpZGVudGl0eSBvZiBlbnRpdHkgd2l0aCBgZW50aXR5VHlwZWAuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRGb2N1c2VkQ29udGVudCgpLnRoZW4oY29udGVudElkZW50aXR5ID0+IGNvbnNvbGUubG9nKGNvbnRlbnRJZGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRGb2N1c2VkQ29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZm9jdXNlZC1jb250ZW50JykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGdpdmVuIGFwcCdzIGNlcnRpZmljYXRpb24gc3RhdHVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3RVcmwgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6MTIzNC9hcHAuanNvblwiXG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgY2VydGlmaWNhdGlvbkluZm8gPSBhd2FpdCBmaW4uU3lzdGVtLmlzQXBwQ2VydGlmaWVkKG1hbmlmZXN0VXJsKTtcbiAgICAgKiB9IGNhdGNoKGVycikge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgaXNBcHBDZXJ0aWZpZWQobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGE6IHsgY2VydGlmaWVkSW5mbyB9IH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpcy1hcHAtY2VydGlmaWVkJywgeyBtYW5pZmVzdFVybCB9KTtcbiAgICAgICAgcmV0dXJuIGNlcnRpZmllZEluZm87XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIHRoZSBpbnN0YWxsZWQgcnVudGltZSB2ZXJzaW9ucyBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRJbnN0YWxsZWRSdW50aW1lcygpLnRoZW4ocnVudGltZXMgPT4gY29uc29sZS5sb2cocnVudGltZXMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gaW5jb21wYXRpYmxlIHdpdGggc3RhbmRhbG9uZSBub2RlIHByb2Nlc3MuXG4gICAgZ2V0SW5zdGFsbGVkUnVudGltZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWluc3RhbGxlZC1ydW50aW1lcycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEucnVudGltZXMpO1xuICAgIH1cbiAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCBzdGFuZGFsb25lIG5vZGUgcHJvY2Vzcy5cbiAgICBhc3luYyBnZXRJbnN0YWxsZWRBcHBzKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgZGF0YTogeyBpbnN0YWxsZWRBcHBzIH0gfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1pbnN0YWxsZWQtYXBwcycpO1xuICAgICAgICByZXR1cm4gaW5zdGFsbGVkQXBwcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBjb250ZW50cyBvZiB0aGUgbG9nIHdpdGggdGhlIHNwZWNpZmllZCBmaWxlbmFtZS5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIG9iamVjdCB0aGF0IGlkIGRlZmluZWQgYnkgdGhlIEdldExvZ1JlcXVlc3RUeXBlIGludGVyZmFjZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldExvZygpIHtcbiAgICAgKiAgICAgY29uc3QgbG9ncyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0TG9nTGlzdCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZmluLlN5c3RlbS5nZXRMb2cobG9nc1swXSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZ2V0TG9nKCkudGhlbihsb2cgPT4gY29uc29sZS5sb2cobG9nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldExvZyhvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndmlldy1sb2cnLCBvcHRpb25zKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHVuaXF1ZSBpZGVudGlmaWVyIChVVUlEKSBwcm92aWRlZCBieSB0aGUgbWFjaGluZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldE1hY2hpbmVJZCgpLnRoZW4oaWQgPT4gY29uc29sZS5sb2coaWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TWFjaGluZUlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1tYWNoaW5lLWlkJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gKGluY2x1c2l2ZSkgbG9nZ2luZyBsZXZlbCB0aGF0IGlzIGN1cnJlbnRseSBiZWluZyB3cml0dGVuIHRvIHRoZSBsb2cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRNaW5Mb2dMZXZlbCgpLnRoZW4obGV2ZWwgPT4gY29uc29sZS5sb2cobGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TWluTG9nTGV2ZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LW1pbi1sb2ctbGV2ZWwnKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gZm9yIGVhY2ggbG9nIGZpbGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRMb2dMaXN0KCkudGhlbihsb2dMaXN0ID0+IGNvbnNvbGUubG9nKGxvZ0xpc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TG9nTGlzdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsaXN0LWxvZ3MnKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGRhdGEgYWJvdXQgdGhlIG1vbml0b3Igc2V0dXAgb2YgdGhlXG4gICAgICogY29tcHV0ZXIgdGhhdCB0aGUgcnVudGltZSBpcyBydW5uaW5nIG9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0TW9uaXRvckluZm8oKS50aGVuKG1vbml0b3JJbmZvID0+IGNvbnNvbGUubG9nKG1vbml0b3JJbmZvKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldE1vbml0b3JJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1tb25pdG9yLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbW91c2UgaW4gdmlydHVhbCBzY3JlZW4gY29vcmRpbmF0ZXMgKGxlZnQsIHRvcCkuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRNb3VzZVBvc2l0aW9uKCkudGhlbihtb3VzZVBvc2l0aW9uID0+IGNvbnNvbGUubG9nKG1vdXNlUG9zaXRpb24pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TW91c2VQb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtbW91c2UtcG9zaXRpb24nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGFsbCBvZiB0aGUgcnVudGltZSBwcm9jZXNzZXMgdGhhdCBhcmUgY3VycmVudGx5XG4gICAgICogcnVubmluZy4gRWFjaCBlbGVtZW50IGluIHRoZSBhcnJheSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdXVpZFxuICAgICAqIGFuZCB0aGUgbmFtZSBvZiB0aGUgYXBwbGljYXRpb24gdG8gd2hpY2ggdGhlIHByb2Nlc3MgYmVsb25ncy5cbiAgICAgKiBAZGVwcmVjYXRlZCBQbGVhc2UgdXNlIG91ciBuZXcgc2V0IG9mIHByb2Nlc3MgQVBJczpcbiAgICAgKiB7QGxpbmsgV2luZG93Ll9XaW5kb3cjZ2V0UHJvY2Vzc0luZm8gV2luZG93LmdldFByb2Nlc3NJbmZvfVxuICAgICAqIHtAbGluayBWaWV3LlZpZXcjZ2V0UHJvY2Vzc0luZm8gVmlldy5nZXRQcm9jZXNzSW5mb31cbiAgICAgKiB7QGxpbmsgQXBwbGljYXRpb24uQXBwbGljYXRpb24jZ2V0UHJvY2Vzc0luZm8gQXBwbGljYXRpb24uZ2V0UHJvY2Vzc0luZm99XG4gICAgICoge0BsaW5rIFN5c3RlbSNnZXRBbGxQcm9jZXNzSW5mbyBTeXN0ZW0uZ2V0QWxsUHJvY2Vzc0luZm99XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRQcm9jZXNzTGlzdCgpLnRoZW4oUHJvY2Vzc0xpc3QgPT4gY29uc29sZS5sb2coUHJvY2Vzc0xpc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0UHJvY2Vzc0xpc3QoKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUud2FybignU3lzdGVtLmdldFByb2Nlc3NMaXN0IGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBsZWFzZSBjb25zaWRlciB1c2luZyBvdXIgbmV3IHByb2Nlc3MgQVBJczogV2luZG93LmdldFByb2Nlc3NJbmZvLCBWaWV3LmdldFByb2Nlc3NJbmZvLCBBcHBsaWNhdGlvbi5nZXRQcm9jZXNzSW5mbywgU3lzdGVtLmdldEFsbFByb2Nlc3NJbmZvJyk7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncHJvY2Vzcy1zbmFwc2hvdCcpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYWxsIHByb2Nlc3MgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGlzIGluY2x1ZGVzIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIGV2ZXJ5IHByb2Nlc3MgYXNzb2NpYXRlZCB0byBhbGwgZW50aXRpZXMgKHdpbmRvd3MgYW5kIHZpZXdzKS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBhbGxQcm9jZXNzSW5mbyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0QWxsUHJvY2Vzc0luZm8oKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QWxsUHJvY2Vzc0luZm8oKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLXByb2Nlc3MtaW5mbycsIHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBQcm94eSBzZXR0aW5ncy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldFByb3h5U2V0dGluZ3MoKS50aGVuKFByb3h5U2V0dGluZyA9PiBjb25zb2xlLmxvZyhQcm94eVNldHRpbmcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICpcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICBjb25maWc6IHtcbiAgICAgKiAgICAgICAgIHByb3h5QWRkcmVzczogXCJwcm94eUFkZHJlc3NcIiwgLy90aGUgY29uZmlndXJlZCBQcm94eSBBZGRyZXNzXG4gICAgICogICAgICAgICBwcm94eVBvcnQ6IDAsIC8vdGhlIGNvbmZpZ3VyZWQgUHJveHkgcG9ydFxuICAgICAqICAgICAgICAgdHlwZTogXCJzeXN0ZW1cIiAvL1Byb3h5IFR5cGVcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgc3lzdGVtOiB7XG4gICAgICogICAgICAgICBhdXRvQ29uZmlnVXJsOiBcIlwiLFxuICAgICAqICAgICAgICAgYnlwYXNzOiBcIlwiLFxuICAgICAqICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICogICAgICAgICBwcm94eTogXCJcIlxuICAgICAqICAgICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFByb3h5U2V0dGluZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByb3h5LXNldHRpbmdzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJ1bm5pbmcgUnVudGltZSBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRSdW50aW1lSW5mbygpLnRoZW4oUnVudGltZUluZm8gPT4gY29uc29sZS5sb2coUnVudGltZUluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0UnVudGltZUluZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXJ1bnRpbWUtaW5mbycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBydW5uaW5nIFJWTSBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRSdm1JbmZvKCkudGhlbihSdm1JbmZvID0+IGNvbnNvbGUubG9nKFJ2bUluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gaW5jb21wYXRpYmxlIHdpdGggc3RhbmRhbG9uZSBub2RlIHByb2Nlc3MuXG4gICAgZ2V0UnZtSW5mbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtcnZtLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGdlbmVyYWwgc3lzdGVtIGluZm9ybWF0aW9uLiBJZiB5b3UgbmVlZCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZVxuICAgICAqIE9TIGFuZCB0aGUgY3VycmVudGx5IGxvZ2dlZCBpbiB1c2VyLCB1c2UgYGZpbi5TeXN0ZW0uZ2V0T1NJbmZvKClgIGluc3RlYWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRIb3N0U3BlY3MoKS50aGVuKHNwZWNzID0+IGNvbnNvbGUubG9nKHNwZWNzKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEhvc3RTcGVjcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtaG9zdC1zcGVjcycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIE9TIGFuZCB0aGUgY3VycmVudGx5IGxvZ2dlZCBpbiB1c2VyLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0T1NJbmZvKCkudGhlbihzcGVjcyA9PiBjb25zb2xlLmxvZyhzcGVjcykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRPU0luZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LW9zLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUnVucyBhbiBleGVjdXRhYmxlIG9yIGJhdGNoIGZpbGUuIEEgcGF0aCB0byB0aGUgZmlsZSBtdXN0IGJlIGluY2x1ZGVkIGluIG9wdGlvbnMuXG4gICAgICogPGJyPiBBIHV1aWQgbWF5IGJlIG9wdGlvbmFsbHkgcHJvdmlkZWQuIElmIG5vdCBwcm92aWRlZCwgT3BlbkZpbiB3aWxsIGNyZWF0ZSBhIHV1aWQgZm9yIHRoZSBuZXcgcHJvY2Vzcy5cbiAgICAgKiA8YnI+IE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIDxhIGhyZWY9XCJodHRwczovL2RldmVsb3BlcnMub3BlbmZpbi5jby9kb2NzL2FwaS1zZWN1cml0eVwiPkFQSSBzZWN1cml0eSBzZXR0aW5nczwvYT4uIEFsc28sIHRoaXMgYXBpIGhhcyBhbiBlbmhhbmNlZCBwZXJtaXNzaW9uIHNldCB0byBtYWtlIGl0IGxlc3MgZGFuZ2Vyb3VzLiBTbyBhcHBsaWNhdGlvbiBvd25lcnMgY2FuIG9ubHkgYWxsb3cgdG8gbGF1bmNoIHRoZSBhc3NldHMgb3duZWQgYnkgdGhlIGFwcGxpY2F0aW9uLCB0aGUgZW5hYmxlZCBkb3dubG9hZGVkIGZpbGVzIG9yIHRoZSByZXN0cmljdGVkIGV4ZWN1dGFibGVzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEEgb2JqZWN0IHRoYXQgaXMgZGVmaW5lZCBpbiB0aGUgRXh0ZXJuYWxQcm9jZXNzUmVxdWVzdFR5cGUgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJZiBhbiB1bnVzZWQgVVVJRCBpcyBwcm92aWRlZCBpbiBvcHRpb25zLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vIFVVSUQgaXMgcHJvdmlkZWQsIE9wZW5GaW4gd2lsbCBhc3NpZ24gb25lLlxuICAgICAqIFRoaXMgYXBpIGhhcyBhbiBlbmhhbmNlZCBwZXJtaXNzaW9uIHNldCB0byBtYWtlIGl0IGxlc3MgZGFuZ2Vyb3VzLiBTbyBhcHBsaWNhdGlvbiBvd25lcnMgY2FuIG9ubHkgYWxsb3cgdG8gbGF1bmNoIHRoZVxuICAgICAqIGFzc2V0cyBvd25lZCBieSB0aGUgYXBwbGljYXRpb24sIHRoZSBlbmFibGVkIGRvd25sb2FkZWQgZmlsZXMgb3IgdGhlIHJlc3RyaWN0ZWQgZXhlY3V0YWJsZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogU2luY2UgX2FwcEFzc2V0c18gcmVsaWVzIG9uIHRoZSBSVk0sIHdoaWNoIGlzIG1pc3Npbmcgb24gTUFDX09TLCAnYWxpYXMnIGlzIG5vdCBhdmFpbGFibGUuIEluc3RlYWQgcHJvdmlkZVxuICAgICAqIHRoZSBmdWxsIHBhdGggZS5nLiBfL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcC9Db250ZW50cy9NYWNPUy9DYWxjdWxhdG9yXy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogQmFzaWMgRXhhbXBsZTpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ25vdGVwYWQnLFxuICAgICAqICAgICBhcmd1bWVudHM6ICcnLFxuICAgICAqICAgICBsaXN0ZW5lcjogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUHJvbWlzZSByZXNvbHV0aW9uOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICB1dWlkOiBcIkZCM0U2RTM2LTA5NzYtNEMyQi05QTA5LUZCMkU1NEQyRjFCQlwiIC8vIFRoZSBtYXBwZWQgVVVJRCB3aGljaCBpZGVudGlmaWVzIHRoZSBsYXVuY2hlZCBwcm9jZXNzXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTGlzdGVuZXIgY2FsbGJhY2s6XG4gICAgICogYGBganNcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICB0b3BpYzogXCJleGl0ZWRcIiwgLy8gT3IgXCJyZWxlYXNlZFwiIG9uIGEgY2FsbCB0byByZWxlYXNlRXh0ZXJuYWxQcm9jZXNzXG4gICAgICogICAgIHV1aWQ6IFwiRkIzRTZFMzYtMDk3Ni00QzJCLTlBMDktRkIyRTU0RDJGMUJCXCIsIC8vIFRoZSBtYXBwZWQgVVVJRCB3aGljaCBpZGVudGlmaWVzIHRoZSBsYXVuY2hlZCBwcm9jZXNzXG4gICAgICogICAgIGV4aXRDb2RlOiAwIC8vIFByb2Nlc3MgZXhpdCBjb2RlXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQnkgc3BlY2lmeWluZyBhIGxpZmV0aW1lLCBhbiBleHRlcm5hbCBwcm9jZXNzIGNhbiBsaXZlIGFzIGxvbmcgdGhlIHdpbmRvdy9hcHBsaWNhdGlvbiB0aGF0IGxhdW5jaGVkIGl0IG9yXG4gICAgICogcGVyc2lzdCBhZnRlciB0aGUgYXBwbGljYXRpb24gZXhpdHMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG51bGwsIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gJ3BlcnNpc3QnLCBtZWFuaW5nXG4gICAgICogdGhlIHByb2Nlc3MgbGl2ZXMgb24gYWZ0ZXIgdGhlIGFwcGxpY2F0aW9uIGV4aXRzOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmxhdW5jaEV4dGVybmFsUHJvY2Vzcyh7XG4gICAgICogICAgIHBhdGg6ICdub3RlcGFkJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnJyxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbGlmZXRpbWU6ICd3aW5kb3cnXG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTm90ZTogQSBwcm9jZXNzIHRoYXQgZXhpdHMgd2hlbiB0aGUgd2luZG93L2FwcGxpY2F0aW9uIGV4aXRzIGNhbm5vdCBiZSByZWxlYXNlZCB2aWEgZmluLmRlc2t0b3AuU3lzdGVtLnJlbGVhc2VFeHRlcm5hbFByb2Nlc3MuXG4gICAgICpcbiAgICAgKiBCeSBzcGVjaWZ5aW5nIGEgY3dkLCBpdCB3aWxsIHNldCBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IHdoZW4gbGF1bmNoaW5nIGFuIGV4dGVybmFsIHByb2Nlc3M6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ2NtZC5leGUnLFxuICAgICAqICAgICBjd2Q6ICdjOlxcXFx0ZW1wJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnJyxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvY2Vzc0lkZW50aXR5KTtcbiAgICAgKiB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEV4YW1wbGUgdXNpbmcgYW4gYWxpYXMgZnJvbSBhcHAuanNvbiBhcHBBc3NldHMgcHJvcGVydHk6XG4gICAgICpcbiAgICAgKiBgYGBqc29uXG4gICAgICogXCJhcHBBc3NldHNcIjogW1xuICAgICAqICAgICB7XG4gICAgICogICAgICAgICBcInNyY1wiOiBcImV4ZS56aXBcIixcbiAgICAgKiAgICAgICAgIFwiYWxpYXNcIjogXCJteUFwcFwiLFxuICAgICAqICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNC4xMi44XCIsXG4gICAgICogICAgICAgICBcInRhcmdldFwiOiBcIm15QXBwLmV4ZVwiLFxuICAgICAqICAgICAgICAgXCJhcmdzXCI6IFwiYSBiIGMgZFwiXG4gICAgICogICAgIH0sXG4gICAgICogXVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvLyAgV2hlbiBjYWxsZWQsIGlmIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkIHRoZW4gdGhlIGFyZ3VtZW50cyAoaWYgYW55KVxuICAgICAqIC8vICBhcmUgdGFrZW4gZnJvbSB0aGUgJ2FwcC5qc29uJyBmaWxlLCBmcm9tIHRoZSAgJ2FyZ3MnIHBhcmFtZXRlclxuICAgICAqIC8vICBvZiB0aGUgJ2FwcEFzc2V0cycgT2JqZWN0IHdpdGggdGhlIHJlbGV2YW50ICdhbGlhcycuXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICAvL0FkZGl0aW9uYWxseSBub3RlIHRoYXQgdGhlIGV4ZWN1dGFibGUgZm91bmQgaW4gdGhlIHppcCBmaWxlIHNwZWNpZmllZCBpbiBhcHBBc3NldHNcbiAgICAgKiAgICAgLy93aWxsIGRlZmF1bHQgdG8gdGhlIG9uZSBtZW50aW9uZWQgYnkgYXBwQXNzZXRzLnRhcmdldFxuICAgICAqICAgICAvL0lmIHRoZSB0aGUgcGF0aCBiZWxvdyByZWZlcnMgdG8gYSBzcGVjaWZpYyBwYXRoIGl0IHdpbGwgb3ZlcnJpZGUgdGhpcyBkZWZhdWx0XG4gICAgICogICAgIGFsaWFzOiAnbXlBcHAnLFxuICAgICAqICAgICBsaXN0ZW5lcjogKHJlc3VsdCkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhhbXBsZSB1c2luZyBhbiBhbGlhcyBidXQgb3ZlcnJpZGluZyB0aGUgYXJndW1lbnRzOlxuICAgICAqXG4gICAgICogYGBganNvblxuICAgICAqIFwiYXBwQXNzZXRzXCI6IFtcbiAgICAgKiAgICAge1xuICAgICAqICAgICAgICAgXCJzcmNcIjogXCJleGUuemlwXCIsXG4gICAgICogICAgICAgICBcImFsaWFzXCI6IFwibXlBcHBcIixcbiAgICAgKiAgICAgICAgIFwidmVyc2lvblwiOiBcIjQuMTIuOFwiLFxuICAgICAqICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcC5leGVcIixcbiAgICAgKiAgICAgICAgIFwiYXJnc1wiOiBcImEgYiBjIGRcIlxuICAgICAqICAgICB9LFxuICAgICAqIF1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogLy8gIElmICdhcmd1bWVudHMnIGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciBpdCB0YWtlcyBwcmVjZWRlbmNlXG4gICAgICogLy8gIG92ZXIgYW55ICdhcmdzJyBzZXQgaW4gdGhlICdhcHAuanNvbicuXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICBhbGlhczogJ215QXBwJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnZSBmIGcnLFxuICAgICAqICAgICBsaXN0ZW5lcjogKHJlc3VsdCkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSXQgaXMgbm93IHBvc3NpYmxlIHRvIG9wdGlvbmFsbHkgcGVyZm9ybSBhbnkgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyBjZXJ0aWZpY2F0ZSBjaGVja3NcbiAgICAgKiBhZ2FpbnN0IGFuIGFic29sdXRlIHRhcmdldCB2aWEgYGZpbi5kZXNrdG9wLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKWA6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIFwiY2VydGlmaWNhdGVcIjoge1xuICAgICAqICAgICBcInNlcmlhbFwiOiBcIjNjIGE1IC4uLlwiLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgaGV4IHN0cmluZyB3aXRoIG9yIHdpdGhvdXQgc3BhY2VzXG4gICAgICogICAgIFwic3ViamVjdFwiOiBcIk89T3BlbkZpbiBJTkMuLCBMPU5ldyBZb3JrLCAuLi5cIiwgLy8gQW4gaW50ZXJuYWxseSB0b2tlbml6ZWQgYW5kIGNvbW1hIGRlbGltaXRlZCBzdHJpbmcgYWxsb3dpbmcgcGFydGlhbCBvciBmdWxsIGNoZWNrcyBvZiB0aGUgc3ViamVjdCBmaWVsZHNcbiAgICAgKiAgICAgXCJwdWJsaWNrZXlcIjogXCIzYyBhNSAuLi5cIiwgICAgICAgICAgICAgICAgICAgICAvLyBBIGhleCBzdHJpbmcgd2l0aCBvciB3aXRob3V0IHNwYWNlc1xuICAgICAqICAgICBcInRodW1icHJpbnRcIjogXCIzYyBhNSAuLi5cIiwgICAgICAgICAgICAgICAgICAgIC8vIEEgaGV4IHN0cmluZyB3aXRoIG9yIHdpdGhvdXQgc3BhY2VzXG4gICAgICogICAgIFwidHJ1c3RlZFwiOiB0cnVlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHRoYXQgdGhlIGNlcnRpZmljYXRlIGlzIHRydXN0ZWQgYW5kIG5vdCByZXZva2VkXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUHJvdmlkaW5nIHRoaXMgaW5mb3JtYXRpb24gYXMgcGFydCBvZiB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9ucyBmb3IgYXNzZXRzIGluIGFuIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3RcbiAgICAgKiB3aWxsIGJlIGFkZGVkIGluIGEgZnV0dXJlIFJWTSB1cGRhdGU6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ0M6XFxcXFVzZXJzXFxcXEV4YW1wbGVVc2VyXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcT3BlbkZpblxcXFxPcGVuRmluUlZNLmV4ZScsXG4gICAgICogICAgIGFyZ3VtZW50czogJy0tdmVyc2lvbicsXG4gICAgICogICAgIGNlcnRpZmljYXRlOiB7XG4gICAgICogICAgICAgICB0cnVzdGVkOiB0cnVlLFxuICAgICAqICAgICAgICAgc3ViamVjdDogJ089T3BlbkZpbiBJTkMuLCBMPU5ldyBZb3JrLCBTPU5ZLCBDPVVTJyxcbiAgICAgKiAgICAgICAgIHRodW1icHJpbnQ6ICfigI4zYyBhNSAyOCAxOSA4MyAwNSBmZSA2OSA4OCBlNiA4ZiA0YiAzYSBhZiBjNSBjNSAxYiAwNyA4MCA1YidcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvY2Vzc0lkZW50aXR5KTtcbiAgICAgKiB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEl0IGlzIHBvc3NpYmxlIHRvIGxhdW5jaCBmaWxlcyB0aGF0IGhhdmUgYmVlbiBkb3dubG9hZGVkIGJ5IHRoZSB1c2VyIGJ5IGxpc3RlbmluZyB0byB0aGUgd2luZG93XG4gICAgICogYGZpbGUtZG93bmxvYWQtY29tcGxldGVkYCBldmVudCBhbmQgdXNpbmcgdGhlIGBmaWxlVXVpZGAgcHJvdmlkZWQgYnkgdGhlIGV2ZW50OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogd2luLmFkZExpc3RlbmVyKCdmaWxlLWRvd25sb2FkLWNvbXBsZXRlZCcsIChldnQpID0+IHtcbiAgICAgKiAgICAgaWYgKGV2dC5zdGF0ZSA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgKiAgICAgICAgIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgICAgICAgICBmaWxlVXVpZDogZXZ0LmZpbGVVdWlkLFxuICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50czogJycsXG4gICAgICogICAgICAgICAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgYXNzZXRzIHNwZWNpZmllZCBpbiB0aGUgYXBwIG1hbmlmZXN0OlxuICAgICAqXG4gICAgICogU2FtcGxlIGFwcEFzc2V0cyBzZWN0aW9uIGluIGFwcC5qc29uXG4gICAgICogYGBganNcbiAgICAgKiAgICAgXCJhcHBBc3NldHNcIjogW1xuICAgICAqICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgIFwic3JjXCI6IFwiaHR0cDovL2ZpbGVzYW1wbGVzLmNvbS9leGUuemlwXCIsXG4gICAgICogICAgICAgICAgICAgXCJhbGlhc1wiOiBcIm15QXBwXCIsXG4gICAgICogICAgICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNC4xMi44XCIsXG4gICAgICogICAgICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcC5leGVcIixcbiAgICAgKiAgICAgICAgICAgICBcImFyZ3NcIjogXCJhIGIgYyBkXCJcbiAgICAgKiAgICAgICAgIH0sXG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgXCJzcmNcIjogXCJodHRwOi8vZXhhbXBsZXMuY29tL2V4ZS56aXBcIixcbiAgICAgKiAgICAgICAgICAgICBcImFsaWFzXCI6IFwibXlBcHAyXCIsXG4gICAgICogICAgICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNS4xMi44XCIsXG4gICAgICogICAgICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcDIuZXhlXCIsXG4gICAgICogICAgICAgICAgICAgXCJhcmdzXCI6IFwiYSBiIGNcIlxuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICBdXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBUaGlzIHBlcm1pc3Npb24gYWxsb3dzIGZvciBsYXVuY2hpbmcgb2YgYWxsIGFzc2V0cyBzcGVjaWZpZWQgaW4gdGhlIGFib3ZlIGFwcEFzc2V0cyBzZWN0aW9uLiAoXCJteUFwcFwiIGFuZCBcIm15QXBwMlwiKTpcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIFwicGVybWlzc2lvbnNcIjoge1xuICAgICAqICAgICAgICBcIlN5c3RlbVwiOiB7XG4gICAgICogICAgICAgICAgICBcImxhdW5jaEV4dGVybmFsUHJvY2Vzc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgICAgICBcImFzc2V0c1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZVxuICAgICAqICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRoaXMgcGVybWlzc2lvbiBhbGxvd3MgZm9yIGxhdW5jaGluZyBvZiBfb25seV8gdGhlIFwibXlBcHBcIiBhc3NldCBpbiB0aGUgYWJvdmUgYXBwQXNzZXRzIHNlY3Rpb24sIGFzIGRlZmluZWQgaW4gYHNyY1J1bGVzYDpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJsYXVuY2hFeHRlcm5hbFByb2Nlc3NcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJhc3NldHNcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgXCJlbmFibGVkXCI6IHRydWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwic3JjUnVsZXNcIjogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIio6Ly9maWxlc2FtcGxlcy5jb20vKlwiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYmVoYXZpb3JcIjogXCJhbGxvd1wiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibWF0Y2hcIjogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI8YWxsX3VybHM+XCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJiZWhhdmlvclwiOiBcImJsb2NrXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTGF1bmNoaW5nIGRvd25sb2FkZWQgZmlsZXM6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgXCJwZXJtaXNzaW9uc1wiOiB7XG4gICAgICogICAgICAgIFwiU3lzdGVtXCI6IHtcbiAgICAgKiAgICAgICAgICAgIFwibGF1bmNoRXh0ZXJuYWxQcm9jZXNzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJlbmFibGVkXCI6IHRydWUsXG4gICAgICogICAgICAgICAgICAgICAgIFwiZG93bmxvYWRzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVGhpcyBwZXJtaXNzaW9uIGFsbG93cyB0byBsYXVuY2ggYWxsIHRoZSBleGVjdXRhYmxlczpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJsYXVuY2hFeHRlcm5hbFByb2Nlc3NcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJleGVjdXRhYmxlc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZVxuICAgICAqICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqXG4gICAgICogVGhpcyBwZXJtaXNzaW9uIG9ubHkgYWxsb3dzIGxhdW5jaGluZyBvZiBleGVjdXRhYmxlcyB3aG9zZSBmaWxlIHBhdGhzIG1hdGNoIHRoZSBjb3JyZXNwb25kaW5nIGBwYXRoUnVsZXNgOlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIFwicGVybWlzc2lvbnNcIjoge1xuICAgICAqICAgICAgICBcIlN5c3RlbVwiOiB7XG4gICAgICogICAgICAgICAgICBcImxhdW5jaEV4dGVybmFsUHJvY2Vzc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgICAgICBcImV4ZWN1dGFibGVzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlXG4gICAgICogICAgICAgICAgICAgICAgICAgICBcInBhdGhSdWxlc1wiOiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiL1dpbmRvd3MvU3lzdGVtMzIvKi5leGVcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwiYWxsb3dcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKi5leGVcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwiYmxvY2tcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgbGF1bmNoRXh0ZXJuYWxQcm9jZXNzKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZEV4dGVybmFsUHJvY2Vzc1JlcXVlc3QoJ2xhdW5jaC1leHRlcm5hbC1wcm9jZXNzJywgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1vbml0b3JzIGEgcnVubmluZyBwcm9jZXNzLiBBIHBpZCBmb3IgdGhlIHByb2Nlc3MgbXVzdCBiZSBpbmNsdWRlZCBpbiBvcHRpb25zLlxuICAgICAqIDxicj4gQSB1dWlkIG1heSBiZSBvcHRpb25hbGx5IHByb3ZpZGVkLiBJZiBub3QgcHJvdmlkZWQsIE9wZW5GaW4gd2lsbCBjcmVhdGUgYSB1dWlkIGZvciB0aGUgbmV3IHByb2Nlc3MuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJZiBhbiB1bnVzZWQgdXVpZCBpcyBwcm92aWRlZCBpbiBvcHRpb25zLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vIHV1aWQgaXMgcHJvdmlkZWQsIE9wZWZpbkZpbiB3aWxsIGFzc2lnbiBhIHV1aWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubW9uaXRvckV4dGVybmFsUHJvY2Vzcyh7XG4gICAgICogICAgIHBpZDogMTAyMDgsXG4gICAgICogICAgIHV1aWQ6ICdteS1leHRlcm5hbC1wcm9jZXNzJywgLy8gb3B0aW9uYWxcbiAgICAgKiAgICAgbGlzdGVuZXI6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IGNvbnNvbGUubG9nKHByb2Nlc3NJZGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBtb25pdG9yRXh0ZXJuYWxQcm9jZXNzKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZEV4dGVybmFsUHJvY2Vzc1JlcXVlc3QoJ21vbml0b3ItZXh0ZXJuYWwtcHJvY2VzcycsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgdGhlIHBhc3NlZCBtZXNzYWdlIGludG8gYm90aCB0aGUgbG9nIGZpbGUgYW5kIHRoZSBjb25zb2xlLlxuICAgICAqIEBwYXJhbSBsZXZlbCBUaGUgbG9nIGxldmVsIGZvciB0aGUgZW50cnkuIENhbiBiZSBlaXRoZXIgXCJpbmZvXCIsIFwid2FybmluZ1wiIG9yIFwiZXJyb3JcIlxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZSB0ZXh0XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sb2coXCJpbmZvXCIsIFwiQW4gZXhhbXBsZSBsb2cgbWVzc2FnZVwiKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdMb2cgaW5mbyBtZXNzYWdlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBsb2cobGV2ZWwsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3cml0ZS10by1sb2cnLCB7IGxldmVsLCBtZXNzYWdlIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIHBhc3NlZCBVUkwgaW4gdGhlIGRlZmF1bHQgd2ViIGJyb3dzZXIuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJdCBvbmx5IHN1cHBvcnRzIGh0dHAocykgYW5kIGZpbihzKSBwcm90b2NvbHMgYnkgZGVmYXVsdC5cbiAgICAgKiBJbiBvcmRlciB0byB1c2Ugb3RoZXIgY3VzdG9tIHByb3RvY29scywgdGhleSBoYXZlIHRvIGJlIGVuYWJsZWQgdmlhXG4gICAgICogW0FQSSBzZWN1cml0eSBzZXR0aW5nc10oaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9hcGktc2VjdXJpdHkpLlxuICAgICAqIEZpbGUgcHJvdG9jb2wgYW5kIGZpbGUgcGF0aCBhcmUgbm90IHN1cHBvcnRlZC5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSBVUkwgdG8gb3BlblxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ub3BlblVybFdpdGhCcm93c2VyKCdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtU3lzdGVtLm9wZW5VcmxXaXRoQnJvd3Nlci5odG1sJylcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnT3BlbmVkIFVSTCcpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBFeGFtcGxlIG9mIHBlcm1pc3Npb24gZGVmaW5pdGlvbiB0byBlbmFibGUgbm9uLWRlZmF1bHQgcHJvdG9jb2xzOlxuICAgICAqXG4gICAgICogTm90ZTogcGVybWlzc2lvbiBkZWZpbml0aW9uIHNob3VsZCBiZSBzcGVjaWZpZWQgaW4gYW4gYXBwIG1hbmlmZXN0IGZpbGUgaWYgdGhlcmUgaXMgbm8gRE9TIHNldHRpbmdzLlxuICAgICAqIE90aGVyd2lzZSBpdCBoYXMgdG8gYmUgc3BlY2lmaWVkIGluIGJvdGggRE9TIGFuZCBhcHAgbWFuaWZlc3QgZmlsZXMuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJvcGVuVXJsV2l0aEJyb3dzZXJcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJwcm90b2NvbHNcIjogWyBcIm1zdGVhbXNcIiwgXCJzbGFja1wiXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgb3BlblVybFdpdGhCcm93c2VyKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ29wZW4tdXJsLXdpdGgtYnJvd3NlcicsIHsgdXJsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyByZWdpc3RyeSBlbnRyeSB1bmRlciB0aGUgSEtDVSByb290IFdpbmRvd3MgcmVnaXN0cnkga2V5IGlmIHRoZSBnaXZlbiBjdXN0b20gcHJvdG9jb2wgbmFtZSBkb2Vzbid0IGV4aXN0IG9yXG4gICAgICogb3ZlcndyaXRlcyB0aGUgZXhpc3RpbmcgcmVnaXN0cnkgZW50cnkgaWYgdGhlIGdpdmVuIGN1c3RvbSBwcm90b2NvbCBuYW1lIGFscmVhZHkgZXhpc3RzLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5IEFQSSBzZWN1cml0eSBzZXR0aW5nc30uIEl0IHJlcXVpcmVzIFJWTSAxMiBvciBoaWdoZXIgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlc2UgcHJvdG9jb2xzIGFyZSByZXNlcnZlZCBhbmQgY2Fubm90IGJlIHJlZ2lzdGVyZWQ6XG4gICAgICogLSBmaW5cbiAgICAgKiAtIGZpbnNcbiAgICAgKiAtIG9wZW5maW5cbiAgICAgKiAtIFVSSSBTY2hlbWVzIHJlZ2lzdGVyZWQgd2l0aCB7QGxpbmsgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9VUklfc2NoZW1lcyNPZmZpY2lhbF9JQU5BLXJlZ2lzdGVyZWRfc2NoZW1lcyBJQU5BfVxuICAgICAqXG4gICAgICogQHRocm93cyBpZiBhIGdpdmVuIGN1c3RvbSBwcm90b2NvbCBmYWlsZWQgdG8gYmUgcmVnaXN0ZXJlZC5cbiAgICAgKiBAdGhyb3dzIGlmIGEgbWFuaWZlc3QgVVJMIGNvbnRhaW5zIHRoZSAnJTEnIHN0cmluZy5cbiAgICAgKiBAdGhyb3dzIGlmIGEgbWFuaWZlc3QgVVJMIGNvbnRhaW5zIGEgcXVlcnkgc3RyaW5nIHBhcmFtZXRlciB3aGljaCBuYW1lIGVxdWFscyB0byB0aGUgUHJvdG9jb2wgTGF1bmNoIFJlcXVlc3QgUGFyYW1ldGVyIE5hbWUuXG4gICAgICogQHRocm93cyBpZiB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIGNvbW1hbmQgc3RyaW5nIHRoYXQgaXMgdG8gYmUgd3JpdHRlbiB0byB0aGUgcmVnaXN0cnkgZXhjZWVkcyAyMDQ4IGJ5dGVzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ucmVnaXN0ZXJDdXN0b21Qcm90b2NvbCh7cHJvdG9jb2xOYW1lOidwcm90b2NvbDEnfSkudGhlbihjb25zb2xlLmxvZykuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXJDdXN0b21Qcm90b2NvbChvcHRpb25zKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTXVzdCBwcm92aWRlIGFuIG9iamVjdCB3aXRoIGEgYHByb3RvY29sTmFtZWAgcHJvcGVydHkgaGF2aW5nIGEgc3RyaW5nIHZhbHVlLicpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdyZWdpc3Rlci1jdXN0b20tcHJvdG9jb2wnLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcmVnaXN0cnkgZW50cnkgZm9yIGEgZ2l2ZW4gY3VzdG9tIHByb3RvY29sLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5IEFQSSBzZWN1cml0eSBzZXR0aW5nc30uIEl0IHJlcXVpcmVzIFJWTSAxMiBvciBoaWdoZXIgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlc2UgcHJvdG9jb2xzIGFyZSByZXNlcnZlZCBhbmQgY2Fubm90IGJlIHVucmVnaXN0ZXJlZDpcbiAgICAgKiAtIGZpblxuICAgICAqIC0gZmluc1xuICAgICAqIC0gb3BlbmZpblxuICAgICAqIC0gVVJJIFNjaGVtZXMgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX1VSSV9zY2hlbWVzI09mZmljaWFsX0lBTkEtcmVnaXN0ZXJlZF9zY2hlbWVzIElBTkF9XG4gICAgICpcbiAgICAgKiBAdGhyb3dzIGlmIGEgcHJvdG9jb2wgZW50cnkgZmFpbGVkIHRvIGJlIHJlbW92ZWQgaW4gcmVnaXN0cnkuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXdhaXQgZmluLlN5c3RlbS51bnJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2woJ3Byb3RvY29sMScpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXJDdXN0b21Qcm90b2NvbChwcm90b2NvbE5hbWUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3VucmVnaXN0ZXItY3VzdG9tLXByb3RvY29sJywgeyBwcm90b2NvbE5hbWUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgcmVnaXN0cmF0aW9uIHN0YXRlIGZvciBhIGdpdmVuIGN1c3RvbSBwcm90b2NvbC5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIHtAbGluayBodHRwczovL2RldmVsb3BlcnMub3BlbmZpbi5jby9kb2NzL2FwaS1zZWN1cml0eSBBUEkgc2VjdXJpdHkgc2V0dGluZ3N9LiBJdCByZXF1aXJlcyBSVk0gMTIgb3IgaGlnaGVyIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGVzZSBwcm90b2NvbHMgYXJlIHJlc2VydmVkIGFuZCBjYW5ub3QgZ2V0IHN0YXRlcyBmb3IgdGhlbTpcbiAgICAgKiAtIGZpblxuICAgICAqIC0gZmluc1xuICAgICAqIC0gb3BlbmZpblxuICAgICAqIC0gVVJJIFNjaGVtZXMgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX1VSSV9zY2hlbWVzI09mZmljaWFsX0lBTkEtcmVnaXN0ZXJlZF9zY2hlbWVzIElBTkF9XG4gICAgICpcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwcm90b2NvbFN0YXRlID0gYXdhaXQgZmluLlN5c3RlbS5nZXRDdXN0b21Qcm90b2NvbFN0YXRlKCdwcm90b2NvbDEnKTtcbiAgICAgKi9cbiAgICBhc3luYyBnZXRDdXN0b21Qcm90b2NvbFN0YXRlKHByb3RvY29sTmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jdXN0b20tcHJvdG9jb2wtc3RhdGUnLCB7IHByb3RvY29sTmFtZSB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcHJvY2VzcyBlbnRyeSBmb3IgdGhlIHBhc3NlZCBVVUlEIG9idGFpbmVkIGZyb20gYSBwcmlvciBjYWxsXG4gICAgICogb2YgZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKS5cbiAgICAgKiBAcGFyYW0gdXVpZCBUaGUgVVVJRCBmb3IgYSBwcm9jZXNzIG9idGFpbmVkIGZyb20gYSBwcmlvciBjYWxsIHRvIGZpbi5kZXNrdG9wLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogXCJub3RlcGFkXCIsXG4gICAgICogICAgIGxpc3RlbmVyOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhcIlRoZSBleGl0IGNvZGVcIiwgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pXG4gICAgICogLnRoZW4oaWRlbnRpdHkgPT4gZmluLlN5c3RlbS5yZWxlYXNlRXh0ZXJuYWxQcm9jZXNzKGlkZW50aXR5LnV1aWQpKVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQcm9jZXNzIGhhcyBiZWVuIHVubWFwcGVkIScpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVsZWFzZUV4dGVybmFsUHJvY2Vzcyh1dWlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVsZWFzZS1leHRlcm5hbC1wcm9jZXNzJywgeyB1dWlkIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29scyBmb3IgdGhlIHNwZWNpZmllZCB3aW5kb3dcbiAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhpcyBpcyBhIG9iamVjdCB0aGF0IGlzIGRlZmluZWQgYnkgdGhlIElkZW50aXR5IGludGVyZmFjZVxuICAgICAqXG4gICAgICogQHR1dG9yaWFsIFN5c3RlbS5zaG93RGV2ZWxvcGVyVG9vbHNcbiAgICAgKi9cbiAgICBzaG93RGV2ZWxvcGVyVG9vbHMoaWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzaG93LWRldmVsb3Blci10b29scycsIGlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEF0dGVtcHQgdG8gY2xvc2UgYW4gZXh0ZXJuYWwgcHJvY2Vzcy4gVGhlIHByb2Nlc3Mgd2lsbCBiZSB0ZXJtaW5hdGVkIGlmIGl0XG4gICAgICogaGFzIG5vdCBjbG9zZWQgYWZ0ZXIgdGhlIGVsYXBzZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGlzIG1ldGhvZCBpcyByZXN0cmljdGVkIGJ5IGRlZmF1bHQgYW5kIG11c3QgYmUgZW5hYmxlZCB2aWFcbiAgICAgKiA8YSBocmVmPVwiaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9hcGktc2VjdXJpdHlcIj5BUEkgc2VjdXJpdHkgc2V0dGluZ3M8L2E+LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEEgb2JqZWN0IGRlZmluZWQgaW4gdGhlIFRlcm1pbmF0ZUV4dGVybmFsUmVxdWVzdFR5cGUgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICBwYXRoOiBcIm5vdGVwYWRcIixcbiAgICAgKiAgICAgbGlzdGVuZXI6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKFwiVGhlIGV4aXQgY29kZVwiLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSlcbiAgICAgKiAudGhlbihpZGVudGl0eSA9PiBmaW4uU3lzdGVtLnRlcm1pbmF0ZUV4dGVybmFsUHJvY2Vzcyh7dXVpZDogaWRlbnRpdHkudXVpZCwgdGltZW91dDoyMDAwLCBraWxsVHJlZTogZmFsc2V9KSlcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnVGVybWluYXRlIHRoZSBwcm9jZXNzJykpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB0ZXJtaW5hdGVFeHRlcm5hbFByb2Nlc3Mob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Rlcm1pbmF0ZS1leHRlcm5hbC1wcm9jZXNzJywgb3B0aW9ucykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIE9wZW5GaW4gUnVudGltZSBQcm94eSBzZXR0aW5ncy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIGNvbmZpZyBvYmplY3QgZGVmaW5lZCBpbiB0aGUgUHJveHlDb25maWcgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS51cGRhdGVQcm94eVNldHRpbmdzKHtwcm94eUFkZHJlc3M6JzEyNy4wLjAuMScsIHByb3h5UG9ydDo4MDgwLCB0eXBlOidodHRwJ30pXG4gICAgICogLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1VwZGF0ZSBwcm94eSBzdWNjZXNzZnVsbHknKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgdXBkYXRlUHJveHlTZXR0aW5ncyhvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndXBkYXRlLXByb3h5Jywgb3B0aW9ucykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgdGhlIGdpdmVuIGFwcGxpY2F0aW9uIGFzc2V0LlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cbiAgICAgKiBAcGFyYW0gYXBwQXNzZXQgQXBwIGFzc2V0IG9iamVjdFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkQXNzZXQoKSB7XG4gICAgICogICAgIGNvbnN0IGFwcEFzc2V0ID0ge1xuICAgICAqICAgICAgICAgc3JjOiBgJHsgbG9jYXRpb24ub3JpZ2luIH0vYXNzZXRzLnppcGAsXG4gICAgICogICAgICAgICBhbGlhczogJ2RpckFwcCcsXG4gICAgICogICAgICAgICB2ZXJzaW9uOiAnMS4yMy4yNCcsXG4gICAgICogICAgICAgICB0YXJnZXQ6ICdhc3NldHMvcnVuLmJhdCdcbiAgICAgKiAgICAgfTtcbiAgICAgKlxuICAgICAqICAgICByZXR1cm4gZmluLlN5c3RlbS5kb3dubG9hZEFzc2V0KGFwcEFzc2V0LCAocHJvZ3Jlc3MgPT4ge1xuICAgICAqICAgICAvL1ByaW50IHByb2dyZXNzIGFzIHdlIGRvd25sb2FkIHRoZSBhc3NldC5cbiAgICAgKiAgICAgICAgIGNvbnN0IGRvd25sb2FkZWRQZXJjZW50ID0gTWF0aC5mbG9vcigocHJvZ3Jlc3MuZG93bmxvYWRlZEJ5dGVzIC8gcHJvZ3Jlc3MudG90YWxCeXRlcykgKiAxMDApO1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coYERvd25sb2FkZWQgJHtkb3dubG9hZGVkUGVyY2VudH0lYCk7XG4gICAgICogICAgIH0pKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBkb3dubG9hZEFzc2V0KClcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3VjY2VzcycpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIC8vIGluY29tcGF0aWJsZSB3aXRoIHN0YW5kYWxvbmUgbm9kZSBwcm9jZXNzLlxuICAgIGFzeW5jIGRvd25sb2FkQXNzZXQoYXBwQXNzZXQsIHByb2dyZXNzTGlzdGVuZXIpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1mdW5jdGlvbi1yZXR1cm4tdHlwZSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgICAgIGNvbnN0IG5vb3AgPSAoKSA9PiB7IH07XG4gICAgICAgIGxldCByZXNvbHZlID0gbm9vcDtcbiAgICAgICAgbGV0IHJlamVjdCA9IG5vb3A7XG4gICAgICAgIGNvbnN0IGRvd25sb2FkQ29tcGxldGVQcm9taXNlID0gbmV3IFByb21pc2UoKHksIG4pID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUgPSB5O1xuICAgICAgICAgICAgcmVqZWN0ID0gbjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG5vZGUuanMgZW52aXJvbm1lbnQgbm90IHN1cHBvcnRlZFxuICAgICAgICBpZiAodGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgIT09ICdvcGVuZmluJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLk5vdFN1cHBvcnRlZEVycm9yKCdkb3dubG9hZEFzc2V0IG9ubHkgc3VwcG9ydGVkIGluIGFuIE9wZW5GaW4gUmVuZGVyIHByb2Nlc3MnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYWxsU2l0ZSA9IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgpO1xuICAgICAgICBjb25zdCBkb3dubG9hZElkID0gdGhpcy53aXJlLmVudmlyb25tZW50LmdldE5leHRNZXNzYWdlSWQoKS50b1N0cmluZygpO1xuICAgICAgICBjb25zdCBkbFByb2dyZXNzS2V5ID0gYGFzc2V0LWRvd25sb2FkLXByb2dyZXNzLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbEVycm9yS2V5ID0gYGFzc2V0LWRvd25sb2FkLWVycm9yLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbENvbXBsZXRlS2V5ID0gYGFzc2V0LWRvd25sb2FkLWNvbXBsZXRlLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbFByb2dyZXNzID0gKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwID0ge1xuICAgICAgICAgICAgICAgIGRvd25sb2FkZWRCeXRlczogcHJvZ3Jlc3MuZG93bmxvYWRlZEJ5dGVzLFxuICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXM6IHByb2dyZXNzLnRvdGFsQnl0ZXNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVyKHApO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjbGVhbkxpc3RlbmVycyA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihkbFByb2dyZXNzS2V5LCBkbFByb2dyZXNzKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGxFcnJvciA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgY29uc3QgeyByZWFzb24sIGVycjogZXJyb3IgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICByZWplY3QobmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvcih7IHJlYXNvbiwgZXJyb3IgfSwgY2FsbFNpdGUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGxDb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGNsZWFuTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbihkbFByb2dyZXNzS2V5LCBkbFByb2dyZXNzKSxcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbmNlKGRsRXJyb3JLZXksIGRsRXJyb3IpLFxuICAgICAgICAgICAgLy8gVE9ETzogZml4IGludGVybmFsIHR5cGVzXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICB0aGlzLm9uY2UoZGxDb21wbGV0ZUtleSwgZGxDb21wbGV0ZSlcbiAgICAgICAgXSk7XG4gICAgICAgIGNvbnN0IGRvd25sb2FkT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oYXBwQXNzZXQsIHsgZG93bmxvYWRJZCB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rvd25sb2FkLWFzc2V0JywgZG93bmxvYWRPcHRpb25zKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGRvd25sb2FkQ29tcGxldGVQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgYSB2ZXJzaW9uIG9mIHRoZSBydW50aW1lLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gRG93bmxvYWQgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gcHJvZ3Jlc3NMaXN0ZW5lciAtIGNhbGxlZCBhcyB0aGUgcnVudGltZSBpcyBkb3dubG9hZGVkIHdpdGggcHJvZ3Jlc3MgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBPbmx5IHN1cHBvcnRlZCBpbiBhbiBPcGVuRmluIFJlbmRlciBwcm9jZXNzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIHZhciBkb3dubG9hZE9wdGlvbnMgPSB7XG4gICAgICogICAgIC8vU3BlY2lmaWMgdmVyc2lvbiBudW1iZXIgcmVxdWlyZWQsIGlmIGdpdmVuIGEgcmVsZWFzZSBjaGFubmVsIHRoZSBjYWxsIHdpbGwgcHJvZHVjZSBhbiBlcnJvci5cbiAgICAgKiAgICAgdmVyc2lvbjogJzkuNjEuMzAuMSdcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZnVuY3Rpb24gb25Qcm9ncmVzcyhwcm9ncmVzcykge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgJHtNYXRoLmZsb29yKChwcm9ncmVzcy5kb3dubG9hZGVkQnl0ZXMgLyBwcm9ncmVzcy50b3RhbEJ5dGVzKSAqIDEwMCl9JWApO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZpbi5TeXN0ZW0uZG93bmxvYWRSdW50aW1lKGRvd25sb2FkT3B0aW9ucywgb25Qcm9ncmVzcykudGhlbigoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdEb3dubG9hZCBjb21wbGV0ZScpO1xuICAgICAqIH0pLmNhdGNoKGVyciA9PiAgICB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBEb3dubG9hZCBGYWlsZWQsIHdlIGNvdWxkIHJldHJ5OiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGRvd25sb2FkUnVudGltZShvcHRpb25zLCBwcm9ncmVzc0xpc3RlbmVyKSB7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlcyA9IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgpO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgLy8gbm9kZS5qcyBlbnZpcm9ubWVudCBub3Qgc3VwcG9ydGVkXG4gICAgICAgICAgICBpZiAodGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgIT09ICdvcGVuZmluJykge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgdHJhbnNwb3J0X2Vycm9yc18xJDEuTm90U3VwcG9ydGVkRXJyb3IoJ2Rvd25sb2FkUnVudGltZSBvbmx5IHN1cHBvcnRlZCBpbiBhbiBPcGVuRmluIFJlbmRlciBwcm9jZXNzJykpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRvd25sb2FkSWQgPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCBkbFByb2dyZXNzS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtcHJvZ3Jlc3MtJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbEVycm9yS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtZXJyb3ItJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbENvbXBsZXRlS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtY29tcGxldGUtJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbFByb2dyZXNzID0gKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEJ5dGVzOiBwcm9ncmVzcy5kb3dubG9hZGVkQnl0ZXMsXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXM6IHByb2dyZXNzLnRvdGFsQnl0ZXNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHByb2dyZXNzTGlzdGVuZXIocCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY2xlYW5MaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogZml4IGludGVybmFsIHR5cGVzXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZGxQcm9ncmVzc0tleSwgZGxQcm9ncmVzcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZGxFcnJvciA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgY2xlYW5MaXN0ZW5lcnMoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJlYXNvbiwgZXJyOiBlcnJvciB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvcih7IHJlYXNvbiwgZXJyb3IgfSwgY2FsbHNpdGVzKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZGxDb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggaW50ZXJuYWwgdHlwZXNcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHRoaXMub24oZGxQcm9ncmVzc0tleSwgZGxQcm9ncmVzcyk7XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggaW50ZXJuYWwgdHlwZXNcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHRoaXMub25jZShkbEVycm9yS2V5LCBkbEVycm9yKTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbmNlKGRsQ29tcGxldGVLZXksIGRsQ29tcGxldGUpO1xuICAgICAgICAgICAgY29uc3QgZG93bmxvYWRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7IGRvd25sb2FkSWQgfSk7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZG93bmxvYWQtcnVudGltZScsIGRvd25sb2FkT3B0aW9ucykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFuTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERvd25sb2FkIHByZWxvYWQgc2NyaXB0cyBmcm9tIGdpdmVuIFVSTHNcbiAgICAgKiBAcGFyYW0gc2NyaXB0cyAtIFVSTHMgb2YgcHJlbG9hZCBzY3JpcHRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHNjcmlwdHMgPSBbXG4gICAgICogICAgIHsgdXJsOiAnaHR0cDovLy4uLi9wcmVsb2FkLmpzJyB9LFxuICAgICAqICAgICB7IHVybDogJ2h0dHA6Ly8uLi4vcHJlbG9hZDIuanMnIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogZmluLlN5c3RlbS5kb3dubG9hZFByZWxvYWRTY3JpcHRzKHNjcmlwdHMpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICogICAgIHJlc3VsdHMuZm9yRWFjaCgoe3VybCwgc3VjY2VzcywgZXJyb3J9KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhgVVJMOiAke3VybH1gKTtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzOiAke3N1Y2Nlc3N9YCk7XG4gICAgICogICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRXJyb3I6ICR7ZXJyb3J9YCk7XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGRvd25sb2FkUHJlbG9hZFNjcmlwdHMoc2NyaXB0cykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rvd25sb2FkLXByZWxvYWQtc2NyaXB0cycsIHsgc2NyaXB0cyB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGRhdGEgKG5hbWUsIGlkcywgYm91bmRzKSBmb3IgYWxsIGFwcGxpY2F0aW9uIHdpbmRvd3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRBbGxFeHRlcm5hbEFwcGxpY2F0aW9ucygpXG4gICAgICogLnRoZW4oZXh0ZXJuYWxBcHBzID0+IGNvbnNvbGUubG9nKCdUb3RhbCBleHRlcm5hbCBhcHBzOiAnICsgZXh0ZXJuYWxBcHBzLmxlbmd0aCkpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRBbGxFeHRlcm5hbEFwcGxpY2F0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWV4dGVybmFsLWFwcGxpY2F0aW9ucycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYXBwIGFzc2V0IGluZm9ybWF0aW9uLlxuICAgICAqIEBwYXJhbSBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRBcHBBc3NldEluZm8oe2FsaWFzOidwcm9jZXhwJ30pLnRoZW4oYXNzZXRJbmZvID0+IGNvbnNvbGUubG9nKGFzc2V0SW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRBcHBBc3NldEluZm8ob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1hcHAtYXNzZXQtaW5mbycsIG9wdGlvbnMpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWRkaXRpb25hbCBpbmZvIG9mIGNvb2tpZXMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRDb29raWVzKHtuYW1lOiAnbXlDb29raWUnfSkudGhlbihjb29raWVzID0+IGNvbnNvbGUubG9nKGNvb2tpZXMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q29va2llcyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXRVcmwoKTtcbiAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgeyB1cmwgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWNvb2tpZXMnLCBuZXdPcHRpb25zKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBtaW5pbXVtIGxvZyBsZXZlbCBhYm92ZSB3aGljaCBsb2dzIHdpbGwgYmUgd3JpdHRlbiB0byB0aGUgT3BlbkZpbiBsb2dcbiAgICAgKiBAcGFyYW0gVGhlIG1pbmltdW0gbGV2ZWwgKGluY2x1c2l2ZSkgYWJvdmUgd2hpY2ggYWxsIGNhbGxzIHRvIGxvZyB3aWxsIGJlIHdyaXR0ZW5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnNldE1pbkxvZ0xldmVsKFwidmVyYm9zZVwiKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKFwibG9nIGxldmVsIGlzIHNldCB0byB2ZXJib3NlXCIpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgc2V0TWluTG9nTGV2ZWwobGV2ZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtbWluLWxvZy1sZXZlbCcsIHsgbGV2ZWwgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIFVVSUQgb2YgdGhlIGNvbXB1dGVyIG9uIHdoaWNoIHRoZSBydW50aW1lIGlzIGluc3RhbGxlZFxuICAgICAqIEBwYXJhbSB1dWlkIFRoZSB1dWlkIG9mIHRoZSBydW5uaW5nIGFwcGxpY2F0aW9uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5yZXNvbHZlVXVpZCgnT3BlbmZpblBPQycpLnRoZW4oZW50aXR5ID0+IGNvbnNvbGUubG9nKGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICByZXNvbHZlVXVpZCh1dWlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdyZXNvbHZlLXV1aWQnLCB7XG4gICAgICAgICAgICBlbnRpdHlLZXk6IHV1aWRcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGRhdGEgZm9yIGFsbCBleHRlcm5hbCBhcHBsaWNhdGlvbnNcbiAgICAgKiBAcGFyYW0gcmVxdWVzdGluZ0lkZW50aXR5IFRoaXMgb2JqZWN0IGlzIGRlc2NyaWJlZCBpbiB0aGUgSWRlbnRpdHkgdHlwZWRlZlxuICAgICAqIEBwYXJhbSBkYXRhIEFueSBkYXRhIHR5cGUgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICpcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgZXhlY3V0ZU9uUmVtb3RlKHJlcXVlc3RpbmdJZGVudGl0eSwgZGF0YSkge1xuICAgICAgICBkYXRhLnJlcXVlc3RpbmdJZGVudGl0eSA9IHJlcXVlc3RpbmdJZGVudGl0eTtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5mZXJyeUFjdGlvbihkYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZHMgdGhlIHNwZWNpZmVkIHZhbHVlIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIFtBUEkgc2VjdXJpdHkgc2V0dGluZ3NdKGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5KS5cbiAgICAgKiBAcGFyYW0gcm9vdEtleSAtIFRoZSByZWdpc3RyeSByb290IGtleS5cbiAgICAgKiBAcGFyYW0gc3Via2V5IC0gVGhlIHJlZ2lzdHJ5IGtleS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgcmVnaXN0cnkgdmFsdWUgbmFtZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnJlYWRSZWdpc3RyeVZhbHVlKFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsIFwiSEFSRFdBUkVcXFxcREVTQ1JJUFRJT05cXFxcU3lzdGVtXCIsIFwiQm9vdEFyY2hpdGVjdHVyZVwiKS50aGVuKHZhbCA9PiBjb25zb2xlLmxvZyh2YWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvd2luZG93cy9kZXNrdG9wL21zNjgxMzgyKHY9dnMuODUpLmFzcHggaGVyZX0gZm9yIFdpbmRvdydzIGVycm9yIGNvZGUgZGVmaW5pdGlvbnMuXG4gICAgICpcbiAgICAgKiBFeGFtcGxlIHBheWxvYWRzIG9mIGRpZmZlcmVudCByZWdpc3RyeSB0eXBlczpcbiAgICAgKlxuICAgICAqIFNlZSBsaXN0IG9mIHR5cGVzIHtAbGluayBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L3dpbmRvd3MvZGVza3RvcC9tczcyNDg4NCh2PXZzLjg1KS5hc3B4IGhlcmV9LlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvLyBSRUdfRFdPUkRcbiAgICAgKiB7XG4gICAgICogICAgIGRhdGE6IDEsXG4gICAgICogICAgIHJvb3RLZXk6IFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19EV09SRFwiLFxuICAgICAqICAgICB2YWx1ZTogXCJCYXpcIlxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIFJFR19RV09SRFxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogMTMxMDgxNDY2NzEzMzQxMTIsXG4gICAgICogICAgIHJvb3RLZXk6IFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19RV09SRFwiLFxuICAgICAqICAgICB2YWx1ZTogXCJCYXpcIlxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIFJFR19TWlxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogXCJGb29CYXJCYXpcIixcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0xPQ0FMX01BQ0hJTkVcIixcbiAgICAgKiAgICAgc3Via2V5OiBcIkZvb1xcQmFyXCIsXG4gICAgICogICAgIHR5cGU6IFwiUkVHX1NaXCIsXG4gICAgICogICAgIHZhbHVlOiBcIkJhelwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogLy8gUkVHX0VYUEFORF9TWlxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogXCJDOlxcVXNlclxcSm9obkRvZVxcQXBwRGF0YVxcTG9jYWxcIixcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0NVUlJFTlRfVVNFUlwiLFxuICAgICAqICAgICBzdWJrZXk6IFwiRm9vXFxCYXJcIixcbiAgICAgKiAgICAgdHlwZTogXCJSRUdfRVhQQU5EX1NaXCIsXG4gICAgICogICAgIHZhbHVlOiBcIkJhelwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogLy8gUkVHX01VTFRJX1NaXG4gICAgICoge1xuICAgICAqICAgICBkYXRhOiBbXG4gICAgICogICAgICAgICBcIkZvb1wiLFxuICAgICAqICAgICAgICAgXCJCYXJcIixcbiAgICAgKiAgICAgICAgIFwiQmF6XCJcbiAgICAgKiAgICAgXSxcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0NVUlJFTlRfVVNFUlwiLFxuICAgICAqICAgICBzdWJrZXk6IFwiRm9vXFxCYXJcIixcbiAgICAgKiAgICAgdHlwZTogXCJSRUdfTVVMVElfU1pcIixcbiAgICAgKiAgICAgdmFsdWU6IFwiQmF6XCJcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiAvLyBSRUdfQklOQVJZXG4gICAgICoge1xuICAgICAqICAgICBkYXRhOiB7XG4gICAgICogICAgICAgICBkYXRhOiBbXG4gICAgICogICAgICAgICAgICAgMjU1LFxuICAgICAqICAgICAgICAgICAgIDI1NSxcbiAgICAgKiAgICAgICAgICAgICAwLFxuICAgICAqICAgICAgICAgICAgIDQzLFxuICAgICAqICAgICAgICAgICAgIDU1LFxuICAgICAqICAgICAgICAgICAgIDAsXG4gICAgICogICAgICAgICAgICAgMCxcbiAgICAgKiAgICAgICAgICAgICAyNTUsXG4gICAgICogICAgICAgICAgICAgMjU1XG4gICAgICogICAgICAgICBdLFxuICAgICAqICAgICAgICAgdHlwZTogXCJCdWZmZXJcIlxuICAgICAqICAgICB9LFxuICAgICAqICAgICByb290S2V5OiBcIkhLRVlfQ1VSUkVOVF9VU0VSXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19CSU5BUllcIixcbiAgICAgKiAgICAgdmFsdWU6IFwiQmF6XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVhZFJlZ2lzdHJ5VmFsdWUocm9vdEtleSwgc3Via2V5LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlXG4gICAgICAgICAgICAuc2VuZEFjdGlvbigncmVhZC1yZWdpc3RyeS12YWx1ZScsIHtcbiAgICAgICAgICAgIHJvb3RLZXksXG4gICAgICAgICAgICBzdWJrZXksXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNhbGwgd2lsbCByZWdpc3RlciBhIHVuaXF1ZSBpZCBhbmQgcHJvZHVjZSBhIHRva2VuLlxuICAgICAqIFRoZSB0b2tlbiBjYW4gYmUgdXNlZCB0byBicm9rZXIgYW4gZXh0ZXJuYWwgY29ubmVjdGlvbi5cbiAgICAgKiBAcGFyYW0gdXVpZCAtIEEgVVVJRCBmb3IgdGhlIHJlbW90ZSBjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ucmVnaXN0ZXJFeHRlcm5hbENvbm5lY3Rpb24oXCJyZW1vdGUtY29ubmVjdGlvbi11dWlkXCIpLnRoZW4oY29ubiA9PiBjb25zb2xlLmxvZyhjb25uKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICpcbiAgICAgKiAvLyBvYmplY3QgY29tZXMgYmFjayB3aXRoXG4gICAgICogLy8gICAgIHRva2VuOiBcIjA0ODlFQUM1LTY0MDQtNEYwRC05OTNCLTkyQkI4RUFCNDQ1RFwiLCAvLyB0aGlzIHdpbGwgYmUgdW5pcXVlIGVhY2ggdGltZVxuICAgICAqIC8vICAgICB1dWlkOiBcInJlbW90ZS1jb25uZWN0aW9uLXV1aWRcIlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVnaXN0ZXJFeHRlcm5hbENvbm5lY3Rpb24odXVpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlZ2lzdGVyLWV4dGVybmFsLWNvbm5lY3Rpb24nLCB7IHV1aWQgfSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGpzb24gYmxvYiBmb3VuZCBpbiB0aGUgW2Rlc2t0b3Agb3duZXIgc2V0dGluZ3NdKGh0dHBzOi8vb3BlbmZpbi5jby9kb2N1bWVudGF0aW9uL2Rlc2t0b3Atb3duZXItc2V0dGluZ3MvKVxuICAgICAqIGZvciB0aGUgc3BlY2lmaWVkIHNlcnZpY2UuXG4gICAgICogQHBhcmFtIHNlcnZpY2VJZGVudGlmaWVyIEFuIG9iamVjdCBjb250YWluaW5nIGEgbmFtZSBrZXkgdGhhdCBpZGVudGlmaWVzIHRoZSBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgTW9yZSBpbmZvcm1hdGlvbiBhYm91dCBkZXNrdG9wIHNlcnZpY2VzIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9kZXNrdG9wLXNlcnZpY2VzKS5cbiAgICAgKiBUaGlzIGNhbGwgd2lsbCByZWplY3QgaWYgdGhlIGRlc2t0b3Agb3duZXIgc2V0dGluZ3MgZmlsZSBpcyBub3QgcHJlc2VudCwgbm90IGNvcnJlY3RseSBmb3JtYXR0ZWQsIG9yIGlmIHRoZSBzZXJ2aWNlIHJlcXVlc3RlZCBpcyBub3QgY29uZmlndXJlZCBvciBjb25maWd1cmVkIGluY29ycmVjdGx5LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEhlcmUgd2UgYXJlIHVzaW5nIHRoZSBbbGF5b3V0c10oaHR0cHM6Ly9naXRodWIuY29tL0hhZG91a2VuSU8vbGF5b3V0cy1zZXJ2aWNlKSBzZXJ2aWNlLlxuICAgICAqIGZpbi5TeXN0ZW0uZ2V0U2VydmljZUNvbmZpZ3VyYXRpb24oe25hbWU6J2xheW91dHMnfSkudGhlbihjb25zb2xlLmxvZykuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U2VydmljZUNvbmZpZ3VyYXRpb24oc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXJ2aWNlSWRlbnRpZmllci5uYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdXN0IHByb3ZpZGUgYW4gb2JqZWN0IHdpdGggYSBgbmFtZWAgcHJvcGVydHkgaGF2aW5nIGEgc3RyaW5nIHZhbHVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtc2VydmljZS1jb25maWd1cmF0aW9uJywgeyBuYW1lIH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICBhc3luYyBnZXRTeXN0ZW1BcHBDb25maWcobmFtZSkge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ011c3QgcHJvdmlkZSBhIHN0cmluZyB2YWx1ZSBmb3IgbmFtZSBvZiBzeXN0ZW0gYXBwJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtc3lzdGVtLWFwcC1jb25maWd1cmF0aW9uJywgeyBuYW1lIH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSBzeXN0ZW0gc2h1dGRvd24gaGFuZGxlciBzbyB1c2VyIGNhbiBkbyBzb21lIGNsZWFudXAgYmVmb3JlIHN5c3RlbSBpcyBzaHV0dGluZyBkb3duLlxuICAgICAqIEByZW1hcmtzIE9uY2Ugc3lzdGVtIHNodXRkb3duIHN0YXJ0cywgeW91IGFyZSB1bmFibGUgdG8gY2FuY2VsIGl0LlxuICAgICAqIEBwYXJhbSBoYW5kbGVyIHN5c3RlbSBzaHV0ZG93biBoYW5kbGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5yZWdpc3RlclNodXRkb3duSGFuZGxlcigoc2h1dGRvd25FdmVudCkgPT4ge1xuICAgICAqICAgICAgICAgLy8gc2F2ZSBzdGF0ZSBvciBjbGVhbnVwXG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnZG8gc29tZSBjbGVhbnVwIGJlZm9yZSBzaHV0ZG93bicpO1xuICAgICAqICAgICAgICAgLy8gTm90aWZ5IGFwcCBpcyByZWFkeSBmb3IgdGVybWluYXRpb24uXG4gICAgICogICAgICAgICBzaHV0ZG93bkV2ZW50LnByb2NlZWQoKTtcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTaHV0ZG93biBoYW5kbGVyIHJlZ2lzdGVyZWQhJykpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXJTaHV0ZG93bkhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLXJlZ2lzdGVyLXNodXRkb3duLWhhbmRsZXInKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBTeXN0ZW1TaHV0ZG93bkV2ZW50TmFtZSA9ICdzeXN0ZW0tc2h1dGRvd24nO1xuICAgICAgICBjb25zdCBTeXN0ZW1TaHV0ZG93bkhhbmRsZWRFdmVudE5hbWUgPSAnc3lzdGVtLXNodXRkb3duLWhhbmRsZWQnO1xuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcbiAgICAgICAgY29uc3Qgc2h1dGRvd25IYW5kbGVyID0gKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb2NlZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gbm90aWZ5IGNvcmUgdGhhdCB0aGUgYXBwIGlzIHJlYWR5IGZvciBzaHV0ZG93blxuICAgICAgICAgICAgICAgIHRoaXMud2lyZS5lbnZpcm9ubWVudC5yYWlzZUV2ZW50KGBhcHBsaWNhdGlvbi8ke1N5c3RlbVNodXRkb3duSGFuZGxlZEV2ZW50TmFtZX1gLCB7XG4gICAgICAgICAgICAgICAgICAgIHV1aWQsXG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHRvcGljOiAnYXBwbGljYXRpb24nXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaGFuZGxlcih7IHByb2NlZWQgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMub24oU3lzdGVtU2h1dGRvd25FdmVudE5hbWUsIHNodXRkb3duSGFuZGxlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNpZ25hbHMgdGhlIFJWTSB0byBwZXJmb3JtIGEgaGVhbHRoIGNoZWNrIGFuZCByZXR1cm5zIHRoZSByZXN1bHRzIGFzIGpzb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBSZXF1aXJlcyBSVk0gNS41K1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIHRyeSB7XG4gICAgICogICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBmaW4uU3lzdGVtLnJ1blJ2bUhlYWx0aENoZWNrKCk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcnVuUnZtSGVhbHRoQ2hlY2soKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncnVuLXJ2bS1oZWFsdGgtY2hlY2snKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF1bmNoIGFwcGxpY2F0aW9uIHVzaW5nIGEgbWFuaWZlc3QgVVJML3BhdGguIEl0IGRpZmZlcnMgZnJvbSBBcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdCBpbiB0aGF0IHRoaXMgQVBJIGNhbiBhY2NlcHQgYSBtYW5pZmVzdCB1c2luZyB0aGUgZmluIHByb3RvY29sLlxuICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBtYW5pZmVzdCdzIFVSTCBvciBwYXRoLlxuICAgICAqIEBwYXJhbSBvcHRzIC0gUGFyYW1ldGVycyB0aGF0IHRoZSBSVk0gd2lsbCB1c2UuXG4gICAgICpcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHJlbWFya3MgU3VwcG9ydHMgcHJvdG9jb2xzIGh0dHAvcyBhbmQgZmluL3MsIGFuZCBhbHNvIGEgbG9jYWwgcGF0aC5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgQVBJIGlzIFdpbmRvd3Mgb25seS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBUaGlzIEFQSSBjYW4gaGFuZGxlIG1vc3QgbWFuaWZlc3QgdHlwZXMuIFNvbWUgZXhhbXBsZXMgYmVsb3cuXG4gICAgICpcbiAgICAgKiBUcmFkaXRpb25hbDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdChcbiAgICAgKiAgICdodHRwczovL2RlbW9hcHBkaXJlY3Rvcnkub3BlbmYuaW4vZGVza3RvcC9jb25maWcvYXBwcy9PcGVuRmluL0hlbGxvT3BlbkZpbi9hcHAuanNvbicpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFBsYXRmb3JtOlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3QgPSBhd2FpdCBmaW4uU3lzdGVtLmxhdW5jaE1hbmlmZXN0KCdodHRwczovL29wZW5maW4uZ2l0aHViLmlvL3BsYXRmb3JtLWFwaS1wcm9qZWN0LXNlZWQvcHVibGljLmpzb24nKTtcbiAgICAgKiBjb25zb2xlLmxvZyhtYW5pZmVzdCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgdHJhZGl0aW9uYWwgbWFuaWZlc3QgaW50byBhIHBsYXRmb3JtOlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3QgPSBhd2FpdCBmaW4uU3lzdGVtLmxhdW5jaE1hbmlmZXN0KFxuICAgICAqICAgJ2h0dHBzOi8vb3BlbmZpbi5naXRodWIuaW8vcGxhdGZvcm0tYXBpLXByb2plY3Qtc2VlZC9wdWJsaWMuanNvbj9cXFxuICAgICAqICAgJCRhcHBNYW5pZmVzdFVybD1odHRwczovL2RlbW9hcHBkaXJlY3Rvcnkub3BlbmYuaW4vZGVza3RvcC9jb25maWcvXFxcbiAgICAgKiAgIGFwcHMvT3BlbkZpbi9IZWxsb09wZW5GaW4vYXBwLmpzb24nKTtcbiAgICAgKiBjb25zb2xlLmxvZyhtYW5pZmVzdCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgd2l0aCBSVk0gb3B0aW9uczpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdCgnaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9wbGF0Zm9ybS1hcGktcHJvamVjdC1zZWVkL3B1YmxpYy5qc29uJyxcbiAgICAgKiAgICAgeyBub1VpOiB0cnVlLCB1c2VyQXBwQ29uZmlnQXJnczogeyBhYmM6ICcxMjMnLCB4eXo6ICc3ODknIH0gfSk7XG4gICAgICogY29uc29sZS5sb2cobWFuaWZlc3QpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTG9jYWwgUGF0aDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gIGF3YWl0IGZpbi5TeXN0ZW0ubGF1bmNoTWFuaWZlc3QoJ2ZpbGU6Ly9jOlxcXFxwYXRoXFxcXHRvXFxcXG1hbmlmZXN0XFxcXGZpbGUuanNvbicpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIExhdW5jaGluZyB3aXRoIFJWTSAnc3Vic2NyaWJlJyBvcHRpb246XG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiBhbGxvd3MgdXNlcnMgdG8gc3Vic2NyaWJlIHRvIGFwcCB2ZXJzaW9uIHJlc29sdmVyIGV2ZW50cyB3aGVuXG4gICAgICogY2FsbGluZyBsYXVuY2hNYW5pZmVzdCB3aXRoIGZhbGxiYWNrTWFuaWZlc3RzIHNwZWNpZmllZC5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdCgnZmluczovL3N5c3RlbS1hcHBzL25vdGlmaWNhdGlvbnMvYXBwLmpzb24nLCB7IHN1YnNjcmliZTogKGxhdW5jaCkgPT4ge1xuICAgICAqIFx0XHRsYXVuY2gub24oJ2FwcC12ZXJzaW9uLXByb2dyZXNzJywgKHByb2dyZXNzKSA9PiB7XG4gICAgICogXHRcdFx0Y29uc29sZS5sb2coXCJUcnlpbmcgbWFuaWZlc3QgXCIgKyBwcm9ncmVzcy5tYW5pZmVzdClcbiAgICAgKiBcdFx0fSk7XG4gICAgICpcbiAgICAgKiBcdFx0bGF1bmNoLm9uKCdydW50aW1lLXN0YXR1cycsIChzdGF0dXMpID0+IHtcbiAgICAgKiBcdFx0XHRjb25zb2xlLmxvZyhcIlJ1bnRpbWUgc3RhdHVzOiBcIiArIEpTT04uc3RyaW5naWZ5KHN0YXR1cykpO1xuICAgICAqIFx0XHR9KTtcbiAgICAgKlxuICAgICAqIFx0XHQvLyBSVk0gaGFzIHN1Y2Nlc3NmdWxseSBmb3VuZCB0aGUgdGFyZ2V0IHJ1bnRpbWUgdmVyc2lvblxuICAgICAqIFx0XHRsYXVuY2gub24oJ2FwcC12ZXJzaW9uLWNvbXBsZXRlJywgKGNvbXBsZXRlKSA9PiB7XG4gICAgICogXHRcdFx0Y29uc29sZS5sb2coXCJQYXJlbnQgYXBwIFwiICsgY29tcGxldGUuc3JjTWFuaWZlc3QgKyBcIiByZXNvbHZlZCB0byBcIiArIGNvbXBsZXRlLm1hbmlmZXN0KTtcbiAgICAgKiBcdFx0XHRsYXVuY2gucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICogXHRcdH0pO1xuICAgICAqXG4gICAgICogXHRcdC8vIFJWTSBmYWlsZWQgdG8gZmluZCBhbiBhdmFpbGFibGUgcnVudGltZSB2ZXJzaW9uXG4gICAgICogXHRcdGxhdW5jaC5vbignYXBwLXZlcnNpb24tZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgKiBcdFx0XHRjb25zb2xlLmxvZyhcIkZhaWxlZCB0byByZXNvbHZlIFwiICsgZXJyb3Iuc3JjTWFuaWZlc3QgKyBcIiBmcm9tIHRoZSBmYWxsYmFja01hbmlmZXN0c1wiKTtcbiAgICAgKiBcdFx0XHRsYXVuY2gucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICogXHRcdH0pO1xuICAgICAqIFx0fVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGxhdW5jaE1hbmlmZXN0KG1hbmlmZXN0VXJsLCBvcHRzID0ge30pIHtcbiAgICAgICAgY29uc3QgeyBzdWJzY3JpYmUsIC4uLl9zZW5kT3B0cyB9ID0gb3B0cztcbiAgICAgICAgY29uc3Qgc2VuZE9wdHMgPSBfc2VuZE9wdHM7XG4gICAgICAgIGlmIChzdWJzY3JpYmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhdW5jaEVtaXR0ZXIgPSBuZXcgZXZlbnRzXzEkNi5FdmVudEVtaXR0ZXIoKTtcbiAgICAgICAgICAgIHN1YnNjcmliZShsYXVuY2hFbWl0dGVyKTtcbiAgICAgICAgICAgIGNvbnN0IEFwcFZlcnNpb25Qcm9ncmVzc0V2ZW50TmFtZSA9ICdhcHAtdmVyc2lvbi1wcm9ncmVzcyc7XG4gICAgICAgICAgICBjb25zdCBSdW50aW1lU3RhdHVzRXZlbnROYW1lID0gJ3J1bnRpbWUtc3RhdHVzJztcbiAgICAgICAgICAgIGNvbnN0IEFwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZSA9ICdhcHAtdmVyc2lvbi1jb21wbGV0ZSc7XG4gICAgICAgICAgICBjb25zdCBBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWUgPSAnYXBwLXZlcnNpb24tZXJyb3InO1xuICAgICAgICAgICAgLy8gYWRkIGlkIHRvIGF2b2lkIG11bHRpcGxlIGFwaSBjYWxscyBnZXR0aW5nIGR1cGxpY2F0ZWQgZXZlbnRzXG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHNlbmRPcHRzLmFwcFZlcnNpb25JZCA9IGlkO1xuICAgICAgICAgICAgY29uc3Qgc3VwcG9ydGVkRXZlbnRzID0gW1xuICAgICAgICAgICAgICAgIEFwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZSxcbiAgICAgICAgICAgICAgICBBcHBWZXJzaW9uUHJvZ3Jlc3NFdmVudE5hbWUsXG4gICAgICAgICAgICAgICAgUnVudGltZVN0YXR1c0V2ZW50TmFtZSxcbiAgICAgICAgICAgICAgICBBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWVcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBjb25zdCBjbGVhbkV2ZW50UGF5bG9hZCA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBkbyB0eXBlIGNhc3RpbmdzIGJlbG93IHRvIG1ha2Ugc3VyZSB0aGUgcmV0dXJuIHR5cGUgaXMgY29ycmVjdC5cbiAgICAgICAgICAgICAgICBjb25zdCB7IGFwcFZlcnNpb25JZCwgdG9waWMsIHR5cGU6IHR5cGVXaXRoSWQsIC4uLnJlc3QgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IHN1cHBvcnRlZEV2ZW50cy5maW5kKCh4KSA9PiB0eXBlV2l0aElkLmluY2x1ZGVzKHgpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAuLi5yZXN0LFxuICAgICAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBhcHBWZXJzaW9uTGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuUGF5bG9hZCA9IGNsZWFuRXZlbnRQYXlsb2FkKHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGxhdW5jaEVtaXR0ZXIuZW1pdChjbGVhblBheWxvYWQudHlwZSwgY2xlYW5QYXlsb2FkKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCByZW1vdmVBbGxMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihgJHtBcHBWZXJzaW9uUHJvZ3Jlc3NFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke1J1bnRpbWVTdGF0dXNFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke0FwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoYCR7QXBwVmVyc2lvbkVycm9yRXZlbnROYW1lfS4ke2lkfWAsIGFwcFZlcnNpb25MaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihgJHtBcHBWZXJzaW9uQ29tcGxldGVFdmVudE5hbWV9LiR7aWR9YCwgcmVtb3ZlQWxsTGlzdGVuZXJzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke0FwcFZlcnNpb25FcnJvckV2ZW50TmFtZX0uJHtpZH1gLCByZW1vdmVBbGxMaXN0ZW5lcnMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICB0aGlzLm9uKGAke0FwcFZlcnNpb25Qcm9ncmVzc0V2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpLFxuICAgICAgICAgICAgICAgIHRoaXMub24oYCR7UnVudGltZVN0YXR1c0V2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpLFxuICAgICAgICAgICAgICAgIHRoaXMub25jZShgJHtBcHBWZXJzaW9uQ29tcGxldGVFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKSxcbiAgICAgICAgICAgICAgICB0aGlzLm9uY2UoYCR7QXBwVmVyc2lvbkVycm9yRXZlbnROYW1lfS4ke2lkfWAsIGFwcFZlcnNpb25MaXN0ZW5lciksXG4gICAgICAgICAgICAgICAgdGhpcy5vbmNlKGAke0FwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZX0uJHtpZH1gLCByZW1vdmVBbGxMaXN0ZW5lcnMpLFxuICAgICAgICAgICAgICAgIHRoaXMub25jZShgJHtBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWV9LiR7aWR9YCwgcmVtb3ZlQWxsTGlzdGVuZXJzKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF1bmNoLW1hbmlmZXN0Jywge1xuICAgICAgICAgICAgbWFuaWZlc3RVcmwsXG4gICAgICAgICAgICBvcHRzOiBzZW5kT3B0c1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnBheWxvYWQuZGF0YS5tYW5pZmVzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUXVlcnkgcGVybWlzc2lvbiBvZiBhIHNlY3VyZWQgYXBpIGluIGN1cnJlbnQgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhcGlOYW1lIC0gVGhlIGZ1bGwgbmFtZSBvZiBhIHNlY3VyZWQgQVBJLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgYSBmdW5jdGlvbiBoYXMgYSBzdHJ1Y3R1cmVkIHBlcm1pc3Npb24gdmFsdWUsIHRoZSB2YWx1ZSBvZiBgZ3JhbnRlZGAgd2lsbCByZWZsZWN0IHRoZSBgZW5hYmxlZGAga2V5XG4gICAgICogb2YgdGhlIGNhbGwncyBwZXJtaXNzaW9ucyBsaXRlcmFsLiAgSW4gdGhpcyBjYXNlLCAqcGVybWlzc2lvbiBtYXkgc3RpbGwgYmUgZGVuaWVkIHRvIGEgY2FsbCogcGVuZGluZyBhcmd1bWVudHMgb3Igb3RoZXJcbiAgICAgKiBydW50aW1lIHN0YXRlLiAgVGhpcyBpcyBpbmRpY2F0ZWQgd2l0aCBgc3RhdGU6IHVuYXZhaWxhYmxlYC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnF1ZXJ5UGVybWlzc2lvbkZvckN1cnJlbnRDb250ZXh0KCdTeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzJykudGhlbihyZXN1bHQgPT4gY29uc29sZS5sb2cocmVzdWx0KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogLy9UaGlzIHJlc3BvbnNlIGhhcyB0aGUgZm9sbG93aW5nIHNoYXBlOlxuICAgICAqIHtcbiAgICAgKiAgICBwZXJtaXNzaW9uOiAnU3lzdGVtLmxhdW5jaEV4dGVybmFsUHJvY2VzcycsIC8vIGFwaSBmdWxsIG5hbWVcbiAgICAgKiAgICBzdGF0ZTogJ2dyYW50ZWQnLCAvLyBzdGF0ZSBvZiBwZXJtaXNzaW9uXG4gICAgICogICAgZ3JhbnRlZDogdHJ1ZVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBxdWVyeVBlcm1pc3Npb25Gb3JDdXJyZW50Q29udGV4dChhcGlOYW1lKSB7XG4gICAgICAgIGNvbnN0IGlkZW50aXR5ID0geyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCwgbmFtZTogdGhpcy53aXJlLm1lLm5hbWUgfTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncXVlcnktcGVybWlzc2lvbi1mb3ItY3VycmVudC1jb250ZXh0Jywge1xuICAgICAgICAgICAgYXBpTmFtZSxcbiAgICAgICAgICAgIGlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UucGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvLyBOb3QgZG9jdW1lbnRpbmcsIGludGVybmFsIHVzZSBvbmx5LlxuICAgIGFzeW5jIGVuYWJsZU5hdGl2ZVdpbmRvd0ludGVncmF0aW9uUHJvdmlkZXIocGVybWlzc2lvbnMpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZW5hYmxlLW5hdGl2ZS13aW5kb3ctaW50ZWdyYXRpb24tcHJvdmlkZXInLCB7IHBlcm1pc3Npb25zIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAoSW50ZXJuYWwpIFJlZ2lzdGVyIHRoZSB1c2FnZSBvZiBhIGNvbXBvbmVudCB3aXRoIGEgcGxhdGZvcm1cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9iamVjdCB3aXRoIGRhdGEgYW5kIHR5cGVcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWdpc3RlclVzYWdlKCkge1xuICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uU3lzdGVtLmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGZpbi5TeXN0ZW0ucmVnaXN0ZXJVc2FnZSh7XG4gICAgICogICAgICAgICB0eXBlOiAnd29ya3NwYWNlLWxpY2Vuc2luZycsXG4gICAgICogICAgICAgICAvLyBleGFtcGxlIHZhbHVlcyBmb3IgdGhlIGZvbGxvd2luZyBkYXRhIG9iamVjdFxuICAgICAqICAgICAgICAgZGF0YToge1xuICAgICAqICAgICAgICAgICAgIGFwaVZlcnNpb246ICcxLjAnLFxuICAgICAqICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdob21lJyxcbiAgICAgKiAgICAgICAgICAgICBjb21wb25lbnRWZXJzaW9uOiAnMS4wJyxcbiAgICAgKiAgICAgICAgICAgICBhbGxvd2VkOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgIHJlamVjdGlvbkNvZGU6ICcnXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHJlZ2lzdGVyVXNhZ2UoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBjb21wb25lbnQgYXBwbGljYXRpb24nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlZ2lzdGVyVXNhZ2UoeyBkYXRhLCB0eXBlIH0pIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlZ2lzdGVyLXVzYWdlJywgeyBkYXRhLCB0eXBlIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggYWxsIHByaW50ZXJzIG9mIHRoZSBjYWxsZXIgYW5kIG5vdCBhbGwgdGhlIHByaW50ZXJzIG9uIHRoZSBkZXNrdG9wLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0UHJpbnRlcnMoKVxuICAgICAqICAgICAudGhlbigocHJpbnRlcnMpID0+IHtcbiAgICAgKiAgICAgICAgIHByaW50ZXJzLmZvckVhY2goKHByaW50ZXIpID0+IHtcbiAgICAgKiAgICAgICAgICAgICBpZiAocHJpbnRlci5pc0RlZmF1bHQpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocHJpbnRlcik7XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH0pXG4gICAgICogICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRQcmludGVycygpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLWdldC1wcmludGVycycpO1xuICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIFByb2Nlc3MgTG9nZ2luZyB2YWx1ZXM6IHBlcmlvZGljIGludGVydmFsIGFuZCBvdXRsaWVyIGRldGVjdGlvbiBlbnRyaWVzIGFuZCBpbnRlcnZhbC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBQcm9jZXNzIExvZ2dpbmcgdXBkYXRhYmxlIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXaGVuIGVuYWJsaW5nIHZlcmJvc2UgbW9kZSwgYWRkaXRpb25hbCBwcm9jZXNzIGluZm9ybWF0aW9uIGlzIGxvZ2dlZCB0byB0aGUgZGVidWcubG9nOlxuICAgICAqXG4gICAgICogMS4gUGVyaW9kaWNhbGx5IHByb2Nlc3MgdXNhZ2UgKG1lbW9yeSwgY3B1LCBldGMpIHdpbGwgYmUgbG9nZ2VkIGZvciBlYWNoIFBJRCBhbG9uZyB3aXRoIHRoZSB3aW5kb3dzLCB2aWV3cyBhbmRcbiAgICAgKiBpZnJhbWVzIHRoYXQgYmVsb25nIHRvIHRoZW0uIFRoZSBkZWZhdWx0IGlzIGV2ZXJ5IDMwIHNlY29uZHMuIFVwZGF0YWJsZSBieSBwYXNzaW5nIHRoZSBpbnRlcnZhbCBvcHRpb24uXG4gICAgICogMi4gV2hlbiBXaW5kb3dzIGFuZCBWaWV3cyBhcmUgY3JlYXRlZCBvciBuYXZpZ2F0ZWQgdGhlIFBJRCB0aGV5IGJlbG9uZyB0byBhbmQgdGhlaXIgb3B0aW9ucyB3aWxsIGJlIGxvZ2dlZC5cbiAgICAgKiAzLiBXaGVuIFdpbmRvd3MgYW5kIFZpZXdzIGFyZSBkZXN0cm95ZWQgdGhlaXIgbGFzdCBrbm93biBwcm9jZXNzIHVzYWdlIHdpbGwgYmUgbG9nZ2VkLlxuICAgICAqIDQuIFdoZW5ldmVyIGFuIG91dGxpZXIgbWVtb3J5IHVzYWdlIGlzIGRldGVjdGVkIGl0IHdpbGwgYmUgbG9nZ2VkLiBCeSBkZWZhdWx0LCBvbiBhbiBpbnRlcnZhbCBvZiA1IHNlY29uZHMgd2Ugd2lsbFxuICAgICAqIGNvbGxlY3QgcHJvY2VzcyB1c2FnZSBmb3IgYWxsIFBJRHMgYW5kIHdoZW4gMTQ0IHN1Y2ggZW50cmllcyBhcmUgY29sbGVjdGVkLCB3ZSB3aWxsIHN0YXJ0IGFuYWx5emluZyB0aGUgZGF0YSBmb3IgYW55XG4gICAgICogcG9zc2libGUgb3V0bGllcnMgaW4gdGhlIGZvbGxvd2luZyBlbnRyaWVzLiBUaGUgaW50ZXJ2YWwgYW5kIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgc3RvcmVkIGluIHRoZSBydW5uaW5nIGJ1ZmZlclxuICAgICAqIGNhbiBiZSB1cGRhdGFibGUgYnkgcGFzc2luZyB0aGUgb3V0bGllckRldGVjdGlvbi5pbnRlcnZhbCBhbmQgb3V0bGllckRldGVjdGlvbi5lbnRyaWVzIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBhd2FpdCBmaW4uU3lzdGVtLnVwZGF0ZVByb2Nlc3NMb2dnaW5nT3B0aW9ucyh7XG4gICAgICogICAgIGludGVydmFsOiAxMCxcbiAgICAgKiAgICAgb3V0bGllckRldGVjdGlvbjoge1xuICAgICAqICAgICAgICAgaW50ZXJ2YWw6IDE1LFxuICAgICAqICAgICAgICAgZW50cmllczogMjAwXG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVQcm9jZXNzTG9nZ2luZ09wdGlvbnMob3B0aW9ucykge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLXVwZGF0ZS1wcm9jZXNzLWxvZ2dpbmctb3B0aW9ucycsIHsgb3B0aW9ucyB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBkb21haW4gc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLlxuICAgICAqIEluaXRpYWwgc2V0dGluZ3MgYXJlIGNvbmZpZ3VyZWQgd2l0aCB0aGUgZGVmYXVsdERvbWFpblNldHRpbmdzIGFwcGxpY2F0aW9uIG9wdGlvbiB2aWEgbWFuaWZlc3QuXG4gICAgICogRG9tYWluIHNldHRpbmdzIGNhbiBiZSBvdmVyd3JpdHRlbiBkdXJpbmcgcnVudGltZSB3aXRoIFN5c3RlbS5zZXREb21haW5TZXR0aW5ncy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZG9tYWluU2V0dGluZ3MgPSBhd2FpdCBmaW4uU3lzdGVtLmdldERvbWFpblNldHRpbmdzKCk7XG4gICAgICogLy8ge1xuICAgICAqIC8vICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJodHRwczovL29wZW5maW4uY29cIlxuICAgICAqIC8vICAgICAgICAgICAgIF0sXG4gICAgICogLy8gICAgICAgICAgICAgXCJvcHRpb25zXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJkb3dubG9hZFNldHRpbmdzXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgIFwicnVsZXNcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjxhbGxfdXJscz5cIlxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwicHJvbXB0XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgKiAvLyAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICB9XG4gICAgICogLy8gICAgIF1cbiAgICAgKiAvLyB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0RG9tYWluU2V0dGluZ3MoKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZG9tYWluLXNldHRpbmdzJywgdGhpcy5pZGVudGl0eSk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBkb21haW4gc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLlxuICAgICAqIEBwYXJhbSBkb21haW5TZXR0aW5ncyAtIGRvbWFpbiBzZXR0aW5ncyBvYmplY3RcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZG9tYWluU2V0dGluZ3MgPSBhd2FpdCBmaW4uU3lzdGVtLmdldERvbWFpblNldHRpbmdzKCk7XG4gICAgICogLy8ge1xuICAgICAqIC8vICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJodHRwczovL29wZW5maW4uY29cIlxuICAgICAqIC8vICAgICAgICAgICAgIF0sXG4gICAgICogLy8gICAgICAgICAgICAgXCJvcHRpb25zXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJkb3dubG9hZFNldHRpbmdzXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgIFwicnVsZXNcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjxhbGxfdXJscz5cIlxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwicHJvbXB0XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgKiAvLyAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICB9XG4gICAgICogLy8gICAgIF1cbiAgICAgKiAvLyB9XG4gICAgICpcbiAgICAgKiAvLyBWYWxpZCBydWxlIGJlaGF2aW9ycyBhcmUgJ3Byb21wdCcgYW5kICduby1wcm9tcHQnXG4gICAgICogZG9tYWluU2V0dGluZ3MucnVsZXNbMF0ub3B0aW9ucy5kb3dubG9hZFNldHRpbmdzLnJ1bGVzWzBdLmJlaGF2aW9yID0gJ25vLXByb21wdCc7XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4uU3lzdGVtLnNldERvbWFpblNldHRpbmdzKGRvbWFpblNldHRpbmdzKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IG5ld0RvbWFpblNldHRpbmdzID0gYXdhaXQgZmluLlN5c3RlbS5nZXREb21haW5TZXR0aW5ncygpO1xuICAgICAqIC8vIHtcbiAgICAgKiAvLyAgICAgXCJydWxlc1wiOiBbXG4gICAgICogLy8gICAgICAgICB7XG4gICAgICogLy8gICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgIFwiaHR0cHM6Ly9vcGVuZmluLmNvXCJcbiAgICAgKiAvLyAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgIFwib3B0aW9uc1wiOiB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgIFwiZG93bmxvYWRTZXR0aW5nc1wiOiB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibWF0Y2hcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI8YWxsX3VybHM+XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJiZWhhdmlvclwiOiBcIm5vLXByb21wdFwiXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAqIC8vICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgfVxuICAgICAqIC8vICAgICAgICAgfVxuICAgICAqIC8vICAgICBdXG4gICAgICogLy8gfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHNldERvbWFpblNldHRpbmdzKGRvbWFpblNldHRpbmdzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtZG9tYWluLXNldHRpbmdzJywgeyBkb21haW5TZXR0aW5ncywgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIGV4dGVuc2lvbnMgZm9yIHRoZSBzZWN1cml0eSByZWFsbS4gIFVzZXJzIG1heSB3YW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbiBpbiByZXNwb25zZVxuICAgICAqIHRvIGFuIGBleHRlbnNpb25zLWluc3RhbGwtZmFpbGVkYCBldmVudC4gIE9ubHkgZXh0ZW5zaW9ucyBhbGxvd2VkIGJ5IGV2ZXJ5IGFwcGxpY2F0aW9uIG9uIHRoZSBjdXJyZW50IHNlY3VyaXR5IHJlYWxtXG4gICAgICogd2lsbCBiZSBpbnN0YWxsZWQvZW5hYmxlZC5cbiAgICAgKi9cbiAgICBhc3luYyByZWZyZXNoRXh0ZW5zaW9ucygpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVmcmVzaC1leHRlbnNpb25zJyk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGN1cnJlbnRseS1pbnN0YWxsZWRcbiAgICAgKi9cbiAgICBhc3luYyBnZXRJbnN0YWxsZWRFeHRlbnNpb25zKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtaW5zdGFsbGVkLWV4dGVuc2lvbnMnKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG59XG5zeXN0ZW0uU3lzdGVtID0gU3lzdGVtO1xuXG52YXIgaW50ZXJhcHBidXMgPSB7fTtcblxudmFyIHJlZkNvdW50ZXIgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlZkNvdW50ZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xucmVmQ291bnRlci5SZWZDb3VudGVyID0gdm9pZCAwO1xuY2xhc3MgUmVmQ291bnRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudG9waWNSZWZNYXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIC8vIHJldHVybnMgdGhlIHJlZiBjb3VudCBhZnRlciBpbmNyZW1lbnRpbmdcbiAgICBpbmNSZWZDb3VudChrZXkpIHtcbiAgICAgICAgY29uc3QgcmVmQ291bnQgPSB0aGlzLnRvcGljUmVmTWFwLmdldChrZXkpO1xuICAgICAgICBsZXQgcmV0dXJuQ291bnQ7XG4gICAgICAgIGlmICghcmVmQ291bnQpIHtcbiAgICAgICAgICAgIHRoaXMudG9waWNSZWZNYXAuc2V0KGtleSwgMSk7XG4gICAgICAgICAgICByZXR1cm5Db3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWZDb3VudCA9IHJlZkNvdW50ICsgMTtcbiAgICAgICAgICAgIHJldHVybkNvdW50ID0gbmV3UmVmQ291bnQ7XG4gICAgICAgICAgICB0aGlzLnRvcGljUmVmTWFwLnNldChrZXksIG5ld1JlZkNvdW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuQ291bnQ7XG4gICAgfVxuICAgIC8vIHJldHVybnMgdGhlIHJlZiBjb3VudCBhZnRlciBkZWNyZW1lbnRpbmcsIG9yIC0xIGlmIHRoZSBrZXkgYWxyZWFkeSBoYWQgbm8gcmVmZXJlbmNlc1xuICAgIGRlY1JlZkNvdW50KGtleSkge1xuICAgICAgICBjb25zdCByZWZDb3VudCA9IHRoaXMudG9waWNSZWZNYXAuZ2V0KGtleSk7XG4gICAgICAgIGxldCByZXR1cm5Db3VudDtcbiAgICAgICAgaWYgKHJlZkNvdW50KSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWZDb3VudCA9IHJlZkNvdW50IC0gMTtcbiAgICAgICAgICAgIHRoaXMudG9waWNSZWZNYXAuc2V0KGtleSwgbmV3UmVmQ291bnQpO1xuICAgICAgICAgICAgcmV0dXJuQ291bnQgPSBuZXdSZWZDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybkNvdW50ID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldHVybkNvdW50O1xuICAgIH1cbiAgICAvLyBFeGVjdXRlIGZpcnN0QWN0aW9uIGlmIGl0IGlzIHRoZSBmaXJzdCBzdWNoIHJlZiwgZWxzZSBleGVjdXRlIG5vbkZpcnN0QWN0aW9uLlxuICAgIC8vIEluIGVpdGhlciBjYXNlIHRoZSByZXR1cm4gdmFsdWUgaXMgdGhhdCBvZiB0aGUgYWN0aW9uIGV4ZWN1dGVkXG4gICAgYWN0T25GaXJzdChrZXksIGZpcnN0QWN0aW9uLCBub25GaXJzdEFjdGlvbikge1xuICAgICAgICBjb25zdCBudW1SZWZzID0gdGhpcy5pbmNSZWZDb3VudChrZXkpO1xuICAgICAgICBjb25zdCBpc0ZpcnN0UmVmID0gbnVtUmVmcyA9PT0gMTtcbiAgICAgICAgcmV0dXJuIGlzRmlyc3RSZWYgPyBmaXJzdEFjdGlvbigpIDogbm9uRmlyc3RBY3Rpb24oKTtcbiAgICB9XG4gICAgLy8gRXhlY3V0ZSBsYXN0QWN0aW9uIGlmIGl0IGlzIHRoZSBmaXJzdCBzdWNoIHJlZiwgZWxzZSBleGVjdXRlIG5vbkxhc3RBY3Rpb24uXG4gICAgLy8gSW4gZWl0aGVyIGNhc2UgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGF0IG9mIHRoZSBhY3Rpb24gZXhlY3V0ZWRcbiAgICBhY3RPbkxhc3Qoa2V5LCBsYXN0QWN0aW9uLCBub25MYXN0QWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IG51bVJlZnMgPSB0aGlzLmRlY1JlZkNvdW50KGtleSk7XG4gICAgICAgIGNvbnN0IGlzTGFzdFJlZiA9IG51bVJlZnMgPT09IDA7XG4gICAgICAgIHJldHVybiBpc0xhc3RSZWYgPyBsYXN0QWN0aW9uKCkgOiBub25MYXN0QWN0aW9uKCk7XG4gICAgfVxufVxucmVmQ291bnRlci5SZWZDb3VudGVyID0gUmVmQ291bnRlcjtcblxudmFyIGNoYW5uZWwkMSA9IHt9O1xuXG52YXIgY2xpZW50ID0ge307XG5cbnZhciBjaGFubmVsID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWwuQ2hhbm5lbEJhc2UgPSBjaGFubmVsLlByb3RlY3RlZEl0ZW1zID0gdm9pZCAwO1xuY29uc3QgcmVzdWx0T3JQYXlsb2FkID0gKGZ1bmMpID0+IGFzeW5jICh0b3BpYywgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBmdW5jKHRvcGljLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSk7XG4gICAgcmV0dXJuIHJlcyA9PT0gdW5kZWZpbmVkID8gcGF5bG9hZCA6IHJlcztcbn07XG5jbGFzcyBQcm90ZWN0ZWRJdGVtcyB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY29uc3RydWN0b3JcbiAgICBjb25zdHJ1Y3Rvcihwcm92aWRlcklkZW50aXR5LCBjbG9zZSkge1xuICAgICAgICB0aGlzLnByb3ZpZGVySWRlbnRpdHkgPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICB0aGlzLmNsb3NlID0gY2xvc2U7XG4gICAgfVxufVxuY2hhbm5lbC5Qcm90ZWN0ZWRJdGVtcyA9IFByb3RlY3RlZEl0ZW1zO1xuY2xhc3MgQ2hhbm5lbEJhc2Uge1xuICAgIHN0YXRpYyBkZWZhdWx0QWN0aW9uKHRvcGljKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gYWN0aW9uIHJlZ2lzdGVyZWQgYXQgdGFyZ2V0IGZvciAke3RvcGljfWApO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBhc3luYyBwcm9jZXNzQWN0aW9uKHRvcGljLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbWFpbkFjdGlvbiA9IHRoaXMuc3Vic2NyaXB0aW9ucy5oYXModG9waWMpXG4gICAgICAgICAgICAgICAgPyB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KHRvcGljKVxuICAgICAgICAgICAgICAgIDogKGN1cnJlbnRQYXlsb2FkLCBpZCkgPT4gKHRoaXMuZGVmYXVsdEFjdGlvbiA/PyBDaGFubmVsQmFzZS5kZWZhdWx0QWN0aW9uKSh0b3BpYywgY3VycmVudFBheWxvYWQsIGlkKTtcbiAgICAgICAgICAgIGNvbnN0IHByZUFjdGlvblByb2Nlc3NlZCA9IHRoaXMucHJlQWN0aW9uID8gYXdhaXQgdGhpcy5wcmVBY3Rpb24odG9waWMsIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KSA6IHBheWxvYWQ7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25Qcm9jZXNzZWQgPSBhd2FpdCBtYWluQWN0aW9uKHByZUFjdGlvblByb2Nlc3NlZCwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucG9zdEFjdGlvbiA/IGF3YWl0IHRoaXMucG9zdEFjdGlvbih0b3BpYywgYWN0aW9uUHJvY2Vzc2VkLCBzZW5kZXJJZGVudGl0eSkgOiBhY3Rpb25Qcm9jZXNzZWQ7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVycm9yTWlkZGxld2FyZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yTWlkZGxld2FyZSh0b3BpYywgZSwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBtaWRkbGV3YXJlIHRoYXQgZmlyZXMgYmVmb3JlIHRoZSBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZnVuY1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIENoYW5uZWwgUHJvdmlkZXI6XG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBwcm92aWRlci5iZWZvcmVBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vVGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBiZWZvcmUgaGFuZGxpbmcgdGhlIGFjdGlvbi5cbiAgICAgKiAgICAgICAgIHBheWxvYWQucmVjZWl2ZWQgPSBEYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNsaWVudC5iZWZvcmVBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vVGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBiZWZvcmUgaGFuZGxpbmcgdGhlIGFjdGlvbi5cbiAgICAgKiAgICAgICAgIHBheWxvYWQucmVjZWl2ZWQgPSBEYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3Byb3ZpZGVyLWFjdGlvbicsIHsgbWVzc2FnZTogJ0hlbGxvIEZyb20gdGhlIGNsaWVudCcgfSk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHByb3ZpZGVyUmVzcG9uc2UpO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYmVmb3JlQWN0aW9uKGZ1bmMpIHtcbiAgICAgICAgaWYgKHRoaXMucHJlQWN0aW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FscmVhZHkgcmVnaXN0ZXJlZCBiZWZvcmVBY3Rpb24gbWlkZGxld2FyZScpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJlQWN0aW9uID0gcmVzdWx0T3JQYXlsb2FkKGZ1bmMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBlcnJvciBoYW5kbGVyLiBUaGlzIGlzIGNhbGxlZCBiZWZvcmUgcmVzcG9uZGluZyBvbiBhbnkgZXJyb3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZnVuY1xuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAgICAgKiAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGVycm9yJyk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uRXJyb3IoKGFjdGlvbiwgZXJyb3IsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygndW5jYXVnaHQgRXhjZXB0aW9uIGluIGFjdGlvbjonLCBhY3Rpb24pO1xuICAgICAqICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAgICAgKiAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGVycm9yJyk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNsaWVudC5vbkVycm9yKChhY3Rpb24sIGVycm9yLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3VuY2F1Z2h0IEV4Y2VwdGlvbiBpbiBhY3Rpb246JywgYWN0aW9uKTtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIG9uRXJyb3IoZnVuYykge1xuICAgICAgICBpZiAodGhpcy5lcnJvck1pZGRsZXdhcmUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWxyZWFkeSByZWdpc3RlcmVkIGVycm9yIG1pZGRsZXdhcmUnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVycm9yTWlkZGxld2FyZSA9IGZ1bmM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIG1pZGRsZXdhcmUgdGhhdCBmaXJlcyBhZnRlciB0aGUgYWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZ1bmNcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIElmIHRoZSBhY3Rpb24gZG9lcyBub3QgcmV0dXJuIHRoZSBwYXlsb2FkLCB0aGVuIHRoZSBhZnRlckFjdGlvbiB3aWxsIG5vdCBoYXZlIGFjY2VzcyB0byB0aGUgcGF5bG9hZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHByb3ZpZGVyLmFmdGVyQWN0aW9uKChhY3Rpb24sIHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICAvL3RoZSBwYXlsb2FkIGNhbiBiZSBhbHRlcmVkIGhlcmUgYWZ0ZXIgaGFuZGxpbmcgdGhlIGFjdGlvbiBidXQgYmVmb3JlIHNlbmRpbmcgYW4gYWNrbm93bGVkZ2VtZW50LlxuICAgICAqICAgICAgICAgcGF5bG9hZC5zZW50ID0gZGF0ZS5ub3coKTtcbiAgICAgKiAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBDaGFubmVsIENsaWVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IGNsaWVudC5yZWdpc3RlcignY2xpZW50LWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBjbGllbnQuYWZ0ZXJBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vdGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBhZnRlciBoYW5kbGluZyB0aGUgYWN0aW9uIGJ1dCBiZWZvcmUgc2VuZGluZyBhbiBhY2tub3dsZWRnZW1lbnQuXG4gICAgICogICAgICAgICBwYXlsb2FkLnNlbnQgPSBkYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhZnRlckFjdGlvbihmdW5jKSB7XG4gICAgICAgIGlmICh0aGlzLnBvc3RBY3Rpb24pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWxyZWFkeSByZWdpc3RlcmVkIGFmdGVyQWN0aW9uIG1pZGRsZXdhcmUnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBvc3RBY3Rpb24gPSByZXN1bHRPclBheWxvYWQoZnVuYyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBhY3Rpb24gYnkgYWN0aW9uIG5hbWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHByb3ZpZGVyLnJlbW92ZSgncHJvdmlkZXItYWN0aW9uJyk7XG4gICAgICpcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHJlbW92ZShhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShhY3Rpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSBkZWZhdWx0IGFjdGlvbi4gVGhpcyBpcyB1c2VkIGFueSB0aW1lIGFuIGFjdGlvbiB0aGF0IGhhcyBub3QgYmVlbiByZWdpc3RlcmVkIGlzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5zZXREZWZhdWx0QWN0aW9uKChhY3Rpb24sIHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhgQ2xpZW50IHdpdGggaWRlbnRpdHkgJHtKU09OLnN0cmluZ2lmeShpZGVudGl0eSl9IGhhcyBhdHRlbXB0ZWQgdG8gZGlzcGF0Y2ggdW5yZWdpc3RlcmVkIGFjdGlvbjogJHthY3Rpb259LmApO1xuICAgICAqXG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50LnNldERlZmF1bHRBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGBQcm92aWRlciB3aXRoIGlkZW50aXR5ICR7SlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpfSBoYXMgYXR0ZW1wdGVkIHRvIGRpc3BhdGNoIHVucmVnaXN0ZXJlZCBhY3Rpb246ICR7YWN0aW9ufS5gKTtcbiAgICAgKlxuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICogQHBhcmFtIGZ1bmNcbiAgICAgKi9cbiAgICBzZXREZWZhdWx0QWN0aW9uKGZ1bmMpIHtcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdEFjdGlvbikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZWZhdWx0IGFjdGlvbiBjYW4gb25seSBiZSBzZXQgb25jZScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0QWN0aW9uID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBhY3Rpb24gdG8gYmUgY2FsbGVkIGJ5IGRpc3BhdGNoaW5nIGZyb20gYW55IGNoYW5uZWxDbGllbnQgb3IgY2hhbm5lbFByb3ZpZGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRvcGljXG4gICAgICogQHBhcmFtIGxpc3RlbmVyXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgYmUgc2VudCBiYWNrIGFzIGFuIGFja25vd2xlZGdlbWVudCB0byB0aGUgb3JpZ2luYWwgY2FsbGVyLiBZb3UgY2FuIHRocm93IGFuXG4gICAgICogZXJyb3IgdG8gc2VuZCBhIG5lZ2F0aXZlLWFja25vd2xlZGdlbWVudCBhbmQgdGhlIGVycm9yIHdpbGwgcmVqZWN0IHRoZSBwcm9taXNlIHJldHVybmVkIHRvIHRoZSBzZW5kZXIgYnkgdGhlXG4gICAgICogZGlzcGF0Y2ggY2FsbC4gIE9uY2UgYSBsaXN0ZW5lciBpcyByZWdpc3RlcmVkIGZvciBhIHBhcnRpY3VsYXIgYWN0aW9uLCBpdCBzdGF5cyBpbiBwbGFjZSByZWNlaXZpbmcgYW5kIHJlc3BvbmRpbmdcbiAgICAgKiB0byBpbmNvbWluZyBtZXNzYWdlcyB1bnRpbCBpdCBpcyByZW1vdmVkLiAgVGhpcyBtZXNzYWdpbmcgbWVjaGFuaXNtIHdvcmtzIGV4YWN0bHkgdGhlIHNhbWUgd2hlbiBtZXNzYWdlcyBhcmVcbiAgICAgKiBkaXNwYXRjaGVkIGZyb20gdGhlIHByb3ZpZGVyIHRvIGEgY2xpZW50LiAgSG93ZXZlciwgdGhlIHByb3ZpZGVyIGhhcyBhbiBhZGRpdGlvbmFsIHB1Ymxpc2ggbWV0aG9kIHRoYXQgc2VuZHMgbWVzc2FnZXNcbiAgICAgKiB0byBhbGwgY29ubmVjdGVkIGNsaWVudHMuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIG11bHRpcGxlIGNsaWVudHMgY2FuIHNoYXJlIHRoZSBzYW1lIGBuYW1lYCBhbmQgYHV1aWRgLCBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGluZGl2aWR1YWwgY2xpZW50cyxcbiAgICAgKiB0aGUgYGlkZW50aXR5YCBhcmd1bWVudCBpbiBhIHByb3ZpZGVyJ3MgcmVnaXN0ZXJlZCBhY3Rpb24gY2FsbGJhY2sgY29udGFpbnMgYW4gYGVuZHBvaW50SWRgIHByb3BlcnR5LiBXaGVuIGRpc3BhdGNoaW5nXG4gICAgICogZnJvbSBhIHByb3ZpZGVyIHRvIGEgY2xpZW50LCB0aGUgYGVuZHBvaW50SWRgIHByb3BlcnR5IG11c3QgYmUgcHJvdmlkZWQgaW4gb3JkZXIgdG8gc2VuZCBhbiBhY3Rpb24gdG8gYSBzcGVjaWZpYyBjbGllbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdBY3Rpb24gZGlzcGF0Y2hlZCBieSBjbGllbnQ6ICcsIGlkZW50aXR5KTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgcGF5bG9hZCk7XG4gICAgICpcbiAgICAgKiAgICAgICAgcmV0dXJuIHsgZWNobzogcGF5bG9hZCB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBDaGFubmVsIENsaWVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IGNsaWVudC5yZWdpc3RlcignY2xpZW50LWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICBjb25zb2xlLmxvZygnQWN0aW9uIGRpc3BhdGNoZWQgYnkgY2xpZW50OiAnLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdQYXlsb2FkIHNlbnQgaW4gZGlzcGF0Y2g6ICcsIHBheWxvYWQpO1xuICAgICAqXG4gICAgICogICAgICAgIHJldHVybiB7IGVjaG86IHBheWxvYWQgfTtcbiAgICAgKiAgICB9KTtcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHJlZ2lzdGVyKHRvcGljLCBsaXN0ZW5lcikge1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25zLmhhcyh0b3BpYykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3Vic2NyaXB0aW9uIGFscmVhZHkgcmVnaXN0ZXJlZCBmb3IgYWN0aW9uOiAke3RvcGljfS4gVW5zdWJzY3JpYmUgYmVmb3JlIGFkZGluZyBuZXcgc3Vic2NyaXB0aW9uYCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KHRvcGljLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmNoYW5uZWwuQ2hhbm5lbEJhc2UgPSBDaGFubmVsQmFzZTtcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgX0NoYW5uZWxDbGllbnRfY2xvc2U7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY2xpZW50LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNsaWVudC5DaGFubmVsQ2xpZW50ID0gdm9pZCAwO1xuY29uc3QgY2hhbm5lbF8xJDEgPSBjaGFubmVsO1xuY29uc3QgY2hhbm5lbENsaWVudHNCeUVuZHBvaW50SWQgPSBuZXcgTWFwKCk7XG4vKipcbiAqIEluc3RhbmNlIGNyZWF0ZWQgdG8gZW5hYmxlIHVzZSBvZiBhIGNoYW5uZWwgYXMgYSBjbGllbnQuICBBbGxvd3MgZm9yIGNvbW11bmljYXRpb24gd2l0aCB0aGVcbiAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIgQ2hhbm5lbFByb3ZpZGVyfSBieSBpbnZva2luZyBhbiBhY3Rpb24gb24gdGhlXG4gKiBwcm92aWRlciB2aWEge0BsaW5rIENoYW5uZWxDbGllbnQjZGlzcGF0Y2ggZGlzcGF0Y2h9IGFuZCB0byBsaXN0ZW4gZm9yIGNvbW11bmljYXRpb25cbiAqIGZyb20gdGhlIHByb3ZpZGVyIGJ5IHJlZ2lzdGVyaW5nIGFuIGFjdGlvbiB2aWEge0BsaW5rIENoYW5uZWxDbGllbnQjcmVnaXN0ZXIgcmVnaXN0ZXJ9LlxuICpcbiAqICMjIyBTeW5jaHJvbm91cyBNZXRob2RzOlxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjb25EaXNjb25uZWN0aW9uIG9uRGlzY29ubmVjdGlvbihsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbENsaWVudCNyZWdpc3RlciByZWdpc3RlcihhY3Rpb24sIGxpc3RlbmVyKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I3JlbW92ZSByZW1vdmUoYWN0aW9uKX1cbiAqXG4gKiAjIyMgQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbENsaWVudCNkaXNjb25uZWN0IGRpc2Nvbm5lY3QoKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I2Rpc3BhdGNoIGRpc3BhdGNoKGFjdGlvbiwgcGF5bG9hZCl9XG4gKlxuICogIyMjIE1pZGRsZXdhcmU6XG4gKiBNaWRkbGV3YXJlIGZ1bmN0aW9ucyByZWNlaXZlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOiAoYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZCkuXG4gKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIG9uIGFzIHRoZSBwYXlsb2FkIGZyb20gYmVmb3JlQWN0aW9uLCB0byB0aGUgYWN0aW9uIGxpc3RlbmVyLCB0byBhZnRlckFjdGlvblxuICogdW5sZXNzIGl0IGlzIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB0aGUgb3JpZ2luYWwgcGF5bG9hZCBpcyB1c2VkLiAgTWlkZGxld2FyZSBjYW4gYmUgdXNlZCBmb3Igc2lkZSBlZmZlY3RzLlxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjc2V0RGVmYXVsdEFjdGlvbiBzZXREZWZhdWx0QWN0aW9uKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjb25FcnJvciBvbkVycm9yKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjYmVmb3JlQWN0aW9uIGJlZm9yZUFjdGlvbihtaWRkbGV3YXJlKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I2FmdGVyQWN0aW9uIGFmdGVyQWN0aW9uKG1pZGRsZXdhcmUpfVxuICovXG5jbGFzcyBDaGFubmVsQ2xpZW50IGV4dGVuZHMgY2hhbm5lbF8xJDEuQ2hhbm5lbEJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHN0YXRpYyBjbG9zZUNoYW5uZWxCeUVuZHBvaW50SWQoaWQpIHtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IGNoYW5uZWxDbGllbnRzQnlFbmRwb2ludElkLmdldChpZCk7XG4gICAgICAgIGlmIChjaGFubmVsKSB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGMoY2hhbm5lbCwgX0NoYW5uZWxDbGllbnRfY2xvc2UsIFwiZlwiKS5jYWxsKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqIGNsb3NlcyB0aGUgY29ycmVzcG9uZGluZyBjaGFubmVsIGFuZCBpbnZva2VzIHRoZSBkaXNjb25uZWN0IGxpc3RlbmVyIGlmIGFuIGV2ZW50IHBheWxvYWQgaXMgcGFzc2VkLlxuICAgICAqL1xuICAgIHN0YXRpYyBoYW5kbGVQcm92aWRlckRpc2Nvbm5lY3QoZXZlbnRQYXlsb2FkKSB7XG4gICAgICAgIGZvciAoY29uc3QgY2hhbm5lbENsaWVudCBvZiBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxDbGllbnQucHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQgPT09IGV2ZW50UGF5bG9hZC5jaGFubmVsSWQpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ2xpZW50LmRpc2Nvbm5lY3RMaXN0ZW5lcihldmVudFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyhjaGFubmVsQ2xpZW50LCBfQ2hhbm5lbENsaWVudF9jbG9zZSwgXCJmXCIpLmNhbGwoY2hhbm5lbENsaWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iocm91dGluZ0luZm8sIGNsb3NlLCBzdHJhdGVneSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBfQ2hhbm5lbENsaWVudF9wcm90ZWN0ZWRPYmouc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIF9DaGFubmVsQ2xpZW50X3N0cmF0ZWd5LnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICAvLyBuZWVkcyB0byBiZSBib3VuZDtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWN0aW9uID0gKGFjdGlvbiwgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpID0+IHN1cGVyLnByb2Nlc3NBY3Rpb24oYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSk7XG4gICAgICAgIF9DaGFubmVsQ2xpZW50X2Nsb3NlLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC5kZWxldGUodGhpcy5lbmRwb2ludElkKTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyh0aGlzLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgXCJmXCIpLmNsb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JGEodGhpcywgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBuZXcgY2hhbm5lbF8xJDEuUHJvdGVjdGVkSXRlbXMocm91dGluZ0luZm8sIGNsb3NlKSwgXCJmXCIpO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RMaXN0ZW5lciA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5lbmRwb2ludElkID0gcm91dGluZ0luZm8uZW5kcG9pbnRJZDtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCRhKHRoaXMsIF9DaGFubmVsQ2xpZW50X3N0cmF0ZWd5LCBzdHJhdGVneSwgXCJmXCIpO1xuICAgICAgICBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC5zZXQodGhpcy5lbmRwb2ludElkLCB0aGlzKTtcbiAgICAgICAgc3RyYXRlZ3kucmVjZWl2ZSh0aGlzLnByb2Nlc3NBY3Rpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBhIHJlYWQtb25seSBwcm92aWRlciBpZGVudGl0eVxuICAgICAqL1xuICAgIGdldCBwcm92aWRlcklkZW50aXR5KCkge1xuICAgICAgICBjb25zdCBwcm90ZWN0ZWRPYmogPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBcImZcIik7XG4gICAgICAgIHJldHVybiBwcm90ZWN0ZWRPYmoucHJvdmlkZXJJZGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2ggdGhlIGdpdmVuIGFjdGlvbiB0byB0aGUgY2hhbm5lbCBwcm92aWRlci4gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSByZXNwb25zZSBmcm9tXG4gICAgICogdGhlIHByb3ZpZGVyIGZvciB0aGF0IGFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb25cbiAgICAgKiBAcGFyYW0gcGF5bG9hZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3Byb3ZpZGVyLWFjdGlvbicsIHsgbWVzc2FnZTogJ0hlbGxvIEZyb20gdGhlIGNsaWVudCd9KTtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvdmlkZXJSZXNwb25zZSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBkaXNwYXRjaChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyh0aGlzLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgXCJmXCIpLmlzRW5kcG9pbnRDb25uZWN0ZWQodGhpcy5wcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfc3RyYXRlZ3ksIFwiZlwiKS5zZW5kKHRoaXMucHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQsIGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY2xpZW50IHlvdSBhcmUgdHJ5aW5nIHRvIGRpc3BhdGNoIGZyb20gaXMgZGlzY29ubmVjdGVkIGZyb20gdGhlIHRhcmdldCBwcm92aWRlci4nKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCBvbiBwcm92aWRlciBkaXNjb25uZWN0aW9uLiBJdCBpcyBwYXNzZWQgdGhlIGRpc2Nvbm5lY3Rpb24gZXZlbnQgb2YgdGhlXG4gICAgICogZGlzY29ubmVjdGluZyBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsaXN0ZW5lclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50Lm9uRGlzY29ubmVjdGlvbihldnQgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1Byb3ZpZGVyIGRpc2Nvbm5lY3RlZCcsIGB1dWlkOiAke2V2dC51dWlkfSwgbmFtZTogJHtldnQubmFtZX1gKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0TGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcihwYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdoaWxlIGNhbGxpbmcgdGhlIG9uRGlzY29ubmVjdGlvbiBjYWxsYmFjazogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEaXNjb25uZWN0cyB0aGUgY2xpZW50IGZyb20gdGhlIGNoYW5uZWwuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdCgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBjbGllbnQuZGlzY29ubmVjdCgpO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZGlzY29ubmVjdCgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zZW5kRGlzY29ubmVjdEFjdGlvbigpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfY2xvc2UsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGlzY29ubmVjdEFjdGlvbigpIHtcbiAgICAgICAgY29uc3QgcHJvdGVjdGVkT2JqID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRjKHRoaXMsIF9DaGFubmVsQ2xpZW50X3Byb3RlY3RlZE9iaiwgXCJmXCIpO1xuICAgICAgICBhd2FpdCBwcm90ZWN0ZWRPYmouY2xvc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICogV3JpdGluZyB0aGlzIGFzIGEgc3RhdGljIHRvIGtlZXAgY29kZSB0b2dldGhlciwgYnV0IGluIGVudmlyb25tZW50cyB3aXRoIGEgd2lyZSwgdGhpcyB3aWxsIGJlIERJJ2QgaW50byB0aGUgcHJvdGVjdGVkT2JqZWN0IGNsYXNzIGFzIGNsb3NlLlxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyB3aXJlQ2xvc2Uod2lyZSwgcHJvdmlkZXJJZGVudGl0eSwgZW5kcG9pbnRJZCkge1xuICAgICAgICBjb25zdCB7IGNoYW5uZWxOYW1lLCB1dWlkLCBuYW1lIH0gPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICBhd2FpdCB3aXJlLnNlbmRBY3Rpb24oJ2Rpc2Nvbm5lY3QtZnJvbS1jaGFubmVsJywge1xuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgICB1dWlkLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGVuZHBvaW50SWRcbiAgICAgICAgfSk7XG4gICAgfVxufVxuY2xpZW50LkNoYW5uZWxDbGllbnQgPSBDaGFubmVsQ2xpZW50O1xuX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqID0gbmV3IFdlYWtNYXAoKSwgX0NoYW5uZWxDbGllbnRfc3RyYXRlZ3kgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbENsaWVudF9jbG9zZSA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBjb25uZWN0aW9uTWFuYWdlciA9IHt9O1xuXG52YXIgZXhoYXVzdGl2ZSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhoYXVzdGl2ZSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leGhhdXN0aXZlLmV4aGF1c3RpdmVDaGVjayA9IHZvaWQgMDtcbmZ1bmN0aW9uIGV4aGF1c3RpdmVDaGVjayh2YWx1ZSwgYWxsb3dlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdmFsdWU6ICR7dmFsdWV9JHthbGxvd2VkID8gYFxcbiBTdXBwb3J0ZWQgdmFsdWVzIGFyZTogJHthbGxvd2VkLmpvaW4oJycpfWAgOiAnJ31gKTtcbn1cbmV4aGF1c3RpdmUuZXhoYXVzdGl2ZUNoZWNrID0gZXhoYXVzdGl2ZUNoZWNrO1xuXG52YXIgc3RyYXRlZ3kkMyA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ5ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfQ2xhc3NpY1N0cmF0ZWd5X3dpcmUsIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCwgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQ7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RyYXRlZ3kkMywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5zdHJhdGVneSQzLkNsYXNzaWNJbmZvID0gc3RyYXRlZ3kkMy5DbGFzc2ljU3RyYXRlZ3kgPSB2b2lkIDA7XG4vKlxuVGhpcyBpcyB1c2VkIHRvIGFic3RyYWN0IG91dCBpcGMgbWVzc2FnaW5nIGZyb20gdGhlIGNoYW5uZWxzIGltcGxlbWVudGF0aW9uLiBJdCBpcyBvbmx5IGNvbmNlcm5lZCB3aXRoIHNlbmRpbmcgbWVzc2FnZXMgYW5kIHJlZ2lzdHJhdGlvbiB3aXRoIHRoZSBNZXNzYWdlUmVjZWl2ZXJcbiovXG5jbGFzcyBDbGFzc2ljU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIG1lc3NhZ2VSZWNlaXZlciwgZW5kcG9pbnRJZCwgLy8gUHJvdmlkZXIgZW5kcG9pbnRJZCBpcyBjaGFubmVsSWRcbiAgICBwcm92aWRlcklkZW50aXR5KSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVyID0gbWVzc2FnZVJlY2VpdmVyO1xuICAgICAgICB0aGlzLmVuZHBvaW50SWQgPSBlbmRwb2ludElkO1xuICAgICAgICB0aGlzLnByb3ZpZGVySWRlbnRpdHkgPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICBfQ2xhc3NpY1N0cmF0ZWd5X3dpcmUuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8vIFN0b3JlIGZ1bGwgZW5kcG9pbnRJZGVudGl0eSBieSBlbmRwb2ludElkIG9mIGFsbCBrbm93biBlbmRwb2ludHMgZm9yIHRoaXMgc3RyYXRlZ3kgaW5zdGFuY2UuXG4gICAgICAgIC8vIChjbGllbnRzIHdpbGwgb25seSBoYXZlIDE6IHRoZSBwcm92aWRlciwgdGhlIHByb3ZpZGVyIHdpbGwgaGF2ZSBhbGwgY2xpZW50cylcbiAgICAgICAgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLnNldCh0aGlzLCBuZXcgTWFwKCkpO1xuICAgICAgICAvLyBTdG9yZSBhIHNldCBvZiBjYW5jZWxsYWJsZSBwcm9taXNlcyB0byBiZSBhYmxlIHRvIHJlamVjdCB0aGVtIHdoZW4gY2xpZW50XG4gICAgICAgIC8vIGNvbm5lY3Rpb24gcHJvYmxlbXMgb2NjdXJcbiAgICAgICAgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQuc2V0KHRoaXMsIG5ldyBNYXApO1xuICAgICAgICB0aGlzLnNlbmQgPSBhc3luYyAoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0byA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYih0aGlzLCBfQ2xhc3NpY1N0cmF0ZWd5X2VuZHBvaW50SWRlbnRpdHlNYXAsIFwiZlwiKS5nZXQoZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBpZiAoIXRvKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgbG9jYXRlIHJvdXRpbmcgaW5mbyBmb3IgZW5kcG9pbnQgJHtlbmRwb2ludElkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gYXMgY2FzdGluZyB0byBhbnkgYmVjYXVzZSB0eXBlc2NyaXB0IGNvbXBsYWlucy4gVGhlIGZvbGxvd2luZyBpcyBvbmx5IHJlbGV2YW50IGlmIHRoaXMgaXMgYSBsb2NhbGx5IHNldCBlbmRwb2ludElkIG9uIGEgQ2xpZW50SWRlbnRpdHkuXG4gICAgICAgICAgICAvLyBXZSBkZWxldGUgdGhlc2UgcHJvcGVydGllcyB0byBub3QgY2hhbmdlIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuICAgICAgICAgICAgY29uc3QgY2xlYW5JZCA9IHsgLi4udG8gfTtcbiAgICAgICAgICAgIGlmIChjbGVhbklkLmlzTG9jYWxFbmRwb2ludElkKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNsZWFuSWQuZW5kcG9pbnRJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBjbGVhbklkLmlzTG9jYWxFbmRwb2ludElkO1xuICAgICAgICAgICAgLy8gZ3JhYiB0aGUgcHJvbWlzZSBiZWZvcmUgYXdhaXRpbmcgaXQgdG8gc2F2ZSBpbiBvdXIgcGVuZGluZyBtZXNzYWdlcyBtYXBcbiAgICAgICAgICAgIGNvbnN0IHAgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV93aXJlLCBcImZcIilcbiAgICAgICAgICAgICAgICAuc2VuZEFjdGlvbignc2VuZC1jaGFubmVsLW1lc3NhZ2UnLCB7XG4gICAgICAgICAgICAgICAgLi4uY2xlYW5JZCxcbiAgICAgICAgICAgICAgICBwcm92aWRlcklkZW50aXR5OiB0aGlzLnByb3ZpZGVySWRlbnRpdHksXG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpPy5hZGQocCk7XG4gICAgICAgICAgICBjb25zdCByYXcgPSBhd2FpdCBwLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGNsZWFuIHVwIHRoZSBwZW5kaW5nIHByb21pc2VcbiAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQsIFwiZlwiKS5nZXQoZW5kcG9pbnRJZCk/LmRlbGV0ZShwKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJhdy5wYXlsb2FkLmRhdGEucmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNsb3NlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlUmVjZWl2ZXIucmVtb3ZlRW5kcG9pbnQodGhpcy5wcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCwgdGhpcy5lbmRwb2ludElkKTtcbiAgICAgICAgICAgIFsuLi5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikua2V5cygpXS5mb3JFYWNoKChpZCkgPT4gdGhpcy5jbG9zZUVuZHBvaW50KGlkKSk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDkodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBuZXcgTWFwKCksIFwiZlwiKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ5KHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfd2lyZSwgd2lyZSwgXCJmXCIpO1xuICAgIH1cbiAgICBvbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCBsaXN0ZW5lcikge1xuICAgICAgICAvLyBOZXZlciBmaXJlcyBmb3IgJ2NsYXNzaWMnLlxuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVyLmFkZEVuZHBvaW50KGxpc3RlbmVyLCB0aGlzLnByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkLCB0aGlzLmVuZHBvaW50SWQpO1xuICAgIH1cbiAgICBhc3luYyBjbG9zZUVuZHBvaW50KGVuZHBvaW50SWQpIHtcbiAgICAgICAgY29uc3QgaWQgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuZGVsZXRlKGVuZHBvaW50SWQpO1xuICAgICAgICBjb25zdCBwZW5kaW5nU2V0ID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpO1xuICAgICAgICBwZW5kaW5nU2V0Py5mb3JFYWNoKChwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IGBDaGFubmVsIGNvbm5lY3Rpb24gd2l0aCBpZGVudGl0eSB1dWlkOiAke2lkPy51dWlkfSAvIG5hbWU6ICR7aWQ/Lm5hbWV9IC8gZW5kcG9pbnRJZDogJHtlbmRwb2ludElkfSBubyBsb25nZXIgY29ubmVjdGVkLmA7XG4gICAgICAgICAgICBwLmNhbmNlbChuZXcgRXJyb3IoZXJyb3JNc2cpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkge1xuICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCwgXCJmXCIpLmhhcyhlbmRwb2ludElkKTtcbiAgICB9XG4gICAgYWRkRW5kcG9pbnQoZW5kcG9pbnRJZCwgcGF5bG9hZCkge1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuc2V0KGVuZHBvaW50SWQsIHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eSk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYih0aGlzLCBfQ2xhc3NpY1N0cmF0ZWd5X3BlbmRpbmdNZXNzYWdlc0J5RW5kcG9pbnRJZCwgXCJmXCIpLnNldChlbmRwb2ludElkLCBuZXcgU2V0KCkpO1xuICAgIH1cbiAgICBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuICh0eXBlb2YgcGF5bG9hZD8uZW5kcG9pbnRJZGVudGl0eT8uZW5kcG9pbnRJZCA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgICAgIHR5cGVvZiBwYXlsb2FkPy5lbmRwb2ludElkZW50aXR5Py5jaGFubmVsSWQgPT09ICdzdHJpbmcnKTtcbiAgICB9XG59XG5zdHJhdGVneSQzLkNsYXNzaWNTdHJhdGVneSA9IENsYXNzaWNTdHJhdGVneTtcbl9DbGFzc2ljU3RyYXRlZ3lfd2lyZSA9IG5ldyBXZWFrTWFwKCksIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCA9IG5ldyBXZWFrTWFwKCksIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkID0gbmV3IFdlYWtNYXAoKTtcbi8vIEFyYml0cmFyaWx5IHN0YXJ0aW5nIGF0IDUgdG8gbGVhdmUgdGhlIGRvb3Igb3BlbiB0byBiYWNrZmlsbGluZyBwcmUgZW5kcG9pbnRJZCBldGMuXG5zdHJhdGVneSQzLkNsYXNzaWNJbmZvID0geyB2ZXJzaW9uOiA1LCBtaW5pbXVtVmVyc2lvbjogMCwgdHlwZTogJ2NsYXNzaWMnIH07XG5cbnZhciBzdHJhdGVneSQyID0ge307XG5cbnZhciBlbmRwb2ludCA9IHt9O1xuXG52YXIgZXJyb3JzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlcnJvcnMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXJyb3JzLmVycm9yVG9QT0pPID0gdm9pZCAwO1xuZnVuY3Rpb24gZXJyb3JUb1BPSk8oZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFjazogZXJyb3Iuc3RhY2ssXG4gICAgICAgIG5hbWU6IGVycm9yLm5hbWUsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgIC8vIHN1cHBvcnQgdGhlIGNhc2Ugd2hlcmUgc3RhY2sgaXMgZW1wdHkgb3IgbWlzc2luZ1xuICAgICAgICB0b1N0cmluZzogKCkgPT4gZXJyb3Iuc3RhY2sgfHwgZXJyb3IudG9TdHJpbmcoKVxuICAgIH07XG59XG5lcnJvcnMuZXJyb3JUb1BPSk8gPSBlcnJvclRvUE9KTztcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkOCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24sIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZW5kcG9pbnQsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZW5kcG9pbnQuUlRDRW5kcG9pbnQgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IGVycm9yc18xJDEgPSBlcnJvcnM7XG4vKlxuVGhpcyBoYW5kbGVzIHNlbmRpbmcgUlRDIG1lc3NhZ2VzIGJldHdlZW4gUlRDIGNvbm5lY3Rpb25zIG92ZXIgdGhlIHJlcXVlc3QgYW5kIHJlc3BvbnNlIGRhdGEgY2hhbm5lbHMuXG4qL1xuY2xhc3MgUlRDRW5kcG9pbnQge1xuICAgIHN0YXRpYyBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgaXNPYmplY3QgPSAoeCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnb2JqZWN0JyAmJiB4ICE9PSBudWxsO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAvLyBUT0RPIGluIGZhY3RvcnkgUFI6XG4gICAgICAgIC8vIHBheWxvYWQudHlwZSA9PT0gJ3J0YycgJiZcbiAgICAgICAgaXNPYmplY3QocGF5bG9hZCkgJiZcbiAgICAgICAgICAgIGlzT2JqZWN0KHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eSkgJiZcbiAgICAgICAgICAgIGlzT2JqZWN0KHBheWxvYWQucnRjKSAmJlxuICAgICAgICAgICAgdHlwZW9mIHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eS5lbmRwb2ludElkID09PSAnc3RyaW5nJyk7XG4gICAgfVxuICAgIGNvbnN0cnVjdG9yKHsgcnRjLCBlbmRwb2ludElkZW50aXR5IH0pIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZU1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24uc2V0KHRoaXMsIG51bGwpO1xuICAgICAgICBfUlRDRW5kcG9pbnRfZGlzY29ubmVjdExpc3RlbmVyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnJ0Yy5ydGNDbGllbnQuY29ubmVjdGlvblN0YXRlICE9PSAnY29ubmVjdGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCRhKHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIFwiZlwiKSkge1xuICAgICAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X2Rpc2Nvbm5lY3RMaXN0ZW5lciwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNlbmQgPSBhc3luYyAoYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlSWQgPSBgbWVzc2FnZS0ke01hdGgucmFuZG9tKCl9YDtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNwb25zZU1hcC5zZXQobWVzc2FnZUlkLCB7IHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVxdWVzdC5zZW5kKEpTT04uc3RyaW5naWZ5KHsgYWN0aW9uLCBwYXlsb2FkLCBtZXNzYWdlSWQgfSkpO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2xvc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwLmZvckVhY2goKHJlc3BvbnNlKSA9PiByZXNwb25zZS5yZWplY3QoJ0Nvbm5lY3Rpb24gaGFzIGNsb3NlZC4nKSk7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVxdWVzdC5jbG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5jbG9zZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJ0YyA9IHJ0YztcbiAgICAgICAgdGhpcy5lbmRwb2ludElkZW50aXR5ID0gZW5kcG9pbnRJZGVudGl0eTtcbiAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIChlKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkYXRhIH0gPSBlO1xuICAgICAgICAgICAgaWYgKGUuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShlLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBtZXNzYWdlSWQsIHBheWxvYWQsIHN1Y2Nlc3MsIGVycm9yIH0gPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgICAgY29uc3QgeyByZXNvbHZlLCByZWplY3QgfSA9IHRoaXMucmVzcG9uc2VNYXAuZ2V0KG1lc3NhZ2VJZCkgPz8ge307XG4gICAgICAgICAgICBpZiAocmVzb2x2ZSAmJiByZWplY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwLmRlbGV0ZShtZXNzYWdlSWQpO1xuICAgICAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDb3VsZCBub3QgZmluZCBpZCBpbiByZXNwb25zZU1hcC4nKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucnRjLmNoYW5uZWxzLnJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkYXRhIH0gPSBlO1xuICAgICAgICAgICAgaWYgKGUuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShlLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBtZXNzYWdlSWQsIGFjdGlvbiwgcGF5bG9hZCB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpLmNhbGwodGhpcywgYWN0aW9uLCBwYXlsb2FkLCBlbmRwb2ludElkZW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2Uuc2VuZChKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiByZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFJUQ0RhdGFDaGFubmVsIGlzIG9wZW4gYmVmb3JlIHNlbmRpbmcsIGVycm9yIGdldHMgc3dhbGxvd2VkIGhlcmUgaW4gdGhlIGNhc2Ugd2hlcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xpZW50IGRpc3BhdGNoZWQgdGhlbiBjbG9zZWQgb3IgZGlzY29ubmVjdGVkIGJlZm9yZSB0aGUgZGlzcGF0Y2ggcmVzb2x2ZXMuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJ0Yy5jaGFubmVscy5yZXNwb25zZS5yZWFkeVN0YXRlID09PSAnb3BlbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucnRjLmNoYW5uZWxzLnJlc3BvbnNlLnNlbmQoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKDAsIGVycm9yc18xJDEuZXJyb3JUb1BPSk8pKGVycm9yKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFJUQ0RhdGFDaGFubmVsIGlzIG9wZW4gZm9yIHNhbWUgcmVhc29uIGFzIGNhdGNoIGJsb2NrIGFib3ZlLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2Uuc2VuZChKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiAnQ29ubmVjdGlvbiBub3QgcmVhZHkuJ1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5hZGRFdmVudExpc3RlbmVyKCdjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIpO1xuICAgICAgICAvLyBEaXNjb25uZWN0IGlmIGRhdGEgY2hhbm5lbHMgY2xvc2UgdW5leHBlY3RlZGx5LCBlLmcuIGNhbiBoYXBwZW4gZHVlIHRvIG1lc3NhZ2Ugc2l6ZSA+IH4yNTVrQiAoUlRDUGVlckNvbm5lY3Rpb24uc2N0cC5tYXhNZXNzYWdlU2l6ZUxpbWl0OiAyNjIxNDQpXG4gICAgICAgIE9iamVjdC52YWx1ZXModGhpcy5ydGMuY2hhbm5lbHMpLmZvckVhY2goKGRhdGFjaGFubmVsKSA9PiB7XG4gICAgICAgICAgICBkYXRhY2hhbm5lbC5vbmNsb3NlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICBbLi4udGhpcy5yZXNwb25zZU1hcC52YWx1ZXMoKV0uZm9yRWFjaCgocHJvbWlzZSkgPT4gcHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdSVENEYXRhQ2hhbm5lbCBjbG9zZWQgdW5leHBlY3RlZGx5LCB0aGlzIGlzIG1vc3QgY29tbW9ubHkgY2F1c2VkIGJ5IG1lc3NhZ2Ugc2l6ZS4gTm90ZTogUlRDIENoYW5uZWxzIGhhdmUgYSBtZXNzYWdlIHNpemUgbGltaXQgb2YgfjI1NWtCLicpKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X2Rpc2Nvbm5lY3RMaXN0ZW5lciwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfZGlzY29ubmVjdExpc3RlbmVyLCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgb25EaXNjb25uZWN0KGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCRhKHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIFwiZlwiKSkge1xuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ4KHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIGxpc3RlbmVyLCBcImZcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JUQ0VuZHBvaW50IGRpc2Nvbm5lY3RMaXN0ZW5lciBjYW5ub3QgYmUgc2V0IHR3aWNlLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlY2VpdmUobGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBoYXZlIGFscmVhZHkgc2V0IGEgbGlzdGVuZXIgZm9yIHRoaXMgUlRDIEVuZHBvaW50LicpO1xuICAgICAgICB9XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkOCh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgbGlzdGVuZXIsIFwiZlwiKTtcbiAgICB9XG4gICAgZ2V0IGNvbm5lY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucnRjLnJ0Y0NsaWVudC5jb25uZWN0aW9uU3RhdGUgPT09ICdjb25uZWN0ZWQnO1xuICAgIH1cbn1cbmVuZHBvaW50LlJUQ0VuZHBvaW50ID0gUlRDRW5kcG9pbnQ7XG5fUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgc3RyYXRlZ3kkMSA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ3ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0cmF0ZWd5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3RyYXRlZ3kkMS5FbmRwb2ludFN0cmF0ZWd5ID0gdm9pZCAwO1xuY2xhc3MgRW5kcG9pbnRTdHJhdGVneSB7XG4gICAgLy8gTmVlZCB0byBwYXNzIGluIHZhbGlkYXRlIGVuZHBvaW50IHNlcGFyYXRlbHkgZnJvbSBjb25zdHJ1Y3RvciBiZWNhdXNlIHRzIGludGVyZmFjZXMgZG9uJ3QgZG8gd2VsbCB3aXRoIHN0YXRpYyBtZXRob2RzXG4gICAgY29uc3RydWN0b3IoRW5kcG9pbnRUeXBlLCB2YWxpZGF0ZUVuZHBvaW50LCBTdHJhdGVneU5hbWUpIHtcbiAgICAgICAgdGhpcy5FbmRwb2ludFR5cGUgPSBFbmRwb2ludFR5cGU7XG4gICAgICAgIHRoaXMuU3RyYXRlZ3lOYW1lID0gU3RyYXRlZ3lOYW1lO1xuICAgICAgICBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLnNldCh0aGlzLCBudWxsKTtcbiAgICAgICAgX0VuZHBvaW50U3RyYXRlZ3lfZW5kcG9pbnRNYXAuc2V0KHRoaXMsIG5ldyBNYXAoKSk7XG4gICAgICAgIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZC5zZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2VuZCA9IGFzeW5jIChlbmRwb2ludElkLCBhY3Rpb24sIHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVuZHBvaW50QnlJZChlbmRwb2ludElkKS5zZW5kKGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2xvc2UgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuZm9yRWFjaCgoZW5kcG9pbnQpID0+IGVuZHBvaW50LmNsb3NlKCkpO1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNyh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgbmV3IE1hcCgpLCBcImZcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDcodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkLCBmYWxzZSwgXCJmXCIpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmlzVmFsaWRFbmRwb2ludFBheWxvYWQgPSB2YWxpZGF0ZUVuZHBvaW50O1xuICAgIH1cbiAgICBvbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmdldEVuZHBvaW50QnlJZChlbmRwb2ludElkKS5vbkRpc2Nvbm5lY3QobGlzdGVuZXIpO1xuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDkodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdSBoYXZlIGFscmVhZHkgc2V0IGEgbGlzdGVuZXIgZm9yIHRoaXMgJHt0aGlzLlN0cmF0ZWd5TmFtZX0gU3RyYXRlZ3lgKTtcbiAgICAgICAgfVxuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDcodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiwgbGlzdGVuZXIsIFwiZlwiKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuZm9yRWFjaCgoZW5kcG9pbnQpID0+IGVuZHBvaW50LnJlY2VpdmUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSkpO1xuICAgIH1cbiAgICBnZXRFbmRwb2ludEJ5SWQoZW5kcG9pbnRJZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgXCJmXCIpLmdldChlbmRwb2ludElkKTtcbiAgICAgICAgaWYgKCFlbmRwb2ludCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBlbmRwb2ludCBpZCAke2VuZHBvaW50SWR9IGlzIG5vdCBjb25uZWN0ZWRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW5kcG9pbnQ7XG4gICAgfVxuICAgIGdldCBjb25uZWN0ZWQoKSB7XG4gICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDkodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkLCBcImZcIik7XG4gICAgfVxuICAgIGlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkge1xuICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuaGFzKGVuZHBvaW50SWQpO1xuICAgIH1cbiAgICBhZGRFbmRwb2ludChlbmRwb2ludElkLCBwYXlsb2FkKSB7XG4gICAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEFkZGluZyBlbmRwb2ludCB0byBkaXNjb25uZWN0ZWQgJHt0aGlzLlN0cmF0ZWd5TmFtZX0gU3RyYXRlZ3lgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGllbnRTdHJhdCA9IG5ldyB0aGlzLkVuZHBvaW50VHlwZShwYXlsb2FkKTtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLCBcImZcIikpIHtcbiAgICAgICAgICAgIGNsaWVudFN0cmF0LnJlY2VpdmUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuc2V0KGVuZHBvaW50SWQsIGNsaWVudFN0cmF0KTtcbiAgICB9XG4gICAgYXN5bmMgY2xvc2VFbmRwb2ludChlbmRwb2ludElkKSB7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgXCJmXCIpLmRlbGV0ZShlbmRwb2ludElkKTtcbiAgICB9XG59XG5zdHJhdGVneSQxLkVuZHBvaW50U3RyYXRlZ3kgPSBFbmRwb2ludFN0cmF0ZWd5O1xuX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwID0gbmV3IFdlYWtNYXAoKSwgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkID0gbmV3IFdlYWtNYXAoKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0cmF0ZWd5JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3RyYXRlZ3kkMi5SVENJbmZvID0gc3RyYXRlZ3kkMi5SVENTdHJhdGVneSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuLyogZXNsaW50LWRpc2FibGUgY2xhc3MtbWV0aG9kcy11c2UtdGhpcyAqL1xuY29uc3QgZW5kcG9pbnRfMSA9IGVuZHBvaW50O1xuY29uc3Qgc3RyYXRlZ3lfMSQxID0gc3RyYXRlZ3kkMTtcbi8qXG5UaGlzIGlzIHVzZWQgdG8gYWJzdHJhY3Qgb3V0IHJ0YyBtZXNzYWdpbmcgZnJvbSB0aGUgY2hhbm5lbHMgaW1wbGVtZW50YXRpb24gdXNpbmcgUlRDRW5kcG9pbnRzLlxuKi9cbmNsYXNzIFJUQ1N0cmF0ZWd5IGV4dGVuZHMgc3RyYXRlZ3lfMSQxLkVuZHBvaW50U3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihlbmRwb2ludF8xLlJUQ0VuZHBvaW50LCBlbmRwb2ludF8xLlJUQ0VuZHBvaW50LmlzVmFsaWRFbmRwb2ludFBheWxvYWQsICdSVEMnKTtcbiAgICB9XG59XG5zdHJhdGVneSQyLlJUQ1N0cmF0ZWd5ID0gUlRDU3RyYXRlZ3k7XG5zdHJhdGVneSQyLlJUQ0luZm8gPSB7IHZlcnNpb246IDIsIG1pbmltdW1WZXJzaW9uOiAwLCB0eXBlOiAncnRjJyB9O1xuXG52YXIgaWNlTWFuYWdlciA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoaWNlTWFuYWdlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5pY2VNYW5hZ2VyLlJUQ0lDRU1hbmFnZXIgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEkaCA9IGJhc2U7XG4vKlxuU2luZ2xldG9uIHRoYXQgZmFjaWxpdGF0ZXMgT2ZmZXIgYW5kIEFuc3dlciBleGNoYW5nZSByZXF1aXJlZCBmb3IgZXN0YWJsaXNoaW5nIFJUQyBjb25uZWN0aW9ucy5cbiovXG5jbGFzcyBSVENJQ0VNYW5hZ2VyIGV4dGVuZHMgYmFzZV8xJGguRW1pdHRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgJ2NoYW5uZWwnKTtcbiAgICAgICAgdGhpcy5lbnN1cmVDaGFubmVsT3BlbmVkID0gKGNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNoYW5uZWwucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hhbm5lbC5yZWFkeVN0YXRlID09PSAnY29ubmVjdGluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29wZW4nLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWwuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1RoaXMgQ2hhbm5lbCBoYXMgYWxyZWFkeSBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UobGFiZWwsIHJ0Y0NsaWVudCkge1xuICAgICAgICBsZXQgcmVzb2x2ZXI7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZXIgPSByZXNvbHZlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3Blbkxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGUuY2hhbm5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdvcGVuJywgb3Blbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlcihlLmNoYW5uZWwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChlLmNoYW5uZWwubGFiZWwgPT09IGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgZS5jaGFubmVsLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBvcGVuTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHJ0Y0NsaWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdkYXRhY2hhbm5lbCcsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcnRjQ2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RhdGFjaGFubmVsJywgbGlzdGVuZXIpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgYXN5bmMgbGlzdGVuRm9yUHJvdmlkZXJJY2UocnRjQ29ubmVjdGlvbklkLCBsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKHRoaXMuY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSwgbGlzdGVuZXIsIHsgdGltZXN0YW1wOiBEYXRlLm5vdygpIH0pO1xuICAgIH1cbiAgICBhc3luYyByYWlzZVByb3ZpZGVySWNlKHJ0Y0Nvbm5lY3Rpb25JZCwgcGF5bG9hZCkge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuZW52aXJvbm1lbnQucmFpc2VFdmVudCh0aGlzLmNyZWF0ZVJvdXRlU3RyaW5nKHRoaXMuY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSksIHBheWxvYWQpO1xuICAgIH1cbiAgICBhc3luYyBsaXN0ZW5Gb3JDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKHRoaXMuY3JlYXRlQ2xpZW50RXZlbnROYW1lKHJ0Y0Nvbm5lY3Rpb25JZCksIGxpc3RlbmVyLCB7IHRpbWVzdGFtcDogRGF0ZS5ub3coKSB9KTtcbiAgICB9XG4gICAgYXN5bmMgcmFpc2VDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBwYXlsb2FkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5yYWlzZUV2ZW50KHRoaXMuY3JlYXRlUm91dGVTdHJpbmcodGhpcy5jcmVhdGVDbGllbnRFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSksIHBheWxvYWQpO1xuICAgIH1cbiAgICBjbGVhbnVwSWNlTGlzdGVuZXJzKHJ0Y0Nvbm5lY3Rpb25JZCkge1xuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyh0aGlzLmNyZWF0ZUNsaWVudEV2ZW50TmFtZShydGNDb25uZWN0aW9uSWQpKTtcbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnModGhpcy5jcmVhdGVQcm92aWRlckV2ZW50TmFtZShydGNDb25uZWN0aW9uSWQpKTtcbiAgICB9XG4gICAgY3JlYXRlQ2xpZW50RXZlbnROYW1lKHJ0Y0Nvbm5lY3Rpb25JZCkge1xuICAgICAgICByZXR1cm4gYGljZS1jbGllbnQtJHtydGNDb25uZWN0aW9uSWR9YDtcbiAgICB9XG4gICAgY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSB7XG4gICAgICAgIHJldHVybiBgaWNlLXByb3ZpZGVyLSR7cnRjQ29ubmVjdGlvbklkfWA7XG4gICAgfVxuICAgIGNyZWF0ZVJvdXRlU3RyaW5nKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGBjaGFubmVsLyR7bmFtZX1gO1xuICAgIH1cbiAgICBjcmVhdGVSdGNQZWVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LmdldFJ0Y1BlZXIoKTtcbiAgICB9XG4gICAgYXN5bmMgc3RhcnRDbGllbnRPZmZlcigpIHtcbiAgICAgICAgLy8gVE9ETyByZXBsYWNlIHdpdGggcmVhbCBndWlkLlxuICAgICAgICBjb25zdCBydGNDb25uZWN0aW9uSWQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IHJ0Y0NsaWVudCA9IHRoaXMuY3JlYXRlUnRjUGVlcigpO1xuICAgICAgICBydGNDbGllbnQuYWRkRXZlbnRMaXN0ZW5lcignaWNlY2FuZGlkYXRlJywgYXN5bmMgKGUpID0+IHtcbiAgICAgICAgICAgIGlmIChlLmNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmFpc2VDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCB7IGNhbmRpZGF0ZTogZS5jYW5kaWRhdGU/LnRvSlNPTigpIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5saXN0ZW5Gb3JQcm92aWRlckljZShydGNDb25uZWN0aW9uSWQsIGFzeW5jIChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBydGNDbGllbnQuYWRkSWNlQ2FuZGlkYXRlKHBheWxvYWQuY2FuZGlkYXRlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0ge1xuICAgICAgICAgICAgcmVxdWVzdDogcnRjQ2xpZW50LmNyZWF0ZURhdGFDaGFubmVsKCdyZXF1ZXN0JyksXG4gICAgICAgICAgICByZXNwb25zZTogcnRjQ2xpZW50LmNyZWF0ZURhdGFDaGFubmVsKCdyZXNwb25zZScpXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG9mZmVyID0gYXdhaXQgcnRjQ2xpZW50LmNyZWF0ZU9mZmVyKCk7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgY29uc3QgY2hhbm5lbHNPcGVuZWQgPSBQcm9taXNlLmFsbChbY2hhbm5lbHMucmVxdWVzdCwgY2hhbm5lbHMucmVzcG9uc2VdLm1hcCh0aGlzLmVuc3VyZUNoYW5uZWxPcGVuZWQpKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiB7IHJ0Y0NsaWVudCwgY2hhbm5lbHMsIG9mZmVyLCBydGNDb25uZWN0aW9uSWQsIGNoYW5uZWxzT3BlbmVkIH07XG4gICAgfVxuICAgIGFzeW5jIGZpbmlzaENsaWVudE9mZmVyKHJ0Y0NsaWVudCwgYW5zd2VyLCBwcm92aWRlclJlYWR5KSB7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpO1xuICAgICAgICBhd2FpdCBwcm92aWRlclJlYWR5O1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlUHJvdmlkZXJBbnN3ZXIocnRjQ29ubmVjdGlvbklkLCBvZmZlcikge1xuICAgICAgICBjb25zdCBydGNDbGllbnQgPSB0aGlzLmNyZWF0ZVJ0Y1BlZXIoKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdENoYW5uZWxQcm9taXNlID0gUlRDSUNFTWFuYWdlci5jcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UoJ3JlcXVlc3QnLCBydGNDbGllbnQpO1xuICAgICAgICBjb25zdCByZXNwb25zZUNoYW5uZWxQcm9taXNlID0gUlRDSUNFTWFuYWdlci5jcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UoJ3Jlc3BvbnNlJywgcnRjQ2xpZW50KTtcbiAgICAgICAgcnRjQ2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2ljZWNhbmRpZGF0ZScsIGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBpZiAoZS5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJhaXNlUHJvdmlkZXJJY2UocnRjQ29ubmVjdGlvbklkLCB7IGNhbmRpZGF0ZTogZS5jYW5kaWRhdGU/LnRvSlNPTigpIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5saXN0ZW5Gb3JDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBhc3luYyAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgcnRjQ2xpZW50LmFkZEljZUNhbmRpZGF0ZShwYXlsb2FkLmNhbmRpZGF0ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBydGNDbGllbnQuc2V0UmVtb3RlRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICBjb25zdCBhbnN3ZXIgPSBhd2FpdCBydGNDbGllbnQuY3JlYXRlQW5zd2VyKCk7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcik7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gUHJvbWlzZS5hbGwoW3JlcXVlc3RDaGFubmVsUHJvbWlzZSwgcmVzcG9uc2VDaGFubmVsUHJvbWlzZV0pLnRoZW4oKFtyZXF1ZXN0LCByZXNwb25zZV0pID0+IHtcbiAgICAgICAgICAgIC8vIENsZWFuIHVwIGljZSBldmVudHMuXG4gICAgICAgICAgICB0aGlzLmNsZWFudXBJY2VMaXN0ZW5lcnMocnRjQ29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHJldHVybiB7IHJlcXVlc3QsIHJlc3BvbnNlIH07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcnRjQ2xpZW50LFxuICAgICAgICAgICAgYW5zd2VyLFxuICAgICAgICAgICAgY2hhbm5lbHNcbiAgICAgICAgfTtcbiAgICB9XG59XG5pY2VNYW5hZ2VyLlJUQ0lDRU1hbmFnZXIgPSBSVENJQ0VNYW5hZ2VyO1xuXG52YXIgcHJvdmlkZXIgPSB7fTtcblxudmFyIHJ1bnRpbWVWZXJzaW9uaW5nID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShydW50aW1lVmVyc2lvbmluZywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5ydW50aW1lVmVyc2lvbmluZy5ydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uID0gcnVudGltZVZlcnNpb25pbmcucGFyc2VSdW50aW1lVXVpZCA9IHJ1bnRpbWVWZXJzaW9uaW5nLm1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uID0gdm9pZCAwO1xuZnVuY3Rpb24gdk51bSh4KSB7XG4gICAgcmV0dXJuIFsuLi54LnNwbGl0KCcuJykucmV2ZXJzZSgpLmVudHJpZXMoKV0ucmVkdWNlKChwLCBbaSwgdl0pID0+IHAgKyArdiAqIDEwMDAwICoqIGksIDApO1xufVxuLypcbiAgQ29tcGFyZXMgcnVudGltZSB2ZXJzaW9ucyB0byBzZWUgaWYgdGhlIGN1cnJlbnQgcnVudGltZSBtZWV0cyB5b3VyIGRlc2lyZWQgbWluaW11bS5cbiovXG5mdW5jdGlvbiBtZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbihjdXJyZW50VmVyc2lvbiwgbWluVmVyc2lvbikge1xuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uUGFyc2VkID0gdk51bShjdXJyZW50VmVyc2lvbik7XG4gICAgY29uc3QgbWluVmVyc2lvblBhcnNlZCA9IHZOdW0obWluVmVyc2lvbik7XG4gICAgcmV0dXJuIGN1cnJlbnRWZXJzaW9uUGFyc2VkID49IG1pblZlcnNpb25QYXJzZWQ7XG59XG5ydW50aW1lVmVyc2lvbmluZy5tZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbiA9IG1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uO1xuLy8gU3RyaXBzIHRoZSBwb3J0IGluZm8gZnJvbSB0aGUgcnVudGltZVV1aWQsIGxlYXZpbmcganVzdCB0aGUgcnVudGltZSB2ZXJzaW9uLlxuZnVuY3Rpb24gcGFyc2VSdW50aW1lVXVpZChydW50aW1lVXVpZCkge1xuICAgIHJldHVybiBydW50aW1lVXVpZC5zcGxpdCgnLycpWzBdO1xufVxucnVudGltZVZlcnNpb25pbmcucGFyc2VSdW50aW1lVXVpZCA9IHBhcnNlUnVudGltZVV1aWQ7XG5mdW5jdGlvbiBydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uKHJ1bnRpbWVVdWlkLCBtaW5WZXJzaW9uKSB7XG4gICAgY29uc3QgcnVudGltZVZlcnNpb24gPSBwYXJzZVJ1bnRpbWVVdWlkKHJ1bnRpbWVVdWlkKTtcbiAgICByZXR1cm4gbWVldHNNaW5pbXVtUnVudGltZVZlcnNpb24ocnVudGltZVZlcnNpb24sIG1pblZlcnNpb24pO1xufVxucnVudGltZVZlcnNpb25pbmcucnVudGltZVV1aWRNZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbiA9IHJ1bnRpbWVVdWlkTWVldHNNaW5pbXVtUnVudGltZVZlcnNpb247XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDggPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIF9DaGFubmVsUHJvdmlkZXJfcHJvdGVjdGVkT2JqLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBfQ2hhbm5lbFByb3ZpZGVyX3JlbW92ZUVuZHBvaW50LCBfQ2hhbm5lbFByb3ZpZGVyX2Nsb3NlO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3ZpZGVyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnByb3ZpZGVyLkNoYW5uZWxQcm92aWRlciA9IHZvaWQgMDtcbmNvbnN0IGNoYW5uZWxfMSA9IGNoYW5uZWw7XG5jb25zdCBydW50aW1lVmVyc2lvbmluZ18xID0gcnVudGltZVZlcnNpb25pbmc7XG4vKipcbiAqIEluc3RhbmNlIGNyZWF0ZWQgdG8gZW5hYmxlIHVzZSBvZiBhIGNoYW5uZWwgYXMgYSBwcm92aWRlci4gQWxsb3dzIGZvciBjb21tdW5pY2F0aW9uIHdpdGggdGhlIHtAbGluayBDaGFubmVsQ2xpZW50IENoYW5uZWxDbGllbnRzfSBieSBpbnZva2luZyBhbiBhY3Rpb24gb25cbiAqIGEgc2luZ2xlIGNsaWVudCB2aWEge0BsaW5rIENoYW5uZWxQcm92aWRlciNkaXNwYXRjaCBkaXNwYXRjaH0gb3IgYWxsIGNsaWVudHMgdmlhIHtAbGluayBDaGFubmVsUHJvdmlkZXIjcHVibGlzaCBwdWJsaXNofVxuICogYW5kIHRvIGxpc3RlbiBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIGNsaWVudHMgYnkgcmVnaXN0ZXJpbmcgYW4gYWN0aW9uIHZpYSB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI3JlZ2lzdGVyIHJlZ2lzdGVyfS5cbiAqXG4gKiAjIyMgU3luY2hyb25vdXMgTWV0aG9kczpcbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjb25Db25uZWN0aW9uIG9uQ29ubmVjdGlvbihsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI29uRGlzY29ubmVjdGlvbiBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNwdWJsaXNoIHB1Ymxpc2goYWN0aW9uLCBwYXlsb2FkKX1cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjcmVnaXN0ZXIgcmVnaXN0ZXIoYWN0aW9uLCBsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI3JlbW92ZSByZW1vdmUoYWN0aW9uKX1cbiAqXG4gKiAjIyMgQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2Rlc3Ryb3kgZGVzdHJveSgpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNkaXNwYXRjaCBkaXNwYXRjaCh0bywgYWN0aW9uLCBwYXlsb2FkKX1cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjZ2V0QWxsQ2xpZW50SW5mbyBnZXRBbGxDbGllbnRJbmZvKCl9XG4gKlxuICogIyMjIE1pZGRsZXdhcmU6XG4gKiBNaWRkbGV3YXJlIGZ1bmN0aW9ucyByZWNlaXZlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOiAoYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZCkuXG4gKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIG9uIGFzIHRoZSBwYXlsb2FkIGZyb20gYmVmb3JlQWN0aW9uLCB0byB0aGUgYWN0aW9uIGxpc3RlbmVyLCB0byBhZnRlckFjdGlvblxuICogdW5sZXNzIGl0IGlzIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB0aGUgbW9zdCByZWNlbnRseSBkZWZpbmVkIHBheWxvYWQgaXMgdXNlZC4gIE1pZGRsZXdhcmUgY2FuIGJlIHVzZWQgZm9yIHNpZGUgZWZmZWN0cy5cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjc2V0RGVmYXVsdEFjdGlvbiBzZXREZWZhdWx0QWN0aW9uKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNvbkVycm9yIG9uRXJyb3IobWlkZGxld2FyZSl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2JlZm9yZUFjdGlvbiBiZWZvcmVBY3Rpb24obWlkZGxld2FyZSl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2FmdGVyQWN0aW9uIGFmdGVyQWN0aW9uKG1pZGRsZXdhcmUpfVxuICovXG5jbGFzcyBDaGFubmVsUHJvdmlkZXIgZXh0ZW5kcyBjaGFubmVsXzEuQ2hhbm5lbEJhc2Uge1xuICAgIC8qKlxuICAgICAqIGEgcmVhZC1vbmx5IGFycmF5IGNvbnRhaW5pbmcgYWxsIHRoZSBpZGVudGl0aWVzIG9mIGNvbm5lY3RpbmcgY2xpZW50cy5cbiAgICAgKi9cbiAgICBnZXQgY29ubmVjdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiBbLi4uX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIFwiZlwiKV07XG4gICAgfVxuICAgIHN0YXRpYyBoYW5kbGVDbGllbnREaXNjb25uZWN0aW9uKGNoYW5uZWwsIHBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgcmVtb3ZlQnlJZCA9IGNoYW5uZWwuY29ubmVjdGlvbnMuZmluZCgoaWRlbnRpdHkpID0+IGlkZW50aXR5LmVuZHBvaW50SWQgPT09IHBheWxvYWQuZW5kcG9pbnRJZCk7XG4gICAgICAgIGlmIChyZW1vdmVCeUlkKSB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgoY2hhbm5lbCwgX0NoYW5uZWxQcm92aWRlcl9yZW1vdmVFbmRwb2ludCwgXCJmXCIpLmNhbGwoY2hhbm5lbCwgcmVtb3ZlQnlJZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtdWx0aXBsZVJlbW92ZXMgPSBjaGFubmVsLmNvbm5lY3Rpb25zLmZpbHRlcigoaWRlbnRpdHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWRlbnRpdHkudXVpZCA9PT0gcGF5bG9hZC51dWlkICYmIGlkZW50aXR5Lm5hbWUgPT09IHBheWxvYWQubmFtZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbXVsdGlwbGVSZW1vdmVzLmZvckVhY2goX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KGNoYW5uZWwsIF9DaGFubmVsUHJvdmlkZXJfcmVtb3ZlRW5kcG9pbnQsIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2hhbm5lbC5kaXNjb25uZWN0TGlzdGVuZXIocGF5bG9hZCk7XG4gICAgfVxuICAgIHN0YXRpYyBzZXRQcm92aWRlclJlbW92YWwocHJvdmlkZXIsIHJlbW92ZSkge1xuICAgICAgICBDaGFubmVsUHJvdmlkZXIucmVtb3ZhbE1hcC5zZXQocHJvdmlkZXIsIHJlbW92ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByb3ZpZGVySWRlbnRpdHksIGNsb3NlLCBzdHJhdGVneSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX2Nvbm5lY3Rpb25zLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iai5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneS5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0NoYW5uZWxQcm92aWRlcl9yZW1vdmVFbmRwb2ludC5zZXQodGhpcywgKGlkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdDb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjbGllbnRJZGVudGl0eSkgPT4gY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAhPT0gaWRlbnRpdHkuZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneSwgXCJmXCIpLmNsb3NlRW5kcG9pbnQoaWRlbnRpdHkuZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYodGhpcywgX0NoYW5uZWxQcm92aWRlcl9jb25uZWN0aW9ucywgcmVtYWluaW5nQ29ubmVjdGlvbnMsIFwiZlwiKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIE11c3QgYmUgYm91bmQuXG4gICAgICAgIHRoaXMucHJvY2Vzc0FjdGlvbiA9IGFzeW5jIChhY3Rpb24sIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBpZiAoQ2hhbm5lbFByb3ZpZGVyLmNsaWVudElzTXVsdGlSdW50aW1lKHNlbmRlcklkZW50aXR5KSAmJlxuICAgICAgICAgICAgICAgICEoMCwgcnVudGltZVZlcnNpb25pbmdfMS5ydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uKShzZW5kZXJJZGVudGl0eS5ydW50aW1lVXVpZCwgJzE4Ljg3LjU2LjAnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTXVsdGlSdW50aW1lTGVnYWN5Q2xpZW50KHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tGb3JDbGllbnRDb25uZWN0aW9uKHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBlci5wcm9jZXNzQWN0aW9uKGFjdGlvbiwgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICB9O1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX2Nsb3NlLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneSwgXCJmXCIpLmNsb3NlKCk7XG4gICAgICAgICAgICBjb25zdCByZW1vdmUgPSBDaGFubmVsUHJvdmlkZXIucmVtb3ZhbE1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYodGhpcywgX0NoYW5uZWxQcm92aWRlcl9wcm90ZWN0ZWRPYmosIG5ldyBjaGFubmVsXzEuUHJvdGVjdGVkSXRlbXMocHJvdmlkZXJJZGVudGl0eSwgY2xvc2UpLCBcImZcIik7XG4gICAgICAgIHRoaXMuY29ubmVjdExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RMaXN0ZW5lciA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ2KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIFtdLCBcImZcIik7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNih0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBzdHJhdGVneSwgXCJmXCIpO1xuICAgICAgICBzdHJhdGVneS5yZWNlaXZlKHRoaXMucHJvY2Vzc0FjdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc3BhdGNoIGFuIGFjdGlvbiB0byBhIHNwZWNpZmllZCBjbGllbnQuIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGF0IGFjdGlvbiBvbiB0aGUgY2xpZW50IHNpZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG8gLSBJZGVudGl0eSBvZiB0aGUgdGFyZ2V0IGNsaWVudC5cbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gTmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGludm9rZWQgYnkgdGhlIGNsaWVudC5cbiAgICAgKiBAcGFyYW0gcGF5bG9hZCAtIFBheWxvYWQgdG8gYmUgc2VudCBhbG9uZyB3aXRoIHRoZSBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqXG4gICAgICogQmVjYXVzZSBtdWx0aXBsZSBjbGllbnRzIGNhbiBzaGFyZSB0aGUgc2FtZSBgbmFtZWAgYW5kIGB1dWlkYCwgd2hlbiBkaXNwYXRjaGluZyBmcm9tIGEgcHJvdmlkZXIgdG8gYSBjbGllbnQsXG4gICAgICogdGhlIGBpZGVudGl0eWAgeW91IHByb3ZpZGUgbXVzdCBpbmNsdWRlIHRoZSBjbGllbnQncyB1bmlxdWUgYGVuZHBvaW50SWRgIHByb3BlcnR5LiBUaGlzIGBlbmRwb2ludElkYCBpc1xuICAgICAqIHBhc3NlZCB0byB0aGUgcHJvdmlkZXIgaW4gYm90aCB0aGUgYFByb3ZpZGVyLm9uQ29ubmVjdGlvbmAgY2FsbGJhY2sgYW5kIGluIGFueSByZWdpc3RlcmVkIGFjdGlvbiBjYWxsYmFja3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIGFzeW5jIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIGF3YWl0IHByb3ZpZGVyLmRpc3BhdGNoKGlkZW50aXR5LCAnY2xpZW50LWFjdGlvbicsICdIZWxsbywgV29ybGQhJyk7XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGlzcGF0Y2godG8sIGFjdGlvbiwgcGF5bG9hZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludElkID0gdG8uZW5kcG9pbnRJZCA/PyB0aGlzLmdldEVuZHBvaW50SWRGb3JPcGVuRmluSWQodG8sIGFjdGlvbik7XG4gICAgICAgIGlmIChlbmRwb2ludElkICYmIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBcImZcIikuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBcImZcIikuc2VuZChlbmRwb2ludElkLCBhY3Rpb24sIHBheWxvYWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYENsaWVudCBjb25uZWN0aW9uIHdpdGggaWRlbnRpdHkgdXVpZDogJHt0by51dWlkfSAvIG5hbWU6ICR7dG8ubmFtZX0gLyBlbmRwb2ludElkOiAke2VuZHBvaW50SWR9IG5vIGxvbmdlciBjb25uZWN0ZWQuYCkpO1xuICAgIH1cbiAgICBhc3luYyBwcm9jZXNzQ29ubmVjdGlvbihzZW5kZXJJZCwgcGF5bG9hZCkge1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9jb25uZWN0aW9ucywgXCJmXCIpLnB1c2goc2VuZGVySWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0TGlzdGVuZXIoc2VuZGVySWQsIHBheWxvYWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIGFuIGFjdGlvbiBhbmQgcGF5bG9hZCB0byBldmVyeSBjb25uZWN0ZWQgY2xpZW50LlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBmb3IgZWFjaCBhY3Rpb24gKHNlZSBkaXNwYXRjaCkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uXG4gICAgICogQHBhcmFtIHBheWxvYWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIGFzeW5jIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKHByb3ZpZGVyLnB1Ymxpc2goJ2NsaWVudC1hY3Rpb24nLCB7IG1lc3NhZ2U6ICdCcm9hZGNhc3QgZnJvbSBwcm92aWRlcid9KSk7XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGlzaChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMubWFwKCh0bykgPT4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfc3RyYXRlZ3ksIFwiZlwiKS5zZW5kKHRvLmVuZHBvaW50SWQsIGFjdGlvbiwgcGF5bG9hZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIGxpc3RlbmVyIHRoYXQgaXMgY2FsbGVkIG9uIGV2ZXJ5IG5ldyBjbGllbnQgY29ubmVjdGlvbi5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEl0IGlzIHBhc3NlZCB0aGUgaWRlbnRpdHkgb2YgdGhlIGNvbm5lY3RpbmcgY2xpZW50IGFuZCBhIHBheWxvYWQgaWYgaXQgd2FzIHByb3ZpZGVkIHRvIENoYW5uZWwuY29ubmVjdC5cbiAgICAgKiBJZiB5b3Ugd2lzaCB0byByZWplY3QgdGhlIGNvbm5lY3Rpb24sIHRocm93IGFuIGVycm9yLiBCZSBzdXJlIHRvIHN5bmNocm9ub3VzbHkgcHJvdmlkZSBhbiBvbkNvbm5lY3Rpb24gdXBvbiByZWNlaXB0IG9mXG4gICAgICogdGhlIGNoYW5uZWxQcm92aWRlciB0byBlbnN1cmUgYWxsIHBvdGVudGlhbCBjbGllbnQgY29ubmVjdGlvbnMgYXJlIGNhdWdodCBieSB0aGUgbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIG11bHRpcGxlIGNsaWVudHMgY2FuIGV4aXN0IGF0IHRoZSBzYW1lIGBuYW1lYCBhbmQgYHV1aWRgLCBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGluZGl2aWR1YWwgY2xpZW50cyxcbiAgICAgKiB0aGUgYGlkZW50aXR5YCBhcmd1bWVudCBpbiBhIHByb3ZpZGVyJ3MgYG9uQ29ubmVjdGlvbmAgY2FsbGJhY2sgY29udGFpbnMgYW4gYGVuZHBvaW50SWRgIHByb3BlcnR5LiBXaGVuIGRpc3BhdGNoaW5nIGZyb20gYVxuICAgICAqIHByb3ZpZGVyIHRvIGEgY2xpZW50LCB0aGUgYGVuZHBvaW50SWRgIHByb3BlcnR5IG11c3QgYmUgcHJvdmlkZWQgaW4gb3JkZXIgdG8gc2VuZCBhbiBhY3Rpb24gdG8gYSBzcGVjaWZpYyBjbGllbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uQ29ubmVjdGlvbihpZGVudGl0eSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGNvbm5lY3RlZCcsIGlkZW50aXR5KTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFJlamVjdCBjb25uZWN0aW9uOlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uQ29ubmVjdGlvbihpZGVudGl0eSA9PiB7XG4gICAgICogICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gUmVqZWN0ZWQnKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBvbkNvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0TGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCBvbiBjbGllbnQgZGlzY29ubmVjdGlvbi4gSXQgaXMgcGFzc2VkIHRoZSBkaXNjb25uZWN0aW9uIGV2ZW50IG9mIHRoZSBkaXNjb25uZWN0aW5nXG4gICAgICogY2xpZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIGxpc3RlbmVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIub25EaXNjb25uZWN0aW9uKGV2dCA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGRpc2Nvbm5lY3RlZCcsIGB1dWlkOiAke2V2dC51dWlkfSwgbmFtZTogJHtldnQubmFtZX1gKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0TGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzdHJveSB0aGUgY2hhbm5lbCwgcmFpc2VzIGBkaXNjb25uZWN0ZWRgIGV2ZW50cyBvbiBhbGwgY29ubmVjdGVkIGNoYW5uZWwgY2xpZW50cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5kZXN0cm95KCk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBkZXN0cm95KCkge1xuICAgICAgICBjb25zdCBwcm90ZWN0ZWRPYmogPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9wcm90ZWN0ZWRPYmosIFwiZlwiKTtcbiAgICAgICAgcHJvdGVjdGVkT2JqLnByb3ZpZGVySWRlbnRpdHk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNih0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX2Nvbm5lY3Rpb25zLCBbXSwgXCJmXCIpO1xuICAgICAgICBhd2FpdCBwcm90ZWN0ZWRPYmouY2xvc2UoKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY2xvc2UsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggaW5mbyBvbiBldmVyeSBDbGllbnQgY29ubmVjdGVkIHRvIHRoZSBQcm92aWRlclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnb3BlbmZpbicpO1xuICAgICAqIGNvbnN0IGNsaWVudCA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdCgnb3BlbmZpbicpO1xuICAgICAqIGNvbnN0IGNsaWVudEluZm8gPSBhd2FpdCBwcm92aWRlci5nZXRBbGxDbGllbnRJbmZvKCk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhjbGllbnRJbmZvKTtcbiAgICAgKlxuICAgICAqIC8vIFtcbiAgICAgKiAvLyAgICB7XG4gICAgICogLy8gICAgICAgIFwidXVpZFwiOiBcIm9wZW5maW5cIixcbiAgICAgKiAvLyAgICAgICAgXCJuYW1lXCI6IFwib3BlbmZpbi12aWV3XCIsXG4gICAgICogLy8gICAgICAgIFwiZW5kcG9pbnRJZFwiOiBcIjZkNGM3Y2E4LTRhNzQtNDYzNC04N2Y4LTc2MDU1ODIyOTYxM1wiLFxuICAgICAqIC8vICAgICAgICBcImVudGl0eVR5cGVcIjogXCJ2aWV3XCIsXG4gICAgICogLy8gICAgICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9vcGVuZmluLmNvXCJcbiAgICAgKiAvLyAgICB9LFxuICAgICAqIC8vICAgIHtcbiAgICAgKiAvLyAgICAgICAgXCJ1dWlkXCI6IFwib3BlbmZpbjJcIixcbiAgICAgKiAvLyAgICAgICAgXCJuYW1lXCI6IFwib3BlbmZpbi12aWV3MlwiLFxuICAgICAqIC8vICAgICAgICBcImVuZHBvaW50SWRcIjogXCI0ejVkOGFiOS0yYjgxLTM2OTEtOTFleC0xNDIxNzkzODI1MTFcIixcbiAgICAgKiAvLyAgICAgICAgXCJlbnRpdHlUeXBlXCI6IFwidmlld1wiLFxuICAgICAqIC8vICAgICAgICBcInVybFwiOiBcImh0dHBzOi8vZXhhbXBsZS5jb21cIlxuICAgICAqIC8vICAgIH1cbiAgICAgKiAvL11cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGxDbGllbnRJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5tYXAoKGNsaWVudEluZm8pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSwgZW5kcG9pbnRJZCwgZW50aXR5VHlwZSwgY29ubmVjdGlvblVybCB9ID0gY2xpZW50SW5mbztcbiAgICAgICAgICAgIHJldHVybiB7IHV1aWQsIG5hbWUsIGVuZHBvaW50SWQsIGVudGl0eVR5cGUsIGNvbm5lY3Rpb25VcmwgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNoZWNrRm9yQ2xpZW50Q29ubmVjdGlvbihjbGllbnRJZGVudGl0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNDbGllbnRDb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoaXMgYWN0aW9uIHdhcyBzZW50IGZyb20gYSBjbGllbnQgdGhhdCBpcyBub3QgY29ubmVjdGVkIHRvIHRoZSBwcm92aWRlci5cbiAgICAgICAgICAgICAgICAgICAgQ2xpZW50IElkZW50aXR5OiB7dXVpZDogJHtjbGllbnRJZGVudGl0eS51dWlkfSwgbmFtZTogJHtjbGllbnRJZGVudGl0eS5uYW1lfSwgZW5kcG9pbnRJZDogJHtjbGllbnRJZGVudGl0eS5lbmRwb2ludElkfX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc0NsaWVudENvbm5lY3RlZChjbGllbnRJZGVudGl0eSkge1xuICAgICAgICBpZiAoQ2hhbm5lbFByb3ZpZGVyLmNsaWVudElkZW50aXR5SW5jbHVkZXNFbmRwb2ludElkKGNsaWVudElkZW50aXR5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMuc29tZSgoaWRlbnRpdHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIC8vIE1pZ2h0IGJlIHJlZHVuZGFudCB0byBjaGVjayBmb3IgdXVpZCBhbmQgbmFtZSBoZXJlIGFmdGVyIHdlIGdldCBhbiBlbmRwb2ludElkIG1hdGNoLCBidXQganVzdCBpbiBjYXNlXG4gICAgICAgICAgICAgICAgaWRlbnRpdHkuZW5kcG9pbnRJZCA9PT0gY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAmJlxuICAgICAgICAgICAgICAgICAgICBpZGVudGl0eS51dWlkID09PSBjbGllbnRJZGVudGl0eS51dWlkICYmXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5Lm5hbWUgPT09IGNsaWVudElkZW50aXR5Lm5hbWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaXNMZWdhY3lDbGllbnRDb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpO1xuICAgIH1cbiAgICBpc0xlZ2FjeUNsaWVudENvbm5lY3RlZChjbGllbnRJZGVudGl0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5zb21lKChpZGVudGl0eSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGlkZW50aXR5LnV1aWQgPT09IGNsaWVudElkZW50aXR5LnV1aWQgJiYgaWRlbnRpdHkubmFtZSA9PT0gY2xpZW50SWRlbnRpdHkubmFtZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGhhbmRsZU11bHRpUnVudGltZUxlZ2FjeUNsaWVudChzZW5kZXJJZGVudGl0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNMZWdhY3lDbGllbnRDb25uZWN0ZWQoc2VuZGVySWRlbnRpdHkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoaXMgYWN0aW9uIHdhcyBzZW50IGZyb20gYSBjbGllbnQgdGhhdCBpcyBub3QgY29ubmVjdGVkIHRvIHRoZSBwcm92aWRlci4gQ2xpZW50IElkZW50aXR5OlxuICAgICAgICAgICAgICAgICAgICB7dXVpZDogJHtzZW5kZXJJZGVudGl0eS51dWlkfSwgbmFtZTogJHtzZW5kZXJJZGVudGl0eS5uYW1lfSwgZW5kcG9pbnRJZDogJHtzZW5kZXJJZGVudGl0eS5lbmRwb2ludElkfX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRFbmRwb2ludElkRm9yT3BlbkZpbklkKGNsaWVudElkZW50aXR5LCBhY3Rpb24pIHtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjKSA9PiBjLm5hbWUgPT09IGNsaWVudElkZW50aXR5Lm5hbWUgJiYgYy51dWlkID09PSBjbGllbnRJZGVudGl0eS51dWlkKTtcbiAgICAgICAgaWYgKG1hdGNoaW5nQ29ubmVjdGlvbnMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb3RlY3RlZE9iaiA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iaiwgXCJmXCIpO1xuICAgICAgICAgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSBjbGllbnRJZGVudGl0eTtcbiAgICAgICAgICAgIGNvbnN0IHByb3ZpZGVyVXVpZCA9IHByb3RlY3RlZE9iaj8ucHJvdmlkZXJJZGVudGl0eS51dWlkO1xuICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJOYW1lID0gcHJvdGVjdGVkT2JqPy5wcm92aWRlcklkZW50aXR5Lm5hbWU7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBXQVJOSU5HOiBEaXNwYXRjaCBjYWxsIG1heSBoYXZlIHVuaW50ZW5kZWQgcmVzdWx0cy4gVGhlIFwidG9cIiBhcmd1bWVudCBvZiB5b3VyIGRpc3BhdGNoIGNhbGwgaXMgbWlzc2luZyB0aGVcbiAgICAgICAgICAgICAgICBcImVuZHBvaW50SWRcIiBwYXJhbWV0ZXIuIFRoZSBpZGVudGl0eSB5b3UgYXJlIGRpc3BhdGNoaW5nIHRvICh7dXVpZDogJHt1dWlkfSwgbmFtZTogJHtuYW1lfX0pXG4gICAgICAgICAgICAgICAgaGFzIG11bHRpcGxlIGNoYW5uZWxDbGllbnRzIGZvciB0aGlzIGNoYW5uZWwuIFlvdXIgZGlzcGF0Y2hlZCBhY3Rpb246ICgke2FjdGlvbn0pIGZyb20gdGhlIHByb3ZpZGVyOlxuICAgICAgICAgICAgICAgICh7dXVpZDogJHtwcm92aWRlclV1aWR9LCBuYW1lOiAke3Byb3ZpZGVyTmFtZX19KSB3aWxsIG9ubHkgYmUgcHJvY2Vzc2VkIGJ5IHRoZSBtb3N0IHJlY2VudGx5LWNyZWF0ZWQgY2xpZW50LmApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFBvcCB0byByZXR1cm4gdGhlIG1vc3QgcmVjZW50bHkgY3JlYXRlZCBlbmRwb2ludElkLlxuICAgICAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9ucy5wb3AoKT8uZW5kcG9pbnRJZDtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBzdGF0aWMgY2xpZW50SWRlbnRpdHlJbmNsdWRlc0VuZHBvaW50SWQoc3Vic2NyaXB0aW9uSWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbklkZW50aXR5LmVuZHBvaW50SWQgIT09IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBzdGF0aWMgY2xpZW50SXNNdWx0aVJ1bnRpbWUoc3Vic2NyaXB0aW9uSWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbklkZW50aXR5LnJ1bnRpbWVVdWlkICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyB3aXJlQ2xvc2Uod2lyZSwgY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgYXdhaXQgd2lyZS5zZW5kQWN0aW9uKCdkZXN0cm95LWNoYW5uZWwnLCB7IGNoYW5uZWxOYW1lIH0pO1xuICAgIH1cbn1cbnByb3ZpZGVyLkNoYW5uZWxQcm92aWRlciA9IENoYW5uZWxQcm92aWRlcjtcbl9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iaiA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsUHJvdmlkZXJfc3RyYXRlZ3kgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbFByb3ZpZGVyX3JlbW92ZUVuZHBvaW50ID0gbmV3IFdlYWtNYXAoKSwgX0NoYW5uZWxQcm92aWRlcl9jbG9zZSA9IG5ldyBXZWFrTWFwKCk7XG4vLyBUaGUgZm9sbG93aW5nIGxpbmUgc2hvdWxkIGJlIGNoYW5nZWQgZm9sbG93aW5nIGEgdHlwZXNjcmlwdCB1cGRhdGUuXG4vLyBzdGF0aWMgI3JlbW92YWxNYXAgPSBuZXcgV2Vha01hcDxDaGFubmVsUHJvdmlkZXIsIEZ1bmN0aW9uPigpO1xuQ2hhbm5lbFByb3ZpZGVyLnJlbW92YWxNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgbWVzc2FnZVJlY2VpdmVyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXNzYWdlUmVjZWl2ZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xubWVzc2FnZVJlY2VpdmVyLk1lc3NhZ2VSZWNlaXZlciA9IHZvaWQgMDtcbmNvbnN0IGNsaWVudF8xJDEgPSBjbGllbnQ7XG5jb25zdCBiYXNlXzEkZyA9IGJhc2U7XG4vKlxuVGhpcyBpcyBhIHNpbmdsZXRvbiAocGVyIGZpbiBvYmplY3QpIHRhc2tlZCB3aXRoIHJvdXRpbmcgbWVzc2FnZXMgY29taW5nIG9mZiB0aGUgaXBjIHRvIHRoZSBjb3JyZWN0IGVuZHBvaW50LlxuSXQgbmVlZHMgdG8gYmUgYSBzaW5nbGV0b24gYmVjYXVzZSB0aGVyZSBjYW4gb25seSBiZSBvbmUgcGVyIHdpcmUuIEl0IHRyYWNrcyBib3RoIGNsaWVudHMgYW5kIHByb3ZpZGVycycgcHJvY2Vzc0FjdGlvbiBwYXNzZWQgaW4gdmlhIHRoZSBzdHJhdGVneS5cbklmIGZ1bmN0aW9uYWxpdHkgaXMgbm90IGFib3V0IHJlY2VpdmluZyBtZXNzYWdlcywgaXQgZG9lcyBub3QgYmVsb25nIGhlcmUuXG4qL1xuY2xhc3MgTWVzc2FnZVJlY2VpdmVyIGV4dGVuZHMgYmFzZV8xJGcuQmFzZSB7XG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgdGhpcy5vbm1lc3NhZ2UgPSAobXNnKSA9PiB7XG4gICAgICAgICAgICBpZiAobXNnLmFjdGlvbiA9PT0gJ3Byb2Nlc3MtY2hhbm5lbC1tZXNzYWdlJykge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0NoYW5uZWxNZXNzYWdlKG1zZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW5kcG9pbnRNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkID0gbmV3IE1hcCgpO1xuICAgICAgICB3aXJlLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5vbm1lc3NhZ2UuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIGFzeW5jIHByb2Nlc3NDaGFubmVsTWVzc2FnZShtc2cpIHtcbiAgICAgICAgY29uc3QgeyBzZW5kZXJJZGVudGl0eSwgcHJvdmlkZXJJZGVudGl0eSwgYWN0aW9uLCBhY2tUb1NlbmRlciwgcGF5bG9hZCwgaW50ZW5kZWRUYXJnZXRJZGVudGl0eSB9ID0gbXNnLnBheWxvYWQ7XG4gICAgICAgIGNvbnN0IGtleSA9IGludGVuZGVkVGFyZ2V0SWRlbnRpdHkuY2hhbm5lbElkID8/IC8vIFRoZSByZWNpcGllbnQgaXMgYSBwcm92aWRlclxuICAgICAgICAgICAgaW50ZW5kZWRUYXJnZXRJZGVudGl0eS5lbmRwb2ludElkID8/IC8vIFRoZSByZWNpcGllbnQgaXMgYSBjbGllbnRcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmdldChwcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCk7IC8vIE5vIGVuZHBvaW50SWQgd2FzIHBhc3NlZCwgbWFrZSBiZXN0IGF0dGVtcHRcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuZW5kcG9pbnRNYXAuZ2V0KGtleSk7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5zdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnJlYXNvbiA9IGBDbGllbnQgY29ubmVjdGlvbiB3aXRoIGlkZW50aXR5IHV1aWQ6ICR7dGhpcy53aXJlLm1lLnV1aWR9IC8gbmFtZTogJHt0aGlzLndpcmUubWUubmFtZX0gLyBlbmRwb2ludElkOiAke2tleX0gbm8gbG9uZ2VyIGNvbm5lY3RlZC5gO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgaGFuZGxlcihhY3Rpb24sIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCA9IGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCB8fCB7fTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZC5yZXN1bHQgPSByZXM7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRSYXcoYWNrVG9TZW5kZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnN1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucmVhc29uID0gZS5tZXNzYWdlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRFbmRwb2ludChoYW5kbGVyLCBjaGFubmVsSWQsIGVuZHBvaW50SWQpIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludE1hcC5zZXQoZW5kcG9pbnRJZCwgaGFuZGxlcik7XG4gICAgICAgIC8vIFByb3ZpZGVycyBoYXZlIHRoZSBzYW1lIGVuZHBvaW50SWQgYW5kIGNoYW5uZWxJZC5cbiAgICAgICAgLy8gVGhpcyBpcyBvbmx5IHVzZWQgd2hlbiBjbGllbnRzIGFyZSByZWNlaXZpbmcgbWVzc2FnZXMgZnJvbSBwcm92aWRlcnMsIHNvIHdlIHNob3VsZG4ndCBzYXZlIHByb3ZpZGVyIGVuZHBvaW50SWQgaGVyZS5cbiAgICAgICAgaWYgKGNoYW5uZWxJZCAhPT0gZW5kcG9pbnRJZCkge1xuICAgICAgICAgICAgdGhpcy5sYXRlc3RFbmRwb2ludElkQnlDaGFubmVsSWQuc2V0KGNoYW5uZWxJZCwgZW5kcG9pbnRJZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlRW5kcG9pbnQoY2hhbm5lbElkLCBlbmRwb2ludElkKSB7XG4gICAgICAgIHRoaXMuZW5kcG9pbnRNYXAuZGVsZXRlKGVuZHBvaW50SWQpO1xuICAgICAgICBpZiAodGhpcy5sYXRlc3RFbmRwb2ludElkQnlDaGFubmVsSWQuZ2V0KGNoYW5uZWxJZCkgPT09IGVuZHBvaW50SWQpIHtcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmRlbGV0ZShjaGFubmVsSWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrRm9yUHJldmlvdXNDbGllbnRDb25uZWN0aW9uKGNoYW5uZWxJZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludElkRnJvbVByZXZpb3VzQ29ubmVjdGlvbiA9IHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmdldChjaGFubmVsSWQpO1xuICAgICAgICBpZiAoZW5kcG9pbnRJZEZyb21QcmV2aW91c0Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIC8vIE5vdCBjb252aW5jZWQgYnkgdGhpcyB3YXkgb2YgZG9pbmcgdGhpbmdzLCBidXQgcHVzaGluZyB1cCBmb3Igbm93LlxuICAgICAgICAgICAgY2xpZW50XzEkMS5DaGFubmVsQ2xpZW50LmNsb3NlQ2hhbm5lbEJ5RW5kcG9pbnRJZChlbmRwb2ludElkRnJvbVByZXZpb3VzQ29ubmVjdGlvbik7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdZb3UgaGF2ZSBjcmVhdGVkIGEgc2Vjb25kIGNvbm5lY3Rpb24gdG8gYW4gb2xkZXIgcHJvdmlkZXIuIEZpcnN0IGNvbm5lY3Rpb24gaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBjbGllbnRNYXAnKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0lmIHRoZSBwcm92aWRlciBjYWxscyBwdWJsaXNoKCksIHlvdSBtYXkgcmVjZWl2ZSBtdWx0aXBsZSBtZXNzYWdlcy4nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbm1lc3NhZ2VSZWNlaXZlci5NZXNzYWdlUmVjZWl2ZXIgPSBNZXNzYWdlUmVjZWl2ZXI7XG5cbnZhciBwcm90b2NvbE1hbmFnZXIgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvY29sTWFuYWdlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5wcm90b2NvbE1hbmFnZXIuUHJvdG9jb2xNYW5hZ2VyID0gdm9pZCAwO1xuLypcblRoaXMgc2hvdWxkIGJlIGFnbm9zdGljIG9mIGFueSBhY3R1YWwgb3BlbmZpbiBjb2RlIHRvIGJlIHVuaXQgdGVzdGFibGUuXG5EZXBlbmRlbmNpZXMgb24gdGhlIGFjdHVhbCBzcmF0ZWdpZXMgc2hvdWxkIGJlIGhhbmRsZWQgaW4gQ29ubmVjdGlvbk1hbmFnZXJcbiovXG5jbGFzcyBQcm90b2NvbE1hbmFnZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNvbnN0cnVjdG9yXG4gICAgY29uc3RydWN0b3IoUHJvdG9jb2xzSW5QcmVmZXJlbmNlT3JkZXIpIHtcbiAgICAgICAgdGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlciA9IFByb3RvY29sc0luUHJlZmVyZW5jZU9yZGVyO1xuICAgICAgICB0aGlzLkRlZmF1bHRDbGllbnRQcm90b2NvbHMgPSBbJ2NsYXNzaWMnXTtcbiAgICAgICAgdGhpcy5EZWZhdWx0UHJvdmlkZXJQcm90b2NvbHMgPSBbJ2NsYXNzaWMnXTtcbiAgICAgICAgdGhpcy5nZXRDbGllbnRQcm90b2NvbHMgPSAocHJvdG9jb2xzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdXBwb3J0ZWQgPSBwcm90b2NvbHNcbiAgICAgICAgICAgICAgICA/IHRoaXMuUHJvdG9jb2xzSW5QcmVmZXJlbmNlT3JkZXIuZmlsdGVyKCh4KSA9PiBwcm90b2NvbHMuaW5jbHVkZXMoeCkpXG4gICAgICAgICAgICAgICAgOiB0aGlzLkRlZmF1bHRDbGllbnRQcm90b2NvbHM7XG4gICAgICAgICAgICBpZiAoIXN1cHBvcnRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHZhbGlkIHByb3RvY29scyB3ZXJlIHBhc3NlZCBpbi4gQWNjZXB0ZWQgdmFsdWVzIGFyZTogJHt0aGlzLlByb3RvY29sc0luUHJlZmVyZW5jZU9yZGVyLmpvaW4oJywgJyl9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN1cHBvcnRlZDtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRQcm92aWRlclByb3RvY29scyA9IChwcm90b2NvbHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1cHBvcnRlZCA9IHByb3RvY29sc1xuICAgICAgICAgICAgICAgID8gdGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlci5maWx0ZXIoKHgpID0+IHByb3RvY29scy5pbmNsdWRlcyh4KSlcbiAgICAgICAgICAgICAgICA6IHRoaXMuRGVmYXVsdFByb3ZpZGVyUHJvdG9jb2xzO1xuICAgICAgICAgICAgaWYgKCFzdXBwb3J0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB2YWxpZCBwcm90b2NvbHMgd2VyZSBwYXNzZWQgaW4uIEFjY2VwdGVkIHZhbHVlcyBhcmU6ICR7dGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlci5qb2luKCcsICcpfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBwb3J0ZWQ7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0Q29tcGF0aWJsZVByb3RvY29scyA9IChwcm92aWRlclByb3RvY29scywgY2xpZW50T2ZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1cHBvcnRlZCA9IGNsaWVudE9mZmVyLnN1cHBvcnRlZFByb3RvY29scy5maWx0ZXIoKGNsaWVudFByb3RvY29sKSA9PiBwcm92aWRlclByb3RvY29scy5zb21lKChwcm92aWRlclByb3RvY29sKSA9PiBwcm92aWRlclByb3RvY29sLnR5cGUgPT09IGNsaWVudFByb3RvY29sLnR5cGUgJiZcbiAgICAgICAgICAgICAgICBjbGllbnRQcm90b2NvbC52ZXJzaW9uID49IHByb3ZpZGVyUHJvdG9jb2wubWluaW11bVZlcnNpb24gJiZcbiAgICAgICAgICAgICAgICBwcm92aWRlclByb3RvY29sLnZlcnNpb24gPj0gKGNsaWVudFByb3RvY29sLm1pbmltdW1WZXJzaW9uID8/IDApKSk7XG4gICAgICAgICAgICByZXR1cm4gc3VwcG9ydGVkLnNsaWNlKDAsIGNsaWVudE9mZmVyLm1heFByb3RvY29scyk7XG4gICAgICAgIH07XG4gICAgfVxufVxucHJvdG9jb2xNYW5hZ2VyLlByb3RvY29sTWFuYWdlciA9IFByb3RvY29sTWFuYWdlcjtcblxudmFyIHN0cmF0ZWd5ID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdHJhdGVneSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jbGFzcyBDb21iaW5lZFN0cmF0ZWd5IHtcbiAgICAvLyBNYWtpbmcgdGhpcyBhIHN0YXRpYyBtZXRob2QgYmVjYXVzZSB0aGUgY29uc3RydWN0b3IgY2FuJ3QgYmUgdHlwZWQuXG4gICAgLy8gT3RoZXJ3aXNlIGl0IHdpbGwgZXJyb3Igd2hlbiBjYWxsaW5nIGFkZEVuZHBvaW50IGJ1dCBJJ2QgcmF0aGVyIHRoZSB3aG9sZSBpbnN0YW5jZSBiZSB0eXBlZCBhcyBuZXZlci5cbiAgICBzdGF0aWMgY29tYmluZShhLCBiKSB7XG4gICAgICAgIHJldHVybiBuZXcgQ29tYmluZWRTdHJhdGVneShhLCBiKTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY29uc3RydWN0b3JcbiAgICBjb25zdHJ1Y3RvcihwcmltYXJ5LCBzZWNvbmRhcnkpIHtcbiAgICAgICAgdGhpcy5wcmltYXJ5ID0gcHJpbWFyeTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkgPSBzZWNvbmRhcnk7XG4gICAgfVxuICAgIG9uRW5kcG9pbnREaXNjb25uZWN0KGVuZHBvaW50SWQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucHJpbWFyeS5vbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vjb25kYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkub25FbmRwb2ludERpc2Nvbm5lY3QoZW5kcG9pbnRJZCwgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnByaW1hcnkuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJpbWFyeS5pc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHx8IHRoaXMuc2Vjb25kYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCk7XG4gICAgfVxuICAgIGFzeW5jIGNsb3NlRW5kcG9pbnQoZW5kcG9pbnRJZCkge1xuICAgICAgICBhd2FpdCB0aGlzLnByaW1hcnkuY2xvc2VFbmRwb2ludChlbmRwb2ludElkKTtcbiAgICAgICAgYXdhaXQgdGhpcy5zZWNvbmRhcnkuY2xvc2VFbmRwb2ludChlbmRwb2ludElkKTtcbiAgICB9XG4gICAgaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcmltYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnQpIHx8IHRoaXMuc2Vjb25kYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnQpO1xuICAgIH1cbiAgICBhc3luYyBhZGRFbmRwb2ludChlbmRwb2ludCwgcGF5bG9hZCkge1xuICAgICAgICBpZiAodGhpcy5wcmltYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucHJpbWFyeS5hZGRFbmRwb2ludChlbmRwb2ludCwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2Vjb25kYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2Vjb25kYXJ5LmFkZEVuZHBvaW50KGVuZHBvaW50LCBwYXlsb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucHJpbWFyeS5yZWNlaXZlKGxpc3RlbmVyKTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkucmVjZWl2ZShsaXN0ZW5lcik7XG4gICAgfVxuICAgIHNlbmQoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKSB7XG4gICAgICAgIGlmICh0aGlzLnByaW1hcnkuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJpbWFyeS5zZW5kKGVuZHBvaW50SWQsIGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vjb25kYXJ5LnNlbmQoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKTtcbiAgICB9XG4gICAgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLnByaW1hcnkuY2xvc2UoKSwgdGhpcy5zZWNvbmRhcnkuY2xvc2UoKV0pO1xuICAgIH1cbn1cbnN0cmF0ZWd5LmRlZmF1bHQgPSBDb21iaW5lZFN0cmF0ZWd5O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ1ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2ltcG9ydERlZmF1bHQkMSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2ltcG9ydERlZmF1bHQpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcbn07XG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgX0Nvbm5lY3Rpb25NYW5hZ2VyX3J0Y0Nvbm5lY3Rpb25NYW5hZ2VyO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbm5lY3Rpb25NYW5hZ2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbm5lY3Rpb25NYW5hZ2VyLkNvbm5lY3Rpb25NYW5hZ2VyID0gdm9pZCAwO1xuY29uc3QgZXhoYXVzdGl2ZV8xID0gZXhoYXVzdGl2ZTtcbmNvbnN0IGJhc2VfMSRmID0gYmFzZTtcbmNvbnN0IHN0cmF0ZWd5XzEgPSBzdHJhdGVneSQzO1xuY29uc3Qgc3RyYXRlZ3lfMiA9IHN0cmF0ZWd5JDI7XG5jb25zdCBpY2VfbWFuYWdlcl8xID0gaWNlTWFuYWdlcjtcbmNvbnN0IHByb3ZpZGVyXzEkMSA9IHByb3ZpZGVyO1xuY29uc3QgbWVzc2FnZV9yZWNlaXZlcl8xID0gbWVzc2FnZVJlY2VpdmVyO1xuY29uc3QgcHJvdG9jb2xfbWFuYWdlcl8xID0gcHJvdG9jb2xNYW5hZ2VyO1xuY29uc3Qgc3RyYXRlZ3lfMyA9IF9faW1wb3J0RGVmYXVsdCQxKHN0cmF0ZWd5KTtcbmNsYXNzIENvbm5lY3Rpb25NYW5hZ2VyIGV4dGVuZHMgYmFzZV8xJGYuQmFzZSB7XG4gICAgc3RhdGljIGdldFByb3RvY29sT3B0aW9uc0Zyb21TdHJpbmdzKHByb3RvY29scykge1xuICAgICAgICByZXR1cm4gcHJvdG9jb2xzLm1hcCgocHJvdG9jb2wpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAocHJvdG9jb2wpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdydGMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyYXRlZ3lfMi5SVENJbmZvO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NsYXNzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyYXRlZ3lfMS5DbGFzc2ljSW5mbztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKDAsIGV4aGF1c3RpdmVfMS5leGhhdXN0aXZlQ2hlY2spKHByb3RvY29sLCBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlci5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0Nvbm5lY3Rpb25NYW5hZ2VyX3J0Y0Nvbm5lY3Rpb25NYW5hZ2VyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICB0aGlzLnJlbW92ZUNoYW5uZWxGcm9tUHJvdmlkZXJNYXAgPSAoY2hhbm5lbElkKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVyTWFwLmRlbGV0ZShjaGFubmVsSWQpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9ubWVzc2FnZSA9IChtc2cpID0+IHtcbiAgICAgICAgICAgIGlmIChtc2cuYWN0aW9uID09PSAncHJvY2Vzcy1jaGFubmVsLWNvbm5lY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ2hhbm5lbENvbm5lY3Rpb24obXNnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcm92aWRlck1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5wcm90b2NvbE1hbmFnZXIgPSBuZXcgcHJvdG9jb2xfbWFuYWdlcl8xLlByb3RvY29sTWFuYWdlcih0aGlzLndpcmUuZW52aXJvbm1lbnQudHlwZSA9PT0gJ25vZGUnID8gWydjbGFzc2ljJ10gOiBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDUodGhpcywgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgbmV3IG1lc3NhZ2VfcmVjZWl2ZXJfMS5NZXNzYWdlUmVjZWl2ZXIod2lyZSksIFwiZlwiKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ1KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9ydGNDb25uZWN0aW9uTWFuYWdlciwgbmV3IGljZV9tYW5hZ2VyXzEuUlRDSUNFTWFuYWdlcih3aXJlKSwgXCJmXCIpO1xuICAgICAgICB3aXJlLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5vbm1lc3NhZ2UuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIGNyZWF0ZVByb3ZpZGVyKG9wdGlvbnMsIHByb3ZpZGVySWRlbnRpdHkpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IE9iamVjdC5hc3NpZ24odGhpcy53aXJlLmVudmlyb25tZW50LmdldERlZmF1bHRDaGFubmVsT3B0aW9ucygpLmNyZWF0ZSwgb3B0aW9ucyB8fCB7fSk7XG4gICAgICAgIGNvbnN0IHByb3RvY29scyA9IHRoaXMucHJvdG9jb2xNYW5hZ2VyLmdldFByb3ZpZGVyUHJvdG9jb2xzKG9wdHM/LnByb3RvY29scyk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVNpbmdsZVN0cmF0ZWd5ID0gKHN0cmF0VHlwZSkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChzdHJhdFR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdydGMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3koKTtcbiAgICAgICAgICAgICAgICBjYXNlICdjbGFzc2ljJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBzdHJhdGVneV8xLkNsYXNzaWNTdHJhdGVneSh0aGlzLndpcmUsIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfbWVzc2FnZVJlY2VpdmVyLCBcImZcIiksIFxuICAgICAgICAgICAgICAgICAgICAvLyBQcm92aWRlcnMgZG8gbm90IGhhdmUgYW4gZW5kcG9pbnRJZCwgdXNlIGNoYW5uZWxJZCBhcyBlbmRwb2ludElkIGluIHRoZSBzdHJhdGVneS5cbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQsIHByb3ZpZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoMCwgZXhoYXVzdGl2ZV8xLmV4aGF1c3RpdmVDaGVjaykoc3RyYXRUeXBlLCBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzdHJhdGVnaWVzID0gcHJvdG9jb2xzLm1hcChjcmVhdGVTaW5nbGVTdHJhdGVneSk7XG4gICAgICAgIGxldCBzdHJhdGVneTtcbiAgICAgICAgaWYgKHN0cmF0ZWdpZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjb25zdCBbYSwgYl0gPSBzdHJhdGVnaWVzO1xuICAgICAgICAgICAgc3RyYXRlZ3kgPSBzdHJhdGVneV8zLmRlZmF1bHQuY29tYmluZShhLCBiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdHJhdGVnaWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgW3N0cmF0ZWd5XSA9IHN0cmF0ZWdpZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTaG91bGQgYmUgaW1wb3NzaWJsZS5cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIGNvbWJpbmUgc3RyYXRlZ2llcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgcHJvdmlkZXJfMSQxLkNoYW5uZWxQcm92aWRlcihwcm92aWRlcklkZW50aXR5LCAoKSA9PiBwcm92aWRlcl8xJDEuQ2hhbm5lbFByb3ZpZGVyLndpcmVDbG9zZSh0aGlzLndpcmUsIHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbE5hbWUpLCBzdHJhdGVneSk7XG4gICAgICAgIGNvbnN0IGtleSA9IHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkO1xuICAgICAgICB0aGlzLnByb3ZpZGVyTWFwLnNldChrZXksIHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBjaGFubmVsLFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHM6IENvbm5lY3Rpb25NYW5hZ2VyLmdldFByb3RvY29sT3B0aW9uc0Zyb21TdHJpbmdzKHByb3RvY29scylcbiAgICAgICAgfSk7XG4gICAgICAgIHByb3ZpZGVyXzEkMS5DaGFubmVsUHJvdmlkZXIuc2V0UHJvdmlkZXJSZW1vdmFsKGNoYW5uZWwsIHRoaXMucmVtb3ZlQ2hhbm5lbEZyb21Qcm92aWRlck1hcC5iaW5kKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIGNoYW5uZWw7XG4gICAgfVxuICAgIGFzeW5jIGNyZWF0ZUNsaWVudE9mZmVyKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgcHJvdG9jb2xzID0gdGhpcy5wcm90b2NvbE1hbmFnZXIuZ2V0Q2xpZW50UHJvdG9jb2xzKG9wdGlvbnM/LnByb3RvY29scyk7XG4gICAgICAgIGxldCBydGNQYWNrZXQ7XG4gICAgICAgIGNvbnN0IHN1cHBvcnRlZFByb3RvY29scyA9IGF3YWl0IFByb21pc2UuYWxsKHByb3RvY29scy5tYXAoYXN5bmMgKHR5cGUpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3J0Yyc6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBydGNDbGllbnQsIGNoYW5uZWxzLCBvZmZlciwgcnRjQ29ubmVjdGlvbklkLCBjaGFubmVsc09wZW5lZCB9ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ3KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9ydGNDb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLnN0YXJ0Q2xpZW50T2ZmZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgcnRjUGFja2V0ID0geyBydGNDbGllbnQsIGNoYW5uZWxzLCBjaGFubmVsc09wZW5lZCB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3J0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzdHJhdGVneV8yLlJUQ0luZm8udmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgb2ZmZXIsIHJ0Y0Nvbm5lY3Rpb25JZCB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgJ2NsYXNzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnY2xhc3NpYycsIHZlcnNpb246IHN0cmF0ZWd5XzEuQ2xhc3NpY0luZm8udmVyc2lvbiB9O1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoMCwgZXhoYXVzdGl2ZV8xLmV4aGF1c3RpdmVDaGVjaykodHlwZSwgWydydGMnLCAnY2xhc3NpYyddKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2ZmZXI6IHtcbiAgICAgICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHMsXG4gICAgICAgICAgICAgICAgbWF4UHJvdG9jb2xzOiAyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnRjOiBydGNQYWNrZXRcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlQ2xpZW50U3RyYXRlZ3kocnRjUGFja2V0LCByb3V0aW5nSW5mbykge1xuICAgICAgICBpZiAoIXJvdXRpbmdJbmZvLmVuZHBvaW50SWQpIHtcbiAgICAgICAgICAgIHJvdXRpbmdJbmZvLmVuZHBvaW50SWQgPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpO1xuICAgICAgICAgICAgLy8gRm9yIE5ldyBDbGllbnRzIGNvbm5lY3RpbmcgdG8gT2xkIFByb3ZpZGVycy4gVG8gcHJldmVudCBtdWx0aS1kaXNwYXRjaGluZyBhbmQgcHVibGlzaGluZywgd2UgZGVsZXRlIHByZXZpb3VzbHktY29ubmVjdGVkXG4gICAgICAgICAgICAvLyBjbGllbnRzIHRoYXQgYXJlIGluIHRoZSBzYW1lIGNvbnRleHQgYXMgdGhlIG5ld2x5LWNvbm5lY3RlZCBjbGllbnQuXG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDcodGhpcywgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgXCJmXCIpLmNoZWNrRm9yUHJldmlvdXNDbGllbnRDb25uZWN0aW9uKHJvdXRpbmdJbmZvLmNoYW5uZWxJZCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYW5zd2VyID0gcm91dGluZ0luZm8uYW5zd2VyID8/IHtcbiAgICAgICAgICAgIHN1cHBvcnRlZFByb3RvY29sczogW3sgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiAxIH1dXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNyZWF0ZVN0cmF0ZWd5RnJvbUFuc3dlciA9IGFzeW5jIChwcm90b2NvbCkgPT4ge1xuICAgICAgICAgICAgaWYgKHByb3RvY29sLnR5cGUgPT09ICdydGMnICYmIHJ0Y1BhY2tldCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5maW5pc2hDbGllbnRPZmZlcihydGNQYWNrZXQucnRjQ2xpZW50LCBwcm90b2NvbC5wYXlsb2FkLmFuc3dlciwgcnRjUGFja2V0LmNoYW5uZWxzT3BlbmVkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3koKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcm90b2NvbC50eXBlID09PSAnY2xhc3NpYycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzEuQ2xhc3NpY1N0cmF0ZWd5KHRoaXMud2lyZSwgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ3KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9tZXNzYWdlUmVjZWl2ZXIsIFwiZlwiKSwgcm91dGluZ0luZm8uZW5kcG9pbnRJZCwgcm91dGluZ0luZm8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFsbFByb3RvY29scyA9IChhd2FpdCBQcm9taXNlLmFsbChhbnN3ZXIuc3VwcG9ydGVkUHJvdG9jb2xzLm1hcChjcmVhdGVTdHJhdGVneUZyb21BbnN3ZXIpKSkuZmlsdGVyKCh4KSA9PiB4ICE9PSBudWxsKTtcbiAgICAgICAgLy8gQ2xlYW4gdXAgbG9naWMgaWYgcHJvdmlkZXIgZGlkbid0IHN1cHBvcnQgcnRjLlxuICAgICAgICBpZiAocnRjUGFja2V0ICYmICFhbGxQcm90b2NvbHMuc29tZSgoeCkgPT4geCBpbnN0YW5jZW9mIHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3kpKSB7XG4gICAgICAgICAgICBpZiAocnRjUGFja2V0KSB7XG4gICAgICAgICAgICAgICAgcnRjUGFja2V0LnJ0Y0NsaWVudC5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBzdHJhdGVneTtcbiAgICAgICAgaWYgKGFsbFByb3RvY29scy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgc3RyYXRlZ3kgPSBzdHJhdGVneV8zLmRlZmF1bHQuY29tYmluZShhbGxQcm90b2NvbHNbMF0sIGFsbFByb3RvY29sc1sxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWxsUHJvdG9jb2xzLmxlbmd0aCkge1xuICAgICAgICAgICAgW3N0cmF0ZWd5XSA9IGFsbFByb3RvY29scztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNob3VsZCBiZSBpbXBvc3NpYmxlLlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb21wYXRpYmxlIHByb3RvY29scycpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFzIGNhc3RpbmcgcnRjUGFja2V0IGJlY2F1c2Ugd2Ugd29uJ3QgaGF2ZSBhbiBydGNTdHJhdGVneSBpZiBydGNQYWNrZXQgaXMgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBlbmRwb2ludFBheWxvYWQgPSB7IGVuZHBvaW50SWRlbnRpdHk6IHJvdXRpbmdJbmZvLCBydGM6IHJ0Y1BhY2tldCB9O1xuICAgICAgICBzdHJhdGVneS5hZGRFbmRwb2ludChyb3V0aW5nSW5mby5jaGFubmVsSWQsIGVuZHBvaW50UGF5bG9hZCk7XG4gICAgICAgIHJldHVybiBzdHJhdGVneTtcbiAgICB9XG4gICAgYXN5bmMgcHJvY2Vzc0NoYW5uZWxDb25uZWN0aW9uKG1zZykge1xuICAgICAgICBjb25zdCB7IGNsaWVudElkZW50aXR5LCBwcm92aWRlcklkZW50aXR5LCBhY2tUb1NlbmRlciwgcGF5bG9hZCwgb2ZmZXI6IGNsaWVudE9mZmVyIH0gPSBtc2cucGF5bG9hZDtcbiAgICAgICAgaWYgKCFjbGllbnRJZGVudGl0eS5lbmRwb2ludElkKSB7XG4gICAgICAgICAgICAvLyBTaG91bGQgYmUgcG9seWZpbGxlZCBieSBjb3JlIGJ1dCBub3QgaW4gY2FzZXMgb2Ygbm9kZSBjb25uZWN0aW5nIHRvIGFuIG9sZCBydW50aW1lLlxuICAgICAgICAgICAgY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCk7XG4gICAgICAgICAgICBjbGllbnRJZGVudGl0eS5pc0xvY2FsRW5kcG9pbnRJZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjbGllbnRJZGVudGl0eS5pc0xvY2FsRW5kcG9pbnRJZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkO1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLnByb3ZpZGVyTWFwLmdldChrZXkpO1xuICAgICAgICBpZiAoIWJ1cykge1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5zdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnJlYXNvbiA9IGBDaGFubmVsIFwiJHtwcm92aWRlcklkZW50aXR5LmNoYW5uZWxOYW1lfVwiIGhhcyBiZWVuIGRlc3Ryb3llZC5gO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHByb3ZpZGVyLCBzdHJhdGVneSwgc3VwcG9ydGVkUHJvdG9jb2xzIH0gPSBidXM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIShwcm92aWRlciBpbnN0YW5jZW9mIHByb3ZpZGVyXzEkMS5DaGFubmVsUHJvdmlkZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0Nhbm5vdCBjb25uZWN0IHRvIGEgY2hhbm5lbCBjbGllbnQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyID0gY2xpZW50T2ZmZXIgPz8ge1xuICAgICAgICAgICAgICAgIHN1cHBvcnRlZFByb3RvY29sczogW3sgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiAxIH1dLFxuICAgICAgICAgICAgICAgIG1heFByb3RvY29sczogMVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IG92ZXJsYXBwaW5nUHJvdG9jb2xzID0gdGhpcy5wcm90b2NvbE1hbmFnZXIuZ2V0Q29tcGF0aWJsZVByb3RvY29scyhzdXBwb3J0ZWRQcm90b2NvbHMsIG9mZmVyKTtcbiAgICAgICAgICAgIGlmICghb3ZlcmxhcHBpbmdQcm90b2NvbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHByb3ZpZGVyIGRvZXMgbm90IHN1cHBvcnQgYW55IG9mIHRoZSBvZmZlcmVkIHByb3RvY29scy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHByb3ZpZGVyLnByb2Nlc3NDb25uZWN0aW9uKGNsaWVudElkZW50aXR5LCBwYXlsb2FkKTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCA9IGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCB8fCB7fTtcbiAgICAgICAgICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgc3VwcG9ydGVkIHByb3RvY29scyBhbmQgYWNjdW11bGF0ZSB0aGVtIGludG8gdGhlIGFuc3dlclxuICAgICAgICAgICAgLy8gYWRkRW5kcG9pbnQgaXMgdHJpY2t5IGJ1dCB3ZSBuZWVkIHRvIHdhaXQgZm9yIGNoYW5uZWwgcmVzb2x1dGlvbiBiZWZvcmUgYWRkaW5nIHRoZSBlbmRwb2ludC5cbiAgICAgICAgICAgIGxldCBjbGllbnRBbnN3ZXIgPSB7XG4gICAgICAgICAgICAgICAgc3VwcG9ydGVkUHJvdG9jb2xzOiBbXSxcbiAgICAgICAgICAgICAgICBlbmRwb2ludFBheWxvYWRQcm9taXNlOiBQcm9taXNlLnJlc29sdmUoeyBlbmRwb2ludElkZW50aXR5OiBjbGllbnRJZGVudGl0eSB9KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNsaWVudEFuc3dlciA9IGF3YWl0IG92ZXJsYXBwaW5nUHJvdG9jb2xzLnJlZHVjZShhc3luYyAoYWNjdW1QLCBwcm90b2NvbFRvVXNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYW5zd2VyID0gYXdhaXQgYWNjdW1QO1xuICAgICAgICAgICAgICAgIGlmIChwcm90b2NvbFRvVXNlLnR5cGUgPT09ICdydGMnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgYW5zd2VyOiBydGNBbnN3ZXIsIHJ0Y0NsaWVudCwgY2hhbm5lbHMgfSA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5jcmVhdGVQcm92aWRlckFuc3dlcihwcm90b2NvbFRvVXNlLnBheWxvYWQucnRjQ29ubmVjdGlvbklkLCBwcm90b2NvbFRvVXNlLnBheWxvYWQub2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICBhbnN3ZXIuc3VwcG9ydGVkUHJvdG9jb2xzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3J0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzdHJhdGVneV8yLlJUQ0luZm8udmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnN3ZXI6IHJ0Y0Fuc3dlclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgYW5zd2VyLmVuZHBvaW50UGF5bG9hZFByb21pc2UgPSBhbnN3ZXIuZW5kcG9pbnRQYXlsb2FkUHJvbWlzZS50aGVuKChlbmRwb2ludFBheWxvYWQpID0+IGNoYW5uZWxzLnRoZW4oKHJlc29sdmVkQ2hhbm5lbHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZW5kcG9pbnRQYXlsb2FkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ0Yzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGNDbGllbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzOiByZXNvbHZlZENoYW5uZWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYW5zd2VyLnN1cHBvcnRlZFByb3RvY29scy5wdXNoKHsgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiBzdHJhdGVneV8xLkNsYXNzaWNJbmZvLnZlcnNpb24gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICAgICAgICB9LCBQcm9taXNlLnJlc29sdmUoY2xpZW50QW5zd2VyKSk7XG4gICAgICAgICAgICAvLyBOZWVkIHRvIGFzIGNhc3QgaGVyZS5cbiAgICAgICAgICAgIGNsaWVudEFuc3dlci5lbmRwb2ludFBheWxvYWRQcm9taXNlLnRoZW4oKGVuZHBvaW50UGF5bG9hZCkgPT4gc3RyYXRlZ3kuYWRkRW5kcG9pbnQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCwgZW5kcG9pbnRQYXlsb2FkKSk7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnBheWxvYWQucmVzdWx0ID0gcmVzO1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5wYXlsb2FkLmFuc3dlciA9IGNsaWVudEFuc3dlcjtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZFJhdyhhY2tUb1NlbmRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQuc3VjY2VzcyA9IGZhbHNlO1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5yZWFzb24gPSBlLm1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRSYXcoYWNrVG9TZW5kZXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuY29ubmVjdGlvbk1hbmFnZXIuQ29ubmVjdGlvbk1hbmFnZXIgPSBDb25uZWN0aW9uTWFuYWdlcjtcbl9Db25uZWN0aW9uTWFuYWdlcl9tZXNzYWdlUmVjZWl2ZXIgPSBuZXcgV2Vha01hcCgpLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIgPSBuZXcgV2Vha01hcCgpO1xuXG4vKipcbiAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIGBDaGFubmVsYCBzdWJzZXQgb2YgdGhlIGBJbnRlckFwcGxpY2F0aW9uQnVzYCBBUEkgKGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsYCkuXG4gKlxuICogKiB7QGxpbmsgQ2hhbm5lbH0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBDaGFubmVsYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbGAuXG4gKiAqIHtAbGluayBPcGVuRmluLkNoYW5uZWxDbGllbnR9IGRlc2NyaWJlcyBhIGNsaWVudCBvZiBhIGNoYW5uZWwsIGUuZy4gYXMgcmV0dXJuZWQgYnkgYGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdGAuXG4gKiAqIHtAbGluayBPcGVuRmluLkNoYW5uZWxQcm92aWRlcn0gZGVzY3JpYmVzIGEgcHJvdmlkZXIgb2YgYSBjaGFubmVsLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZWAuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNiA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWwkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jaGFubmVsJDEuQ2hhbm5lbCA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmNvbnN0IGV2ZW50c18xJDUgPSByZXF1aXJlJCQwO1xuY29uc3QgbGF6eV8xJDEgPSBsYXp5O1xuY29uc3QgYmFzZV8xJGUgPSBiYXNlO1xuY29uc3QgY2xpZW50XzEgPSBjbGllbnQ7XG5jb25zdCBjb25uZWN0aW9uX21hbmFnZXJfMSA9IGNvbm5lY3Rpb25NYW5hZ2VyO1xuY29uc3QgcHJvdmlkZXJfMSA9IHByb3ZpZGVyO1xuZnVuY3Rpb24gcmV0cnlEZWxheShjb3VudCkge1xuICAgIGNvbnN0IGludGVydmFsID0gNTAwOyAvLyBiYXNlIGRlbGF5XG4gICAgY29uc3Qgc3RlcHMgPSAxMDsgLy8gSG93IG1hbnkgcmV0cmllcyB0byBkbyBiZWZvcmUgaW5jcmVtZW50aW5nIHRoZSBkZWxheVxuICAgIGNvbnN0IGJhc2UgPSAyOyAvLyBIb3cgbXVjaCB0byBtdWx0aXBseSB0aGUgcHJldmlvdXMgZGVsYXkgYnlcbiAgICBjb25zdCBtYXggPSAzMDAwMDsgLy8gbWF4IGRlbGF5XG4gICAgY29uc3Qgc3RlcCA9IE1hdGguZmxvb3IoY291bnQgLyBzdGVwcyk7XG4gICAgY29uc3QgZGVsYXkgPSBNYXRoLm1pbihtYXgsIGludGVydmFsICogYmFzZSAqKiBzdGVwKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfSwgZGVsYXkpO1xuICAgIH0pO1xufVxuLyoqXG4gKiBUaGUgQ2hhbm5lbCBBUEkgYWxsb3dzIGFuIE9wZW5GaW4gYXBwbGljYXRpb24gdG8gY3JlYXRlIGEgY2hhbm5lbCBhcyBhIHtAbGluayBDaGFubmVsUHJvdmlkZXIgQ2hhbm5lbFByb3ZpZGVyfSxcbiAqIG9yIGNvbm5lY3QgdG8gYSBjaGFubmVsIGFzIGEge0BsaW5rIENoYW5uZWxDbGllbnQgQ2hhbm5lbENsaWVudH0uXG4gKiBAcmVtYXJrcyBUaGUgXCJoYW5kc2hha2VcIiBiZXR3ZWVuIHRoZSBjb21tdW5pY2F0aW9uIHBhcnRuZXJzIGlzXG4gKiBzaW1wbGlmaWVkIHdoZW4gdXNpbmcgYSBjaGFubmVsLiAgQSByZXF1ZXN0IHRvIGNvbm5lY3QgdG8gYSBjaGFubmVsIGFzIGEgY2xpZW50IHdpbGwgcmV0dXJuIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGlmL3doZW4gdGhlIGNoYW5uZWwgaGFzIGJlZW4gY3JlYXRlZC4gQm90aCB0aGVcbiAqIHByb3ZpZGVyIGFuZCBjbGllbnQgY2FuIGRpc3BhdGNoIGFjdGlvbnMgdGhhdCBoYXZlIGJlZW4gcmVnaXN0ZXJlZCBvbiB0aGVpciBvcHBvc2l0ZXMsIGFuZCBkaXNwYXRjaCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYSBwYXlsb2FkIGZyb20gdGhlIG90aGVyXG4gKiBjb21tdW5pY2F0aW9uIHBhcnRpY2lwYW50LiBUaGVyZSBjYW4gYmUgb25seSBvbmUgcHJvdmlkZXIgcGVyIGNoYW5uZWwsIGJ1dCBtYW55IGNsaWVudHMuICBWZXJzaW9uIGA5LjYxLjM1LipgIG9yIGxhdGVyIGlzIHJlcXVpcmVkIGZvciBib3RoIGNvbW11bmljYXRpb24gcGFydG5lcnMuXG4gKlxuICogQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbC5jcmVhdGUgY3JlYXRlKGNoYW5uZWxOYW1lLCBvcHRpb25zKX1cbiAqICAqIHtAbGluayBDaGFubmVsLmNvbm5lY3QgY29ubmVjdChjaGFubmVsTmFtZSwgb3B0aW9ucyl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbC5vbkNoYW5uZWxDb25uZWN0IG9uQ2hhbm5lbENvbm5lY3QobGlzdGVuZXIpfVxuICogICoge0BsaW5rIENoYW5uZWwub25DaGFubmVsRGlzY29ubmVjdCBvbkNoYW5uZWxEaXNjb25uZWN0KGxpc3RlbmVyKX1cbiAqL1xuY2xhc3MgQ2hhbm5lbCBleHRlbmRzIGJhc2VfMSRlLkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlKSB7XG4gICAgICAgIHN1cGVyKHdpcmUsICdjaGFubmVsJyk7XG4gICAgICAgIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIuc2V0KHRoaXMsIG5ldyBldmVudHNfMSQ1LkV2ZW50RW1pdHRlcigpKTtcbiAgICAgICAgLy8gT3BlbkZpbiBBUEkgaGFzIG5vdCBiZWVuIGluamVjdGVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lLCAqbXVzdCogd2FpdCBmb3IgQVBJIHRvIGJlIHJlYWR5LlxuICAgICAgICBfQ2hhbm5lbF9yZWFkeVRvQ29ubmVjdC5zZXQodGhpcywgbmV3IGxhenlfMSQxLkFzeW5jUmV0cnlhYmxlTGF6eShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpcy5vbignZGlzY29ubmVjdGVkJywgKGV2ZW50UGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjbGllbnRfMS5DaGFubmVsQ2xpZW50LmhhbmRsZVByb3ZpZGVyRGlzY29ubmVjdChldmVudFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMub24oJ2Nvbm5lY3RlZCcsICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5lbWl0KCdjb25uZWN0ZWQnLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSkuY2F0Y2goKCkgPT4gbmV3IEVycm9yKCdlcnJvciBzZXR0aW5nIHVwIGNoYW5uZWwgY29ubmVjdGlvbiBsaXN0ZW5lcnMnKSk7XG4gICAgICAgIH0pKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ0KHRoaXMsIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLCBuZXcgY29ubmVjdGlvbl9tYW5hZ2VyXzEuQ29ubmVjdGlvbk1hbmFnZXIod2lyZSksIFwiZlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGxDaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWNoYW5uZWxzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3RlbnMgZm9yIGNoYW5uZWwgY29ubmVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXIgLSBjYWxsYmFjayB0byBleGVjdXRlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbGlzdGVuZXIgPSAoY2hhbm5lbFBheWxvYWQpID0+IGNvbnNvbGUubG9nKGNoYW5uZWxQYXlsb2FkKTsgLy8gc2VlIHJldHVybiB2YWx1ZSBiZWxvd1xuICAgICAqXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5vbkNoYW5uZWxDb25uZWN0KGxpc3RlbmVyKTtcbiAgICAgKlxuICAgICAqIC8vIGV4YW1wbGUgc2hhcGVcbiAgICAgKiB7XG4gICAgICogICAgIFwidG9waWNcIjogXCJjaGFubmVsXCIsXG4gICAgICogICAgIFwidHlwZVwiOiBcImNvbm5lY3RlZFwiLFxuICAgICAqICAgICBcInV1aWRcIjogXCJPcGVuZmluUE9DXCIsXG4gICAgICogICAgIFwibmFtZVwiOiBcIk9wZW5maW5QT0NcIixcbiAgICAgKiAgICAgXCJjaGFubmVsTmFtZVwiOiBcImNvdW50ZXJcIixcbiAgICAgKiAgICAgXCJjaGFubmVsSWRcIjogXCJPcGVuZmluUE9DL09wZW5maW5QT0MvY291bnRlclwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgb25DaGFubmVsQ29ubmVjdChsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKCdjb25uZWN0ZWQnLCBsaXN0ZW5lcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3RlbiBmb3IgY2hhbm5lbCBkaXNjb25uZWN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsaXN0ZW5lciAtIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsaXN0ZW5lciA9IChjaGFubmVsUGF5bG9hZCkgPT4gY29uc29sZS5sb2coY2hhbm5lbFBheWxvYWQpOyAvLyBzZWUgcmV0dXJuIHZhbHVlIGJlbG93XG4gICAgICpcbiAgICAgKiBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLm9uQ2hhbm5lbERpc2Nvbm5lY3QobGlzdGVuZXIpO1xuICAgICAqXG4gICAgICogLy8gZXhhbXBsZSBzaGFwZVxuICAgICAqIHtcbiAgICAgKiAgICAgXCJ0b3BpY1wiOiBcImNoYW5uZWxcIixcbiAgICAgKiAgICAgXCJ0eXBlXCI6IFwiZGlzY29ubmVjdGVkXCIsXG4gICAgICogICAgIFwidXVpZFwiOiBcIk9wZW5maW5QT0NcIixcbiAgICAgKiAgICAgXCJuYW1lXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICBcImNoYW5uZWxOYW1lXCI6IFwiY291bnRlclwiLFxuICAgICAqICAgICBcImNoYW5uZWxJZFwiOiBcIk9wZW5maW5QT0MvT3BlbmZpblBPQy9jb3VudGVyXCJcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBvbkNoYW5uZWxEaXNjb25uZWN0KGxpc3RlbmVyKSB7XG4gICAgICAgIGF3YWl0IHRoaXMub24oJ2Rpc2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICB9XG4gICAgYXN5bmMgc2FmZUNvbm5lY3QoY2hhbm5lbE5hbWUsIHNob3VsZFdhaXQsIGNvbm5lY3RQYXlsb2FkKSB7XG4gICAgICAgIGNvbnN0IHJldHJ5SW5mbyA9IHsgY291bnQ6IDAgfTtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCwgbm8tY29uc3RhbnQtY29uZGl0aW9uICovXG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIC8vIHNldHVwIGEgbGlzdGVuZXIgYW5kIGEgY29ubmVjdGVkIHByb21pc2UgdG8gYXdhaXQgaW4gY2FzZSB3ZSBjb25uZWN0IGJlZm9yZSB0aGUgY2hhbm5lbCBpcyByZWFkeVxuICAgICAgICAgICAgbGV0IGNvbm5lY3RlZExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGVkTGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbE5hbWUgPT09IHBheWxvYWQuY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5vbignY29ubmVjdGVkJywgY29ubmVjdGVkTGlzdGVuZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChyZXRyeUluZm8uY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdhaXQgYmVmb3JlIHJldHJ5aW5nXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGF5IHJldHVybnMgZmFsc2UgY29ubmVjdGVkUHJvbWlzZSByZXR1cm5zIHRydWUgc28gd2UgY2FuIGtub3cgaWYgYSByZXRyeSBpcyBkdWUgdG8gY29ubmVjdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHJldHJ5SW5mby5nb3RDb25uZWN0ZWRFdmVudCA9IGF3YWl0IFByb21pc2UucmFjZShbcmV0cnlEZWxheShyZXRyeUluZm8uY291bnQpLCBjb25uZWN0ZWRQcm9taXNlXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjb25uZWN0LXRvLWNoYW5uZWwnLCB7IC4uLmNvbm5lY3RQYXlsb2FkLCByZXRyeUluZm8gfSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvZyBvbmx5IGlmIHRoZXJlIHdhcyBhIHJldHJ5XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzZnVsbHkgY29ubmVjdGVkIHRvIGNoYW5uZWxOYW1lOiAke2NoYW5uZWxOYW1lfWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnBheWxvYWQuZGF0YTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gU2VuZCByZXRyeUluZm8gdG8gdGhlIGNvcmUgZm9yIGRlYnVnIGxvZyBpbmNsdXNpb25cbiAgICAgICAgICAgICAgICBjb25zdCBzZW50TWVzc2FnZVByb21pc2UgPSB0aGlzLndpcmUuc2VuZEFjdGlvbignY29ubmVjdC10by1jaGFubmVsJywgY29ubmVjdFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIC8vIFNhdmUgbWVzc2FnZUlkIGZyb20gdGhlIGZpcnN0IGNvbm5lY3Rpb24gYXR0ZW1wdFxuICAgICAgICAgICAgICAgIHJldHJ5SW5mby5vcmlnaW5hbE1lc3NhZ2VJZCA9IHNlbnRNZXNzYWdlUHJvbWlzZS5tZXNzYWdlSWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VudE1lc3NhZ2VQcm9taXNlO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucGF5bG9hZC5kYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdpbnRlcm5hbC1uYWNrJykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90IGFuIGludGVybmFsIG5hY2ssIGJyZWFrIHRoZSBsb29wXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkV2FpdCAmJiByZXRyeUluZm8uY291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgd2FpdGluZyBvbiB0aGUgbmV4dCBpdGVyYXRpb24sIHdhcm4gdGhlIHVzZXJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBObyBjaGFubmVsIGZvdW5kIGZvciBjaGFubmVsTmFtZTogJHtjaGFubmVsTmFtZX0uIFdhaXRpbmcgZm9yIGNvbm5lY3Rpb24uLi5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICByZXRyeUluZm8uY291bnQgKz0gMTtcbiAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIG9mIG90aGVyIGVycm9ycywgcmVtb3ZlIG91ciBsaXN0ZW5lclxuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5yZW1vdmVMaXN0ZW5lcignY29ubmVjdGVkJywgY29ubmVjdGVkTGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IHdoaWxlIChzaG91bGRXYWl0KTsgLy8gSWYgd2UncmUgd2FpdGluZyB3ZSByZXRyeSB0aGUgYWJvdmUgbG9vcFxuICAgICAgICAvLyBTaG91bGQgd2FpdCB3YXMgZmFsc2UsIG5vIGNoYW5uZWwgd2FzIGZvdW5kLlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGNoYW5uZWwgZm91bmQgZm9yIGNoYW5uZWxOYW1lOiAke2NoYW5uZWxOYW1lfS5gKTtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1hd2FpdC1pbi1sb29wLCBuby1jb25zdGFudC1jb25kaXRpb24gKi9cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0byBhIGNoYW5uZWwuIElmIHlvdSB3aXNoIHRvIHNlbmQgYSBwYXlsb2FkIHRvIHRoZSBwcm92aWRlciwgYWRkIGEgcGF5bG9hZCBwcm9wZXJ0eSB0byB0aGUgb3B0aW9ucyBhcmd1bWVudC5cbiAgICAgKiBFWFBFUklNRU5UQUw6IHBhc3MgeyBwcm90b2NvbHM6IFsncnRjJ10gfSBhcyBvcHRpb25zIHRvIG9wdC1pbiB0byBIaWdoIFRocm91Z2hwdXQgQ2hhbm5lbHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hhbm5lbE5hbWUgLSBOYW1lIG9mIHRoZSB0YXJnZXQgY2hhbm5lbC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIENvbm5lY3Rpb24gb3B0aW9ucy5cbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENoYW5uZWxDbGllbnQgQ2hhbm5lbENsaWVudH0uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgY29ubmVjdGlvbiByZXF1ZXN0IHdpbGwgYmUgcm91dGVkIHRvIHRoZSBjaGFubmVsUHJvdmlkZXIgaWYvd2hlbiB0aGUgY2hhbm5lbCBpcyBjcmVhdGVkLiAgSWYgdGhlIGNvbm5lY3RcbiAgICAgKiByZXF1ZXN0IGlzIHNlbnQgcHJpb3IgdG8gY3JlYXRpb24sIHRoZSBwcm9taXNlIHdpbGwgbm90IHJlc29sdmUgb3IgcmVqZWN0IHVudGlsIHRoZSBjaGFubmVsIGlzIGNyZWF0ZWQgYnkgYSBjaGFubmVsUHJvdmlkZXJcbiAgICAgKiAod2hldGhlciBvciBub3QgdG8gd2FpdCBmb3IgY3JlYXRpb24gaXMgY29uZmlndXJhYmxlIGluIHRoZSBjb25uZWN0T3B0aW9ucykuXG4gICAgICpcbiAgICAgKiBUaGUgY29ubmVjdCBjYWxsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdpdGggYSBjaGFubmVsQ2xpZW50IGJ1cyBpZiBhY2NlcHRlZCBieSB0aGUgY2hhbm5lbFByb3ZpZGVyLCBvciByZWplY3QgaWZcbiAgICAgKiB0aGUgY2hhbm5lbFByb3ZpZGVyIHRocm93cyBhbiBlcnJvciB0byByZWplY3QgdGhlIGNvbm5lY3Rpb24uIFRoaXMgYnVzIGNhbiBjb21tdW5pY2F0ZSB3aXRoIHRoZSBQcm92aWRlciwgYnV0IG5vdCB0byBvdGhlclxuICAgICAqIGNsaWVudHMgb24gdGhlIGNoYW5uZWwuIFVzaW5nIHRoZSBidXMsIHRoZSBjaGFubmVsQ2xpZW50IGNhbiByZWdpc3RlciBhY3Rpb25zIGFuZCBtaWRkbGV3YXJlLiBDaGFubmVsIGxpZmVjeWNsZSBjYW4gYWxzbyBiZVxuICAgICAqIGhhbmRsZWQgd2l0aCBhbiBvbkRpc2Nvbm5lY3Rpb24gbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBtYWtlQ2xpZW50KGNoYW5uZWxOYW1lKSB7XG4gICAgICogICAgLy8gQSBwYXlsb2FkIGNhbiBiZSBzZW50IGFsb25nIHdpdGggY2hhbm5lbCBjb25uZWN0aW9uIHJlcXVlc3RzIHRvIGhlbHAgd2l0aCBhdXRoZW50aWNhdGlvblxuICAgICAqICAgIGNvbnN0IGNvbm5lY3RQYXlsb2FkID0geyBwYXlsb2FkOiAndG9rZW4nIH07XG4gICAgICpcbiAgICAgKiAgICAvLyBJZiB0aGUgY2hhbm5lbCBoYXMgYmVlbiBjcmVhdGVkIHRoaXMgcmVxdWVzdCB3aWxsIGJlIHNlbnQgdG8gdGhlIHByb3ZpZGVyLiAgSWYgbm90LCB0aGVcbiAgICAgKiAgICAvLyBwcm9taXNlIHdpbGwgbm90IGJlIHJlc29sdmVkIG9yIHJlamVjdGVkIHVudGlsIHRoZSBjaGFubmVsIGhhcyBiZWVuIGNyZWF0ZWQuXG4gICAgICogICAgY29uc3QgY2xpZW50QnVzID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxOYW1lLCBjb25uZWN0UGF5bG9hZCk7XG4gICAgICpcbiAgICAgKiAgICBjbGllbnRCdXMub25EaXNjb25uZWN0aW9uKGNoYW5uZWxJbmZvID0+IHtcbiAgICAgKiAgICAgICAgLy8gaGFuZGxlIHRoZSBjaGFubmVsIGxpZmVjeWNsZSBoZXJlIC0gd2UgY2FuIGNvbm5lY3QgYWdhaW4gd2hpY2ggd2lsbCByZXR1cm4gYSBwcm9taXNlXG4gICAgICogICAgICAgIC8vIHRoYXQgd2lsbCByZXNvbHZlIGlmL3doZW4gdGhlIGNoYW5uZWwgaXMgcmUtY3JlYXRlZC5cbiAgICAgKiAgICAgICAgbWFrZUNsaWVudChjaGFubmVsSW5mby5jaGFubmVsTmFtZSk7XG4gICAgICogICAgfSlcbiAgICAgKlxuICAgICAqICAgIGNsaWVudEJ1cy5yZWdpc3RlcigndG9waWMnLCAocGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgLy8gcmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgYSB0b3BpYyB0byB3aGljaCB0aGUgY2hhbm5lbCBwcm92aWRlciBjYW4gZGlzcGF0Y2ggYW4gYWN0aW9uXG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdBY3Rpb24gZGlzcGF0Y2hlZCBieSBwcm92aWRlcjogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgZWNobzogcGF5bG9hZFxuICAgICAqICAgICAgICB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIG1ha2VDbGllbnQoJ2NoYW5uZWxOYW1lJylcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ29ubmVjdGVkJykpXG4gICAgICogLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGNvbm5lY3QoY2hhbm5lbE5hbWUsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgY29ubmVjdCBiZWZvcmUgbGlzdGVuZXJzIGFyZSBzZXQgdXBcbiAgICAgICAgLy8gVGhpcyBhbHNvIGVycm9ycyBpZiB3ZSdyZSBub3QgaW4gT3BlbkZpbiwgZW5zdXJpbmcgd2UgZG9uJ3QgcnVuIHVubmVjZXNzYXJ5IGNvZGVcbiAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ2KHRoaXMsIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0LCBcImZcIikuZ2V0VmFsdWUoKTtcbiAgICAgICAgaWYgKCFjaGFubmVsTmFtZSB8fCB0eXBlb2YgY2hhbm5lbE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgY2hhbm5lbE5hbWUgc3RyaW5nIHRvIGNvbm5lY3QgdG8gYSBjaGFubmVsLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdHMgPSB7IHdhaXQ6IHRydWUsIC4uLnRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXREZWZhdWx0Q2hhbm5lbE9wdGlvbnMoKS5jb25uZWN0LCAuLi5vcHRpb25zIH07XG4gICAgICAgIGNvbnN0IHsgb2ZmZXIsIHJ0YzogcnRjUGFja2V0IH0gPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDYodGhpcywgX0NoYW5uZWxfY29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5jcmVhdGVDbGllbnRPZmZlcihvcHRzKTtcbiAgICAgICAgbGV0IGNvbm5lY3Rpb25Vcmw7XG4gICAgICAgIGlmICh0aGlzLmZpbi5tZS5pc0ZyYW1lIHx8IHRoaXMuZmluLm1lLmlzVmlldyB8fCB0aGlzLmZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgICAgY29ubmVjdGlvblVybCA9IChhd2FpdCB0aGlzLmZpbi5tZS5nZXRJbmZvKCkpLnVybDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb25uZWN0UGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgICAgLi4ub3B0cyxcbiAgICAgICAgICAgIG9mZmVyLFxuICAgICAgICAgICAgY29ubmVjdGlvblVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByb3V0aW5nSW5mbyA9IGF3YWl0IHRoaXMuc2FmZUNvbm5lY3QoY2hhbm5lbE5hbWUsIG9wdHMud2FpdCwgY29ubmVjdFBheWxvYWQpO1xuICAgICAgICBjb25zdCBzdHJhdGVneSA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLmNyZWF0ZUNsaWVudFN0cmF0ZWd5KHJ0Y1BhY2tldCwgcm91dGluZ0luZm8pO1xuICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IGNsaWVudF8xLkNoYW5uZWxDbGllbnQocm91dGluZ0luZm8sICgpID0+IGNsaWVudF8xLkNoYW5uZWxDbGllbnQud2lyZUNsb3NlKHRoaXMud2lyZSwgcm91dGluZ0luZm8sIHJvdXRpbmdJbmZvLmVuZHBvaW50SWQpLCBzdHJhdGVneSk7XG4gICAgICAgIC8vIEl0IGlzIHRoZSBjbGllbnQncyByZXNwb25zaWJpbGl0eSB0byBoYW5kbGUgZW5kcG9pbnQgZGlzY29ubmVjdGlvbiB0byB0aGUgcHJvdmlkZXIuXG4gICAgICAgIC8vIElmIHRoZSBlbmRwb2ludCBkaWVzLCB0aGUgY2xpZW50IHdpbGwgZm9yY2UgYSBkaXNjb25uZWN0aW9uIHRocm91Z2ggdGhlIGNvcmUuXG4gICAgICAgIC8vIFRoZSBwcm92aWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IGVuZHBvaW50IGRpc2Nvbm5lY3Rpb24uXG4gICAgICAgIHN0cmF0ZWd5Lm9uRW5kcG9pbnREaXNjb25uZWN0KHJvdXRpbmdJbmZvLmNoYW5uZWxJZCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjaGFubmVsLnNlbmREaXNjb25uZWN0QWN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFNvbWV0aGluZyB3ZW50IHdyb25nIGR1cmluZyBkaXNjb25uZWN0IGZvciBjbGllbnQgd2l0aCB1dWlkOiAke3JvdXRpbmdJbmZvLnV1aWR9IC8gbmFtZTogJHtyb3V0aW5nSW5mby5uYW1lfSAvIGVuZHBvaW50SWQ6ICR7cm91dGluZ0luZm8uZW5kcG9pbnRJZH0uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBjbGllbnRfMS5DaGFubmVsQ2xpZW50LmhhbmRsZVByb3ZpZGVyRGlzY29ubmVjdChyb3V0aW5nSW5mbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hhbm5lbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGNoYW5uZWwuXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBhIHVuaXF1ZSBjaGFubmVsTmFtZS4gSWYgYSBjaGFubmVsTmFtZSBpcyBub3QgcHJvdmlkZWQsIG9yIGl0IGlzIG5vdCB1bmlxdWUsIHRoZSBjcmVhdGlvbiB3aWxsIGZhaWwuXG4gICAgICogRVhQRVJJTUVOVEFMOiBwYXNzIHsgcHJvdG9jb2xzOiBbJ3J0YyddIH0gYXMgb3B0aW9ucyB0byBvcHQtaW4gdG8gSGlnaCBUaHJvdWdocHV0IENoYW5uZWxzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoYW5uZWxOYW1lIC0gTmFtZSBvZiB0aGUgY2hhbm5lbCB0byBiZSBjcmVhdGVkLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gQ3JlYXRpb24gb3B0aW9ucy5cbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENoYW5uZWxQcm92aWRlciBDaGFubmVsUHJvdmlkZXJ9LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgc3VjY2Vzc2Z1bCwgdGhlIGNyZWF0ZSBtZXRob2QgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBpbnN0YW5jZSBvZiB0aGUgY2hhbm5lbFByb3ZpZGVyIGJ1cy4gVGhlIGNhbGxlclxuICAgICAqIHRoZW4gYmVjb21lcyB0aGUg4oCcY2hhbm5lbCBwcm92aWRlcuKAnSBhbmQgY2FuIHVzZSB0aGUgY2hhbm5lbFByb3ZpZGVyIGJ1cyB0byByZWdpc3RlciBhY3Rpb25zIGFuZCBtaWRkbGV3YXJlLlxuICAgICAqXG4gICAgICogVGhlIGNhbGxlciBjYW4gYWxzbyBzZXQgYW4gb25Db25uZWN0aW9uIGFuZC9vciBvbkRpc2Nvbm5lY3Rpb24gbGlzdGVuZXIgdGhhdCB3aWxsIGV4ZWN1dGUgb24gYW55IG5ldyBjaGFubmVsXG4gICAgICogY29ubmVjdGlvbi9kaXNjb25uZWN0aW9uIGF0dGVtcHQgZnJvbSBhIGNoYW5uZWwgY2xpZW50LiBUbyByZWplY3QgYSBjb25uZWN0aW9uLCBzaW1wbHkgdGhyb3cgYW4gZXJyb3IgaW4gdGhlXG4gICAgICogb25Db25uZWN0aW9uIGxpc3RlbmVyLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gYWNjZXB0IGFsbCBuZXcgY29ubmVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBBIG1hcCBvZiBjbGllbnQgY29ubmVjdGlvbnMgaXMgdXBkYXRlZCBhdXRvbWF0aWNhbGx5IG9uIGNsaWVudCBjb25uZWN0aW9uIGFuZCBkaXNjb25uZWN0aW9uIGFuZCBzYXZlZCBpbiB0aGVcbiAgICAgKiBbcmVhZC1vbmx5XSBgY29ubmVjdGlvbnNgIHByb3BlcnR5IG9uIHRoZSBjaGFubmVsUHJvdmlkZXIgYnVzLiAgVGhlIGNoYW5uZWwgd2lsbCBleGlzdCB1bnRpbCB0aGUgcHJvdmlkZXJcbiAgICAgKiBkZXN0cm95cyBpdCBvciBkaXNjb25uZWN0cyBieSBjbG9zaW5nIG9yIGRlc3Ryb3lpbmcgdGhlIGNvbnRleHQgKG5hdmlnYXRpbmcgb3IgcmVsb2FkaW5nKS4gVG8gc2V0dXAgYSBjaGFubmVsXG4gICAgICogYXMgYSBjaGFubmVsUHJvdmlkZXIsIGNhbGwgYENoYW5uZWwuY3JlYXRlYCB3aXRoIGEgdW5pcXVlIGNoYW5uZWwgbmFtZS4gQSBtYXAgb2YgY2xpZW50IGNvbm5lY3Rpb25zIGlzIHVwZGF0ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5IG9uIGNsaWVudCBjb25uZWN0aW9uIGFuZCBkaXNjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgIC8vIGVudGl0eSBjcmVhdGVzIGEgY2hhbm5lbCBhbmQgYmVjb21lcyB0aGUgY2hhbm5lbFByb3ZpZGVyXG4gICAgICogICAgY29uc3QgcHJvdmlkZXJCdXMgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgIHByb3ZpZGVyQnVzLm9uQ29ubmVjdGlvbigoaWRlbnRpdHksIHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgLy8gY2FuIHJlamVjdCBhIGNvbm5lY3Rpb24gaGVyZSBieSB0aHJvd2luZyBhbiBlcnJvclxuICAgICAqICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGNvbm5lY3Rpb24gcmVxdWVzdCBpZGVudGl0eTogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ0NsaWVudCBjb25uZWN0aW9uIHJlcXVlc3QgcGF5bG9hZDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgIH0pO1xuICAgICAqXG4gICAgICogICAgcHJvdmlkZXJCdXMucmVnaXN0ZXIoJ3RvcGljJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgIC8vIHJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIGEgJ3RvcGljJyB0byB3aGljaCBjbGllbnRzIGNhbiBkaXNwYXRjaCBhbiBhY3Rpb25cbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ0FjdGlvbiBkaXNwYXRjaGVkIGJ5IGNsaWVudDogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgZWNobzogcGF5bG9hZFxuICAgICAqICAgICAgICB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlKGNoYW5uZWxOYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgYSBjaGFubmVsTmFtZSB0byBjcmVhdGUgYSBjaGFubmVsJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGE6IHByb3ZpZGVySWRlbnRpdHkgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NyZWF0ZS1jaGFubmVsJywgeyBjaGFubmVsTmFtZSB9KTtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLmNyZWF0ZVByb3ZpZGVyKG9wdGlvbnMsIHByb3ZpZGVySWRlbnRpdHkpO1xuICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICB0aGlzLm9uKCdjbGllbnQtZGlzY29ubmVjdGVkJywgKGV2ZW50UGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50UGF5bG9hZC5jaGFubmVsTmFtZSA9PT0gY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICBwcm92aWRlcl8xLkNoYW5uZWxQcm92aWRlci5oYW5kbGVDbGllbnREaXNjb25uZWN0aW9uKGNoYW5uZWwsIGV2ZW50UGF5bG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hhbm5lbDtcbiAgICB9XG59XG5jaGFubmVsJDEuQ2hhbm5lbCA9IENoYW5uZWw7XG5fQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsX2ludGVybmFsRW1pdHRlciA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0ID0gbmV3IFdlYWtNYXAoKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGludGVyYXBwYnVzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmludGVyYXBwYnVzLkludGVyQXBwUGF5bG9hZCA9IGludGVyYXBwYnVzLkludGVyQXBwbGljYXRpb25CdXMgPSB2b2lkIDA7XG4vKipcbiAqIEVudHJ5IHBvaW50IGZvciB0aGUgT3BlbkZpbiBgSW50ZXJBcHBsaWNhdGlvbkJ1c2AgQVBJIChgZmluLkludGVyQXBwbGljYXRpb25CdXNgKS5cbiAqXG4gKiAqIHtAbGluayBJbnRlckFwcGxpY2F0aW9uQnVzfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEludGVyQXBwbGljYXRpb25CdXNgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1c2AuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbmNvbnN0IGV2ZW50c18xJDQgPSByZXF1aXJlJCQwO1xuY29uc3QgYmFzZV8xJGQgPSBiYXNlO1xuY29uc3QgcmVmX2NvdW50ZXJfMSA9IHJlZkNvdW50ZXI7XG5jb25zdCBpbmRleF8xJDIgPSBjaGFubmVsJDE7XG5jb25zdCB2YWxpZGF0ZV8xJDMgPSB2YWxpZGF0ZTtcbi8qKlxuICogQSBtZXNzYWdpbmcgYnVzIHRoYXQgYWxsb3dzIGZvciBwdWIvc3ViIG1lc3NhZ2luZyBiZXR3ZWVuIGRpZmZlcmVudCBhcHBsaWNhdGlvbnMuXG4gKlxuICovXG5jbGFzcyBJbnRlckFwcGxpY2F0aW9uQnVzIGV4dGVuZHMgYmFzZV8xJGQuQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgdGhpcy5ldmVudHMgPSB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyQWRkZWQ6ICdzdWJzY3JpYmVyLWFkZGVkJyxcbiAgICAgICAgICAgIHN1YnNjcmliZXJSZW1vdmVkOiAnc3Vic2NyaWJlci1yZW1vdmVkJ1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJlZkNvdW50ZXIgPSBuZXcgcmVmX2NvdW50ZXJfMS5SZWZDb3VudGVyKCk7XG4gICAgICAgIHRoaXMuQ2hhbm5lbCA9IG5ldyBpbmRleF8xJDIuQ2hhbm5lbCh3aXJlKTtcbiAgICAgICAgdGhpcy5lbWl0dGVyID0gbmV3IGV2ZW50c18xJDQuRXZlbnRFbWl0dGVyKCk7XG4gICAgICAgIHdpcmUucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcih0aGlzLm9ubWVzc2FnZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5vbiA9IHRoaXMuZW1pdHRlci5vbi5iaW5kKHRoaXMuZW1pdHRlcik7XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzID0gdGhpcy5lbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycy5iaW5kKHRoaXMuZW1pdHRlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyBhIG1lc3NhZ2UgdG8gYWxsIGFwcGxpY2F0aW9ucyBydW5uaW5nIG9uIE9wZW5GaW4gUnVudGltZSB0aGF0XG4gICAgICogYXJlIHN1YnNjcmliZWQgdG8gdGhlIHNwZWNpZmllZCB0b3BpYy5cbiAgICAgKiBAcGFyYW0gdG9waWMgVGhlIHRvcGljIG9uIHdoaWNoIHRoZSBtZXNzYWdlIGlzIHNlbnRcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBiZSBwdWJsaXNoZWQuIENhbiBiZSBlaXRoZXIgYSBwcmltaXRpdmVcbiAgICAgKiBkYXRhIHR5cGUgKHN0cmluZywgbnVtYmVyLCBvciBib29sZWFuKSBvciBjb21wb3NpdGUgZGF0YSB0eXBlIChvYmplY3QsIGFycmF5KVxuICAgICAqIHRoYXQgaXMgY29tcG9zZWQgb2Ygb3RoZXIgcHJpbWl0aXZlIG9yIGNvbXBvc2l0ZSBkYXRhIHR5cGVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMucHVibGlzaCgndG9waWMnLCAnaGVsbG8nKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQdWJsaXNoZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHB1Ymxpc2godG9waWMsIG1lc3NhZ2UpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3B1Ymxpc2gtbWVzc2FnZScsIHtcbiAgICAgICAgICAgIHRvcGljLFxuICAgICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWU6IHRoaXMubWUubmFtZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBtZXNzYWdlIHRvIGEgc3BlY2lmaWMgYXBwbGljYXRpb24gb24gYSBzcGVjaWZpYyB0b3BpYy5cbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGlkZW50aXR5IG9mIHRoZSBhcHBsaWNhdGlvbiB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIHRvcGljIFRoZSB0b3BpYyBvbiB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gYmUgc2VudC4gQ2FuIGJlIGVpdGhlciBhIHByaW1pdGl2ZSBkYXRhXG4gICAgICogdHlwZSAoc3RyaW5nLCBudW1iZXIsIG9yIGJvb2xlYW4pIG9yIGNvbXBvc2l0ZSBkYXRhIHR5cGUgKG9iamVjdCwgYXJyYXkpIHRoYXRcbiAgICAgKiBpcyBjb21wb3NlZCBvZiBvdGhlciBwcmltaXRpdmUgb3IgY29tcG9zaXRlIGRhdGEgdHlwZXNcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5zZW5kKGZpbi5tZSwgJ3RvcGljJywgJ0hlbGxvIHRoZXJlIScpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01lc3NhZ2Ugc2VudCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgc2VuZChkZXN0aW5hdGlvbiwgdG9waWMsIG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMSQzLnZhbGlkYXRlSWRlbnRpdHkpKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZW5kLW1lc3NhZ2UnLCB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvblV1aWQ6IGRlc3RpbmF0aW9uLnV1aWQsXG4gICAgICAgICAgICBkZXN0aW5hdGlvbldpbmRvd05hbWU6IGRlc3RpbmF0aW9uLm5hbWUsXG4gICAgICAgICAgICB0b3BpYyxcbiAgICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICBzb3VyY2VXaW5kb3dOYW1lOiB0aGlzLm1lLm5hbWVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gbWVzc2FnZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGFwcGxpY2F0aW9uIG9uIHRoZSBzcGVjaWZpZWQgdG9waWMuXG4gICAgICogQHBhcmFtIHNvdXJjZSBUaGlzIG9iamVjdCBpcyBkZXNjcmliZWQgaW4gdGhlIElkZW50aXR5IGluIHRoZSB0eXBlZGVmXG4gICAgICogQHBhcmFtIHRvcGljIFRoZSB0b3BpYyBvbiB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIGxpc3RlbmVyIEEgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiBhIG1lc3NhZ2UgaGFzXG4gICAgICogYmVlbiByZWNlaXZlZC4gSXQgaXMgcGFzc2VkIHRoZSBtZXNzYWdlLCB1dWlkIGFuZCBuYW1lIG9mIHRoZSBzZW5kaW5nIGFwcGxpY2F0aW9uLlxuICAgICAqIFRoZSBtZXNzYWdlIGNhbiBiZSBlaXRoZXIgYSBwcmltaXRpdmUgZGF0YSB0eXBlIChzdHJpbmcsIG51bWJlciwgb3IgYm9vbGVhbikgb3JcbiAgICAgKiBjb21wb3NpdGUgZGF0YSB0eXBlIChvYmplY3QsIGFycmF5KSB0aGF0IGlzIGNvbXBvc2VkIG9mIG90aGVyIHByaW1pdGl2ZSBvciBjb21wb3NpdGVcbiAgICAgKiBkYXRhIHR5cGVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogLy8gc3Vic2NyaWJlIHRvIGEgc3BlY2lmaWVkIGFwcGxpY2F0aW9uXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMuc3Vic2NyaWJlKGZpbi5tZSwgJ3RvcGljJywgc3ViX21zZyA9PiBjb25zb2xlLmxvZyhzdWJfbXNnKSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3Vic2NyaWJlZCB0byB0aGUgc3BlY2lmaWVkIGFwcGxpY2F0aW9uJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIC8vIHN1YnNjcmliZSB0byB3aWxkY2FyZFxuICAgICAqIGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLnN1YnNjcmliZSh7IHV1aWQ6ICcqJyB9LCAndG9waWMnLCBzdWJfbXNnID0+IGNvbnNvbGUubG9nKHN1Yl9tc2cpKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTdWJzY3JpYmVkIHRvIConKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHN1YnNjcmliZShzb3VyY2UsIHRvcGljLCBsaXN0ZW5lcikge1xuICAgICAgICBjb25zdCBzdWJLZXkgPSB0aGlzLmNyZWF0ZVN1YnNjcmlwdGlvbktleShzb3VyY2UudXVpZCwgc291cmNlLm5hbWUgfHwgJyonLCB0b3BpYyk7XG4gICAgICAgIGNvbnN0IHNlbmRTdWJzY3JpcHRpb24gPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3Vic2NyaWJlJywge1xuICAgICAgICAgICAgICAgIHNvdXJjZVV1aWQ6IHNvdXJjZS51dWlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWU6IHNvdXJjZS5uYW1lIHx8ICcqJyxcbiAgICAgICAgICAgICAgICB0b3BpYyxcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbldpbmRvd05hbWU6IHRoaXMubWUubmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFscmVhZHlTdWJzY3JpYmVkID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmVtaXR0ZXIub24oc3ViS2V5LCBsaXN0ZW5lcik7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZkNvdW50ZXIuYWN0T25GaXJzdChzdWJLZXksIHNlbmRTdWJzY3JpcHRpb24sIGFscmVhZHlTdWJzY3JpYmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIHRvIG1lc3NhZ2VzIGZyb20gdGhlIHNwZWNpZmllZCBhcHBsaWNhdGlvbiBvbiB0aGUgc3BlY2lmaWVkIHRvcGljLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgeW91IGFyZSBsaXN0ZW5pbmcgdG8gYWxsIGFwcHMgb24gYSB0b3BpYywgKGkuZSB5b3UgcGFzc2VkIGB7IHV1aWQ6JyonIH1gIHRvIHRoZSBzdWJzY3JpYmUgZnVuY3Rpb24pXG4gICAgICogdGhlbiB5b3UgbmVlZCB0byBwYXNzIGB7IHV1aWQ6JyonIH1gIHRvIHVuc3Vic2NyaWJlIGFzIHdlbGwuIElmIHlvdSBhcmUgbGlzdGVuaW5nIHRvIGEgc3BlY2lmaWMgYXBwbGljYXRpb24sXG4gICAgICogKGkuZSB5b3UgcGFzc2VkIGB7IHV1aWQ6J3NvbWVfYXBwJyB9YCB0byB0aGUgc3Vic2NyaWJlIGZ1bmN0aW9uKSB0aGVuIHlvdSBuZWVkIHRvIHByb3ZpZGUgdGhlIHNhbWUgaWRlbnRpZmllciB0b1xuICAgICAqIHVuc3Vic2NyaWJlLCB1bnN1YnNjcmliaW5nIHRvIGAqYCBvbiB0aGF0IHNhbWUgdG9waWMgd2lsbCBub3QgdW5ob29rIHlvdXIgaW5pdGlhbCBsaXN0ZW5lciBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc291cmNlIFRoaXMgb2JqZWN0IGlzIGRlc2NyaWJlZCBpbiB0aGUgSWRlbnRpdHkgaW4gdGhlIHR5cGVkZWZcbiAgICAgKiBAcGFyYW0gdG9waWMgVGhlIHRvcGljIG9uIHdoaWNoIHRoZSBtZXNzYWdlIGlzIHNlbnRcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXIgQSBjYWxsYmFjayBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBzdWJzY3JpYmUoKVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGxpc3RlbmVyID0gY29uc29sZS5sb2c7XG4gICAgICpcbiAgICAgKiAvLyBJZiBhbnkgYXBwbGljYXRpb24gcHVibGlzaGVzIGEgbWVzc2FnZSBvbiB0b3BpYyBgZm9vYCwgb3VyIGxpc3RlbmVyIHdpbGwgYmUgY2FsbGVkLlxuICAgICAqIGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLnN1YnNjcmliZSh7IHV1aWQ6JyonIH0sICdmb28nLCBsaXN0ZW5lcilcbiAgICAgKlxuICAgICAqIC8vIFdoZW4geW91IHdhbnQgdG8gdW5zdWJzY3JpYmUsIHlvdSBuZWVkIHRvIHNwZWNpZnkgdGhlIHV1aWQgb2YgdGhlIGFwcCB5b3UnZCBsaWtlIHRvXG4gICAgICogLy8gdW5zdWJzY3JpYmUgZnJvbSAob3IgYCpgKSBhbmQgcHJvdmlkZSB0aGUgc2FtZSBmdW5jdGlvbiB5b3UgZ2F2ZSB0aGUgc3Vic2NyaWJlIGZ1bmN0aW9uXG4gICAgICogYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMudW5zdWJzY3JpYmUoeyB1dWlkOicqJyB9LCAnZm9vJywgbGlzdGVuZXIpXG4gICAgICogYGBgXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmUoc291cmNlLCB0b3BpYywgbGlzdGVuZXIpIHtcbiAgICAgICAgY29uc3Qgc291cmNlV2luZG93TmFtZSA9IHNvdXJjZS5uYW1lIHx8ICcqJztcbiAgICAgICAgY29uc3Qgc3ViS2V5ID0gdGhpcy5jcmVhdGVTdWJzY3JpcHRpb25LZXkoc291cmNlLnV1aWQsIHNvdXJjZVdpbmRvd05hbWUsIHRvcGljKTtcbiAgICAgICAgY29uc3Qgc2VuZFVuc3Vic2NyaXB0aW9uID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Vuc3Vic2NyaWJlJywge1xuICAgICAgICAgICAgICAgIHNvdXJjZVV1aWQ6IHNvdXJjZS51dWlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWUsXG4gICAgICAgICAgICAgICAgdG9waWMsXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25XaW5kb3dOYW1lOiB0aGlzLm1lLm5hbWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBkb250U2VuZFVuc3Vic2NyaXB0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyKSA9PiByKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihzdWJLZXksIGxpc3RlbmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVmQ291bnRlci5hY3RPbkxhc3Qoc3ViS2V5LCBzZW5kVW5zdWJzY3JpcHRpb24sIGRvbnRTZW5kVW5zdWJzY3JpcHRpb24pO1xuICAgIH1cbiAgICBwcm9jZXNzTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBtZXNzYWdlOiBwYXlsb2FkTWVzc2FnZSwgc291cmNlV2luZG93TmFtZSwgc291cmNlVXVpZCwgdG9waWMgfSB9ID0gbWVzc2FnZTtcbiAgICAgICAgY29uc3Qga2V5cyA9IFtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHNvdXJjZVV1aWQsIHNvdXJjZVdpbmRvd05hbWUsIHRvcGljKSxcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHNvdXJjZVV1aWQsICcqJywgdG9waWMpLFxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdWJzY3JpcHRpb25LZXkoJyonLCAnKicsIHRvcGljKVxuICAgICAgICBdO1xuICAgICAgICBjb25zdCBpZE9mU2VuZGVyID0geyB1dWlkOiBzb3VyY2VVdWlkLCBuYW1lOiBzb3VyY2VXaW5kb3dOYW1lIH07XG4gICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIuZW1pdChrZXksIHBheWxvYWRNZXNzYWdlLCBpZE9mU2VuZGVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtaXRTdWJzY3JpdmVyRXZlbnQodHlwZSwgbWVzc2FnZSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgdGFyZ2V0TmFtZTogbmFtZSwgdXVpZCwgdG9waWMgfSB9ID0gbWVzc2FnZTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHsgbmFtZSwgdXVpZCwgdG9waWMgfTtcbiAgICAgICAgdGhpcy5lbWl0dGVyLmVtaXQodHlwZSwgcGF5bG9hZCk7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG4gICAgY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHV1aWQsIG5hbWUsIHRvcGljKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuYW1lIHx8ICcqJztcbiAgICAgICAgaWYgKCEodXVpZCAmJiBuICYmIHRvcGljKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHV1aWQsIG5hbWUsIG9yIHRvcGljIHN0cmluZycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjcmVhdGVLZXkodXVpZCwgbiwgdG9waWMpO1xuICAgIH1cbiAgICBvbm1lc3NhZ2UobWVzc2FnZSkge1xuICAgICAgICBjb25zdCB7IGFjdGlvbiB9ID0gbWVzc2FnZTtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24pIHtcbiAgICAgICAgICAgIGNhc2UgJ3Byb2Nlc3MtbWVzc2FnZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzTWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgdGhpcy5ldmVudHMuc3Vic2NyaWJlckFkZGVkOlxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdFN1YnNjcml2ZXJFdmVudCh0aGlzLmV2ZW50cy5zdWJzY3JpYmVyQWRkZWQsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0aGlzLmV2ZW50cy5zdWJzY3JpYmVyUmVtb3ZlZDpcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRTdWJzY3JpdmVyRXZlbnQodGhpcy5ldmVudHMuc3Vic2NyaWJlclJlbW92ZWQsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmludGVyYXBwYnVzLkludGVyQXBwbGljYXRpb25CdXMgPSBJbnRlckFwcGxpY2F0aW9uQnVzO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgSW50ZXJBcHBQYXlsb2FkIHtcbn1cbmludGVyYXBwYnVzLkludGVyQXBwUGF5bG9hZCA9IEludGVyQXBwUGF5bG9hZDtcbmZ1bmN0aW9uIGNyZWF0ZUtleSguLi50b0hhc2gpIHtcbiAgICByZXR1cm4gdG9IYXNoXG4gICAgICAgIC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGAke2l0ZW19YCkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIH0pXG4gICAgICAgIC5qb2luKCcvJyk7XG59XG5cbnZhciBjbGlwYm9hcmQgPSB7fTtcblxuLyoqXG4gKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYENsaXBib2FyZGAgQVBJIChgZmluLkNsaXBib2FyZGApLlxuICpcbiAqICoge0BsaW5rIENsaXBib2FyZH0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBDbGlwYm9hcmRgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uQ2xpcGJvYXJkYC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNsaXBib2FyZCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jbGlwYm9hcmQuQ2xpcGJvYXJkID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJGMgPSBiYXNlO1xuLyoqXG4gKiBUaGUgQ2xpcGJvYXJkIEFQSSBhbGxvd3MgcmVhZGluZyBhbmQgd3JpdGluZyB0byB0aGUgY2xpcGJvYXJkIGluIG11bHRpcGxlIGZvcm1hdHMuXG4gKlxuICovXG5jbGFzcyBDbGlwYm9hcmQgZXh0ZW5kcyBiYXNlXzEkYy5CYXNlIHtcbiAgICAvKipcbiAgICAgKiBXcml0ZXMgZGF0YSBpbnRvIHRoZSBjbGlwYm9hcmQgYXMgcGxhaW4gdGV4dFxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZVRleHQoe1xuICAgICAqICAgICBkYXRhOiAnaGVsbG8sIHdvcmxkJ1xuICAgICAqIH0pLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1RleHQgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVRleHQod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS10ZXh0Jywgd3JpdGVPYmopO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjb250ZW50IG9mIHRoZSBjbGlwYm9hcmQgYXMgcGxhaW4gdGV4dFxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkVGV4dCgpLnRoZW4odGV4dCA9PiBjb25zb2xlLmxvZyh0ZXh0KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRUZXh0KHR5cGUpIHtcbiAgICAgICAgLy8gTk9URTogV2hlbiB3ZSBzdGFydCBzdXBwb3J0aW5nIGxpbnV4LCB3ZSBjb3VsZCBkZXRlY3QgdGhlIE9TIGFuZCBjaG9vc2UgJ3NlbGVjdGlvbicgYXV0b21hdGljYWxseSBmb3IgdGhlIHVzZXJcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXJlYWQtdGV4dCcsIHsgdHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIGFuIEltYWdlXG4gICAgICogQHBhcmFtIHdyaXRlUmVxdWVzdCBUaGUgb2JqZWN0IHRvIHdyaXRlIGFuIGltYWdlIHRvIHRoZSBjbGlwYm9hcmRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uQ2xpcGJvYXJkLndyaXRlSW1hZ2Uoe1xuICAgICAqICAgLy8gcmF3IGJhc2U2NCBzdHJpbmcsIG9yIGRhdGFVUkwgb2YgZWl0aGVyIGRhdGE6aW1hZ2UvcG5nIG9yIGRhdGE6aW1hZ2UvanBlZyB0eXBlXG4gICAgICogICBpbWFnZTogJy4uLidcbiAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdJbWFnZSB3cml0dGVuIHRvIGNsaXBib2FyZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JpdGVJbWFnZSh3cml0ZVJlcXVlc3QpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS1pbWFnZScsIHdyaXRlUmVxdWVzdCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZCBhcyBhIGJhc2U2NCBzdHJpbmcgb3IgYSBkYXRhVVJMIGJhc2VkIG9uIHRoZSBpbnB1dCBwYXJhbWV0ZXIgJ2Zvcm1hdCcsIGRlZmF1bHRzIHRvICdkYXRhVVJMJ1xuICAgICAqIEBwYXJhbSByZWFkUmVxdWVzdCBDbGlwYm9hcmQgUmVhZCBJbWFnZSByZXF1ZXN0IHdpdGggZm9ybWF0dGluZyBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogLy8gc2VlIFRTIHR5cGU6IE9wZW5GaW4uSW1hZ2VGb3JtYXRPcHRpb25zXG4gICAgICpcbiAgICAgKiBjb25zdCBwbmdPckRhdGFVUkxPckJtcE9wdGlvbnMgPSB7XG4gICAgICogICAgIGZvcm1hdDogJ3BuZycsIC8vIGNhbiBiZTogJ3BuZycgfCAnZGF0YVVSTCcgfCAnYm1wJ1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBjb25zdCBqcGdPcHRpb25zID0ge1xuICAgICAqICAgICBmb3JtYXQ6ICdqcGcnLFxuICAgICAqICAgICBxdWFsaXR5OiA4MCAvLyBvcHRpb25hbCwgaWYgb21pdHRlZCBkZWZhdWx0cyB0byAxMDBcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSW1hZ2UocG5nT3JEYXRhVVJMT3JCbXBPcHRpb25zKVxuICAgICAqICAgICAudGhlbihpbWFnZSA9PiBjb25zb2xlLmxvZygnSW1hZ2UgcmVhZCBmcm9tIGNsaXBib2FyZCBhcyBQTkcsIERhdGFVUkwgb3IgQk1QJywgaW1hZ2UpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSW1hZ2UoanBnT3B0aW9ucylcbiAgICAgKiAgICAgLnRoZW4oaW1hZ2UgPT4gY29uc29sZS5sb2coJ0ltYWdlIHJlYWQgZnJvbSBjbGlwYm9hcmQgYXMgSlBHJywgaW1hZ2UpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogLy8gZGVmYXVsdHMgdG8ge2Zvcm1hdDogJ2RhdGFVUkwnfVxuICAgICAqIGZpbi5DbGlwYm9hcmQucmVhZEltYWdlKClcbiAgICAgKiAgICAgLnRoZW4oaW1hZ2UgPT4gY29uc29sZS5sb2coJ0ltYWdlIHJlYWQgZnJvbSBjbGlwYm9hcmQgYXMgRGF0YVVSTCcsIGltYWdlKSlcbiAgICAgKiAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRJbWFnZShyZWFkUmVxdWVzdCA9IHsgZm9ybWF0OiAnZGF0YVVSTCcgfSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGlwYm9hcmQtcmVhZC1pbWFnZScsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIEh0bWxcbiAgICAgKiBAcGFyYW0gd3JpdGVPYmogVGhlIG9iamVjdCBmb3Igd3JpdGluZyBkYXRhIGludG8gdGhlIGNsaXBib2FyZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5DbGlwYm9hcmQud3JpdGVIdG1sKHtcbiAgICAgKiAgICAgICAgIGRhdGE6ICc8aDE+SGVsbG8sIFdvcmxkITwvaDE+J1xuICAgICAqIH0pLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0hUTUwgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZUh0bWwod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS1odG1sJywgd3JpdGVPYmopO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjb250ZW50IG9mIHRoZSBjbGlwYm9hcmQgYXMgSHRtbFxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSHRtbCgpLnRoZW4oaHRtbCA9PiBjb25zb2xlLmxvZyhodG1sKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRIdG1sKHR5cGUpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXJlYWQtaHRtbCcsIHsgdHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIFJ0ZlxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZVJ0Zih7XG4gICAgICogICAgICAgICBkYXRhOiAnc29tZSB0ZXh0IGdvZXMgaGVyZSdcbiAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdSVEYgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVJ0Zih3cml0ZU9iaikge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXdyaXRlLXJ0ZicsIHdyaXRlT2JqKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY29udGVudCBvZiB0aGUgY2xpcGJvYXJkIGFzIFJ0ZlxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3cml0ZU9iaiA9IHtcbiAgICAgKiAgICAgZGF0YTogJ3NvbWUgdGV4dCBnb2VzIGhlcmUnXG4gICAgICogfTtcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWFkUnRmKCkge1xuICAgICAqICAgICBhd2FpdCBmaW4uQ2xpcGJvYXJkLndyaXRlUnRmKHdyaXRlT2JqKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGZpbi5DbGlwYm9hcmQucmVhZFJ0ZigpO1xuICAgICAqIH1cbiAgICAgKiByZWFkUnRmKCkudGhlbihydGYgPT4gY29uc29sZS5sb2cocnRmKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRSdGYodHlwZSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGlwYm9hcmQtcmVhZC1ydGYnLCB7IHR5cGUgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyaXRlcyBkYXRhIGludG8gdGhlIGNsaXBib2FyZFxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZSh7XG4gICAgICogICBkYXRhOiB7XG4gICAgICogICAgIHRleHQ6ICdhJyxcbiAgICAgKiAgICAgaHRtbDogJ2InLFxuICAgICAqICAgICBydGY6ICdjJyxcbiAgICAgKiAgICAgLy8gQ2FuIGJlIGVpdGhlciBhIGJhc2U2NCBzdHJpbmcsIG9yIGEgRGF0YVVSTCBzdHJpbmcuIElmIHVzaW5nIERhdGFVUkwsIHRoZVxuICAgICAqICAgICAvLyBzdXBwb3J0ZWQgZm9ybWF0cyBhcmUgYGRhdGE6aW1hZ2UvcG5nWztiYXNlNjRdLGAgYW5kIGBkYXRhOmltYWdlL2pwZWdbO2Jhc2U2NF0sYC5cbiAgICAgKiAgICAgLy8gVXNpbmcgb3RoZXIgaW1hZ2UvPGZvcm1hdD4gRGF0YVVSTHMgd2lsbCB0aHJvdyBhbiBFcnJvci5cbiAgICAgKiAgICAgaW1hZ2U6ICcuLi4nXG4gICAgICogICB9XG4gICAgICogfSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnd3JpdGUgZGF0YSBpbnRvIGNsaXBib2FyZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JpdGUod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZScsIHdyaXRlT2JqKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZHMgYXZhaWxhYmxlIGZvcm1hdHMgZm9yIHRoZSBjbGlwYm9hcmQgdHlwZVxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5nZXRBdmFpbGFibGVGb3JtYXRzKCkudGhlbihmb3JtYXRzID0+IGNvbnNvbGUubG9nKGZvcm1hdHMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QXZhaWxhYmxlRm9ybWF0cyh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC1yZWFkLWZvcm1hdHMnLCB7IHR5cGUgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxufVxuY2xpcGJvYXJkLkNsaXBib2FyZCA9IENsaXBib2FyZDtcblxudmFyIGV4dGVybmFsQXBwbGljYXRpb24gPSB7fTtcblxudmFyIEZhY3RvcnkkNSA9IHt9O1xuXG52YXIgSW5zdGFuY2UkNCA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW5zdGFuY2UkNCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZSQ0LkV4dGVybmFsQXBwbGljYXRpb24gPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5jb25zdCBiYXNlXzEkYiA9IGJhc2U7XG4vKipcbiAqIEFuIEV4dGVybmFsQXBwbGljYXRpb24gb2JqZWN0IHJlcHJlc2VudGluZyBuYXRpdmUgbGFuZ3VhZ2UgYWRhcHRlciBjb25uZWN0aW9ucyB0byB0aGUgcnVudGltZS4gQWxsb3dzXG4gKiB0aGUgZGV2ZWxvcGVyIHRvIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzIGV4dGVybmFsIGFwcGxpY2F0aW9uIGV2ZW50c30uXG4gKiBEaXNjb3Zlcnkgb2YgY29ubmVjdGlvbnMgaXMgcHJvdmlkZWQgYnkge0BsaW5rIFN5c3RlbS5TeXN0ZW0uZ2V0QWxsRXh0ZXJuYWxBcHBsaWNhdGlvbnMgZ2V0QWxsRXh0ZXJuYWxBcHBsaWNhdGlvbnN9LjwvYT5cbiAqXG4gKiBQcm9jZXNzZXMgdGhhdCBjYW4gYmUgd3JhcHBlZCBhcyBgRXh0ZXJuYWxBcHBsaWNhdGlvbmBzIGluY2x1ZGUgdGhlIGZvbGxvd2luZzpcbiAqIC0gUHJvY2Vzc2VzIHdoaWNoIGhhdmUgY29ubmVjdGVkIHRvIGFuIE9wZW5GaW4gcnVudGltZSB2aWEgYW4gYWRhcHRlclxuICogLSBQcm9jZXNzZXMgc3RhcnRlZCB2aWEgYFN5c3RlbS5sYXVuY2hFeHRlcm5hbEFwcGxpY2F0aW9uYFxuICogLSBQcm9jZXNzZXMgbW9uaXRvcmVkIHZpYSBgU3lzdGVtLm1vbml0b3JFeHRlcm5hbFByb2Nlc3NgXG4gKi9cbmNsYXNzIEV4dGVybmFsQXBwbGljYXRpb24gZXh0ZW5kcyBiYXNlXzEkYi5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgJ2V4dGVybmFsLWFwcGxpY2F0aW9uJywgaWRlbnRpdHkudXVpZCk7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBleHRlcm5hbCBhcHBsaWNhdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRJbmZvKCkge1xuICAgICAqICAgICBjb25zdCBleHRBcHAgPSBhd2FpdCBmaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbi53cmFwKCdqYXZhQXBwLXV1aWQnKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGV4dEFwcC5nZXRJbmZvKCk7XG4gICAgICogfVxuICAgICAqIGdldEluZm8oKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1leHRlcm5hbC1hcHBsaWNhdGlvbi1pbmZvJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxufVxuSW5zdGFuY2UkNC5FeHRlcm5hbEFwcGxpY2F0aW9uID0gRXh0ZXJuYWxBcHBsaWNhdGlvbjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkNSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDUuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSRhID0gYmFzZTtcbmNvbnN0IEluc3RhbmNlXzEkNCA9IEluc3RhbmNlJDQ7XG4vKipcbiAqIFN0YXRpYyBuYW1lc3BhY2UgZm9yIE9wZW5GaW4gQVBJIG1ldGhvZHMgdGhhdCBpbnRlcmFjdCB3aXRoIHRoZSB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbn0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkV4dGVybmFsQXBwbGljYXRpb25gLlxuICovXG5jbGFzcyBFeHRlcm5hbEFwcGxpY2F0aW9uTW9kdWxlIGV4dGVuZHMgYmFzZV8xJGEuQmFzZSB7XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBFeHRlcm5hbCBBcHBsaWNhdGlvbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGFuIGV4dGVybmFsIGFwcGxpY2F0aW9uLlxuICAgICAqIDxicj5JdCBpcyBwb3NzaWJsZSB0byB3cmFwIGEgcHJvY2VzcyB0aGF0IGRvZXMgbm90IHlldCBleGlzdCwgKGZvciBleGFtcGxlLCB0byBsaXN0ZW4gZm9yIHN0YXJ0dXAtcmVsYXRlZCBldmVudHMpXG4gICAgICogcHJvdmlkZWQgaXRzIHV1aWQgaXMgYWxyZWFkeSBrbm93bi5cbiAgICAgKiBAcGFyYW0gdXVpZCBUaGUgVVVJRCBvZiB0aGUgZXh0ZXJuYWwgYXBwbGljYXRpb24gdG8gYmUgd3JhcHBlZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uLndyYXAoJ2phdmFBcHAtdXVpZCcpO1xuICAgICAqIC50aGVuKGV4dEFwcCA9PiBjb25zb2xlLmxvZygnd3JhcHBlZCBleHRlcm5hbCBhcHBsaWNhdGlvbicpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgd3JhcCh1dWlkKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdleHRlcm5hbC1hcHBsaWNhdGlvbi13cmFwJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgSW5zdGFuY2VfMSQ0LkV4dGVybmFsQXBwbGljYXRpb24odGhpcy53aXJlLCB7IHV1aWQgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gRXh0ZXJuYWwgQXBwbGljYXRpb24gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleHRlcm5hbCBhcHBsaWNhdGlvbi5cbiAgICAgKiA8YnI+SXQgaXMgcG9zc2libGUgdG8gd3JhcCBhIHByb2Nlc3MgdGhhdCBkb2VzIG5vdCB5ZXQgZXhpc3QsIChmb3IgZXhhbXBsZSwgdG8gbGlzdGVuIGZvciBzdGFydHVwLXJlbGF0ZWQgZXZlbnRzKVxuICAgICAqIHByb3ZpZGVkIGl0cyB1dWlkIGlzIGFscmVhZHkga25vd24uXG4gICAgICogQHBhcmFtIHV1aWQgVGhlIFVVSUQgb2YgdGhlIGV4dGVybmFsIGFwcGxpY2F0aW9uIHRvIGJlIHdyYXBwZWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBleHRBcHAgPSBmaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbi53cmFwU3luYygnamF2YUFwcC11dWlkJyk7XG4gICAgICogY29uc3QgaW5mbyA9IGF3YWl0IGV4dEFwcC5nZXRJbmZvKCk7XG4gICAgICogY29uc29sZS5sb2coaW5mbyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgd3JhcFN5bmModXVpZCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZXh0ZXJuYWwtYXBwbGljYXRpb24td3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDQuRXh0ZXJuYWxBcHBsaWNhdGlvbih0aGlzLndpcmUsIHsgdXVpZCB9KTtcbiAgICB9XG59XG5GYWN0b3J5JDUuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSA9IEV4dGVybmFsQXBwbGljYXRpb25Nb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgRXh0ZXJuYWxBcHBsaWNhdGlvbmAgQVBJIChgZmluLkV4dGVybmFsQXBwbGljYXRpb25gKS5cblx0ICpcblx0ICogKiB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBFeHRlcm5hbEFwcGxpY2F0aW9uYCB0eXBlLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uYC5cblx0ICogKiB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbn0gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gRXh0ZXJuYWxBcHBsaWNhdGlvbiwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLkV4dGVybmFsQXBwbGljYXRpb24uZ2V0Q3VycmVudGAuXG5cdCAqXG5cdCAqIFRoZXNlIGFyZSBzZXBhcmF0ZSBjb2RlIGVudGl0aWVzLCBhbmQgYXJlIGRvY3VtZW50ZWQgc2VwYXJhdGVseS4gIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdCAqL1xuXHRfX2V4cG9ydFN0YXIoRmFjdG9yeSQ1LCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKEluc3RhbmNlJDQsIGV4cG9ydHMpOyBcbn0gKGV4dGVybmFsQXBwbGljYXRpb24pKTtcblxudmFyIGZyYW1lID0ge307XG5cbnZhciBGYWN0b3J5JDQgPSB7fTtcblxudmFyIEluc3RhbmNlJDMgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuSW5zdGFuY2UkMy5fRnJhbWUgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5jb25zdCBiYXNlXzEkOSA9IGJhc2U7XG4vKipcbiAqIEFuIGlmcmFtZSByZXByZXNlbnRzIGFuIGVtYmVkZGVkIEhUTUwgcGFnZSB3aXRoaW4gYSBwYXJlbnQgSFRNTCBwYWdlLiBCZWNhdXNlIHRoaXMgZW1iZWRkZWQgcGFnZVxuICogaGFzIGl0cyBvd24gRE9NIGFuZCBnbG9iYWwgSlMgY29udGV4dCAod2hpY2ggbWF5IG9yIG1heSBub3QgYmUgbGlua2VkIHRvIHRoYXQgb2YgdGhlIHBhcmVudCBkZXBlbmRpbmdcbiAqIG9uIGlmIGl0IGlzIGNvbnNpZGVyZWQgb3V0IG9mIHRoZSByb290IGRvbWFpbiBvciBub3QpLCBpdCByZXByZXNlbnRzIGEgdW5pcXVlIGVuZHBvaW50IGFzIGFuIE9wZW5GaW5cbiAqIGNvbm5lY3Rpb24uIElmcmFtZXMgbWF5IGJlIGdlbmVyYXRlZCBkeW5hbWljYWxseSwgb3IgYmUgcHJlc2VudCBvbiBpbml0aWFsIHBhZ2UgbG9hZCBhbmQgZWFjaCBub24tQ09SU1xuICogaWZyYW1lIGhhcyB0aGUgT3BlbkZpbiBBUEkgaW5qZWN0ZWQgYnkgZGVmYXVsdC4gSXQgaXMgcG9zc2libGUgdG8gb3B0IGludG8gY3Jvc3Mtb3JpZ2luIGlmcmFtZXMgaGF2aW5nXG4gKiB0aGUgQVBJIGJ5IHNldHRpbmcgYXBpLmlmcmFtZS5jcm9zc09yaWdpbkluamVjdGlvbiB0byB0cnVlIGluIGEgd2luZG93J3Mgb3B0aW9ucy4gVG8gYmxvY2sgYWxsIGlmcmFtZXNcbiAqIGZyb20gZ2V0dGluZyB0aGUgQVBJIGluamVjdGVkIHlvdSBjYW4gc2V0IGFwaS5mcmFtZS5zYW1lT3JpZ2luSW5qZWN0aW9uXG4gKiB0byBmYWxzZSA8YSBocmVmPVwiV2luZG93Lmh0bWwjfm9wdGlvbnNcIiB0YXJnZXQ9XCJfYmxhbmtcIj4oe0BsaW5rIE9wZW5GaW4uV2luZG93Q3JlYXRpb25PcHRpb25zIHNlZSBXaW5kb3cgT3B0aW9uc30pPC9hPi5cbiAqXG4gKiBUbyBiZSBhYmxlIHRvIGRpcmVjdGx5IGFkZHJlc3MgdGhpcyBjb250ZXh0IGZvciBldmVudGluZyBhbmQgbWVzc2FnaW5nIHB1cnBvc2VzLCBpdCBuZWVkcyBhXG4gKiB1bmlxdWUgdXVpZCBuYW1lIHBhaXJpbmcuIEZvciBPcGVuRmluIGFwcGxpY2F0aW9ucyBhbmQgd2luZG93cyB0aGlzIGlzIHByb3ZpZGVkIHZpYSBhIGNvbmZpZ3VyYXRpb25cbiAqIG9iamVjdCBpbiB0aGUgZm9ybSBvZiBhIG1hbmlmZXN0IFVSTCBvciBvcHRpb25zIG9iamVjdCwgYnV0IHRoZXJlIGlzIG5vIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciBpZnJhbWVzLlxuICogSnVzdCBhcyBhIGNhbGwgdG8gd2luZG93Lm9wZW4gb3V0c2lkZSBvZiBvdXIgV2luZG93IEFQSSByZXR1cm5zIGEgbmV3IHdpbmRvdyB3aXRoIGEgcmFuZG9tIEdVSUQgYXNzaWduZWRcbiAqIGZvciB0aGUgbmFtZSwgZWFjaCBpZnJhbWUgdGhhdCBoYXMgdGhlIEFQSSBpbmplY3RlZCB3aWxsIGJlIGFzc2lnbmVkIGEgR1VJRCBhcyBpdHMgbmFtZSwgdGhlIFVVSUQgd2lsbCBiZVxuICogdGhlIHNhbWUgYXMgdGhlIHBhcmVudCB3aW5kb3cncy5cbiAqXG4gKiBUaGUgZmluLkZyYW1lIG5hbWVzcGFjZSByZXByZXNlbnRzIGEgd2F5IHRvIGludGVyYWN0IHdpdGggYGlmcmFtZXNgIGFuZCBmYWNpbGl0YXRlcyB0aGUgZGlzY292ZXJ5IG9mIGN1cnJlbnQgY29udGV4dFxuICogKGlmcmFtZSBvciBtYWluIHdpbmRvdykgYXMgd2VsbCBhcyB0aGUgYWJpbGl0eSB0byBsaXN0ZW4gZm9yIHtAbGluayBPcGVuRmluLkZyYW1lRXZlbnRzIGZyYW1lLXNwZWNpZmljIGV2ZW50c30uXG4gKi9cbmNsYXNzIF9GcmFtZSBleHRlbmRzIGJhc2VfMSQ5LkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlLCBpZGVudGl0eSkge1xuICAgICAgICBzdXBlcih3aXJlLCAnZnJhbWUnLCBpZGVudGl0eS51dWlkLCBpZGVudGl0eS5uYW1lKTtcbiAgICAgICAgdGhpcy5pZGVudGl0eSA9IGlkZW50aXR5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgZnJhbWUgaW5mbyBvYmplY3QgZm9yIHRoZSByZXByZXNlbnRlZCBmcmFtZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRJbmZvKCkge1xuICAgICAqICAgICBjb25zdCBmcm0gPSBhd2FpdCBmaW4uRnJhbWUuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZnJtLmdldEluZm8oKTtcbiAgICAgKiB9XG4gICAgICogZ2V0SW5mbygpLnRoZW4oaW5mbyA9PiBjb25zb2xlLmxvZyhpbmZvKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEluZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWZyYW1lLWluZm8nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGZyYW1lIGluZm8gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgd2luZG93IHRoYXQgdGhlIHJlZmVyZW5jZWQgaWZyYW1lIGlzXG4gICAgICogY3VycmVudGx5IGVtYmVkZGVkIGluLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgdGhlIGZyYW1lIGlzIGVtYmVkZGVkIGluIGEgdmlldywgdGhpcyB3aWxsIHJldHVybiBhbiBpbnZhbGlkIHN0dWIgd2l0aCBlbXB0eSBmaWVsZHMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50V2luZG93KCkge1xuICAgICAqICAgICBjb25zdCBmcm0gPSBhd2FpdCBmaW4uRnJhbWUuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZnJtLmdldFBhcmVudFdpbmRvdygpO1xuICAgICAqIH1cbiAgICAgKiBnZXRQYXJlbnRXaW5kb3coKS50aGVuKHdpbkluZm8gPT4gY29uc29sZS5sb2cod2luSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRQYXJlbnRXaW5kb3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXBhcmVudC13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG59XG5JbnN0YW5jZSQzLl9GcmFtZSA9IF9GcmFtZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkNCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDQuX0ZyYW1lTW9kdWxlID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJDggPSBiYXNlO1xuY29uc3QgdmFsaWRhdGVfMSQyID0gdmFsaWRhdGU7XG5jb25zdCBJbnN0YW5jZV8xJDMgPSBJbnN0YW5jZSQzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIF9GcmFtZX0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkZyYW1lYC5cbiAqL1xuY2xhc3MgX0ZyYW1lTW9kdWxlIGV4dGVuZHMgYmFzZV8xJDguQmFzZSB7XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBBUEkgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gRnJhbWUgaWRlbnRpdHkuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXcmFwcGluZyBhIEZyYW1lIGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG4gICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuICAgICAqIGZvciBhIEZyYW1lIHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkZyYW1lLndyYXAoeyB1dWlkOiAndGVzdEZyYW1lJywgbmFtZTogJ3Rlc3RGcmFtZScgfSlcbiAgICAgKiAudGhlbihmcm0gPT4gY29uc29sZS5sb2coJ3dyYXBwZWQgZnJhbWUnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHdyYXAoaWRlbnRpdHkpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZyYW1lLXdyYXAnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xJDIudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuICAgICAgICBpZiAoZXJyb3JNc2cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDMuX0ZyYW1lKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIEZyYW1lIGlkZW50aXR5LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBGcmFtZSBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuICAgICAqIHJldHVybnMgYSBzdHViIG9iamVjdCB0aGF0IGNhbm5vdCB5ZXQgcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGx1bWJpbmcgZXZlbnRpbmdcbiAgICAgKiBmb3IgYSBGcmFtZSB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGZybSA9IGZpbi5GcmFtZS53cmFwU3luYyh7IHV1aWQ6ICd0ZXN0RnJhbWUnLCBuYW1lOiAndGVzdEZyYW1lJyB9KTtcbiAgICAgKiBjb25zdCBpbmZvID0gYXdhaXQgZnJtLmdldEluZm8oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhpbmZvKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZnJhbWUtd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMSQyLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMSQzLl9GcmFtZSh0aGlzLndpcmUsIGlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBmcmFtZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5GcmFtZS5nZXRDdXJyZW50KClcbiAgICAgKiAudGhlbihmcm0gPT4gY29uc29sZS5sb2coJ2N1cnJlbnQgZnJhbWUnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmcmFtZS1nZXQtY3VycmVudCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEluc3RhbmNlXzEkMy5fRnJhbWUodGhpcy53aXJlLCB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0Q3VycmVudEVudGl0eUlkZW50aXR5KCkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IGZyYW1lXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZnJtID0gZmluLkZyYW1lLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgaW5mbyA9IGF3YWl0IGZybS5nZXRJbmZvKCk7XG4gICAgICogY29uc29sZS5sb2coaW5mbyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q3VycmVudFN5bmMoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmcmFtZS1nZXQtY3VycmVudC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDMuX0ZyYW1lKHRoaXMud2lyZSwgdGhpcy53aXJlLmVudmlyb25tZW50LmdldEN1cnJlbnRFbnRpdHlJZGVudGl0eSgpKTtcbiAgICB9XG59XG5GYWN0b3J5JDQuX0ZyYW1lTW9kdWxlID0gX0ZyYW1lTW9kdWxlO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0LyoqXG5cdCAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIE9wZW5GaW4gYEZyYW1lYCBBUEkgKGBmaW4uRnJhbWVgKS5cblx0ICpcblx0ICogKiB7QGxpbmsgX0ZyYW1lTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEZyYW1lYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLkZyYW1lYC5cblx0ICogKiB7QGxpbmsgX0ZyYW1lfSBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gT3BlbkZpbiBGcmFtZSwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLkZyYW1lLmdldEN1cnJlbnRgLlxuXHQgKlxuXHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogVW5kZXJzY29yZSBwcmVmaXhpbmcgb2YgT3BlbkZpbiB0eXBlcyB0aGF0IGFsaWFzIERPTSBlbnRpdGllcyB3aWxsIGJlIGZpeGVkIGluIGEgZnV0dXJlIHZlcnNpb24uXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnkkNCwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihJbnN0YW5jZSQzLCBleHBvcnRzKTsgXG59IChmcmFtZSkpO1xuXG52YXIgZ2xvYmFsSG90a2V5ID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxIb3RrZXksIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZ2xvYmFsSG90a2V5Lkdsb2JhbEhvdGtleSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSQ3ID0gYmFzZTtcbi8qKlxuICogVGhlIEdsb2JhbEhvdGtleSBtb2R1bGUgY2FuIHJlZ2lzdGVyL3VucmVnaXN0ZXIgYSBnbG9iYWwgaG90a2V5cy5cbiAqXG4gKi9cbmNsYXNzIEdsb2JhbEhvdGtleSBleHRlbmRzIGJhc2VfMSQ3LkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlKSB7XG4gICAgICAgIHN1cGVyKHdpcmUsICdnbG9iYWwtaG90a2V5Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVycyBhIGdsb2JhbCBob3RrZXkgd2l0aCB0aGUgb3BlcmF0aW5nIHN5c3RlbS5cbiAgICAgKiBAcGFyYW0gaG90a2V5IGEgaG90a2V5IHN0cmluZ1xuICAgICAqIEBwYXJhbSBsaXN0ZW5lciBjYWxsZWQgd2hlbiB0aGUgcmVnaXN0ZXJlZCBob3RrZXkgaXMgcHJlc3NlZCBieSB0aGUgdXNlci5cbiAgICAgKiBAdGhyb3dzIElmIHRoZSBgaG90a2V5YCBpcyByZXNlcnZlZCwgc2VlIGxpc3QgYmVsb3cuXG4gICAgICogQHRocm93cyBpZiB0aGUgYGhvdGtleWAgaXMgYWxyZWFkeSByZWdpc3RlcmVkIGJ5IGFub3RoZXIgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgYGhvdGtleWAgcGFyYW1ldGVyIGV4cGVjdHMgYW4gZWxlY3Ryb24gY29tcGF0aWJsZSBbYWNjZWxlcmF0b3JdKGh0dHBzOi8vZ2l0aHViLmNvbS9lbGVjdHJvbi9lbGVjdHJvbi9ibG9iL21hc3Rlci9kb2NzL2FwaS9hY2NlbGVyYXRvci5tZCkgYW5kIHRoZSBgbGlzdGVuZXJgIHdpbGwgYmUgY2FsbGVkIGlmIHRoZSBgaG90a2V5YCBpcyBwcmVzc2VkIGJ5IHRoZSB1c2VyLlxuICAgICAqIElmIHN1Y2Nlc3NmdWxsLCB0aGUgaG90a2V5IHdpbGwgYmUgJ2NsYWltZWQnIGJ5IHRoZSBhcHBsaWNhdGlvbiwgbWVhbmluZyB0aGF0IHRoaXMgcmVnaXN0ZXIgY2FsbCBjYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGZyb20gd2l0aGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGJ1dCB3aWxsIGZhaWwgaWYgYW5vdGhlciBhcHBsaWNhdGlvbiBoYXMgcmVnaXN0ZXJlZCB0aGUgaG90a2V5LlxuICAgICAqIDxicj5UaGUgcmVnaXN0ZXIgY2FsbCB3aWxsIGZhaWwgaWYgZ2l2ZW4gYW55IG9mIHRoZXNlIHJlc2VydmVkIEhvdGtleXM6XG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCswYFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrPWBcbiAgICAgKiAqIGBDb21tYW5kT3JDb250cm9sK1BsdXNgXG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCstYFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrX2BcbiAgICAgKiAqIGBDb21tYW5kT3JDb250cm9sK1NoaWZ0K0lgXG4gICAgICogKiBgRjVgXG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCtSYFxuICAgICAqICogYFNoaWZ0K0Y1YFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrU2hpZnQrUmBcbiAgICAgKlxuICAgICAqIFJhaXNlcyB0aGUgYHJlZ2lzdGVyZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGhvdGtleSA9ICdDb21tYW5kT3JDb250cm9sK1gnO1xuICAgICAqXG4gICAgICogZmluLkdsb2JhbEhvdGtleS5yZWdpc3Rlcihob3RrZXksICgpID0+IHtcbiAgICAgKiBjb25zb2xlLmxvZyhgJHtob3RrZXl9IHByZXNzZWRgKTtcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ1N1Y2Nlc3MnKTtcbiAgICAgKiB9KVxuICAgICAqIC5jYXRjaChlcnIgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnRXJyb3IgcmVnaXN0ZXJpbmcgdGhlIGhvdGtleScsIGVycik7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXIoaG90a2V5LCBsaXN0ZW5lcikge1xuICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChob3RrZXkgZXZlbnRzIGFyZSBub3QgdHlwZWQpXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgYXdhaXQgdGhpcy5vbihob3RrZXksIGxpc3RlbmVyKTtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dsb2JhbC1ob3RrZXktcmVnaXN0ZXInLCB7IGhvdGtleSB9KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5yZWdpc3RlcnMgYSBnbG9iYWwgaG90a2V5IHdpdGggdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICogQHBhcmFtIGhvdGtleSBhIGhvdGtleSBzdHJpbmdcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIHdpbGwgdW5yZWdpc3RlciBhbGwgZXhpc3RpbmcgcmVnaXN0cmF0aW9ucyBvZiB0aGUgaG90a2V5IHdpdGhpbiB0aGUgYXBwbGljYXRpb24uXG4gICAgICogUmFpc2VzIHRoZSBgdW5yZWdpc3RlcmVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBob3RrZXkgPSAnQ29tbWFuZE9yQ29udHJvbCtYJztcbiAgICAgKlxuICAgICAqIGZpbi5HbG9iYWxIb3RrZXkudW5yZWdpc3Rlcihob3RrZXkpXG4gICAgICogLnRoZW4oKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnU3VjY2VzcycpO1xuICAgICAqIH0pXG4gICAgICogLmNhdGNoKGVyciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnJlZ2lzdGVyaW5nIHRoZSBob3RrZXknLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXIoaG90a2V5KSB7XG4gICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGhvdGtleSBldmVudHMgYXJlIG5vdCB0eXBlZClcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhob3RrZXkpO1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2xvYmFsLWhvdGtleS11bnJlZ2lzdGVyJywgeyBob3RrZXkgfSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVucmVnaXN0ZXJzIGFsbCBnbG9iYWwgaG90a2V5cyBmb3IgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBSYWlzZXMgdGhlIGB1bnJlZ2lzdGVyZWRgIGV2ZW50IGZvciBlYWNoIGhvdGtleSB1bnJlZ2lzdGVyZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkdsb2JhbEhvdGtleS51bnJlZ2lzdGVyQWxsKClcbiAgICAgKiAudGhlbigoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdTdWNjZXNzJyk7XG4gICAgICogfSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0Vycm9yIHVucmVnaXN0ZXJpbmcgYWxsIGhvdGtleXMgZm9yIHRoaXMgYXBwbGljYXRpb24nLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXJBbGwoKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMuZXZlbnROYW1lcygpXG4gICAgICAgICAgICAuZmlsdGVyKChuYW1lKSA9PiAhKG5hbWUgPT09ICdyZWdpc3RlcmVkJyB8fCBuYW1lID09PSAndW5yZWdpc3RlcmVkJykpXG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChob3RrZXkgZXZlbnRzIGFyZSBub3QgdHlwZWQpXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAubWFwKChuYW1lKSA9PiB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhuYW1lKSkpO1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2xvYmFsLWhvdGtleS11bnJlZ2lzdGVyLWFsbCcsIHt9KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgZ2l2ZW4gaG90a2V5IGhhcyBiZWVuIHJlZ2lzdGVyZWQgYnkgYW4gYXBwbGljYXRpb24gd2l0aGluIHRoZSBjdXJyZW50IHJ1bnRpbWUuXG4gICAgICogQHBhcmFtIGhvdGtleSBhIGhvdGtleSBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBob3RrZXkgPSAnQ29tbWFuZE9yQ29udHJvbCtYJztcbiAgICAgKlxuICAgICAqIGZpbi5HbG9iYWxIb3RrZXkuaXNSZWdpc3RlcmVkKGhvdGtleSlcbiAgICAgKiAudGhlbigocmVnaXN0ZXJlZCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgaG90a2V5ICR7aG90a2V5fSBpcyByZWdpc3RlcmVkID8gJHtyZWdpc3RlcmVkfWApO1xuICAgICAqIH0pXG4gICAgICogLmNhdGNoKGVyciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnJlZ2lzdGVyaW5nIHRoZSBob3RrZXknLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGlzUmVnaXN0ZXJlZChob3RrZXkpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGEgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dsb2JhbC1ob3RrZXktaXMtcmVnaXN0ZXJlZCcsIHsgaG90a2V5IH0pO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG59XG5nbG9iYWxIb3RrZXkuR2xvYmFsSG90a2V5ID0gR2xvYmFsSG90a2V5O1xuXG52YXIgcGxhdGZvcm0gPSB7fTtcblxudmFyIEZhY3RvcnkkMyA9IHt9O1xuXG52YXIgSW5zdGFuY2UkMiA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ1ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX1BsYXRmb3JtX2Nvbm5lY3RUb1Byb3ZpZGVyO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuSW5zdGFuY2UkMi5QbGF0Zm9ybSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9wcmVmZXItZGVmYXVsdC1leHBvcnQsIG5vLXVuZGVmICovXG5jb25zdCBiYXNlXzEkNiA9IGJhc2U7XG5jb25zdCB2YWxpZGF0ZV8xJDEgPSB2YWxpZGF0ZTtcbi8vIFJldXNlIGNsaWVudHMgdG8gYXZvaWQgb3ZlcndyaXRpbmcgYWxyZWFkeS1yZWdpc3RlcmVkIGNsaWVudCBpbiBwcm92aWRlclxuY29uc3QgY2xpZW50TWFwID0gbmV3IE1hcCgpO1xuLyoqIE1hbmFnZXMgdGhlIGxpZmUgY3ljbGUgb2Ygd2luZG93cyBhbmQgdmlld3MgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICpcbiAqIEVuYWJsZXMgdGFraW5nIHNuYXBzaG90cyBvZiBpdHNlbGYgYW5kIGFwcGx5aW5nIHRoZW0gdG8gcmVzdG9yZSBhIHByZXZpb3VzIGNvbmZpZ3VyYXRpb25cbiAqIGFzIHdlbGwgYXMgbGlzdGVuIHRvIHtAbGluayBPcGVuRmluLlBsYXRmb3JtRXZlbnRzIHBsYXRmb3JtIGV2ZW50c30uXG4gKi9cbmNsYXNzIFBsYXRmb3JtIGV4dGVuZHMgYmFzZV8xJDYuRW1pdHRlckJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdHJ1Y3RvcihpZGVudGl0eSwgY2hhbm5lbCkge1xuICAgICAgICAvLyB3ZSBwaWdneWJhY2sgb2ZmIG9mIGFwcGxpY2F0aW9uIGV2ZW50IGVtaXR0ZXIgYmVjYXVzZSBmcm9tIHRoZSBjb3JlJ3MgcGVyc3BlY3RpdmUgcGxhdGZvcm0gaXMganVzdCBhbiBhcHAuXG4gICAgICAgIHN1cGVyKGNoYW5uZWwud2lyZSwgJ2FwcGxpY2F0aW9uJywgaWRlbnRpdHkudXVpZCk7XG4gICAgICAgIHRoaXMuZ2V0Q2xpZW50ID0gKGlkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tZ2V0LWNsaWVudCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGlkZW50aXR5IHx8IHRoaXMuaWRlbnRpdHk7XG4gICAgICAgICAgICBjb25zdCB7IHV1aWQgfSA9IHRhcmdldDtcbiAgICAgICAgICAgIGlmICghY2xpZW50TWFwLmhhcyh1dWlkKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFByb21pc2UgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDUodGhpcywgX1BsYXRmb3JtX2Nvbm5lY3RUb1Byb3ZpZGVyLCBcImZcIikuY2FsbCh0aGlzLCB1dWlkKTtcbiAgICAgICAgICAgICAgICBjbGllbnRNYXAuc2V0KHV1aWQsIGNsaWVudFByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gd2Ugc2V0IGl0IGFib3ZlXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgcmV0dXJuIGNsaWVudE1hcC5nZXQodXVpZCk7XG4gICAgICAgIH07XG4gICAgICAgIF9QbGF0Zm9ybV9jb25uZWN0VG9Qcm92aWRlci5zZXQodGhpcywgYXN5bmMgKHV1aWQpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSBgY3VzdG9tLWZyYW1lLSR7dXVpZH1gO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuX2NoYW5uZWwuY29ubmVjdChjaGFubmVsTmFtZSwgeyB3YWl0OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICBjbGllbnQub25EaXNjb25uZWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50TWFwLmRlbGV0ZSh1dWlkKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjbGllbnRNYXAuZGVsZXRlKHV1aWQpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHRhcmdldGVkIFBsYXRmb3JtIGlzIG5vdCBjdXJyZW50bHkgcnVubmluZy4gTGlzdGVuIGZvciBhcHBsaWNhdGlvbi1zdGFydGVkIGV2ZW50IGZvciB0aGUgZ2l2ZW4gVXVpZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVwcmVjYXRlZCAocmVuYW1lZClcbiAgICAgICAgICogQGlnbm9yZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYXVuY2hMZWdhY3lNYW5pZmVzdCA9IHRoaXMubGF1bmNoQ29udGVudE1hbmlmZXN0O1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xJDEudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuICAgICAgICBpZiAoZXJyb3JNc2cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2hhbm5lbCA9IGNoYW5uZWw7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSB7IHV1aWQ6IGlkZW50aXR5LnV1aWQgfTtcbiAgICAgICAgdGhpcy5MYXlvdXQgPSB0aGlzLmZpbi5QbGF0Zm9ybS5MYXlvdXQ7XG4gICAgICAgIHRoaXMuQXBwbGljYXRpb24gPSB0aGlzLmZpbi5BcHBsaWNhdGlvbi53cmFwU3luYyh0aGlzLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyB2aWV3IGFuZCBhdHRhY2hlcyBpdCB0byBhIHNwZWNpZmllZCB0YXJnZXQgd2luZG93LlxuICAgICAqIEBwYXJhbSB2aWV3T3B0aW9ucyBWaWV3IGNyZWF0aW9uIG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB3aW5kb3cgdG8gd2hpY2ggdGhlIG5ldyB2aWV3IGlzIHRvIGJlIGF0dGFjaGVkLiBJZiBubyB0YXJnZXQsIGNyZWF0ZSBhIHZpZXcgaW4gYSBuZXcgd2luZG93LlxuICAgICAqIEBwYXJhbSB0YXJnZXRWaWV3IElmIHByb3ZpZGVkLCB0aGUgbmV3IHZpZXcgd2lsbCBiZSBhZGRlZCB0byB0aGUgc2FtZSB0YWJzdHJpcCBhcyB0YXJnZXRWaWV3LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgdGhlIHZpZXcgYWxyZWFkeSBleGlzdHMsIHdpbGwgcmVwYXJlbnQgdGhlIHZpZXcgdG8gdGhlIG5ldyB0YXJnZXQuIFlvdSBkbyBub3QgbmVlZCB0byBzZXQgYSBuYW1lIGZvciBhIFZpZXcuXG4gICAgICogVmlld3MgdGhhdCBhcmUgbm90IHBhc3NlZCBhIG5hbWUgZ2V0IGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG9uZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBsZXQgd2luZG93SWRlbnRpdHk7XG4gICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKlxuICAgICAqIHBsYXRmb3JtLmNyZWF0ZVZpZXcoe1xuICAgICAqICAgICBuYW1lOiAndGVzdF92aWV3JyxcbiAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9wbGF0Zm9ybS1hcGknXG4gICAgICogfSwgd2luZG93SWRlbnRpdHkpLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUmVwYXJlbnRpbmcgYSB2aWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogbGV0IHdpbmRvd0lkZW50aXR5O1xuICAgICAqIGlmIChmaW4ubWUuaXNXaW5kb3cpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSBmaW4ubWUuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICogICAgIHdpbmRvd0lkZW50aXR5ID0gKGF3YWl0IGZpbi5tZS5nZXRDdXJyZW50V2luZG93KCkpLmlkZW50aXR5O1xuICAgICAqIH0gZWxzZSB7XG4gICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGxldCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGxldCB2aWV3T3B0aW9ucyA9IHtcbiAgICAgKiAgICAgbmFtZTogJ2V4YW1wbGVfdmlldycsXG4gICAgICogICAgIHVybDogJ2h0dHBzOi8vZXhhbXBsZS5jb20nXG4gICAgICogfTtcbiAgICAgKiAvLyBhIG5ldyB2aWV3IHdpbGwgbm93IHNob3cgaW4gdGhlIGN1cnJlbnQgd2luZG93XG4gICAgICogYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgd2luZG93SWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogd2luZG93SWRlbnRpdHkudXVpZCwgbmFtZTogJ3lhaG9vX3ZpZXcnIH0pO1xuICAgICAqIC8vIHJlcGFyZW50IGBleGFtcGxlX3ZpZXdgIHdoZW4gYSB2aWV3IGluIHRoZSBuZXcgd2luZG93IGlzIHNob3duXG4gICAgICogdmlldy5vbignc2hvd24nLCBhc3luYyAoKSA9PiB7XG4gICAgICogICAgIGxldCB2aWV3SWRlbnRpdHkgPSB7IHV1aWQ6IHdpbmRvd0lkZW50aXR5LnV1aWQsIG5hbWU6ICdleGFtcGxlX3ZpZXcnfTtcbiAgICAgKiAgICAgbGV0IHRhcmdldCA9IHt1dWlkOiB3aW5kb3dJZGVudGl0eS51dWlkLCBuYW1lOiAndGVzdF93aW4nfTtcbiAgICAgKiAgICAgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgdGFyZ2V0KTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIGNyZWF0ZSBhIG5ldyB3aW5kb3dcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5jcmVhdGVXaW5kb3coe1xuICAgICAqICAgICBuYW1lOiBcInRlc3Rfd2luXCIsXG4gICAgICogICAgIGxheW91dDoge1xuICAgICAqICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgKiAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAneWFob29fdmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8veWFob28uY29tJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIF1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVZpZXcodmlld09wdGlvbnMsIHRhcmdldCwgdGFyZ2V0Vmlldykge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tY3JlYXRlLXZpZXcnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnY3JlYXRlLXZpZXcnLCB7XG4gICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICBvcHRzOiB2aWV3T3B0aW9ucyxcbiAgICAgICAgICAgIHRhcmdldFZpZXdcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghcmVzcG9uc2UgfHwgKDAsIHZhbGlkYXRlXzEkMS52YWxpZGF0ZUlkZW50aXR5KShyZXNwb25zZS5pZGVudGl0eSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgV2hlbiBvdmVyd3JpdGluZyB0aGUgY3JlYXRlVmlldyBjYWxsLCBwbGVhc2UgcmV0dXJuIGFuIG9iamVjdCB0aGF0IGhhcyBhIHZhbGlkICdpZGVudGl0eScgcHJvcGVydHk6ICR7SlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmZpbi5WaWV3LndyYXBTeW5jKHJlc3BvbnNlLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBXaW5kb3cuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgV2luZG93IGNyZWF0aW9uIG9wdGlvbnNcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoZXJlIGFyZSB0d28gV2luZG93IHR5cGVzIGF0IHlvdXIgZGlzcG9zYWwgd2hpbGUgdXNpbmcgT3BlbkZpbiBQbGF0Zm9ybXMgLSBEZWZhdWx0IFdpbmRvdyBhbmQgQ3VzdG9tIFdpbmRvdy5cbiAgICAgKlxuICAgICAqIFRoZSBEZWZhdWx0IFdpbmRvdyB1c2VzIHRoZSBzdGFuZGFyZCBPcGVuRmluIFdpbmRvdyBVSS4gSXQgY29udGFpbnMgdGhlIHN0YW5kYXJkIGNsb3NlLCBtYXhpbWl6ZSBhbmQgbWluaW1pemUgYnV0dG9ucyxcbiAgICAgKiBhbmQgd2lsbCBhdXRvbWF0aWNhbGx5IHJlbmRlciB0aGUgV2luZG93J3MgbGF5b3V0IGlmIG9uZSBpcyBzcGVjaWZpZWQuXG4gICAgICpcbiAgICAgKiBGb3IgZGVlcGVyIGN1c3RvbWl6YXRpb24sIHlvdSBjYW4gYnJpbmcgeW91ciBvd24gV2luZG93IGNvZGUgaW50byBhIFBsYXRmb3JtLiBUaGlzIGlzIGNhbGxlZCBhIEN1c3RvbSBXaW5kb3cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICpcbiAgICAgKiBUaGUgZXhhbXBsZSBiZWxvdyB3aWxsIGNyZWF0ZSBhIERlZmF1bHQgV2luZG93IHdoaWNoIHVzZXMgT3BlbkZpbiBkZWZhdWx0IFdpbmRvdyBVSS48YnI+XG4gICAgICogVGhlIFdpbmRvdyBjb250YWlucyB0d28gVmlld3MgaW4gYSBzdGFjayBMYXlvdXQ6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogcGxhdGZvcm0uY3JlYXRlV2luZG93KHtcbiAgICAgKiAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICBjb250ZW50OiBbXG4gICAgICogICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ3ZpZXcnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ3ZpZXcnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMicsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIF1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqIFRoZSBEZWZhdWx0IFdpbmRvdydzIGRlc2lnbiBjYW4gYmUgY3VzdG9taXplZCBieSBzcGVjaWZ5aW5nIHRoZSBgc3R5bGVzaGVldFVybGAgcHJvcGVydHkgaW4gdGhlIG1hbmlmZXN0OlxuICAgICAqXG4gICAgICogYGBganNvblxuICAgICAqIHtcbiAgICAgKiAgICAgcGxhdGZvcm06IHtcbiAgICAgKiAgICAgICAgIGRlZmF1bHRXaW5kb3dPcHRpb25zOiB7XG4gICAgICogICAgICAgICAgICAgc3R5bGVzaGVldFVybDogJ3NvbWUtdXJsLmNzcycsXG4gICAgICogICAgICAgICAgICAgLi4uXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogRm9yIGEgbGlzdCBvZiBjb21tb24gTGF5b3V0IENTUyBjbGFzc2VzIHlvdSBjYW4gb3ZlcnJpZGUgaW4geW91ciBjdXN0b20gc3R5bGVzaGVldCwgc2VlIDxhIGhyZWY9XCJ0dXRvcmlhbC1sYXlvdXRTdHlsZXMuaHRtbFwiPlVzZWZ1bCBMYXlvdXQgQ1NTIENsYXNzZXM8L2E+XG4gICAgICoqXG4gICAgICogVG8gc3BlY2lmeSBhIFBsYXRmb3JtIEN1c3RvbSBXaW5kb3csIHByb3ZpZGUgYSBgdXJsYCBwcm9wZXJ0eSB3aGVuIGNyZWF0aW5nIGEgV2luZG93LlxuICAgICAqIElmIHlvdSBpbnRlbmQgdG8gcmVuZGVyIGEgTGF5b3V0IGluIHlvdXIgQ3VzdG9tIFdpbmRvdywgeW91IG11c3QgYWxzbyBzcGVjaWZ5IGFuIGBIVE1MRWxlbWVudGAgdGhhdCB0aGUgTGF5b3V0IHdpbGwgaW5qZWN0IGludG8gYW5kIHNldCBpdHMgYGlkYCBwcm9wZXJ0eSB0byBgXCJsYXlvdXQtY29udGFpbmVyXCJgLlxuICAgICAqXG4gICAgICogVGhlIGV4YW1wbGUgYmVsb3cgd2lsbCBjcmVhdGUgYSBQbGF0Zm9ybSBDdXN0b20gV2luZG93OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAgICAgLy8gaW4gYW4gT3BlbkZpbiBhcHA6XG4gICAgICogICAgIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogICAgIGNvbnN0IHdpbmRvd0NvbmZpZyA9XG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vd3d3Lm15LWRvbWFpbi5jb20vbXktY3VzdG9tLXdpbmRvdy5odG1sXCIsIC8vIGhlcmUgd2UgcG9pbnQgdG8gd2hlcmUgdGhlIEN1c3RvbSBGcmFtZSBpcyBob3N0ZWQuXG4gICAgICogICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0YWNrXCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImNvbXBvbmVudFwiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogXCJ2aWV3XCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiYXBwICMxXCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJjb21wb25lbnRcIixcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6IFwidmlld1wiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U3RhdGU6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImFwcCAjMlwiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogXCJodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9jYW5hcnkvUGxhdGZvcm0uaHRtbFwiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICBwbGF0Zm9ybS5jcmVhdGVXaW5kb3cod2luZG93Q29uZmlnKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEhlcmUncyBhbiBleGFtcGxlIG9mIGEgbWluaW1hbGlzdCBDdXN0b20gUGxhdGZvcm0gV2luZG93IGltcGxlbWVudGF0aW9uOlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aHRtbD5cbiAgICAgKiAgICAgPGhlYWQ+XG4gICAgICogICAgICAgICA8bWV0YSBjaGFyc2V0PVwidXRmLThcIj5cbiAgICAgKiAgICAgICAgIDxtZXRhIG5hbWU9XCJ2aWV3cG9ydFwiIGNvbnRlbnQ9XCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MVwiPlxuICAgICAqICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIHR5cGU9XCJ0ZXh0L2Nzc1wiIGhyZWY9XCIuL3N0eWxlcy5jc3NcIj5cbiAgICAgKiAgICAgPC9oZWFkPlxuICAgICAqICAgICA8Ym9keT5cbiAgICAgKiAgICAgICAgIDxkaXYgaWQ9XCJvZi1mcmFtZS1tYWluXCI+XG4gICAgICogICAgICAgICAgICAgPGRpdiBpZD1cInRpdGxlLWJhclwiPlxuICAgICAqICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGUtYmFyLWRyYWdnYWJsZVwiPlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInRpdGxlXCI+IFRoaXMgaXMgYSBjdXN0b20gZnJhbWUhIDwvZGl2PlxuICAgICAqICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgKiAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImJ1dHRvbnMtd3JhcHBlclwiPlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvblwiIGlkPVwibWluaW1pemUtYnV0dG9uXCI+PC9kaXY+XG4gICAgICogICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uXCIgaWQ9XCJleHBhbmQtYnV0dG9uXCI+PC9kaXY+XG4gICAgICogICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uXCIgaWQ9XCJjbG9zZS1idXR0b25cIj48L2Rpdj5cbiAgICAgKiAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICAgICAgICAgPGRpdiBpZD1cImxheW91dC1jb250YWluZXJcIj48L2Rpdj4gPCEtLSBPcGVuRmluIGxheW91dCB3b3VsZCBiZSBpbmplY3RlZCBoZXJlIC0tPlxuICAgICAqICAgICAgICAgICAgIDxzY3JpcHQgc3JjPVwiLi9jdXN0b20tZnJhbWUuanNcIj48L3NjcmlwdD5cbiAgICAgKiAgICAgICAgIDwvZGl2PlxuICAgICAqICAgICA8L2JvZHk+XG4gICAgICogPC9odG1sPlxuICAgICAqIGBgYFxuICAgICAqIFlvdXIgQ3VzdG9tIFdpbmRvdyBjYW4gdXNlIGluLWRvbWFpbiByZXNvdXJjZXMgZm9yIGZ1cnRoZXIgY3VzdG9taXphdGlvbiAoc3VjaCBhcyBDU1MsIHNjcmlwdHMsIGV0Yy4pLjxicj5cbiAgICAgKiBGb3IgYSBsaXN0IG9mIGNvbW1vbiBMYXlvdXQgQ1NTIGNsYXNzZXMgeW91IGNhbiBvdmVycmlkZSBpbiB5b3VyIHN0eWxlc2hlZXQsIHNlZSA8YSBocmVmPVwidHV0b3JpYWwtbGF5b3V0U3R5bGVzLmh0bWxcIj5Vc2VmdWwgTGF5b3V0IENTUyBDbGFzc2VzPC9hPlxuICAgICAqXG4gICAgICogVGhlIGV4YW1wbGUgYWJvdmUgd2lsbCByZXF1aXJlIHRoZSBgYm9keWAgZWxlbWVudCB0byBoYXZlIGBoZWlnaHQ6IDEwMCU7YCBzZXQgaW4gb3JkZXIgdG8gcmVuZGVyIHRoZSBsYXlvdXQgY29ycmVjdGx5LlxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVdpbmRvdyhvcHRpb25zKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1jcmVhdGUtd2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgaWYgKCFvcHRpb25zLnJlYXNvbikge1xuICAgICAgICAgICAgb3B0aW9ucy5yZWFzb24gPSAnYXBpLWNhbGwnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdjcmVhdGUtdmlldy1jb250YWluZXInLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSB8fCAoMCwgdmFsaWRhdGVfMSQxLnZhbGlkYXRlSWRlbnRpdHkpKHJlc3BvbnNlLmlkZW50aXR5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXaGVuIG92ZXJ3cml0aW5nIHRoZSBjcmVhdGVXaW5kb3cgY2FsbCwgcGxlYXNlIHJldHVybiBhbiBvYmplY3QgdGhhdCBoYXMgYSB2YWxpZCAnaWRlbnRpdHknIHByb3BlcnR5OiAke0pTT04uc3RyaW5naWZ5KHJlc3BvbnNlKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGlkZW50aXR5IH0gPSByZXNwb25zZTtcbiAgICAgICAgY29uc3QgcmVzID0gdGhpcy5maW4uV2luZG93LndyYXBTeW5jKGlkZW50aXR5KTtcbiAgICAgICAgLy8gd2UgYWRkIHRoZSBpZGVudGl0eSBhdCB0aGUgdG9wIGxldmVsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgICAgICAgcmVzLm5hbWUgPSBpZGVudGl0eS5uYW1lO1xuICAgICAgICByZXMudXVpZCA9IGlkZW50aXR5LnV1aWQ7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBjdXJyZW50IHBsYXRmb3JtLCBhbGwgaXRzIHdpbmRvd3MsIGFuZCB0aGVpciB2aWV3cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogcGxhdGZvcm0ucXVpdCgpO1xuICAgICAqIC8vIEFsbCB3aW5kb3dzL3ZpZXdzIGluIGN1cnJlbnQgbGF5b3V0IHBsYXRmb3JtIHdpbGwgY2xvc2UgYW5kIHBsYXRmb3JtIHdpbGwgc2h1dCBkb3duXG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcXVpdCgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLXF1aXQnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdxdWl0Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBhIHNwZWNpZmllZCB2aWV3IGluIGEgdGFyZ2V0IHdpbmRvdy5cbiAgICAgKiBAcGFyYW0gdmlld0lkZW50aXR5IFZpZXcgaWRlbnRpdHlcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBsZXQgd2luZG93SWRlbnRpdHk7XG4gICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3Qgdmlld09wdGlvbnMgPSB7XG4gICAgICogICAgIG5hbWU6ICd0ZXN0X3ZpZXcnLFxuICAgICAqICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tJ1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzbGVlcChtcykge1xuICAgICAqICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgd2luZG93SWRlbnRpdHkpO1xuICAgICAqIC8vIGEgbmV3IHZpZXcgd2lsbCBub3cgc2hvdyBpbiB0aGUgY3VycmVudCB3aW5kb3dcbiAgICAgKlxuICAgICAqIGF3YWl0IHNsZWVwKDUwMDApO1xuICAgICAqXG4gICAgICogY29uc3Qgdmlld0lkZW50aXR5ID0geyB1dWlkOiB3aW5kb3dJZGVudGl0eS51dWlkLCBuYW1lOiAndGVzdF92aWV3J307XG4gICAgICogcGxhdGZvcm0uY2xvc2VWaWV3KHZpZXdJZGVudGl0eSk7XG4gICAgICogLy8gdGhlIHZpZXcgd2lsbCBub3cgY2xvc2VcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZVZpZXcodmlld0lkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1jbG9zZS12aWV3JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdjbG9zZS12aWV3Jywge1xuICAgICAgICAgICAgdmlldzogdmlld0lkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqKipERVBSRUNBVEVEIC0gcGxlYXNlIHVzZSB7QGxpbmsgUGxhdGZvcm0uY3JlYXRlVmlldyBQbGF0Zm9ybS5jcmVhdGVWaWV3fS4qKipcbiAgICAgKiBSZXBhcmVudHMgYSBzcGVjaWZpZWQgdmlldyBpbiBhIG5ldyB0YXJnZXQgd2luZG93LlxuICAgICAqIEBwYXJhbSB2aWV3SWRlbnRpdHkgVmlldyBpZGVudGl0eVxuICAgICAqIEBwYXJhbSB0YXJnZXQgbmV3IG93bmVyIHdpbmRvdyBpZGVudGl0eVxuICAgICAqXG4gICAgICovXG4gICAgYXN5bmMgcmVwYXJlbnRWaWV3KHZpZXdJZGVudGl0eSwgdGFyZ2V0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUud2FybignUGxhdGZvcm0ucmVwYXJlbnRWaWV3IGhhcyBiZWVuIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgUGxhdGZvcm0uY3JlYXRlVmlldycpO1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tcmVwYXJlbnQtdmlldycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWaWV3SWRlbnRpdHkgPSB7XG4gICAgICAgICAgICAuLi52aWV3SWRlbnRpdHksXG4gICAgICAgICAgICB1dWlkOiB2aWV3SWRlbnRpdHkudXVpZCA/PyB0aGlzLmlkZW50aXR5LnV1aWRcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdmlldyA9IGF3YWl0IHRoaXMuZmluLlZpZXcud3JhcChub3JtYWxpemVkVmlld0lkZW50aXR5KTtcbiAgICAgICAgY29uc3Qgdmlld09wdGlvbnMgPSBhd2FpdCB2aWV3LmdldE9wdGlvbnMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgdGFyZ2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIHRoZSBwbGF0Zm9ybSBpbiBpdHMgY3VycmVudCBzdGF0ZS4gWW91IGNhbiBwYXNzIHRoZSByZXR1cm5pbmcgb2JqZWN0IHRvXG4gICAgICogW1BsYXRmb3JtLmFwcGx5U25hcHNob3Rde0BsaW5rIFBsYXRmb3JtI2FwcGx5U25hcHNob3R9IHRvIGxhdW5jaCBpdC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoZSBzbmFwc2hvdCB3aWxsIGluY2x1ZGUgZGV0YWlscyBzdWNoIGFzIGFuIFtJU08gZm9ybWF0XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiB0aW1lc3RhbXAgb2Ygd2hlbiB0aGUgc25hcHNob3Qgd2FzIHRha2VuLCBPcGVuRmluIHJ1bnRpbWUgdmVyc2lvbiB0aGUgcGxhdGZvcm0gaXMgcnVubmluZyBvbiwgbW9uaXRvciBpbmZvcm1hdGlvblxuICAgICAqIGFuZCB0aGUgbGlzdCBvZiBjdXJyZW50bHkgcnVubmluZyB3aW5kb3dzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHBsYXRmb3JtLmdldFNuYXBzaG90KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1nZXQtc25hcHNob3QnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXQtc25hcHNob3QnKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKipOT1RFKio6IEludGVybmFsIHVzZSBvbmx5LiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdG8gbWFuYWdlIHRoZSBzdGF0ZSBvZiBpbmRpdmlkdWFsIHZpZXdzLlxuICAgICAqXG4gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIGEgc2luZ2xlIHZpZXcncyBvcHRpb25zIGluIGl0cyBjdXJyZW50IHN0YXRlLlxuICAgICAqXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gcmVzdG9yZSBhIHZpZXcgdG8gYSBwcmV2aW91cyBzdGF0ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2aWV3SWRlbnRpdHkgVmlldyBpZGVudGl0eVxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAqIEByZW1hcmtzIFRoaXMgc2xpY2Ugb2Ygc25hcHNob3Qgc3RhdGUgaXMgZXF1aXZhbGVudCB0byB3aGF0IGlzIHN0b3JlZCBhcyBgY29tcG9uZW50U3RhdGVgIGZvciB2aWV3c1xuICAgICAqIHdoZW4gY2FwdHVyaW5nIHBsYXRmb3JtIHN0YXRlIHVzaW5nIFtQbGF0Zm9ybS5nZXRTbmFwc2hvdF17QGxpbmsgUGxhdGZvcm0jZ2V0U25hcHNob3R9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCB1cmwgPSAnaHR0cHM6Ly9nb29nbGUuY29tJztcbiAgICAgKiBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHsgbmFtZTogJ215LXZpZXcnLCB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSwgdXJsIH0pO1xuICAgICAqXG4gICAgICogYXdhaXQgdmlldy5uYXZpZ2F0ZSh1cmwpO1xuICAgICAqXG4gICAgICogY29uc3Qgdmlld1N0YXRlID0gYXdhaXQgcGxhdGZvcm0uZ2V0Vmlld1NuYXBzaG90KHZpZXcuaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2codmlld1N0YXRlKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRWaWV3U25hcHNob3Qodmlld0lkZW50aXR5KSB7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2dldC12aWV3LXNuYXBzaG90JywgeyB2aWV3SWRlbnRpdHkgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBzbmFwc2hvdCB0byBhIHJ1bm5pbmcgUGxhdGZvcm0uXG4gICAgICogUmVxdWVzdGVkIHNuYXBzaG90IG11c3QgYmUgYSB2YWxpZCBTbmFwc2hvdCBvYmplY3QsIG9yIGEgdXJsIG9yIGZpbGVwYXRoIHRvIHN1Y2ggYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQ2FuIG9wdGlvbmFsbHkgY2xvc2UgZXhpc3Rpbmcgd2luZG93cyBhbmQgb3ZlcndyaXRlIGN1cnJlbnQgcGxhdGZvcm0gc3RhdGUgd2l0aCB0aGF0IG9mIGEgc25hcHNob3QuXG4gICAgICpcbiAgICAgKiBUaGUgZnVuY3Rpb24gYWNjZXB0cyBlaXRoZXIgYSBzbmFwc2hvdCB0YWtlbiB1c2luZyB7QGxpbmsgUGxhdGZvcm0jZ2V0U25hcHNob3QgZ2V0U25hcHNob3R9LFxuICAgICAqIG9yIGEgdXJsIG9yIGZpbGVwYXRoIHRvIGEgc25hcHNob3QgSlNPTiBvYmplY3QuXG4gICAgICogQHBhcmFtIHJlcXVlc3RlZFNuYXBzaG90IFNuYXBzaG90IHRvIGFwcGx5LCBvciBhIHVybCBvciBmaWxlcGF0aC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBwYXJhbWV0ZXJzIHRvIHNwZWNpZnkgd2hldGhlciBleGlzdGluZyB3aW5kb3dzIHNob3VsZCBiZSBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXaWxsIGNyZWF0ZSBhbnkgd2luZG93cyBhbmQgdmlld3MgdGhhdCBhcmUgbm90IHJ1bm5pbmcgYnV0IGFyZSBwYXNzZWQgaW4gdGhlIHNuYXBzaG90IG9iamVjdC4gQW55IFZpZXdcbiAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIHNuYXBzaG90IGlzIGFzc2lnbmVkIGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG5hbWUgdG8gYXZvaWQgY29sbGlzaW9ucy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiAvLyBHZXQgYSB3cmFwcGVkIGxheW91dCBwbGF0Zm9ybSBpbnN0YW5jZVxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0ge1xuICAgICAqICAgICB3aW5kb3dzOiBbXG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb21wb25lbnRfWCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly93d3cub3BlbmZpbi5jbydcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb21wb25lbnRfWScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9lbWJlZC13ZWIvY2hhcnQuaHRtbCdcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgXVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHBsYXRmb3JtLmFwcGx5U25hcHNob3Qoc25hcHNob3QpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSW4gcGxhY2Ugb2YgYSBzbmFwc2hvdCBvYmplY3QsIGBhcHBseVNuYXBzaG90YCBjYW4gdGFrZSBhIHVybCBvciBmaWxlcGF0aCBhbmQgdG8gcmV0cmlldmUgYSBKU09OIHNuYXBzaG90LlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogcGxhdGZvcm0uYXBwbHlTbmFwc2hvdCgnaHR0cHM6Ly9hcGkuanNvbmJpbi5pby9iLzVlNmY5MDNlZjQzMzFlNjgxZmMxMjMxZC8xJyk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBPcHRpb25hbGx5LCBgYXBwbHlTbmFwc2hvdGAgY2FuIGNsb3NlIGV4aXN0aW5nIHdpbmRvd3MgYW5kIHJlc3RvcmUgYSBQbGF0Zm9ybSB0byBhIHByZXZpb3VzbHkgc2F2ZWQgc3RhdGUuXG4gICAgICogVGhpcyBpcyBhY2NvbXBsaXNoZWQgYnkgcHJvdmlkaW5nIGB7IGNsb3NlRXhpc3RpbmdXaW5kb3dzOiB0cnVlIH1gIGFzIGFuIG9wdGlvbi5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogLy8gR2V0IGEgd3JhcHBlZCBsYXlvdXQgcGxhdGZvcm0gaW5zdGFuY2VcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICpcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBhZGRWaWV3VG9XaW5kb3cod2luSWQpIHtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHBsYXRmb3JtLmNyZWF0ZVZpZXcoe1xuICAgICAqICAgICAgICAgbmFtZTogJ3Rlc3Rfdmlld18zJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vb3BlbmZpbi5jbydcbiAgICAgKiAgICAgfSwgd2luSWQpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbmRvd1dpdGhUd29WaWV3cygpIHtcbiAgICAgKiAgICAgY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogICAgIHJldHVybiBwbGF0Zm9ybS5jcmVhdGVXaW5kb3coe1xuICAgICAqICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U3RhdGU6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGVzdF92aWV3XzInLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly95YWhvby5jb20nXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbmRvd1dpdGhUd29WaWV3cygpO1xuICAgICAqIC8vIC4uLiB5b3Ugd2lsbCBub3cgc2VlIGEgbmV3IHdpbmRvdyB3aXRoIHR3byB2aWV3cyBpbiBpdFxuICAgICAqXG4gICAgICogLy8gd2UgdGFrZSBhIHNuYXBzaG90IG9mIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBhcHAsIGJlZm9yZSBjaGFuZ2luZyBpdFxuICAgICAqIGNvbnN0IHNuYXBzaG90T2ZJbml0aWFsQXBwU3RhdGUgPSBhd2FpdCBwbGF0Zm9ybS5nZXRTbmFwc2hvdCgpO1xuICAgICAqXG4gICAgICogLy8gbm93IGxldCdzIGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIGFwcDpcbiAgICAgKiBhd2FpdCBhZGRWaWV3VG9XaW5kb3cod2luLmlkZW50aXR5KTtcbiAgICAgKiAvLyAuLi4gdGhlIHdpbmRvdyBub3cgaGFzIHRocmVlIHZpZXdzIGluIGl0XG4gICAgICpcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5hcHBseVNuYXBzaG90KHNuYXBzaG90T2ZJbml0aWFsQXBwU3RhdGUsIHsgY2xvc2VFeGlzdGluZ1dpbmRvd3M6IHRydWUgfSk7XG4gICAgICogLy8gLi4uIHRoZSB3aW5kb3cgd2lsbCByZXZlcnQgdG8gcHJldmlvdXMgc3RhdGUsIHdpdGgganVzdCB0d28gdmlld3NcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGFwcGx5U25hcHNob3QocmVxdWVzdGVkU25hcHNob3QsIG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWFwcGx5LXNuYXBzaG90JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZXJyTXNnID0gJ1JlcXVlc3RlZCBzbmFwc2hvdCBtdXN0IGJlIGEgdmFsaWQgU25hcHNob3Qgb2JqZWN0LCBvciBhIHVybCBvciBmaWxlcGF0aCB0byBzdWNoIGFuIG9iamVjdC4nO1xuICAgICAgICBsZXQgc25hcHNob3Q7XG4gICAgICAgIGlmICh0eXBlb2YgcmVxdWVzdGVkU25hcHNob3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBGZXRjaCBhbmQgcGFyc2Ugc25hcHNob3RcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9jaGFubmVsLndpcmUuc2VuZEFjdGlvbignZ2V0LWFwcGxpY2F0aW9uLW1hbmlmZXN0Jywge1xuICAgICAgICAgICAgICAgICAgICBtYW5pZmVzdFVybDogcmVxdWVzdGVkU25hcHNob3RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzbmFwc2hvdCA9IHJlc3BvbnNlLnBheWxvYWQuZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyTXNnfTogJHtlcnJ9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzbmFwc2hvdCA9IHJlcXVlc3RlZFNuYXBzaG90O1xuICAgICAgICB9XG4gICAgICAgIGlmICghc25hcHNob3Qud2luZG93cykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdhcHBseS1zbmFwc2hvdCcsIHtcbiAgICAgICAgICAgIHNuYXBzaG90LFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgYSBKU09OIG1hbmlmZXN0IHVzaW5nIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIHJldHVybnMgYSBKYXZhc2NyaXB0IG9iamVjdC5cbiAgICAgKiBDYW4gYmUgb3ZlcndyaXR0ZW4gdXNpbmcge0BsaW5rIFBsYXRmb3JtLlBsYXRmb3JtTW9kdWxlLmluaXQgUGxhdGZvcm0uaW5pdH0uXG4gICAgICogQHBhcmFtIG1hbmlmZXN0VXJsIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRvIGZldGNoLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2FuIGJlIG92ZXJ3cml0dGVuIHVzaW5nIHtAbGluayBQbGF0Zm9ybSNpbml0IFBsYXRmb3JtLmluaXR9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKiBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHBsYXRmb3JtLmZldGNoTWFuaWZlc3QoJ2h0dHBzOi8vd3d3LnBhdGgtdG8tbWFuaWZlc3QuY29tL2FwcC5qc29uJyk7XG4gICAgICogY29uc29sZS5sb2cobWFuaWZlc3QpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGZldGNoTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgncGxhdGZvcm0tZmV0Y2gtbWFuaWZlc3QnLCB7IG1hbmlmZXN0VXJsIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYSBtYW5pZmVzdCBieSB1cmwgYW5kIGxhdW5jaGVzIGEgbGVnYWN5IGFwcGxpY2F0aW9uIG1hbmlmZXN0IG9yIHNuYXBzaG90IGludG8gdGhlIHBsYXRmb3JtLiAgUmV0dXJucyBhIHByb21pc2UgdGhhdFxuICAgICAqIHJlc29sdmVzIHRvIHRoZSB3cmFwcGVkIFBsYXRmb3JtLlxuICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRoYXQgd2lsbCBiZSBsYXVuY2hlZCBpbnRvIHRoZSBwbGF0Zm9ybS4gIElmIHRoaXMgYXBwIG1hbmlmZXN0XG4gICAgICogY29udGFpbnMgYSBzbmFwc2hvdCwgdGhhdCB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiAgSWYgbm90LCB0aGUgYXBwbGljYXRpb24gZGVzY3JpYmVkIGluIHN0YXJ0dXBfYXBwIG9wdGlvbnNcbiAgICAgKiB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiBUaGUgYXBwbGljYWJsZSBzdGFydHVwX2FwcCBvcHRpb25zIHdpbGwgYmVjb21lIHtAbGluayBPcGVuRmluLlZpZXdDcmVhdGlvbk9wdGlvbnMgVmlldyBPcHRpb25zfS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIElmIHRoZSBhcHAgbWFuaWZlc3QgY29udGFpbnMgYSBzbmFwc2hvdCwgdGhhdCB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiAgSWYgbm90LCB0aGVcbiAgICAgKiBhcHBsaWNhdGlvbiBkZXNjcmliZWQgaW4gc3RhcnR1cF9hcHAgb3B0aW9ucyB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtIGFzIGEgd2luZG93IHdpdGggYSBzaW5nbGUgdmlldy5cbiAgICAgKiBUaGUgYXBwbGljYWJsZSBzdGFydHVwX2FwcCBvcHRpb25zIHdpbGwgYmVjb21lIFZpZXcgT3B0aW9ucy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqICAgICBhd2FpdCBwbGF0Zm9ybS5sYXVuY2hDb250ZW50TWFuaWZlc3QoJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAuanNvbicpO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgY29udGVudCBsYXVuY2hlZCBzdWNjZXNzZnVsbHkgaW50byBwbGF0Zm9ybWApO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAqIH1cbiAgICAgKiAvLyBGb3IgYSBsb2NhbCBtYW5pZmVzdCBmaWxlOlxuICAgICAqIHRyeSB7XG4gICAgICogICAgIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogICAgIHBsYXRmb3JtLmxhdW5jaENvbnRlbnRNYW5pZmVzdCgnZmlsZTovLy9DOi9zb21lZm9sZGVyL2FwcC5qc29uJyk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBjb250ZW50IGxhdW5jaGVkIHN1Y2Nlc3NmdWxseSBpbnRvIHBsYXRmb3JtYCk7XG4gICAgICogfSBjYXRjaChlKSB7XG4gICAgICogICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgKi9cbiAgICBhc3luYyBsYXVuY2hDb250ZW50TWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWxhdW5jaC1jb250ZW50LW1hbmlmZXN0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHRoaXMuZmV0Y2hNYW5pZmVzdChtYW5pZmVzdFVybCk7XG4gICAgICAgIGNsaWVudC5kaXNwYXRjaCgnbGF1bmNoLWludG8tcGxhdGZvcm0nLCB7IG1hbmlmZXN0LCBtYW5pZmVzdFVybCB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY29udGV4dCBvZiBhIGhvc3Qgd2luZG93LiBUaGUgY29udGV4dCB3aWxsIGJlIGF2YWlsYWJsZSB0byB0aGUgd2luZG93IGl0c2VsZiwgYW5kIHRvIGl0cyBjaGlsZCBWaWV3cy4gSXQgd2lsbCBiZSBzYXZlZCBpbiBhbnkgcGxhdGZvcm0gc25hcHNob3RzLlxuICAgICAqIEl0IGNhbiBiZSByZXRyaWV2ZWQgdXNpbmcge0BsaW5rIFBsYXRmb3JtI2dldFdpbmRvd0NvbnRleHQgZ2V0V2luZG93Q29udGV4dH0uXG4gICAgICogQHBhcmFtIGNvbnRleHQgLSBBIGZpZWxkIHdoZXJlIHNlcmlhbGl6YWJsZSBjb250ZXh0IGRhdGEgY2FuIGJlIHN0b3JlZCB0byBiZSBzYXZlZCBpbiBwbGF0Zm9ybSBzbmFwc2hvdHMuXG4gICAgICogQHBhcmFtIHRhcmdldCAtIEEgdGFyZ2V0IHdpbmRvdyBvciB2aWV3IG1heSBvcHRpb25hbGx5IGJlIHByb3ZpZGVkLiBJZiBubyB0YXJnZXQgaXMgcHJvdmlkZWQsIHRoZSB1cGRhdGUgd2lsbCBiZSBhcHBsaWVkXG4gICAgICogdG8gdGhlIGN1cnJlbnQgd2luZG93IChpZiBjYWxsZWQgZnJvbSBhIFdpbmRvdykgb3IgdGhlIGN1cnJlbnQgaG9zdCB3aW5kb3cgKGlmIGNhbGxlZCBmcm9tIGEgVmlldykuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgY29udGV4dCBkYXRhIG11c3QgYmUgc2VyaWFsaXphYmxlLiAgVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgZnJvbSBhIHdpbmRvdyBvciB2aWV3IHRoYXQgaGFzIGJlZW4gbGF1bmNoZWQgaW50byBhXG4gICAgICogcGxhdGZvcm0uXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBmcm9tIHRoZSB3aW5kb3cgaXRzZWxmLCBvciBmcm9tIGFueSBjaGlsZCB2aWV3LiBDb250ZXh0IGRhdGEgaXMgc2hhcmVkIGJ5IGFsbFxuICAgICAqIGVudGl0aWVzIHdpdGhpbiBhIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogU2V0dGluZyBvd24gY29udGV4dDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGF3YWl0IHBsYXRmb3JtLnNldFdpbmRvd0NvbnRleHQoY29udGV4dERhdGEpO1xuICAgICAqIC8vIENvbnRleHQgb2YgY3VycmVudCB3aW5kb3cgaXMgbm93IHNldCB0byBgY29udGV4dERhdGFgXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoZSBjb250ZXh0IG9mIGFub3RoZXIgd2luZG93IG9yIHZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGNvbnN0IGNvbnRleHREYXRhID0ge1xuICAgICAqICAgICBzZWN1cml0eTogJ1NUT0NLJyxcbiAgICAgKiAgICAgY3VycmVudFZpZXc6ICdkZXRhaWxlZCdcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBjb25zdCB3aW5kb3dPclZpZXdJZGVudGl0eSA9IHsgdXVpZDogZmluLm1lLnV1aWQsIG5hbWU6ICduYW1lT2ZXaW5kb3dPclZpZXcnIH07XG4gICAgICogYXdhaXQgcGxhdGZvcm0uc2V0V2luZG93Q29udGV4dChjb250ZXh0RGF0YSwgd2luZG93T3JWaWV3SWRlbnRpdHkpO1xuICAgICAqIC8vIENvbnRleHQgb2YgdGhlIHRhcmdldCB3aW5kb3cgb3IgdmlldyBpcyBub3cgc2V0IHRvIGBjb250ZXh0RGF0YWBcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEEgdmlldyBjYW4gbGlzdGVuIHRvIGNoYW5nZXMgdG8gaXRzIGhvc3Qgd2luZG93J3MgY29udGV4dCBieSBsaXN0ZW5pbmcgdG8gdGhlIGBob3N0LWNvbnRleHQtY2hhbmdlZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGZpcmUgd2hlbiBhIGhvc3Qgd2luZG93J3MgY29udGV4dCBpcyB1cGRhdGVkIG9yIHdoZW4gdGhlIHZpZXcgaXMgcmVwYXJlbnRlZCB0byBhIG5ldyB3aW5kb3c6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gYSB2aWV3XG4gICAgICogY29uc3QgY29udGV4dENoYW5nZUhhbmRsZXIgPSAoeyBjb250ZXh0IH0pID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0hvc3Qgd2luZG93XFwncyBjb250ZXh0IGhhcyBjaGFuZ2VkLiBOZXcgY29udGV4dCBkYXRhOicsIGNvbnRleHQpO1xuICAgICAqICAgICAvLyByZWFjdCB0byBuZXcgY29udGV4dCBkYXRhIGhlcmVcbiAgICAgKiB9XG4gICAgICogYXdhaXQgZmluLm1lLm9uKCdob3N0LWNvbnRleHQtY2hhbmdlZCcsIGNvbnRleHRDaGFuZ2VIYW5kbGVyKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKiBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGNvbnRleHREYXRhKSAvLyBjb250ZXh0Q2hhbmdlSGFuZGxlciB3aWxsIGxvZyB0aGUgbmV3IGNvbnRleHRcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRvIGxpc3RlbiB0byBhIHdpbmRvdydzIGNvbnRleHQgdXBkYXRlcywgdXNlIHRoZSBgY29udGV4dC1jaGFuZ2VkYCBldmVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gYSB3aW5kb3dcbiAgICAgKiBjb25zdCBjb250ZXh0Q2hhbmdlSGFuZGxlciA9ICh7IGNvbnRleHQgfSkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnVGhpcyB3aW5kb3dcXCdzIGNvbnRleHQgaGFzIGNoYW5nZWQuIE5ldyBjb250ZXh0IGRhdGE6JywgY29udGV4dCk7XG4gICAgICogICAgIC8vIHJlYWN0IHRvIG5ldyBjb250ZXh0IGRhdGEgaGVyZVxuICAgICAqIH1cbiAgICAgKiBhd2FpdCBmaW4ubWUub24oJ2NvbnRleHQtY2hhbmdlZCcsIGNvbnRleHRDaGFuZ2VIYW5kbGVyKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKiBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGNvbnRleHREYXRhKSAvLyBjb250ZXh0Q2hhbmdlSGFuZGxlciB3aWxsIGxvZyB0aGUgbmV3IGNvbnRleHRcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgc2V0V2luZG93Q29udGV4dChjb250ZXh0ID0ge30sIHRhcmdldCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tc2V0LXdpbmRvdy1jb250ZXh0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgc2VyaWFsaXphYmxlIG9iamVjdCBvciBzdHJpbmcgdG8gc2V0IHRoZSBjb250ZXh0LicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5VHlwZSB9ID0gdGFyZ2V0ID8gYXdhaXQgdGhpcy5maW4uU3lzdGVtLmdldEVudGl0eUluZm8odGFyZ2V0LnV1aWQsIHRhcmdldC5uYW1lKSA6IHRoaXMuZmluLm1lO1xuICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3NldC13aW5kb3ctY29udGV4dCcsIHtcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBlbnRpdHlUeXBlLFxuICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQgfHwgeyB1dWlkOiB0aGlzLmZpbi5tZS51dWlkLCBuYW1lOiB0aGlzLmZpbi5tZS5uYW1lIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY29udGV4dCBjb250ZXh0IG9mIGEgaG9zdCB3aW5kb3cgdGhhdCB3YXMgcHJldmlvdXNseSBzZXQgdXNpbmcge0BsaW5rIFBsYXRmb3JtI3NldFdpbmRvd0NvbnRleHQgc2V0V2luZG93Q29udGV4dH0uXG4gICAgICogVGhlIGNvbnRleHQgd2lsbCBiZSBzYXZlZCBpbiBhbnkgcGxhdGZvcm0gc25hcHNob3RzLiAgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gQSB0YXJnZXQgd2luZG93IG9yIHZpZXcgbWF5IG9wdGlvbmFsbHkgYmUgcHJvdmlkZWQuIElmIG5vIHRhcmdldCBpcyBwcm92aWRlZCwgdGFyZ2V0IHdpbGwgYmVcbiAgICAgKiB0aGUgY3VycmVudCB3aW5kb3cgKGlmIGNhbGxlZCBmcm9tIGEgV2luZG93KSBvciB0aGUgY3VycmVudCBob3N0IHdpbmRvdyAoaWYgY2FsbGVkIGZyb20gYSBWaWV3KS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgd2luZG93IGl0c2VsZiwgb3IgZnJvbSBhbnkgY2hpbGQgdmlldy4gQ29udGV4dCBkYXRhIGlzIHNoYXJlZFxuICAgICAqIGJ5IGFsbCBlbnRpdGllcyB3aXRoaW4gYSB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogUmV0cmlldmluZyBjb250ZXh0IGZyb20gY3VycmVudCB3aW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGNvbnN0IGN1c3RvbUNvbnRleHQgPSB7IGFuc3dlcjogNDIgfTtcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGN1c3RvbUNvbnRleHQpO1xuICAgICAqXG4gICAgICogY29uc3QgbXlDb250ZXh0ID0gYXdhaXQgcGxhdGZvcm0uZ2V0V2luZG93Q29udGV4dCgpO1xuICAgICAqIGNvbnNvbGUubG9nKG15Q29udGV4dCk7IC8vIHsgYW5zd2VyOiA0MiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBSZXRyaWV2aW5nIHRoZSBjb250ZXh0IG9mIGFub3RoZXIgd2luZG93IG9yIHZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogY29uc3Qgd2luZG93T3JWaWV3SWRlbnRpdHkgPSB7IHV1aWQ6IGZpbi5tZS51dWlkLCBuYW1lOiAnbmFtZU9mV2luZG93T3JWaWV3JyB9O1xuICAgICAqXG4gICAgICogY29uc3QgdGFyZ2V0V2luZG93Q29udGV4dCA9IGF3YWl0IHBsYXRmb3JtLmdldFdpbmRvd0NvbnRleHQod2luZG93T3JWaWV3SWRlbnRpdHkpO1xuICAgICAqIGNvbnNvbGUubG9nKHRhcmdldFdpbmRvd0NvbnRleHQpOyAvLyBjb250ZXh0IG9mIHRhcmdldCB3aW5kb3dcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0V2luZG93Q29udGV4dCh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWdldC13aW5kb3ctY29udGV4dCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5VHlwZSB9ID0gdGFyZ2V0ID8gYXdhaXQgdGhpcy5maW4uU3lzdGVtLmdldEVudGl0eUluZm8odGFyZ2V0LnV1aWQsIHRhcmdldC5uYW1lKSA6IHRoaXMuZmluLm1lO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXQtd2luZG93LWNvbnRleHQnLCB7XG4gICAgICAgICAgICB0YXJnZXQ6IHRhcmdldCB8fCB7IHV1aWQ6IHRoaXMuZmluLm1lLnV1aWQsIG5hbWU6IHRoaXMuZmluLm1lLm5hbWUgfSxcbiAgICAgICAgICAgIGVudGl0eVR5cGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBhIHdpbmRvdy4gSWYgZW5hYmxlQmVmb3JlVW5sb2FkIGlzIGVuYWJsZWQgaW4gdGhlIFBsYXRmb3JtIG9wdGlvbnMsIGFueSBiZWZvcmV1bmxvYWQgaGFuZGxlciBzZXQgb24gVmlld3Mgd2lsbCBmaXJlXG4gICAgICogVGhpcyBiZWhhdmlvciBjYW4gYmUgZGlzYWJsZWQgYnkgc2V0dGluZyBza2lwQmVmb3JlVW5sb2FkIHRvIGZhbHNlIGluIHRoZSBvcHRpb25zIHBhcmFtZXRlci5cbiAgICAgKiBAcGFyYW0gd2luSWRcbiAgICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhpcyBtZXRob2Qgd29ya3MgYnkgc2V0dGluZyBhIGBjbG9zZS1yZXF1ZXN0ZWRgIGhhbmRsZXIgb24gdGhlIFBsYXRmb3JtIFdpbmRvdy4gSWYgeW91IGhhdmUgeW91ciBvd24gYGNsb3NlLXJlcXVlc3RlZGAgaGFuZGxlciBzZXQgb24gdGhlIFBsYXRmb3JtIFdpbmRvdyBhcyB3ZWxsLFxuICAgICAqIGl0IGlzIHJlY29tbWVuZGVkIHRvIG1vdmUgdGhhdCBsb2dpYyBvdmVyIHRvIHRoZSBbUGxhdGZvcm1Qcm92aWRlci5jbG9zZVdpbmRvd117QGxpbmsgUGxhdGZvcm1Qcm92aWRlciNjbG9zZVdpbmRvd30gb3ZlcnJpZGUgdG8gZW5zdXJlIGl0IHJ1bnMgd2hlbiB0aGUgV2luZG93IGNsb3Nlcy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIENsb3NlIHRoZSBjdXJyZW50IFdpbmRvdyBpbnNpZGUgYSBXaW5kb3cgY29udGV4dFxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBwbGF0Zm9ybS5jbG9zZVdpbmRvdyhmaW4ubWUuaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogLy8gQ2xvc2UgdGhlIFdpbmRvdyBmcm9tIGluc2lkZSBhIFZpZXcgY29udGV4dFxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCBwYXJlbnRXaW5kb3cgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFdpbmRvdygpO1xuICAgICAqIHBsYXRmb3JtLmNsb3NlV2luZG93KHBhcmVudFdpbmRvdy5pZGVudGl0eSk7XG4gICAgICpcbiAgICAgKiAvLyBDbG9zZSB0aGUgV2luZG93IGFuZCBkbyBub3QgZmlyZSB0aGUgYmVmb3JlIHVubG9hZCBoYW5kbGVyIG9uIFZpZXdzXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqIHBsYXRmb3JtLmNsb3NlV2luZG93KGZpbi5tZS5pZGVudGl0eSwgeyBza2lwQmVmb3JlVW5sb2FkOiB0cnVlIH0pO1xuICAgICAqIGBgYFxuICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZVdpbmRvdyh3aW5kb3dJZCwgb3B0aW9ucyA9IHsgc2tpcEJlZm9yZVVubG9hZDogZmFsc2UgfSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tY2xvc2Utd2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnY2xvc2Utd2luZG93JywgeyB3aW5kb3dJZCwgb3B0aW9ucyB9KTtcbiAgICB9XG59XG5JbnN0YW5jZSQyLlBsYXRmb3JtID0gUGxhdGZvcm07XG5fUGxhdGZvcm1fY29ubmVjdFRvUHJvdmlkZXIgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgbGF5b3V0ID0ge307XG5cbnZhciBGYWN0b3J5JDIgPSB7fTtcblxudmFyIEluc3RhbmNlJDEgPSB7fTtcblxudmFyIGNvbW1vblV0aWxzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb21tb25VdGlscywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb21tb25VdGlscy5vdmVycmlkZUZyb21Db21wb3NhYmxlcyA9IGNvbW1vblV0aWxzLmlzVmFsaWRQcmVzZXRUeXBlID0gdm9pZCAwO1xuZnVuY3Rpb24gaXNWYWxpZFByZXNldFR5cGUodHlwZSkge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdjb2x1bW5zJzpcbiAgICAgICAgY2FzZSAnZ3JpZCc6XG4gICAgICAgIGNhc2UgJ3Jvd3MnOlxuICAgICAgICBjYXNlICd0YWJzJzpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmNvbW1vblV0aWxzLmlzVmFsaWRQcmVzZXRUeXBlID0gaXNWYWxpZFByZXNldFR5cGU7XG5mdW5jdGlvbiBvdmVycmlkZUZyb21Db21wb3NhYmxlcyguLi5vdmVycmlkZXMpIHtcbiAgICByZXR1cm4gKGJhc2UpID0+IG92ZXJyaWRlcy5yZWR1Y2VSaWdodCgocCwgYykgPT4gKGIpID0+IGMocChiKSksICh4KSA9PiB4KShiYXNlKTtcbn1cbmNvbW1vblV0aWxzLm92ZXJyaWRlRnJvbUNvbXBvc2FibGVzID0gb3ZlcnJpZGVGcm9tQ29tcG9zYWJsZXM7XG5jb21tb25VdGlscy5kZWZhdWx0ID0geyBpc1ZhbGlkUHJlc2V0VHlwZSB9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX0xheW91dF9sYXlvdXRDbGllbnQ7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW5zdGFuY2UkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZSQxLkxheW91dCA9IHZvaWQgMDtcbmNvbnN0IGxhenlfMSA9IGxhenk7XG5jb25zdCB2YWxpZGF0ZV8xID0gdmFsaWRhdGU7XG5jb25zdCBiYXNlXzEkNSA9IGJhc2U7XG5jb25zdCBjb21tb25fdXRpbHNfMSA9IGNvbW1vblV0aWxzO1xuY29uc3QgbGF5b3V0X2VudGl0aWVzXzEgPSBsYXlvdXRFbnRpdGllcztcbmNvbnN0IGxheW91dF9jb25zdGFudHNfMSQxID0gbGF5b3V0X2NvbnN0YW50cztcbi8qKlxuICpcbiAqIExheW91dHMgZ2l2ZSBhcHAgcHJvdmlkZXJzIHRoZSBhYmlsaXR5IHRvIGVtYmVkIG11bHRpcGxlIHZpZXdzIGluIGEgc2luZ2xlIHdpbmRvdy4gVGhlIExheW91dCBuYW1lc3BhY2VcbiAqIGVuYWJsZXMgdGhlIGluaXRpYWxpemF0aW9uIGFuZCBtYW5pcHVsYXRpb24gb2YgYSB3aW5kb3cncyBMYXlvdXQuIEEgTGF5b3V0IHdpbGxcbiAqIGVtaXQgZXZlbnRzIGxvY2FsbHkgb24gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgbGF5b3V0LWNvbnRhaW5lci5cbiAqXG4gKlxuICogIyMjIExheW91dC5ET01FdmVudHNcbiAqXG4gKiBXaGVuIGEgTGF5b3V0IGlzIGNyZWF0ZWQsIGl0IGVtaXRzIGV2ZW50cyBvbnRvIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRpbmcgdGhlIExheW91dCBjb250YWluZXIuXG4gKiBUaGlzIExheW91dCBjb250YWluZXIgaXMgdGhlIERPTSBlbGVtZW50IHJlZmVyZW5jZWQgYnkgY29udGFpbmVySWQgaW4ge0BsaW5rIExheW91dC5MYXlvdXRNb2R1bGUjaW5pdCBMYXlvdXQuaW5pdH0uXG4gKiBZb3UgY2FuIHVzZSB0aGUgYnVpbHQtaW4gZXZlbnQgZW1pdHRlciB0byBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIHVzaW5nIFthZGRFdmVudExpc3RlbmVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lcikuXG4gKiBUaGUgZXZlbnRzIGFyZSBlbWl0dGVkIHN5bmNocm9ub3VzbHkgYW5kIG9ubHkgaW4gdGhlIHByb2Nlc3Mgd2hlcmUgdGhlIExheW91dCBleGlzdHMuXG4gKiBBbnkgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsZWQgbGlzdGVuZXJzIGFyZSBpZ25vcmVkIGFuZCB3aWxsIGJlIGRpc2NhcmRlZC5cbiAqIElmIHRoZSB0YXJnZXQgRE9NIGVsZW1lbnQgaXMgZGVzdHJveWVkLCBhbnkgZXZlbnRzIHRoYXQgaGF2ZSBiZWVuIHNldCB1cCBvbiB0aGF0IGVsZW1lbnQgd2lsbCBiZSBkZXN0cm95ZWQuXG4gKlxuICogQHJlbWFya3MgVGhlIGJ1aWx0LWluIGV2ZW50IGVtaXR0ZXIgaXMgbm90IGFuIE9wZW5GaW4gZXZlbnQgZW1pdHRlciBzbyBpdCBkb2Vzbid0IHNoYXJlIHByb3BhZ2F0aW9uIHNlbWFudGljcy5cbiAqXG4gKiAjIyMjIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyIFssIG9wdGlvbnNdKTt9XG4gKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBjb25zdCBteUxheW91dENvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsYXlvdXQtY29udGFpbmVyJyk7XG4gKlxuICogbXlMYXlvdXRDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcigndGFiLWNyZWF0ZWQnLCBmdW5jdGlvbihldmVudCkge1xuICogICAgICBjb25zdCB7IHRhYlNlbGVjdG9yIH0gPSBldmVudC5kZXRhaWw7XG4gKiAgICAgIGNvbnN0IHRhYkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJTZWxlY3Rvcik7XG4gKiAgICAgIGNvbnN0IGV4aXN0aW5nQ29sb3IgPSB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvcjtcbiAqICAgICAgdGFiRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcInJlZFwiO1xuICogICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAqICAgICAgICAgIHRhYkVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gZXhpc3RpbmdDb2xvcjtcbiAqICAgICAgfSwgMjAwMCk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqICMjIyMge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9yZW1vdmVFdmVudExpc3RlbmVyIHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIgWywgb3B0aW9uc10pO31cbiAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBganNcbiAqIGNvbnN0IG15TGF5b3V0Q29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xheW91dC1jb250YWluZXInKTtcbiAqXG4gKiBjb25zdCBsaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coZXZlbnQuZGV0YWlsKTtcbiAqICAgICBjb25zb2xlLmxvZygnY29udGFpbmVyLWNyZWF0ZWQgZXZlbnQgZmlyZWQgb25jZSwgcmVtb3ZpbmcgbGlzdGVuZXInKTtcbiAqICAgICBteUxheW91dENvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdjb250YWluZXItY3JlYXRlZCcsIGxpc3RlbmVyKTtcbiAqIH07XG4gKlxuICogbXlMYXlvdXRDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY29udGFpbmVyLWNyZWF0ZWQnLCBsaXN0ZW5lcik7XG4gKiBgYGBcbiAqXG4gKiAjIyMgU3VwcG9ydGVkIGV2ZW50IHR5cGVzIGFyZTpcbiAqXG4gKiAqIHRhYi1jcmVhdGVkXG4gKiAqIGNvbnRhaW5lci1jcmVhdGVkXG4gKiAqIGxheW91dC1zdGF0ZS1jaGFuZ2VkXG4gKiAqIHRhYi1jbG9zZWRcbiAqICogdGFiLWRyb3BwZWRcbiAqXG4gKiAjIyMgTGF5b3V0IERPTSBOb2RlIEV2ZW50c1xuICpcbiAqICMjIyMgdGFiLWNyZWF0ZWRcbiAqIEdlbmVyYXRlZCB3aGVuIGEgdGFiIGlzIGNyZWF0ZWQuICBBcyBhIHVzZXIgZHJhZ3MgYW5kIGRyb3BzIHRhYnMgd2l0aGluIHdpbmRvdywgbmV3IHRhYnMgYXJlIGNyZWF0ZWQuICBBIHNpbmdsZSB2aWV3IG1heSBoYXZlIG11bHRpcGxlIHRhYnMgY3JlYXRlZCBhbmQgZGVzdHJveWVkIGR1cmluZyBpdHMgbGlmZXRpbWUgYXR0YWNoZWQgdG8gYSBzaW5nbGUgd2luZG93LlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWw6XG4gKiB7XG4gKiAgICAgY29udGFpbmVyU2VsZWN0b3I6IFwiY29udGFpbmVyLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgbmFtZTogXCJjb21wb25lbnRfQVwiLFxuICogICAgIHRhYlNlbGVjdG9yOiBcInRhYi1jb21wb25lbnRfQVwiLFxuICogICAgIHRvcGljOiBcIm9wZW5maW4tRE9NLWV2ZW50XCIsXG4gKiAgICAgdHlwZTogXCJ0YWItY3JlYXRlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIyBjb250YWluZXItY3JlYXRlZFxuICogR2VuZXJhdGVkIHdoZW4gYSBjb250YWluZXIgaXMgY3JlYXRlZC4gIEEgc2luZ2xlIHZpZXcgd2lsbCBoYXZlIG9ubHkgb25lIGNvbnRhaW5lciBkdXJpbmcgaXRzIGxpZmV0aW1lIGF0dGFjaGVkIHRvIGEgc2luZ2xlIHdpbmRvdyBhbmQgdGhlIGNvbnRhaW5lcidzIGxpZmVjeWNsZSBpcyB0aWVkIHRvIHRoZSB2aWV3LiAgVG8gZGlzY292ZXIgd2hlbiB0aGUgY29udGFpbmVyIGlzIGRlc3Ryb3llZCwgcGxlYXNlIGxpc3RlbiB0byB2aWV3LWRldGFjaGVkIGV2ZW50LlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWw6XG4gKiB7XG4gKiAgICAgY29udGFpbmVyU2VsZWN0b3I6IFwiY29udGFpbmVyLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgbmFtZTogXCJjb21wb25lbnRfQVwiLFxuICogICAgIHRhYlNlbGVjdG9yOiBcInRhYi1jb21wb25lbnRfQVwiLFxuICogICAgIHRvcGljOiBcIm9wZW5maW4tRE9NLWV2ZW50XCIsXG4gKiAgICAgdHlwZTogXCJjb250YWluZXItY3JlYXRlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIGxheW91dC1zdGF0ZS1jaGFuZ2VkXG4gKiBHZW5lcmF0ZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIGxheW91dCBjaGFuZ2VzIGluIGFueSB3YXksIHN1Y2ggYXMgYSB2aWV3IGFkZGVkL3JlbW92ZWQvcmVwbGFjZWQuIE5vdGUgdGhhdCB0aGlzIGV2ZW50IGNhbiBmaXJlIGZyZXF1ZW50bHkgYXMgdGhlIHVuZGVybHlpbmcgbGF5b3V0IGNhbiBjaGFuZ2UgbXVsdGlwbGUgY29tcG9uZW50cyBmcm9tIGFsbCBraW5kcyBvZiBjaGFuZ2VzIChyZXNpemluZyBmb3IgZXhhbXBsZSkuIEdpdmVuIHRoaXMsIGl0IGlzIHJlY29tbWVuZGVkIHRvIGRlYm91bmNlIHRoaXMgZXZlbnQgYW5kIHRoZW4geW91IGNhbiB1c2UgdGhlIHtAbGluayBMYXlvdXQjZ2V0Q29uZmlnIExheW91dC5nZXRDb25maWd9IEFQSSB0byByZXRyaWV2ZSB0aGUgbW9zdCB1cC10by1kYXRlIHN0YXRlLlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWxcbiAqIHtcbiAqICAgICBjb250YWluZXJTZWxlY3RvcjogXCJjb250YWluZXItY29tcG9uZW50X0FcIixcbiAqICAgICBuYW1lOiBcImNvbXBvbmVudF9BXCIsXG4gKiAgICAgdGFiU2VsZWN0b3I6IFwidGFiLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgdG9waWM6IFwib3BlbmZpbi1ET00tZXZlbnRcIixcbiAqICAgICB0eXBlOiBcImxheW91dC1zdGF0ZS1jaGFuZ2VkXCIsXG4gKiAgICAgdXVpZDogXCJPcGVuRmluIFBPQ1wiXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMjIHRhYi1jbG9zZWRcbiAqIEdlbmVyYXRlZCB3aGVuIGEgdGFiIGlzIGNsb3NlZC5cbiAqIGBgYGpzXG4gKiAvLyBUaGUgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGUgaW4gZXZlbnQuZGV0YWlsOlxuICoge1xuICogICAgIGNvbnRhaW5lclNlbGVjdG9yOiBcImNvbnRhaW5lci1jb21wb25lbnRfQVwiLFxuICogICAgIG5hbWU6IFwiY29tcG9uZW50X0FcIixcbiAqICAgICB0YWJTZWxlY3RvcjogXCJ0YWItY29tcG9uZW50X0FcIixcbiAqICAgICB0b3BpYzogXCJvcGVuZmluLURPTS1ldmVudFwiLFxuICogICAgIHR5cGU6IFwidGFiLWNsb3NlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIixcbiAqICAgICB1cmw6IFwiaHR0cDovL29wZW5maW4uY29cIiAgIC8vIFRoZSB1cmwgb2YgdGhlIHZpZXcgdGhhdCB3YXMgY2xvc2VkLlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIyB0YWItZHJvcHBlZFxuICogR2VuZXJhdGVkIHdoZW4gYSB0YWIgaXMgZHJvcHBlZC5cbiAqIGBgYGpzXG4gKiAvLyBUaGUgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGUgaW4gZXZlbnQuZGV0YWlsOlxuICoge1xuICogICAgIGNvbnRhaW5lclNlbGVjdG9yOiBcImNvbnRhaW5lci1jb21wb25lbnRfQVwiLFxuICogICAgIG5hbWU6IFwiY29tcG9uZW50X0FcIixcbiAqICAgICB0YWJTZWxlY3RvcjogXCJ0YWItY29tcG9uZW50X0FcIixcbiAqICAgICB0b3BpYzogXCJvcGVuZmluLURPTS1ldmVudFwiLFxuICogICAgIHR5cGU6IFwidGFiLWRyb3BwZWRcIixcbiAqICAgICB1dWlkOiBcIk9wZW5GaW4gUE9DXCIsXG4gKiAgICAgdXJsOiBcImh0dHA6Ly9vcGVuZmluLmNvXCIgICAgLy8gVGhlIHVybCBvZiB0aGUgdmlldyBsaW5rZWQgdG8gdGhlIGRyb3BwZWQgdGFiLlxuICogfVxuICogYGBgXG4gKi9cbmNsYXNzIExheW91dCBleHRlbmRzIGJhc2VfMSQ1LkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdHJ1Y3RvcihpZGVudGl0eSwgd2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBMYXppbHkgY29uc3RydWN0ZWQge0BsaW5rIExheW91dEVudGl0aWVzQ2xpZW50fSBib3VuZCB0byB0aGlzIHBsYXRmb3JtJ3MgY2xpZW50IGFuZCBpZGVudGl0eVxuICAgICAgICAgKiBUaGUgY2xpZW50IGlzIGZvciB7QGxpbmsgTGF5b3V0RW50aXRpZXNDb250cm9sbGVyfVxuICAgICAgICAgKi9cbiAgICAgICAgX0xheW91dF9sYXlvdXRDbGllbnQuc2V0KHRoaXMsIG5ldyBsYXp5XzEuTGF6eShhc3luYyAoKSA9PiBsYXlvdXRfZW50aXRpZXNfMS5MYXlvdXROb2RlLm5ld0xheW91dEVudGl0aWVzQ2xpZW50KGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCksIGxheW91dF9jb25zdGFudHNfMSQxLkxBWU9VVF9DT05UUk9MTEVSX0lELCB0aGlzLmlkZW50aXR5KSkpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwbGFjZXMgYSBQbGF0Zm9ybSB3aW5kb3cncyBsYXlvdXQgd2l0aCBhIG5ldyBsYXlvdXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZW1hcmtzIEFueSB2aWV3cyB0aGF0IHdlcmUgaW4gdGhlIG9sZCBsYXlvdXQgYnV0IG5vdCB0aGUgbmV3IGxheW91dCB3aWxsIGJlIGRlc3Ryb3llZC4gVmlld3Mgd2lsbCBiZSBhc3NpZ25lZCBhIHJhbmRvbWx5IGdlbmVyYXRlZCBuYW1lIHRvIGF2b2lkIGNvbGxpc2lvbnMuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSBmaW4ubWUuaWRlbnRpdHk7XG4gICAgICAgICAqIH0gZWxzZSBpZiAoZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICAgICAqIH0gZWxzZSB7XG4gICAgICAgICAqICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluIGEgcGxhdGZvcm0gVmlldyBvciBXaW5kb3cnKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKlxuICAgICAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LndyYXBTeW5jKHdpbmRvd0lkZW50aXR5KTtcbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3QgbmV3TGF5b3V0ID0ge1xuICAgICAgICAgKiAgICAgY29udGVudDogW1xuICAgICAgICAgKiAgICAgICAgIHtcbiAgICAgICAgICogICAgICAgICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgICAgICogICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmV3X2NvbXBvbmVudF9BMScsXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBZmZpbml0eTogJ3BzXzEnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL3d3dy5leGFtcGxlLmNvbSdcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAqICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmV3X2NvbXBvbmVudF9BMicsXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZW1iZWQtd2ViL2NoYXJ0Lmh0bWwnXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgKiAgICAgICAgICAgICBdXG4gICAgICAgICAqICAgICAgICAgfVxuICAgICAgICAgKiAgICAgXVxuICAgICAgICAgKiB9O1xuICAgICAgICAgKlxuICAgICAgICAgKiBsYXlvdXQucmVwbGFjZShuZXdMYXlvdXQpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVwbGFjZSA9IGFzeW5jIChsYXlvdXQpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtcmVwbGFjZScpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlcGxhY2UtbGF5b3V0Jywge1xuICAgICAgICAgICAgICAgIHRhcmdldDogdGhpcy5pZGVudGl0eSxcbiAgICAgICAgICAgICAgICBvcHRzOiB7IGxheW91dCB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGxhY2VzIHRoZSBzcGVjaWZpZWQgdmlldyB3aXRoIGEgdmlldyB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmVtYXJrcyBUaGUgb2xkIHZpZXcgaXMgc3RyaXBwZWQgb2YgaXRzIGxpc3RlbmVycyBhbmQgZWl0aGVyIGNsb3NlZCBvciBhdHRhY2hlZCB0byB0aGUgcHJvdmlkZXIgd2luZG93XG4gICAgICAgICAqIGRlcGVuZGluZyBvbiBgZGV0YWNoT25DbG9zZWAgdmlldyBvcHRpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB2aWV3VG9SZXBsYWNlIElkZW50aXR5IG9mIHRoZSB2aWV3IHRvIGJlIHJlcGxhY2VkXG4gICAgICAgICAqIEBwYXJhbSBuZXdWaWV3IENyZWF0aW9uIG9wdGlvbnMgb2YgdGhlIG5ldyB2aWV3LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBsZXQgY3VycmVudFdpbmRvdztcbiAgICAgICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgKiAgICAgY3VycmVudFdpbmRvdyA9IGZpbi5tZTtcbiAgICAgICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICBjdXJyZW50V2luZG93ID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKTtcbiAgICAgICAgICogfSBlbHNlIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcFN5bmMoY3VycmVudFdpbmRvdy5pZGVudGl0eSk7XG4gICAgICAgICAqIGNvbnN0IHZpZXdUb1JlcGxhY2UgPSAoYXdhaXQgY3VycmVudFdpbmRvdy5nZXRDdXJyZW50Vmlld3MoKSlbMF07XG4gICAgICAgICAqIGNvbnN0IG5ld1ZpZXdDb25maWcgPSB7dXJsOiAnaHR0cHM6Ly9leGFtcGxlLmNvbSd9O1xuICAgICAgICAgKiBhd2FpdCBsYXlvdXQucmVwbGFjZVZpZXcodmlld1RvUmVwbGFjZS5pZGVudGl0eSwgbmV3Vmlld0NvbmZpZyk7XG4gICAgICAgICAqIGBgYFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZXBsYWNlVmlldyA9IGFzeW5jICh2aWV3VG9SZXBsYWNlLCBuZXdWaWV3KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LXJlcGxhY2UtdmlldycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlcGxhY2UtdmlldycsIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3B0czogeyB2aWV3VG9SZXBsYWNlLCBuZXdWaWV3IH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwbGFjZXMgYSBQbGF0Zm9ybSB3aW5kb3cncyBsYXlvdXQgd2l0aCBhIHByZXNldCBsYXlvdXQgYXJyYW5nZW1lbnQgdXNpbmcgdGhlIGV4aXN0aW5nIFZpZXdzIGF0dGFjaGVkIHRvIHRoZSB3aW5kb3cuXG4gICAgICAgICAqIFRoZSBwcmVzZXQgb3B0aW9ucyBhcmUgYGNvbHVtbnNgLCBgZ3JpZGAsIGByb3dzYCwgYW5kIGB0YWJzYC5cbiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgTWFuZGF0b3J5IG9iamVjdCB3aXRoIGBwcmVzZXRUeXBlYCBwcm9wZXJ0eSB0aGF0IHNldHMgd2hpY2ggcHJlc2V0IGxheW91dCBhcnJhbmdlbWVudCB0byB1c2UuXG4gICAgICAgICAqIFRoZSBwcmVzZXQgb3B0aW9ucyBhcmUgYGNvbHVtbnNgLCBgZ3JpZGAsIGByb3dzYCwgYW5kIGB0YWJzYC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogbGV0IHdpbmRvd0lkZW50aXR5O1xuICAgICAgICAgKiBpZiAoZmluLm1lLmlzV2luZG93KSB7XG4gICAgICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IChhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFdpbmRvdygpKS5pZGVudGl0eTtcbiAgICAgICAgICogfSBlbHNlIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcFN5bmMod2luZG93SWRlbnRpdHkpO1xuICAgICAgICAgKiBhd2FpdCBsYXlvdXQuYXBwbHlQcmVzZXQoeyBwcmVzZXRUeXBlOiAnZ3JpZCcgfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIHdhaXQgNSBzZWNvbmRzIHVudGlsIHlvdSBjaGFuZ2UgdGhlIGxheW91dCBmcm9tIGdyaWQgdG8gdGFic1xuICAgICAgICAgKiBhd2FpdCBuZXcgUHJvbWlzZSAocmVzID0+IHNldFRpbWVvdXQocmVzLCA1MDAwKSk7XG4gICAgICAgICAqIGF3YWl0IGxheW91dC5hcHBseVByZXNldCh7IHByZXNldFR5cGU6ICd0YWJzJyB9KTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFwcGx5UHJlc2V0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtYXBwbHktcHJlc2V0JykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5wbGF0Zm9ybS5nZXRDbGllbnQoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgcHJlc2V0VHlwZSB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGlmICghcHJlc2V0VHlwZSB8fCAhKDAsIGNvbW1vbl91dGlsc18xLmlzVmFsaWRQcmVzZXRUeXBlKShwcmVzZXRUeXBlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGFwcGx5IHByZXNldCBsYXlvdXQsIHBsZWFzZSBpbmNsdWRlIGFuIGFwcGxpY2FibGUgcHJlc2V0VHlwZSBwcm9wZXJ0eSBpbiB0aGUgUHJlc2V0TGF5b3V0T3B0aW9ucy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnYXBwbHktcHJlc2V0LWxheW91dCcsIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3B0czogeyBwcmVzZXRUeXBlIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICAgICAgdGhpcy5wbGF0Zm9ybSA9IHRoaXMuZmluLlBsYXRmb3JtLndyYXBTeW5jKHsgdXVpZDogaWRlbnRpdHkudXVpZCB9KTtcbiAgICAgICAgaWYgKGlkZW50aXR5LnV1aWQgPT09IHRoaXMuZmluLm1lLnV1aWQgJiYgaWRlbnRpdHkubmFtZSA9PT0gdGhpcy5maW4ubWUubmFtZSkge1xuICAgICAgICAgICAgdGhpcy5pbml0ID0gdGhpcy5maW4uUGxhdGZvcm0uTGF5b3V0LmluaXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgd2luZG93J3MgbGF5b3V0LiAgUmV0dXJucyB0aGUgc2FtZSBpbmZvcm1hdGlvbiB0aGF0IGlzIHJldHVybmVkIGZvciBhbGwgd2luZG93cyBpbiBnZXRTbmFwc2hvdC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIENhbm5vdCBiZSBjYWxsZWQgZnJvbSBhIFZpZXcuXG4gICAgICpcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gZ2V0IHRoZSBsYXlvdXQgY29uZmlndXJhdGlvbiBvZiB0aGUgY3VycmVudCB3aW5kb3cncyBMYXlvdXQ6XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldENvbmZpZygpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2xheW91dC1nZXQtY29uZmlnJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5wbGF0Zm9ybS5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0LWZyYW1lLXNuYXBzaG90Jywge1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGF0dGFjaGVkIHZpZXdzIGluIGN1cnJlbnQgd2luZG93IGxheW91dC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3Qgdmlld3MgPSBhd2FpdCBsYXlvdXQuZ2V0Q3VycmVudFZpZXdzKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0Q3VycmVudFZpZXdzKCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LWdldC12aWV3cycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHZpZXdJZGVudGl0aWVzID0gYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdnZXQtbGF5b3V0LXZpZXdzJywge1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdmlld0lkZW50aXRpZXMubWFwKChpZGVudGl0eSkgPT4gdGhpcy5maW4uVmlldy53cmFwU3luYyhpZGVudGl0eSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIHRvcCBsZXZlbCBjb250ZW50IGl0ZW0gb2YgdGhlIGxheW91dC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIENhbm5vdCBiZSBjYWxsZWQgZnJvbSBhIHZpZXcuXG4gICAgICpcbiAgICAgKlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGlmICghZmluLm1lLmlzV2luZG93KSB7XG4gICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIEZyb20gdGhlIGxheW91dCB3aW5kb3dcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogLy8gUmV0cmlldmVzIHRoZSBDb2x1bW5PclJvdyBpbnN0YW5jZVxuICAgICAqIGNvbnN0IHJvb3RJdGVtID0gYXdhaXQgbGF5b3V0LmdldFJvb3RJdGVtKCk7XG4gICAgICogY29uc3QgY29udGVudCA9IGF3YWl0IHJvb3RJdGVtLmdldENvbnRlbnQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhgVGhlIHJvb3QgQ29sdW1uT3JSb3cgaW5zdGFuY2UgaGFzICR7Y29udGVudC5sZW5ndGh9IGl0ZW0ocylgKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRSb290SXRlbSgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2xheW91dC1nZXQtcm9vdC1pdGVtJykuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDQodGhpcywgX0xheW91dF9sYXlvdXRDbGllbnQsIFwiZlwiKS5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCByb290ID0gYXdhaXQgY2xpZW50LmdldFJvb3QoJ2xheW91dE5hbWUnIGluIHRoaXMuaWRlbnRpdHkgPyB0aGlzLmlkZW50aXR5IDogdW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIGxheW91dF9lbnRpdGllc18xLkxheW91dE5vZGUuZ2V0RW50aXR5KHJvb3QsIGNsaWVudCk7XG4gICAgfVxufVxuSW5zdGFuY2UkMS5MYXlvdXQgPSBMYXlvdXQ7XG5fTGF5b3V0X2xheW91dENsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDMgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDMgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9MYXlvdXRNb2R1bGVfaW5zdGFuY2VzLCBfTGF5b3V0TW9kdWxlX2xheW91dEluaXRpYWxpemF0aW9uQXR0ZW1wdGVkLCBfTGF5b3V0TW9kdWxlX2xheW91dE1hbmFnZXIsIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweSwgX0xheW91dE1vZHVsZV9nZXRTYWZlTGF5b3V0TWFuYWdlcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuRmFjdG9yeSQyLkxheW91dE1vZHVsZSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSQ0ID0gYmFzZTtcbmNvbnN0IEluc3RhbmNlXzEkMiA9IEluc3RhbmNlJDE7XG5jb25zdCBsYXlvdXRfY29uc3RhbnRzXzEgPSBsYXlvdXRfY29uc3RhbnRzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIExheW91dH0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLlBsYXRmb3JtLkxheW91dGAuXG4gKi9cbmNsYXNzIExheW91dE1vZHVsZSBleHRlbmRzIGJhc2VfMSQ0LkJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcy5hZGQodGhpcyk7XG4gICAgICAgIF9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQuc2V0KHRoaXMsIGZhbHNlKTtcbiAgICAgICAgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLnNldCh0aGlzLCBudWxsKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXRpYWxpemUgdGhlIHdpbmRvdydzIExheW91dC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgTXVzdCBiZSBjYWxsZWQgZnJvbSBhIGN1c3RvbSB3aW5kb3cgdGhhdCBoYXMgYSAnbGF5b3V0JyBvcHRpb24gc2V0IHVwb24gY3JlYXRpb24gb2YgdGhhdCB3aW5kb3cuXG4gICAgICAgICAqIElmIGEgY29udGFpbmVySWQgaXMgbm90IHByb3ZpZGVkLCB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBmaW5kIGFuIGVsZW1lbnQgd2l0aCB0aGUgaWQgYGxheW91dC1jb250YWluZXJgLlxuICAgICAgICAgKiBBIExheW91dCB3aWxsIGVtaXQgZXZlbnRzIGxvY2FsbHkgb24gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgbGF5b3V0LWNvbnRhaW5lci5cbiAgICAgICAgICogSW4gb3JkZXIgdG8gY2FwdHVyZSB0aGUgcmVsZXZhbnQgZXZlbnRzIGR1cmluZyBMYXlvdXQgaW5pdGlhdGlvbiwgc2V0IHVwIHRoZSBsaXN0ZW5lcnMgb24gdGhlIERPTSBlbGVtZW50IHByaW9yIHRvIGNhbGxpbmcgYGluaXRgLlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIExheW91dCBpbml0IG9wdGlvbnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogLy8gSWYgbm8gb3B0aW9ucyBhcmUgaW5jbHVkZWQsIHRoZSBsYXlvdXQgaW4gdGhlIHdpbmRvdyBvcHRpb25zIGlzIGluaXRpYWxpemVkIGluIGFuIGVsZW1lbnQgd2l0aCB0aGUgaWQgYGxheW91dC1jb250YWluZXJgXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5MYXlvdXQuaW5pdCgpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogPGJyPlxuICAgICAgICAgKlxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBjb25zdCBjb250YWluZXJJZCA9ICdteS1jdXN0b20tY29udGFpbmVyLWlkJztcbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3QgbXlMYXlvdXRDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjb250YWluZXJJZCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIG15TGF5b3V0Q29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RhYi1jcmVhdGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICogICAgIGNvbnN0IHsgdGFiU2VsZWN0b3IgfSA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICogICAgIGNvbnN0IHRhYkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJTZWxlY3Rvcik7XG4gICAgICAgICAqICAgICBjb25zdCBleGlzdGluZ0NvbG9yID0gdGFiRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAqICAgICB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgICAgICAqICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICogICAgICAgICB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGV4aXN0aW5nQ29sb3I7XG4gICAgICAgICAqICAgICB9LCAyMDAwKTtcbiAgICAgICAgICogfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIGluaXRpYWxpemUgdGhlIGxheW91dCBpbnRvIGFuIGV4aXN0aW5nIEhUTUwgZWxlbWVudCB3aXRoIHRoZSBkaXYgYG15LWN1c3RvbS1jb250YWluZXItaWRgXG4gICAgICAgICAqIC8vIHRoZSB3aW5kb3cgbXVzdCBoYXZlIGJlZW4gY3JlYXRlZCB3aXRoIGEgbGF5b3V0IGluIGl0cyB3aW5kb3cgb3B0aW9uc1xuICAgICAgICAgKiBjb25zdCBsYXlvdXQgPSBhd2FpdCBmaW4uUGxhdGZvcm0uTGF5b3V0LmluaXQoeyBjb250YWluZXJJZCB9KTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmluaXQgPSBhc3luYyAob3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LWluaXQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMud2lyZS5lbnZpcm9ubWVudC5sYXlvdXRBbGxvd2VkSW5Db250ZXh0KHRoaXMuZmluKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTGF5b3V0LmluaXQgY2FuIG9ubHkgYmUgY2FsbGVkIGZyb20gYSBXaW5kb3cgY29udGV4dC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRJbml0aWFsaXphdGlvbkF0dGVtcHRlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMYXlvdXQuaW5pdCB3YXMgYWxyZWFkeSBjYWxsZWQsIHBsZWFzZSB1c2UgTGF5b3V0LmNyZWF0ZSB0byBhZGQgYWRkaXRpb25hbCBsYXlvdXRzLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMud2lyZS5lbnZpcm9ubWVudC50eXBlID09PSAnb3BlbmZpbicpIHtcbiAgICAgICAgICAgICAgICAvLyBwcmVsb2FkIHRoZSBjbGllbnRcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpLmdldENsaWVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQsIHRydWUsIFwiZlwiKTtcbiAgICAgICAgICAgIC8vIFRPRE86IHJlbmFtZSB0byBjcmVhdGVMYXlvdXRNYW5hZ2VyXG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLCBhd2FpdCB0aGlzLndpcmUuZW52aXJvbm1lbnQuaW5pdExheW91dE1hbmFnZXIodGhpcy5maW4sIHRoaXMud2lyZSwgb3B0aW9ucyksIFwiZlwiKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5hcHBseUxheW91dFNuYXBzaG90KHRoaXMuZmluLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLCBcImZcIiksIG9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgbWVJZGVudGl0eSA9IHsgbmFtZTogdGhpcy5maW4ubWUubmFtZSwgdXVpZDogdGhpcy5maW4ubWUudXVpZCB9O1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmxheW91dE1hbmFnZXJPdmVycmlkZSkge1xuICAgICAgICAgICAgICAgIC8vIENPUkUtMTA4MSB0byBiZSByZW1vdmVkIHdoZW4gd2UgYWN0dWFsbHkgZGVsZXRlIHRoZSBgbGF5b3V0TWFuYWdlcmAgcHJvcFxuICAgICAgICAgICAgICAgIC8vIGluIHNpbmdsZS1sYXlvdXQgY2FzZSwgd2UgcmV0dXJuIHRoZSB1bmRvY3VtZW50ZWQgbGF5b3V0TWFuYWdlciB0eXBlXG4gICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0SWRlbnRpdHkgPSB7IGxheW91dE5hbWU6IGxheW91dF9jb25zdGFudHNfMS5ERUZBVUxUX0xBWU9VVF9LRVksIC4uLm1lSWRlbnRpdHkgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweSwgXCJmXCIpLmNhbGwodGhpcywgbGF5b3V0SWRlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcFN5bmMobWVJZGVudGl0eSk7XG4gICAgICAgIH07XG4gICAgICAgIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweS5zZXQodGhpcywgKGxheW91dElkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSAnW0xheW91dF0gWW91IGFyZSB1c2luZyBhIGRlcHJlY2F0ZWQgcHJvcGVydHkgYGxheW91dE1hbmFnZXJgIC0gaXQgd2lsbCB0aHJvdyBpZiB5b3UgYWNjZXNzIGl0IHN0YXJ0aW5nIGluIHYzNy4nO1xuICAgICAgICAgICAgY29uc3QgbWFuYWdlclByb3h5ID0gbmV3IFByb3h5KHt9LCB7XG4gICAgICAgICAgICAgICAgZ2V0KHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgW0xheW91dC1tZ3ItcHJveHldIGFjY2Vzc2luZyAke2tleS50b1N0cmluZygpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGxheW91dCA9IE9iamVjdC5hc3NpZ24odGhpcy53cmFwU3luYyhsYXlvdXRJZGVudGl0eSksIHsgbGF5b3V0TWFuYWdlcjogbWFuYWdlclByb3h5IH0pO1xuICAgICAgICAgICAgY29uc3QgbGF5b3V0UHJveHkgPSBuZXcgUHJveHkobGF5b3V0LCB7XG4gICAgICAgICAgICAgICAgZ2V0KHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT09ICdsYXlvdXRNYW5hZ2VyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbTGF5b3V0LXByb3h5XSBhY2Nlc3NpbmcgJHtrZXkudG9TdHJpbmcoKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBsYXlvdXRQcm94eTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBsYXlvdXQgbWFuYWdlciBmb3IgdGhlIGN1cnJlbnQgd2luZG93XG4gICAgICAgICAqIEByZXR1cm5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmdldEN1cnJlbnRMYXlvdXRNYW5hZ2VyU3luYyA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9pbnN0YW5jZXMsIFwibVwiLCBfTGF5b3V0TW9kdWxlX2dldFNhZmVMYXlvdXRNYW5hZ2VyKS5jYWxsKHRoaXMsIGBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRMYXlvdXRNYW5hZ2VyU3luYygpYCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY3JlYXRlID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQuY3JlYXRlTGF5b3V0KF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMyh0aGlzLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcywgXCJtXCIsIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIpLmNhbGwodGhpcywgYGZpbi5QbGF0Zm9ybS5MYXlvdXQuY3JlYXRlKClgKSwgb3B0aW9ucyk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZGVzdHJveSA9IGFzeW5jIChsYXlvdXRJZGVudGl0eSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5lbnZpcm9ubWVudC5kZXN0cm95TGF5b3V0KF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMyh0aGlzLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcywgXCJtXCIsIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIpLmNhbGwodGhpcywgYGZpbi5QbGF0Zm9ybS5MYXlvdXQuZGVzdHJveSgpYCksIGxheW91dElkZW50aXR5KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgKiBpZiAoIWZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgbGF5b3V0ID0gYXdhaXQgZmluLlBsYXRmb3JtLkxheW91dC53cmFwKHdpbmRvd0lkZW50aXR5KTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBsYXlvdXRDb25maWcgPSBhd2FpdCBsYXlvdXQuZ2V0Q29uZmlnKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LXdyYXAnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IEluc3RhbmNlXzEkMi5MYXlvdXQoaWRlbnRpdHksIHRoaXMud2lyZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgKiBpZiAoIWZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgbGF5b3V0ID0gZmluLlBsYXRmb3JtLkxheW91dC53cmFwU3luYyh3aW5kb3dJZGVudGl0eSk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDIuTGF5b3V0KGlkZW50aXR5LCB0aGlzLndpcmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgTGF5b3V0IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBXaW5kb3cncyBsYXlvdXQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbGF5b3V0ID0gYXdhaXQgZmluLlBsYXRmb3JtLkxheW91dC5nZXRDdXJyZW50KCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtZ2V0LWN1cnJlbnQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXRoaXMuZmluLm1lLmlzV2luZG93KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IGluIGEgV2luZG93IGNvbnRleHQuICBPbmx5IFdpbmRvd3MgY2FuIGhhdmUgYSBMYXlvdXQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSB0aGlzLmZpbi5tZTtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQsIG5hbWUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2Fubm90IGJlIGNhbGxlZCBmcm9tIGEgdmlldy5cbiAgICAgKlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQuZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBsYXlvdXRDb25maWcgPSBhd2FpdCBsYXlvdXQuZ2V0Q29uZmlnKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q3VycmVudFN5bmMoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtZ2V0LWN1cnJlbnQtc3luYycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghdGhpcy5maW4ubWUuaXNXaW5kb3cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgaW4gYSBXaW5kb3cgY29udGV4dC4gIE9ubHkgV2luZG93cyBjYW4gaGF2ZSBhIExheW91dC4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMuZmluLm1lO1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG4gICAgfVxufVxuRmFjdG9yeSQyLkxheW91dE1vZHVsZSA9IExheW91dE1vZHVsZTtcbl9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2xheW91dE1hbmFnZXIgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2dldExheW91dE1hbmFnZXJTcHkgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcyA9IG5ldyBXZWFrU2V0KCksIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIgPSBmdW5jdGlvbiBfTGF5b3V0TW9kdWxlX2dldFNhZmVMYXlvdXRNYW5hZ2VyKG1ldGhvZCkge1xuICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0TWFuYWdlciwgXCJmXCIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgWW91IG11c3QgY2FsbCBpbml0IGJlZm9yZSB1c2luZyB0aGUgQVBJICR7bWV0aG9kfWApO1xuICAgIH1cbiAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0TWFuYWdlciwgXCJmXCIpO1xufTtcblxuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdC8qKlxuXHQgKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYExheW91dGAgc3Vic2V0IG9mIHRoZSBgUGxhdGZvcm1gIEFQSSAoYGZpbi5QbGF0Zm9ybS5MYXlvdXRgKS5cblx0ICpcblx0ICogKiB7QGxpbmsgTGF5b3V0TW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYExheW91dGAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5QbGF0Zm9ybS5MYXlvdXRgLlxuXHQgKiAqIHtAbGluayBMYXlvdXR9IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIExheW91dCwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlBsYXRmb3JtLkxheW91dC5nZXRDdXJyZW50YC5cblx0ICpcblx0ICogVGhlc2UgYXJlIHNlcGFyYXRlIGNvZGUgZW50aXRpZXMsIGFuZCBhcmUgZG9jdW1lbnRlZCBzZXBhcmF0ZWx5LiBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKlxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnkkMiwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihJbnN0YW5jZSQxLCBleHBvcnRzKTsgXG59IChsYXlvdXQpKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkMywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDMuUGxhdGZvcm1Nb2R1bGUgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEkMyA9IGJhc2U7XG5jb25zdCBJbnN0YW5jZV8xJDEgPSBJbnN0YW5jZSQyO1xuY29uc3QgaW5kZXhfMSQxID0gbGF5b3V0O1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIFBsYXRmb3JtfSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uUGxhdGZvcm1gLlxuICovXG5jbGFzcyBQbGF0Zm9ybU1vZHVsZSBleHRlbmRzIGJhc2VfMSQzLkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIGNoYW5uZWwpIHtcbiAgICAgICAgc3VwZXIod2lyZSk7XG4gICAgICAgIHRoaXMuX2NoYW5uZWwgPSBjaGFubmVsO1xuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogQGRlc2MgTGF5b3V0cyBnaXZlIGFwcCBwcm92aWRlcnMgdGhlIGFiaWxpdHkgdG8gZW1iZWQgbXVsdGlwbGUgdmlld3MgaW4gYSBzaW5nbGUgd2luZG93LiAgVGhlIExheW91dCBuYW1lc3BhY2VcbiAgICAgICAgICogZW5hYmxlcyB0aGUgaW5pdGlhbGl6YXRpb24gYW5kIG1hbmlwdWxhdGlvbiBvZiBhIHdpbmRvdydzIExheW91dC4gIEEgTGF5b3V0IHdpbGxcbiAgICAgICAgICogPGEgaHJlZj1cInR1dG9yaWFsLUxheW91dC5ET01FdmVudHMuaHRtbFwiPmVtaXQgZXZlbnRzIGxvY2FsbHk8L2E+IG9uIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRpbmcgdGhlIGxheW91dC1jb250YWluZXIuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLkxheW91dCA9IG5ldyBpbmRleF8xJDEuTGF5b3V0TW9kdWxlKHRoaXMud2lyZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGEgUGxhdGZvcm0uIE11c3QgYmUgY2FsbGVkIGZyb20gdGhlIFByb3ZpZGVyIHdoZW4gdXNpbmcgYSBjdXN0b20gcHJvdmlkZXIuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBwbGF0Zm9ybSBvcHRpb25zIGluY2x1ZGluZyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZXh0ZW5kIG9yIHJlcGxhY2VcbiAgICAgKiBkZWZhdWx0IFByb3ZpZGVyIGJlaGF2aW9yLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgTXVzdCBiZSBjYWxsZWQgZnJvbSB0aGUgUHJvdmlkZXIgd2hlbiB1c2luZyBhIGN1c3RvbSBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gUHJvdmlkZXIgY29udGV4dFxuICAgICAqIGF3YWl0IGZpbi5QbGF0Zm9ybS5pbml0KCk7XG4gICAgICogLy8gUGxhdGZvcm0gQVBJIGlzIG5vdyBob29rZWQgdXAgYW5kIHdpbmRvd3MgY29udGFpbmVkIGluIHRoZSBtYW5pZmVzdCBzbmFwc2hvdCBhcmUgb3Blbi5cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBQbGF0Zm9ybS5pbml0YCBhY2NlcHRzIGFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCBjYW4gYmUgdXNlZCB0byBleHRlbmQgb3JcbiAgICAgKiByZXBsYWNlIGRlZmF1bHQgUHJvdmlkZXIgYmVoYXZpb3IuIEFzIGFuIGFyZ3VtZW50LCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0aGUgYFByb3ZpZGVyYCBjbGFzcywgd2hpY2ggaXNcbiAgICAgKiB1c2VkIHRvIGhhbmRsZSBQbGF0Zm9ybSBhY3Rpb25zLiBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdpdGggbWV0aG9kcyB0byBoYW5kbGUgUGxhdGZvcm0gQVBJIGFjdGlvbnMuXG4gICAgICogVGhlIHJlY29tbWVuZGVkIGFwcHJvYWNoIGlzIHRvIGV4dGVuZCB0aGUgYFByb3ZpZGVyYCBjbGFzcywgb3ZlcnJpZGluZyB0aGUgbWV0aG9kcyB5b3Ugd2lzaCB0byBhbHRlciwgYW5kIHJldHVybiBhblxuICAgICAqIGluc3RhbmNlIG9mIHlvdXIgc3ViY2xhc3M6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG92ZXJyaWRlQ2FsbGJhY2sgPSBhc3luYyAoUGxhdGZvcm1Qcm92aWRlcikgPT4ge1xuICAgICAqICAgICAvLyBBY3Rpb25zIGNhbiBiZSBwZXJmb3JtZWQgYmVmb3JlIGluaXRpYWxpemF0aW9uLlxuICAgICAqICAgICAvLyBlLmcuIHdlIG1pZ2h0IGF1dGhlbnRpY2F0ZSBhIHVzZXIsIHNldCB1cCBhIENoYW5uZWwsIGV0YyBiZWZvcmUgaW5pdGlhbGl6aW5nIHRoZSBQbGF0Zm9ybS5cbiAgICAgKiAgICAgY29uc3QgeyBtYW5pZmVzdFVybCB9ID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCkuZ2V0SW5mbygpO1xuICAgICAqXG4gICAgICogICAgIC8vIEV4dGVuZCBvciByZXBsYWNlIGRlZmF1bHQgUGxhdGZvcm1Qcm92aWRlciBiZWhhdmlvciBieSBleHRlbmRpbmcgdGhlIFBsYXRmb3JtUHJvdmlkZXIgY2xhc3MuXG4gICAgICogICAgIGNsYXNzIE15T3ZlcnJpZGUgZXh0ZW5kcyBQbGF0Zm9ybVByb3ZpZGVyIHtcbiAgICAgKiAgICAgICAgIC8vIERlZmF1bHQgYmVoYXZpb3IgY2FuIGJlIGNoYW5nZWQgYnkgaW1wbGVtZW50aW5nIG1ldGhvZHMgd2l0aCB0aGUgc2FtZSBuYW1lcyBhcyB0aG9zZSB1c2VkIGJ5IHRoZSBkZWZhdWx0IFBsYXRmb3JtUHJvdmlkZXIuXG4gICAgICogICAgICAgICBhc3luYyBnZXRTbmFwc2hvdCgpIHtcbiAgICAgKiAgICAgICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgZXh0ZW5kaW5nIHRoZSBjbGFzcywgd2UgY2FuIGNhbGwgYHN1cGVyYCBtZXRob2RzIHRvIGFjY2VzcyBkZWZhdWx0IGJlaGF2aW9yLlxuICAgICAqICAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc3VwZXIuZ2V0U25hcHNob3QoKTtcbiAgICAgKiAgICAgICAgICAgICAvLyBCdXQgd2UgY2FuIG1vZGlmeSByZXR1cm4gdmFsdWVzLlxuICAgICAqICAgICAgICAgICAgIHJldHVybiB7IC4uLnNuYXBzaG90LCBhbnN3ZXI6IDQyLCBtYW5pZmVzdFVybCB9O1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICAgICAgYXN5bmMgcmVwbGFjZUxheW91dCh7IG9wdHMsIHRhcmdldCB9KSB7XG4gICAgICogICAgICAgICAgICAgLy8gVG8gZGlzYWJsZSBhbiBBUEkgbWV0aG9kLCBvdmVyd3JpdGUgd2l0aCBhIG5vb3AgZnVuY3Rpb24uXG4gICAgICogICAgICAgICAgICAgcmV0dXJuO1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogICAgIC8vIFJldHVybiBpbnN0YW5jZSB3aXRoIG1ldGhvZHMgdG8gYmUgY29uc3VtZWQgYnkgUGxhdGZvcm0uXG4gICAgICogICAgIC8vIFRoZSByZXR1cm5lZCBvYmplY3QgbXVzdCBpbXBsZW1lbnQgYWxsIG1ldGhvZHMgb2YgdGhlIFBsYXRmb3JtUHJvdmlkZXIgY2xhc3MuXG4gICAgICogICAgIC8vIEJ5IGV4dGVuZGluZyB0aGUgY2xhc3MsIHdlIGNhbiBzaW1wbHkgaW5oZXJpdCBtZXRob2RzIHdlIGRvIG5vdCB3aXNoIHRvIGFsdGVyLlxuICAgICAqICAgICByZXR1cm4gbmV3IE15T3ZlcnJpZGUoKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZmluLlBsYXRmb3JtLmluaXQoe292ZXJyaWRlQ2FsbGJhY2t9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgaW5pdChvcHRpb25zKSB7XG4gICAgICAgIGlmICghZmluLl9faW50ZXJuYWxfLmlzUGxhdGZvcm0gfHwgZmluLm1lLm5hbWUgIT09IGZpbi5tZS51dWlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Zpbi5QbGF0Zm9ybS5pbml0IHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmcm9tIGEgY3VzdG9tIHBsYXRmb3JtIHByb3ZpZGVyIHJ1bm5pbmcgaW4gdGhlIG1haW4gd2luZG93IG9mIHRoZSBhcHBsaWNhdGlvbi4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LmluaXRQbGF0Zm9ybSh0aGlzLmZpbiwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzeW5jaHJvbm91c2x5IHJldHVybnMgYSBQbGF0Zm9ybSBvYmplY3QgdGhhdCByZXByZXNlbnRzIGFuIGV4aXN0aW5nIHBsYXRmb3JtLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHsgaWRlbnRpdHkgfSA9IGZpbi5tZTtcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS53cmFwKGlkZW50aXR5KTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHBsYXRmb3JtLmdldFNuYXBzaG90KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0td3JhcCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMSQxLlBsYXRmb3JtKHsgdXVpZDogaWRlbnRpdHkudXVpZCB9LCB0aGlzLl9jaGFubmVsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleGlzdGluZyBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB7IGlkZW50aXR5IH0gPSBmaW4ubWU7XG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0ud3JhcFN5bmMoaWRlbnRpdHkpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlIHRvIGNvbnRyb2wgbGF5b3V0LCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcGxhdGZvcm0uZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0td3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDEuUGxhdGZvcm0oeyB1dWlkOiBpZGVudGl0eS51dWlkIH0sIHRoaXMuX2NoYW5uZWwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3Qgc25hcHNob3QgPSBhd2FpdCBwbGF0Zm9ybS5nZXRTbmFwc2hvdCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1nZXQtY3VycmVudCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXAoeyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlIHRvIGNvbnRyb2wgbGF5b3V0LCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcGxhdGZvcm0uZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRDdXJyZW50U3luYygpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWdldC1jdXJyZW50LXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQ6IHRoaXMud2lyZS5tZS51dWlkIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuZCBzdGFydHMgYSBQbGF0Zm9ybSBhbmQgcmV0dXJucyBhIHdyYXBwZWQgYW5kIHJ1bm5pbmcgUGxhdGZvcm0gaW5zdGFuY2UuIFRoZSB3cmFwcGVkIFBsYXRmb3JtIG1ldGhvZHMgY2FuXG4gICAgICogYmUgdXNlZCB0byBsYXVuY2ggY29udGVudCBpbnRvIHRoZSBwbGF0Zm9ybS4gIFByb21pc2Ugd2lsbCByZWplY3QgaWYgdGhlIHBsYXRmb3JtIGlzIGFscmVhZHkgcnVubmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5zdGFydCh7XG4gICAgICogICAgICAgICB1dWlkOiAncGxhdGZvcm0tMScsXG4gICAgICogICAgICAgICBhdXRvU2hvdzogZmFsc2UsXG4gICAgICogICAgICAgICBkZWZhdWx0V2luZG93T3B0aW9uczoge1xuICAgICAqICAgICAgICAgICAgIHN0eWxlc2hlZXRVcmw6ICdjc3Mtc2hlZXQtdXJsJyxcbiAgICAgKiAgICAgICAgICAgICBjb3JuZXJSb3VuZGluZzoge1xuICAgICAqICAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwLFxuICAgICAqICAgICAgICAgICAgICAgICB3aWR0aDogMTBcbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqICAgICBjb25zb2xlLmxvZygnUGxhdGZvcm0gaXMgcnVubmluZycsIHBsYXRmb3JtKTtcbiAgICAgKiB9IGNhdGNoKGUpIHtcbiAgICAgKiAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgc3RhcnQocGxhdGZvcm1PcHRpb25zKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1zdGFydCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgdXVpZCB9ID0gcGxhdGZvcm1PcHRpb25zO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSB2YXJpYWJsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLmZpbi5BcHBsaWNhdGlvbi5fY3JlYXRlKHsgLi4ucGxhdGZvcm1PcHRpb25zLCBpc1BsYXRmb3JtQ29udHJvbGxlcjogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgYXBwLm9uY2UoJ3BsYXRmb3JtLWFwaS1yZWFkeScsICgpID0+IHJlc29sdmUodGhpcy53cmFwU3luYyh7IHV1aWQgfSkpKTtcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHVzaW5nIHByaXZhdGUgdmFyaWFibGUuXG4gICAgICAgICAgICAgICAgYXBwLl9ydW4oeyB1dWlkIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgcGxhdGZvcm1zJ3MgbWFuaWZlc3QgYW5kIHJldHVybnMgYSB3cmFwcGVkIGFuZCBydW5uaW5nIFBsYXRmb3JtLiAgSWYgdGhlcmUgaXMgYSBzbmFwc2hvdCBpbiB0aGUgbWFuaWZlc3QsXG4gICAgICogaXQgd2lsbCBiZSBsYXVuY2hlZCBpbnRvIHRoZSBwbGF0Zm9ybS5cbiAgICAgKiBAcGFyYW0gbWFuaWZlc3RVcmwgLSBUaGUgVVJMIG9mIHBsYXRmb3JtJ3MgbWFuaWZlc3QuXG4gICAgICogQHBhcmFtIG9wdHMgLSBQYXJhbWV0ZXJzIHRoYXQgdGhlIFJWTSB3aWxsIHVzZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5zdGFydEZyb21NYW5pZmVzdCgnaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9nb2xkZW4tcHJvdG90eXBlL3B1YmxpYy5qc29uJyk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdQbGF0Zm9ybSBpcyBydW5uaW5nLCB3cmFwcGVkIHBsYXRmb3JtOiAnLCBwbGF0Zm9ybSk7XG4gICAgICogfSBjYXRjaChlKSB7XG4gICAgICogICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICogfVxuICAgICAqIC8vIEZvciBhIGxvY2FsIG1hbmlmZXN0IGZpbGU6XG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uc3RhcnRGcm9tTWFuaWZlc3QoJ2ZpbGU6Ly8vQzovc29tZWZvbGRlci9hcHAuanNvbicpO1xuICAgICAqICAgICBjb25zb2xlLmxvZygnUGxhdGZvcm0gaXMgcnVubmluZywgd3JhcHBlZCBwbGF0Zm9ybTogJywgcGxhdGZvcm0pO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBzdGFydEZyb21NYW5pZmVzdChtYW5pZmVzdFVybCwgb3B0cykge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tc3RhcnQtZnJvbS1tYW5pZmVzdCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSB2YXJpYWJsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLmZpbi5BcHBsaWNhdGlvbi5fY3JlYXRlRnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgYXBwLm9uY2UoJ3BsYXRmb3JtLWFwaS1yZWFkeScsICgpID0+IHJlc29sdmUodGhpcy53cmFwU3luYyh7IHV1aWQ6IGFwcC5pZGVudGl0eS51dWlkIH0pKSk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB1c2luZyBwcml2YXRlIG1ldGhvZCB3aXRob3V0IHdhcm5pbmcuXG4gICAgICAgICAgICAgICAgYXBwLl9ydW4ob3B0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuRmFjdG9yeSQzLlBsYXRmb3JtTW9kdWxlID0gUGxhdGZvcm1Nb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgUGxhdGZvcm1gIEFQSSAoYGZpbi5QbGF0Zm9ybWApXG5cdCAqXG5cdCAqICoge0BsaW5rIFBsYXRmb3JtTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYFBsYXRmb3JtYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLlBsYXRmb3JtYC5cblx0ICogKiB7QGxpbmsgUGxhdGZvcm19IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIFBsYXRmb3JtLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudGAuXG5cdCAqXG5cdCAqIFRoZXNlIGFyZSBzZXBhcmF0ZSBjb2RlIGVudGl0aWVzLCBhbmQgYXJlIGRvY3VtZW50ZWQgc2VwYXJhdGVseS4gIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdCAqL1xuXHRfX2V4cG9ydFN0YXIoRmFjdG9yeSQzLCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKEluc3RhbmNlJDIsIGV4cG9ydHMpOyBcbn0gKHBsYXRmb3JtKSk7XG5cbnZhciBtZSA9IHt9O1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLmdldE1lID0gZXhwb3J0cy5nZXRCYXNlTWUgPSBleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlID0gdm9pZCAwO1xuXHRjb25zdCB2aWV3XzEgPSByZXF1aXJlVmlldygpO1xuXHRjb25zdCBmcmFtZV8xID0gZnJhbWU7XG5cdGNvbnN0IHdpbmRvd18xID0gcmVxdWlyZVdpbmRvdygpO1xuXHRjb25zdCBleHRlcm5hbF9hcHBsaWNhdGlvbl8xID0gZXh0ZXJuYWxBcHBsaWNhdGlvbjtcblx0ZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSA9ICdZb3UgYXJlIG5vdCBydW5uaW5nIGluIE9wZW5GaW4uJztcblx0ZnVuY3Rpb24gZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpIHtcblx0ICAgIGNvbnN0IGVudGl0eVR5cGVIZWxwZXJzID0ge1xuXHQgICAgICAgIGlzVmlldzogZW50aXR5VHlwZSA9PT0gJ3ZpZXcnLFxuXHQgICAgICAgIGlzV2luZG93OiBlbnRpdHlUeXBlID09PSAnd2luZG93Jyxcblx0ICAgICAgICBpc0ZyYW1lOiBlbnRpdHlUeXBlID09PSAnaWZyYW1lJyxcblx0ICAgICAgICBpc0V4dGVybmFsOiBlbnRpdHlUeXBlID09PSAnZXh0ZXJuYWwgY29ubmVjdGlvbidcblx0ICAgIH07XG5cdCAgICByZXR1cm4geyAuLi5lbnRpdHlUeXBlSGVscGVycywgdXVpZCwgbmFtZSwgZW50aXR5VHlwZSB9O1xuXHR9XG5cdGV4cG9ydHMuZ2V0QmFzZU1lID0gZ2V0QmFzZU1lO1xuXHQvLyBXZSBuZWVkIHRvIGRvIGEgbG90IG9mIGNhc3RpbmcgYXMgdW5rbm93biBoZXJlIGJlY2F1c2UgdGhlIGNvbXBpbGVyIGdldCdzIGNvbmZ1c2VkIGFib3V0IG1hdGNoaW5nIHR5cGVzLiBXaGF0IG1hdHRlcnMgaXMgdGhhdCBpdCB3b3JrcyBvbiB0aGUgb3V0c2lkZVxuXHRmdW5jdGlvbiBnZXRNZSh3aXJlKSB7XG5cdCAgICBjb25zdCB7IHV1aWQsIG5hbWUsIGVudGl0eVR5cGUgfSA9IHdpcmUubWU7XG5cdCAgICBjb25zdCB1bnN1cHBvcnRlZEludGVyb3AgPSB7XG5cdCAgICAgICAgc2V0Q29udGV4dCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgYWRkQ29udGV4dEhhbmRsZXIoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldENvbnRleHRHcm91cHMoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGpvaW5Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHJlbW92ZUZyb21Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBjb25zdCBmYWxsYmFja0Vycm9yTWVzc2FnZSA9ICdJbnRlcm9wIEFQSSBoYXMgbm90IGJlZW4gaW5zdGFudGlhdGVkLiBFaXRoZXIgY29ubmVjdGlvbiBoYXMgZmFpbGVkIG9yIHlvdSBoYXZlIG5vdCBkZWNsYXJlZCBpbnRlcm9wIGluIHlvdXIgY29uZmlnLic7XG5cdCAgICBjb25zdCBmYWxsYmFja0ludGVyb3AgPSB7XG5cdCAgICAgICAgc2V0Q29udGV4dCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGFkZENvbnRleHRIYW5kbGVyKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0Q29udGV4dEdyb3VwcygpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGpvaW5Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihmYWxsYmFja0Vycm9yTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICByZW1vdmVGcm9tQ29udGV4dEdyb3VwKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgY29uc3QgdW5zdXBwb3J0ZWRFdmVudEJhc2UgPSB7XG5cdCAgICAgICAgZXZlbnROYW1lczogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBlbWl0OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGxpc3RlbmVyczogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBsaXN0ZW5lckNvdW50OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGFkZExpc3RlbmVyOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uY2U6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcHJlcGVuZExpc3RlbmVyOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHByZXBlbmRPbmNlTGlzdGVuZXI6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcmVtb3ZlTGlzdGVuZXI6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcmVtb3ZlQWxsTGlzdGVuZXJzOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgc3dpdGNoIChlbnRpdHlUeXBlKSB7XG5cdCAgICAgICAgY2FzZSAndmlldyc6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB2aWV3XzEuVmlldyh3aXJlLCB7IHV1aWQsIG5hbWUgfSksIGdldEJhc2VNZShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKSwge1xuXHQgICAgICAgICAgICAgICAgaW50ZXJvcDogZmFsbGJhY2tJbnRlcm9wLFxuXHQgICAgICAgICAgICAgICAgaXNPcGVuRmluOiB0cnVlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIGNhc2UgJ3dpbmRvdyc6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB3aW5kb3dfMS5fV2luZG93KHdpcmUsIHsgdXVpZCwgbmFtZSB9KSwgZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpLCB7XG5cdCAgICAgICAgICAgICAgICBpbnRlcm9wOiBmYWxsYmFja0ludGVyb3AsXG5cdCAgICAgICAgICAgICAgICBpc09wZW5GaW46IHRydWVcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgY2FzZSAnaWZyYW1lJzpcblx0ICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IGZyYW1lXzEuX0ZyYW1lKHdpcmUsIHsgdXVpZCwgbmFtZSB9KSwgZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpLCB7XG5cdCAgICAgICAgICAgICAgICBpbnRlcm9wOiBmYWxsYmFja0ludGVyb3AsXG5cdCAgICAgICAgICAgICAgICBpc09wZW5GaW46IHRydWVcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgY2FzZSAnZXh0ZXJuYWwgY29ubmVjdGlvbic6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBleHRlcm5hbF9hcHBsaWNhdGlvbl8xLkV4dGVybmFsQXBwbGljYXRpb24od2lyZSwgeyB1dWlkIH0pLCBnZXRCYXNlTWUoZW50aXR5VHlwZSwgdXVpZCwgbmFtZSksIHtcblx0ICAgICAgICAgICAgICAgIGludGVyb3A6IGZhbGxiYWNrSW50ZXJvcCxcblx0ICAgICAgICAgICAgICAgIGlzT3BlbkZpbjogZmFsc2Vcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgZGVmYXVsdDpcblx0ICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgICAgIC4uLmdldEJhc2VNZShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKSxcblx0ICAgICAgICAgICAgICAgIC4uLnVuc3VwcG9ydGVkRXZlbnRCYXNlLFxuXHQgICAgICAgICAgICAgICAgaW50ZXJvcDogdW5zdXBwb3J0ZWRJbnRlcm9wLFxuXHQgICAgICAgICAgICAgICAgaXNPcGVuRmluOiBmYWxzZVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgfVxuXHR9XG5cdGV4cG9ydHMuZ2V0TWUgPSBnZXRNZTsgXG59IChtZSkpO1xuXG52YXIgaW50ZXJvcCA9IHt9O1xuXG52YXIgRmFjdG9yeSQxID0ge307XG5cbnZhciBpbmFjY2Vzc2libGVPYmplY3QgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGluYWNjZXNzaWJsZU9iamVjdCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlV2FybmluZ09iamVjdCA9IGluYWNjZXNzaWJsZU9iamVjdC5jcmVhdGVVbnVzYWJsZU9iamVjdCA9IHZvaWQgMDtcbmZ1bmN0aW9uIGNyZWF0ZVVudXNhYmxlT2JqZWN0KG1lc3NhZ2UpIHtcbiAgICBjb25zdCBoYW5kbGUgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJveHkoe30sIHtcbiAgICAgICAgYXBwbHk6IGhhbmRsZSxcbiAgICAgICAgY29uc3RydWN0OiBoYW5kbGUsXG4gICAgICAgIGRlZmluZVByb3BlcnR5OiBoYW5kbGUsXG4gICAgICAgIGRlbGV0ZVByb3BlcnR5OiBoYW5kbGUsXG4gICAgICAgIGdldDogaGFuZGxlLFxuICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6IGhhbmRsZSxcbiAgICAgICAgZ2V0UHJvdG90eXBlT2Y6IGhhbmRsZSxcbiAgICAgICAgaGFzOiBoYW5kbGUsXG4gICAgICAgIGlzRXh0ZW5zaWJsZTogaGFuZGxlLFxuICAgICAgICBvd25LZXlzOiBoYW5kbGUsXG4gICAgICAgIHByZXZlbnRFeHRlbnNpb25zOiBoYW5kbGUsXG4gICAgICAgIHNldDogaGFuZGxlLFxuICAgICAgICBzZXRQcm90b3R5cGVPZjogaGFuZGxlXG4gICAgfSk7XG59XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlVW51c2FibGVPYmplY3QgPSBjcmVhdGVVbnVzYWJsZU9iamVjdDtcbmZ1bmN0aW9uIGNyZWF0ZVdhcm5pbmdPYmplY3QobWVzc2FnZSwgb2JqKSB7XG4gICAgcmV0dXJuIG5ldyBQcm94eShvYmosIHtcbiAgICAgICAgZ2V0OiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LnNldCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb3duS2V5czogKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4obWVzc2FnZSk7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlV2FybmluZ09iamVjdCA9IGNyZWF0ZVdhcm5pbmdPYmplY3Q7XG5cbnZhciBJbnRlcm9wQnJva2VyID0ge307XG5cbnZhciBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyID0ge307XG5cbnZhciBoYXNSZXF1aXJlZFNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXI7XG5cbmZ1bmN0aW9uIHJlcXVpcmVTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcikgcmV0dXJuIFNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXI7XG5cdGhhc1JlcXVpcmVkU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0Y29uc3QgXzEgPSByZXF1aXJlSW50ZXJvcCgpO1xuXHRsZXQgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciQxID0gY2xhc3MgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciB7XG5cdCAgICBjb25zdHJ1Y3Rvcihwcm92aWRlciwgaWQpIHtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7XG5cdCAgICAgICAgdGhpcy5pZCA9IGlkO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHQgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0R3JvdXBNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5jbGllbnRzID0gbmV3IE1hcCgpO1xuXHQgICAgICAgIHRoaXMucmVnaXN0ZXJMaXN0ZW5lcnMoKTtcblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoYHNlc3Npb25Db250ZXh0R3JvdXA6Z2V0Q29udGV4dC0ke3RoaXMuaWR9YCwgdGhpcy5nZXRDdXJyZW50Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKGBzZXNzaW9uQ29udGV4dEdyb3VwOnNldENvbnRleHQtJHt0aGlzLmlkfWAsIHRoaXMuc2V0Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKGBzZXNzaW9uQ29udGV4dEdyb3VwOmhhbmRsZXJBZGRlZC0ke3RoaXMuaWR9YCwgdGhpcy5oYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcihgc2Vzc2lvbkNvbnRleHRHcm91cDpoYW5kbGVyUmVtb3ZlZC0ke3RoaXMuaWR9YCwgdGhpcy5oYW5kbGVyUmVtb3ZlZC5iaW5kKHRoaXMpKTtcblx0ICAgIH1cblx0ICAgIGdldEN1cnJlbnRDb250ZXh0KHBheWxvYWQpIHtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC50eXBlID8gdGhpcy5jb250ZXh0R3JvdXBNYXAuZ2V0KHBheWxvYWQudHlwZSkgOiB0aGlzLmxhc3RDb250ZXh0O1xuXHQgICAgfVxuXHQgICAgc2V0Q29udGV4dChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgY29udGV4dCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQgPSBfMS5JbnRlcm9wQnJva2VyLmNoZWNrQ29udGV4dEludGVncml0eShjb250ZXh0KTtcblx0ICAgICAgICBpZiAoY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0LmlzVmFsaWQgPT09IGZhbHNlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHNldCBDb250ZXh0IC0gYmFkIENvbnRleHQuIFJlYXNvbjogJHtjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQucmVhc29ufS4gQ29udGV4dDogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkbid0IGdldCBoaXQuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0gJHtjbGllbnRJZGVudGl0eS5uYW1lfSBub3QgaW4gU2Vzc2lvbiBDbGllbnQgU3RhdGUgTWFwYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vIHNldCB0aGUgY29udGV4dFxuXHQgICAgICAgIHRoaXMuY29udGV4dEdyb3VwTWFwLnNldChjb250ZXh0LnR5cGUsIGNvbnRleHQpO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHQgPSBjb250ZXh0O1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlcyA9IEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKTtcblx0ICAgICAgICBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZXMuZm9yRWFjaCgoY2xpZW50KSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0ICAgICAgICAgICAgY2xpZW50LmNvbnRleHRIYW5kbGVycy5nZXQoY29udGV4dC50eXBlKT8uZm9yRWFjaCgoaGFuZGxlcklkKSA9PiB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudC5jbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGlmIChjbGllbnQuZ2xvYmFsSGFuZGxlcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnQuY2xpZW50SWRlbnRpdHksIGNsaWVudC5nbG9iYWxIYW5kbGVyLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChpZC5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIGFzeW5jIGhhbmRsZXJBZGRlZChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGlmICghY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBJZGVudGl0eTogJHtjbGllbnRJZGVudGl0eS51dWlkfSAke2NsaWVudElkZW50aXR5Lm5hbWV9IG5vdCBpbiBDbGllbnQgU3RhdGUgTWFwYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50SGFuZGxlckxpc3QgPSBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZS5jb250ZXh0SGFuZGxlcnMuZ2V0KGNvbnRleHRUeXBlKSB8fCBbXTtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEhhbmRsZXJzLnNldChjb250ZXh0VHlwZSwgWy4uLmN1cnJlbnRIYW5kbGVyTGlzdCwgaGFuZGxlcklkXSk7XG5cdCAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gdGhpcy5jb250ZXh0R3JvdXBNYXAuZ2V0KGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250ZXh0KSB7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGN1cnJlbnRDb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuZ2xvYmFsSGFuZGxlciA9IGhhbmRsZXJJZDtcblx0ICAgICAgICAgICAgY29uc3QgZ2xvYmFsRGlzcGF0Y2hQcm9taXNlcyA9IFsuLi50aGlzLmNvbnRleHRHcm91cE1hcC5rZXlzKCldLm1hcChhc3luYyAoY3VycmVudENvbnRleHRUeXBlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dCA9IHRoaXMuY29udGV4dEdyb3VwTWFwLmdldChjdXJyZW50Q29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250ZXh0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjdXJyZW50Q29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChnbG9iYWxEaXNwYXRjaFByb21pc2VzKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBoYW5kbGVyUmVtb3ZlZChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCk7XG5cdCAgICAgICAgaWYgKGNsaWVudCkge1xuXHQgICAgICAgICAgICBBcnJheS5mcm9tKGNsaWVudC5jb250ZXh0SGFuZGxlcnMpLmZvckVhY2goKFssIGhhbmRsZXJzXSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBoYW5kbGVycy5pbmRleE9mKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBpZiAoY2xpZW50Lmdsb2JhbEhhbmRsZXIgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50Lmdsb2JhbEhhbmRsZXIgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybihgVHJ5aW5nIHRvIHJlbW92ZSBhIGhhbmRsZXIgZnJvbSBhIGNsaWVudCB0aGF0IGlzbid0IG1hcHBlZC4gaGFuZGxlcklkOiAke2hhbmRsZXJJZH0uIGNsaWVudElkZW50aXR5OiAke2NsaWVudElkZW50aXR5fWApO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTmV3Q2xpZW50KGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlID0ge1xuXHQgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzOiBuZXcgTWFwKCksXG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eSxcblx0ICAgICAgICAgICAgICAgIGdsb2JhbEhhbmRsZXI6IHVuZGVmaW5lZFxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB0aGlzLmNsaWVudHMuc2V0KGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQsIGNsaWVudFN1YnNjcmlwdGlvblN0YXRlKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBvbkRpc2Nvbm5lY3Rpb24oY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpO1xuXHQgICAgfVxuXHR9O1xuXHRTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyLmRlZmF1bHQgPSBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyJDE7XG5cdHJldHVybiBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyO1xufVxuXG52YXIgdXRpbHMkMyA9IHt9O1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLndyYXBJbnRlbnRIYW5kbGVyID0gZXhwb3J0cy5CUk9LRVJfRVJST1JTID0gZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZyA9IGV4cG9ydHMuZ2VuZXJhdGVPdmVycmlkZUVycm9yID0gZXhwb3J0cy53cmFwQ29udGV4dEhhbmRsZXIgPSBleHBvcnRzLndyYXBJblRyeUNhdGNoID0gZXhwb3J0cy5nZW5lcmF0ZUlkID0gdm9pZCAwO1xuXHRjb25zdCBnZW5lcmF0ZUlkID0gKCkgPT4gYCR7TWF0aC5yYW5kb20oKX0ke0RhdGUubm93KCl9YDtcblx0ZXhwb3J0cy5nZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZDtcblx0Y29uc3Qgd3JhcEluVHJ5Q2F0Y2ggPSAoZiwgcHJlZml4KSA9PiAoLi4uYXJncykgPT4ge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICByZXR1cm4gZiguLi5hcmdzKTtcblx0ICAgIH1cblx0ICAgIGNhdGNoIChlKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKChwcmVmaXggfHwgJycpICsgZSk7XG5cdCAgICB9XG5cdH07XG5cdGV4cG9ydHMud3JhcEluVHJ5Q2F0Y2ggPSB3cmFwSW5UcnlDYXRjaDtcblx0Y29uc3Qgd3JhcENvbnRleHRIYW5kbGVyID0gKGhhbmRsZXIsIGhhbmRsZXJJZCkgPT4ge1xuXHQgICAgcmV0dXJuIGFzeW5jIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgaGFuZGxlcihjb250ZXh0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHRocm93biBieSBoYW5kbGVyICR7aGFuZGxlcklkfSBmb3IgY29udGV4dCB0eXBlICR7Y29udGV4dC50eXBlfTogJHtlcnJvcn1gKTtcblx0ICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy53cmFwQ29udGV4dEhhbmRsZXIgPSB3cmFwQ29udGV4dEhhbmRsZXI7XG5cdGNvbnN0IGdlbmVyYXRlT3ZlcnJpZGVFcnJvciA9IChjbGllbnRBcGksIGJyb2tlckFwaSkgPT4ge1xuXHQgICAgcmV0dXJuIGBZb3UgaGF2ZSB0cmllZCB0byB0byB1c2UgJHtjbGllbnRBcGl9IGJ1dCAke2Jyb2tlckFwaX0gaGFzIG5vdCBiZWVuIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3AgQnJva2VyLiBQbGVhc2Ugb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbi4gUmVmZXIgdG8gb3VyIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mby5gO1xuXHR9O1xuXHRleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvciA9IGdlbmVyYXRlT3ZlcnJpZGVFcnJvcjtcblx0Y29uc3QgZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcgPSAoZmRjM0NsaWVudEFwaSwgYnJva2VyQXBpLCBpZGVudGl0eSwgaW50ZXJvcENsaWVudEFwaSkgPT4ge1xuXHQgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSBpZGVudGl0eTtcblx0ICAgIGNvbnN0IG1lc3NhZ2UgPSBpbnRlcm9wQ2xpZW50QXBpXG5cdCAgICAgICAgPyBgRW50aXR5IHdpdGggaWRlbnRpdHk6ICR7dXVpZH0vJHtuYW1lfSBoYXMgY2FsbGVkICR7aW50ZXJvcENsaWVudEFwaX0gb3IgJHtmZGMzQ2xpZW50QXBpfSBidXQgJHticm9rZXJBcGl9IGhhcyBub3QgYmVlbiBvdmVycmlkZGVuLmBcblx0ICAgICAgICA6IGBFbnRpdHkgd2l0aCBpZGVudGl0eTogJHt1dWlkfS8ke25hbWV9IGhhcyBjYWxsZWQgJHtmZGMzQ2xpZW50QXBpfSBidXQgJHticm9rZXJBcGl9IGhhcyBub3QgYmVlbiBvdmVycmlkZGVuLmA7XG5cdCAgICByZXR1cm4gbWVzc2FnZTtcblx0fTtcblx0ZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZyA9IGdlbmVyYXRlT3ZlcnJpZGVXYXJuaW5nO1xuXHRleHBvcnRzLkJST0tFUl9FUlJPUlMgPSB7XG5cdCAgICBmaXJlSW50ZW50OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdmaXJlSW50ZW50JywgJ2hhbmRsZUZpcmVkSW50ZW50JyksXG5cdCAgICBmaXJlSW50ZW50Rm9yQ29udGV4dDogKDAsIGV4cG9ydHMuZ2VuZXJhdGVPdmVycmlkZUVycm9yKSgnZmlyZUludGVudEZvckNvbnRleHQnLCAnaGFuZGxlRmlyZWRJbnRlbnRGb3JDb250ZXh0JyksXG5cdCAgICBnZXRJbmZvRm9ySW50ZW50OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdnZXRJbmZvRm9ySW50ZW50JywgJ2hhbmRsZUluZm9Gb3JJbnRlbnQnKSxcblx0ICAgIGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdnZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcsICdoYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcpLFxuXHQgICAgam9pblNlc3Npb25Db250ZXh0R3JvdXBXaXRoSm9pbkNvbnRleHRHcm91cDogJ1RoZSBDb250ZXh0IEdyb3VwIHlvdSBoYXZlIHRyaWVkIHRvIGpvaW4gaXMgYSBTZXNzaW9uIENvbnRleHQgR3JvdXAuIEN1c3RvbSBDb250ZXh0IEdyb3VwcyBjYW4gb25seSBiZSBkZWZpbmVkIGJ5IHRoZSBJbnRlcm9wIEJyb2tlciB0aHJvdWdoIGNvZGUgb3IgbWFuaWZlc3QgY29uZmlndXJhdGlvbi4gUGxlYXNlIHVzZSBqb2luU2Vzc2lvbkNvbnRleHRHcm91cC4nLFxuXHQgICAgZmRjM09wZW46ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMub3BlbicsICdmZGMzSGFuZGxlT3BlbicpLFxuXHQgICAgZmRjM0ZpbmRJbnN0YW5jZXM6ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMuZmluZEluc3RhbmNlcycsICdmZGMzSGFuZGxlRmluZEluc3RhbmNlcycpLFxuXHQgICAgZmRjM0dldEFwcE1ldGFkYXRhOiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdmZGMzLmdldEFwcE1ldGFkYXRhJywgJ2ZkYzNIYW5kbGVHZXRBcHBNZXRhZGF0YScpLFxuXHQgICAgZmRjM0dldEluZm86ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMuZ2V0SW5mbycsICdmZGMzSGFuZGxlR2V0SW5mbycpXG5cdH07XG5cdGNvbnN0IHdyYXBJbnRlbnRIYW5kbGVyID0gKGhhbmRsZXIsIGhhbmRsZXJJZCkgPT4ge1xuXHQgICAgcmV0dXJuIGFzeW5jIChpbnRlbnQpID0+IHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gaGFuZGxlcihpbnRlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgdGhyb3duIGJ5IGhhbmRsZXIgJHtoYW5kbGVySWR9OiAke2Vycm9yfWApO1xuXHQgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHR9O1xuXHRleHBvcnRzLndyYXBJbnRlbnRIYW5kbGVyID0gd3JhcEludGVudEhhbmRsZXI7IFxufSAodXRpbHMkMykpO1xuXG52YXIgUHJpdmF0ZUNoYW5uZWxQcm92aWRlciA9IHt9O1xuXG52YXIgaGFzUmVxdWlyZWRQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xuXG5mdW5jdGlvbiByZXF1aXJlUHJpdmF0ZUNoYW5uZWxQcm92aWRlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFByaXZhdGVDaGFubmVsUHJvdmlkZXIpIHJldHVybiBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xuXHRoYXNSZXF1aXJlZFByaXZhdGVDaGFubmVsUHJvdmlkZXIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoUHJpdmF0ZUNoYW5uZWxQcm92aWRlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFByaXZhdGVDaGFubmVsUHJvdmlkZXIuUHJpdmF0ZUNoYW5uZWxQcm92aWRlciA9IHZvaWQgMDtcblx0Y29uc3QgSW50ZXJvcEJyb2tlcl8xID0gcmVxdWlyZUludGVyb3BCcm9rZXIoKTtcblx0bGV0IFByaXZhdGVDaGFubmVsUHJvdmlkZXIkMSA9IGNsYXNzIFByaXZhdGVDaGFubmVsUHJvdmlkZXIge1xuXHQgICAgY29uc3RydWN0b3IocHJvdmlkZXIsIGlkKSB7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyO1xuXHQgICAgICAgIHRoaXMuaWQgPSBpZDtcblx0ICAgICAgICB0aGlzLmNsaWVudHMgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5yZWdpc3Rlckxpc3RlbmVycygpO1xuXHQgICAgICAgIHRoaXMuY29udGV4dEJ5Q29udGV4dFR5cGUgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5sYXN0Q29udGV4dCA9IHVuZGVmaW5lZDtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLm9uQ29ubmVjdGlvbigoY2xpZW50SWRlbnRpdHkpID0+IHRoaXMucmVnaXN0ZXJOZXdDbGllbnQoY2xpZW50SWRlbnRpdHkpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLm9uRGlzY29ubmVjdGlvbihhc3luYyAoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBlbmRwb2ludElkIH0gPSBjbGllbnRJZGVudGl0eTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuY2xpZW50cy5oYXMoZW5kcG9pbnRJZCkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ2xpZW50RGlzY29ubmVjdGluZyhjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3ZpZGVyLmdldEFsbENsaWVudEluZm8oKSkubGVuZ3RoID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRlc3Ryb3koKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChpZC5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2Jyb2FkY2FzdCcsIHRoaXMuYnJvYWRjYXN0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2dldEN1cnJlbnRDb250ZXh0JywgdGhpcy5nZXRDdXJyZW50Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKCdjb250ZXh0SGFuZGxlckFkZGVkJywgdGhpcy5jb250ZXh0SGFuZGxlckFkZGVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2NvbnRleHRIYW5kbGVyUmVtb3ZlZCcsIHRoaXMuY29udGV4dEhhbmRsZXJSZW1vdmVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ25vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQnLCB0aGlzLm5vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25BZGRDb250ZXh0SGFuZGxlckFkZGVkJywgdGhpcy5vbkFkZENvbnRleHRIYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25EaXNjb25uZWN0SGFuZGxlckFkZGVkJywgdGhpcy5vbkRpc2Nvbm5lY3RIYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZCcsIHRoaXMub25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKCdjbGllbnREaXNjb25uZWN0aW5nJywgKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSA9PiB7XG5cdCAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2xpZW50RGlzY29ubmVjdGluZyhjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBicm9hZGNhc3QocGF5bG9hZCwgYnJvYWRjYXN0ZXJDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgY29udGV4dCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBicm9hZGNhc3RlckNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShicm9hZGNhc3RlckNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWJyb2FkY2FzdGVyQ2xpZW50U3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBJZGVudGl0eTogJHticm9hZGNhc3RlckNsaWVudElkZW50aXR5LnV1aWR9ICR7YnJvYWRjYXN0ZXJDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBicm9hZGNhc3QsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0ID0gSW50ZXJvcEJyb2tlcl8xLkludGVyb3BCcm9rZXIuY2hlY2tDb250ZXh0SW50ZWdyaXR5KGNvbnRleHQpO1xuXHQgICAgICAgIGlmIChjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQuaXNWYWxpZCA9PT0gZmFsc2UpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gYnJvYWRjYXN0IC0gYmFkIENvbnRleHQuIFJlYXNvbjogJHtjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQucmVhc29ufS4gQ29udGV4dDogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5jb250ZXh0QnlDb250ZXh0VHlwZS5zZXQoY29udGV4dC50eXBlLCBjb250ZXh0KTtcblx0ICAgICAgICB0aGlzLmxhc3RDb250ZXh0ID0gY29udGV4dDtcblx0ICAgICAgICBBcnJheS5mcm9tKHRoaXMuY2xpZW50cy52YWx1ZXMoKSkuZm9yRWFjaCgoY3VyckNsaWVudFN0YXRlKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJJZHNGb3JDb250ZXh0VHlwZSA9IGN1cnJDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMuZ2V0KGNvbnRleHQudHlwZSk7XG5cdCAgICAgICAgICAgIGlmIChoYW5kbGVySWRzRm9yQ29udGV4dFR5cGUpIHtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJZHNGb3JDb250ZXh0VHlwZS5mb3JFYWNoKChoYW5kbGVySWQpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGN1cnJDbGllbnRTdGF0ZS5jbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChjdXJyQ2xpZW50U3RhdGUuZ2xvYmFsSGFuZGxlcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjdXJyQ2xpZW50U3RhdGUuY2xpZW50SWRlbnRpdHksIGN1cnJDbGllbnRTdGF0ZS5nbG9iYWxIYW5kbGVyLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q3VycmVudENvbnRleHQocGF5bG9hZCwgc2VuZGVyQ2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB7IGNvbnRleHRUeXBlIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShzZW5kZXJDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKCFjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke3NlbmRlckNsaWVudElkZW50aXR5LnV1aWR9ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkubmFtZX0sIHRyaWVkIHRvIGNhbGwgZ2V0Q3VycmVudENvbnRleHQsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGNvbnRleHRUeXBlICE9PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSB0aGlzLmNvbnRleHRCeUNvbnRleHRUeXBlLmdldChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgIGlmIChjdXJyZW50Q29udGV4dClcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dDtcblx0ICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLmxhc3RDb250ZXh0ID8gdGhpcy5sYXN0Q29udGV4dCA6IG51bGw7XG5cdCAgICB9XG5cdCAgICBjb250ZXh0SGFuZGxlckFkZGVkKHBheWxvYWQsIHNlbmRlckNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IHNlbmRlckNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShzZW5kZXJDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKCFzZW5kZXJDbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke3NlbmRlckNsaWVudElkZW50aXR5LnV1aWR9ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkubmFtZX0sIHRyaWVkIHRvIGNhbGwgYWRkQ29udGV4dExpc3RlbmVyLCBpcyBub3QgY29ubmVjdGVkIHRvIHRoaXMgUHJpdmF0ZSBDaGFubmVsYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50SGFuZGxlcnNMaXN0ID0gc2VuZGVyQ2xpZW50U3RhdGUuaGFuZGxlcklkc0J5Q29udGV4dFR5cGVzLmdldChjb250ZXh0VHlwZSkgfHwgW107XG5cdCAgICAgICAgICAgIHNlbmRlckNsaWVudFN0YXRlLmhhbmRsZXJJZHNCeUNvbnRleHRUeXBlcy5zZXQoY29udGV4dFR5cGUsIFsuLi5jdXJyZW50SGFuZGxlcnNMaXN0LCBoYW5kbGVySWRdKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIHNlbmRlckNsaWVudFN0YXRlLmdsb2JhbEhhbmRsZXIgPSBoYW5kbGVySWQ7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKS5mb3JFYWNoKChjdXJyQ2xpZW50U3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgaWYgKGN1cnJDbGllbnRTdGF0ZS5jbGllbnRJZGVudGl0eS5lbmRwb2ludElkICE9PSBzZW5kZXJDbGllbnRJZGVudGl0eS5lbmRwb2ludElkICYmXG5cdCAgICAgICAgICAgICAgICBjdXJyQ2xpZW50U3RhdGUub25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMucHJvdmlkZXIuZGlzcGF0Y2goY3VyckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LCBjdXJyQ2xpZW50U3RhdGUub25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQsIGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgY29udGV4dEhhbmRsZXJSZW1vdmVkKHBheWxvYWQsIHJlbW92aW5nQ2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICAvLyBNQzogTWFkZSB0aGlzIHJlbW92YWwgYXN5bmMgdG8gZW5zdXJlIHRoYXQgb25VbnN1YnNjcmliZSBoYW5kbGVycyBhcmUgaGl0IGJlZm9yZSBhbnl0aGluZyBlbHNlIGhhcHBlbnMuXG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgY29uc3QgcmVtb3ZpbmdDbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUocmVtb3ZpbmdDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKHJlbW92aW5nQ2xpZW50U3RhdGUpIHtcblx0ICAgICAgICAgICAgbGV0IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICBpZiAocmVtb3ZpbmdDbGllbnRTdGF0ZS5nbG9iYWxIYW5kbGVyID09PSBoYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIHJlbW92aW5nQ2xpZW50U3RhdGUuZ2xvYmFsSGFuZGxlciA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2N1cnJDb250ZXh0VHlwZSwgaGFuZGxlcnNJZHNdIG9mIHJlbW92aW5nQ2xpZW50U3RhdGUuaGFuZGxlcklkc0J5Q29udGV4dFR5cGVzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBoYW5kbGVyc0lkcy5pbmRleE9mKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnNJZHMuc3BsaWNlKGluZGV4LCAxKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dFR5cGUgPSBjdXJyQ29udGV4dFR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIGdldHRpbmcgb25seSB2YWxpZCBjbGllbnQgY29ubmVjdGlvbnMgaGVyZSwgaXQgaXMgcG9zc2libGUgd2UgaGF2ZW4ndCByZW1vdmVkIGEgZGlzY29ubmVjdGVkIGNsaWVudCBmcm9tIHRoZSBtYXAgeWV0XG5cdCAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gZW5zdXJlIHdlIGRvbid0IGRpc3BhdGNoIHRvIGFueSBkaXNjb25uZWN0ZWQgY2xpZW50XG5cdCAgICAgICAgICAgIC8vIFRPRE86IFRha2UgYSBsb29rIGF0IG91ciBjbGllbnQgZGlzY29ubmVjdGlvbiBsb2dpYyBhbmQgc2VlIGlmIHdlIGNhbiBoYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3Rpb24gY2xlYW5seVxuXHQgICAgICAgICAgICBjb25zdCBjbGllbnRzVG9EaXNwYXRjaFRvID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWRDbGllbnRzKCk7XG5cdCAgICAgICAgICAgIGNvbnN0IGRpc3BhdGNoUHJvbWlzZXMgPSBjbGllbnRzVG9EaXNwYXRjaFRvLm1hcChhc3luYyAob3RoZXJDbGllbnRTdGF0ZSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgY2xpZW50SWRlbnRpdHk6IHsgZW5kcG9pbnRJZCB9LCBvblVuc3Vic2NyaWJlSGFuZGxlcklkIH0gPSBvdGhlckNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICAgICAgaWYgKGVuZHBvaW50SWQgIT09IHJlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAmJiBvblVuc3Vic2NyaWJlSGFuZGxlcklkKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgb25VbnN1YnNjcmliZUhhbmRsZXJJZCwgY29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGRpc3BhdGNoUHJvbWlzZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgUHJvYmxlbSB3aGVuIGF0dGVtcHRpbmcgdG8gZGlzcGF0Y2ggdG8gb25VbnN1YnNjcmliZUhhbmRsZXJzLiBFcnJvcjogJHtlcnJvcn0gUmVtb3ZpbmcgQ2xpZW50OiAke2hhbmRsZXJJZH0uIHV1aWQ6ICR7cmVtb3ZpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtyZW1vdmluZ0NsaWVudElkZW50aXR5Lm5hbWV9LiBlbmRwb2ludElkOiAke3JlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH1gKTtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybihgVHJ5aW5nIHRvIHJlbW92ZSBhIGhhbmRsZXIgZnJvbSBhIGNsaWVudCB0aGF0IGlzbid0IG1hcHBlZC4gaGFuZGxlcklkOiAke2hhbmRsZXJJZH0uIHV1aWQ6ICR7cmVtb3ZpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtyZW1vdmluZ0NsaWVudElkZW50aXR5Lm5hbWV9LiBlbmRwb2ludElkOiAke3JlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH0uYCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgbm9uU3RhbmRhcmRIYW5kbGVyUmVtb3ZlZChwYXlsb2FkLCBpZCkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShpZCk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGlmIChjbGllbnRTdGF0ZS5vbkRpc2Nvbm5lY3RIYW5kbGVySWQgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3RhdGUub25EaXNjb25uZWN0SGFuZGxlcklkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2UgaWYgKGNsaWVudFN0YXRlLm9uQWRkQ29udGV4dExpc3RlbmVySGFuZGxlcklkID09PSBoYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIGNsaWVudFN0YXRlLm9uQWRkQ29udGV4dExpc3RlbmVySGFuZGxlcklkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2UgaWYgKGNsaWVudFN0YXRlLm9uVW5zdWJzY3JpYmVIYW5kbGVySWQgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3RhdGUub25VbnN1YnNjcmliZUhhbmRsZXJJZCA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKGBUcnlpbmcgdG8gcmVtb3ZlIGEgaGFuZGxlciBmcm9tIGEgY2xpZW50IHRoYXQgaXNuJ3QgbWFwcGVkLiBoYW5kbGVySWQ6ICR7aGFuZGxlcklkfS4gY2xpZW50SWRlbnRpdHk6ICR7aWR9YCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgb25BZGRDb250ZXh0SGFuZGxlckFkZGVkKHBheWxvYWQsIHNlbmRlckNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKHNlbmRlckNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjb25zdCB7IGhhbmRsZXJJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkudXVpZH0gJHtzZW5kZXJDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBvbkFkZENvbnRleHRMaXN0ZW5lciwgaXMgbm90IGNvbm5lY3RlZCB0byB0aGlzIFByaXZhdGUgQ2hhbm5lbGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjbGllbnRTdGF0ZS5vbkFkZENvbnRleHRMaXN0ZW5lckhhbmRsZXJJZCA9IGhhbmRsZXJJZDtcblx0ICAgICAgICAvLyBGREMzIFNwZWMgc2F5cyB0aGF0IHRoZSBhZGRlZCBsaXN0ZW5lciBzaG91bGQgZmlyZSBmb3IgYWxsIHByZXZpb3VzbHktcmVnaXN0ZXJlZCBhZGRDb250ZXh0TGlzdGVuZXJzIGZyb20gdGhlIG90aGVyIGNsaWVudFxuXHQgICAgICAgIEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKS5mb3JFYWNoKChvdGhlckNsaWVudFN0YXRlKSA9PiB7XG5cdCAgICAgICAgICAgIGlmIChvdGhlckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LmVuZHBvaW50SWQgIT09IHNlbmRlckNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpIHtcblx0ICAgICAgICAgICAgICAgIEFycmF5LmZyb20ob3RoZXJDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMua2V5cygpKS5mb3JFYWNoKChzdWJzY3JpYmVkQ29udGV4dFR5cGUpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKHNlbmRlckNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIHN1YnNjcmliZWRDb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgb25EaXNjb25uZWN0SGFuZGxlckFkZGVkKHBheWxvYWQsIGlkKSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGlkKTtcblx0ICAgICAgICBjb25zdCB7IGhhbmRsZXJJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7aWQudXVpZH0gJHtpZC5uYW1lfSwgdHJpZWQgdG8gY2FsbCBvbkRpc2Nvbm5lY3QsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2xpZW50U3RhdGUub25EaXNjb25uZWN0SGFuZGxlcklkID0gaGFuZGxlcklkO1xuXHQgICAgfVxuXHQgICAgb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZChwYXlsb2FkLCBpZCkge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShpZCk7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgaWYgKCFjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2lkLnV1aWR9ICR7aWQubmFtZX0sIHRyaWVkIHRvIGNhbGwgb25VbnN1YnNjcmliZSwgaXMgbm90IGNvbm5lY3RlZCB0byB0aGlzIFByaXZhdGUgQ2hhbm5lbGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjbGllbnRTdGF0ZS5vblVuc3Vic2NyaWJlSGFuZGxlcklkID0gaGFuZGxlcklkO1xuXHQgICAgfVxuXHQgICAgcmVtb3ZlQ2xpZW50KGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS51dWlkfSAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBkaXNjb25uZWN0LCBpcyBub3QgY29ubmVjdGVkIHRvIHRoaXMgUHJpdmF0ZSBDaGFubmVsYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMuY2xlYXIoKTtcblx0ICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIGFzeW5jIGZpcmVPbkRpc2Nvbm5lY3RGb3JPdGhlckNsaWVudHMoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgLy8gVE9ETzogY2FsbCBvbkRpc2Nvbm5lY3QgSGFuZGxlciBvZiB0aGUgb3RoZXIgY2xpZW50IG9ubHkuXG5cdCAgICAgICAgLy8gQ1VSUkVOVExZLCBqdXN0IGNhbGxpbmcgdGhlIG9uRGlzY29ubmVjdCBoYW5kbGVyIGZvciBhbGwgdGhlIG90aGVyIGNsaWVudHMuIE9uY2Ugd2UgbGltaXQgaXQgdG8ganVzdCBvbmUgb3RoZXIgY2xpZW50LCB3ZSBjYW4gZWxpbWluYXRlIGFsbCB0aGUgaXRlcmF0aW9uIGNvZGUuXG5cdCAgICAgICAgY29uc3QgeyBlbmRwb2ludElkIH0gPSBkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHk7XG5cdCAgICAgICAgLy8gZ2V0dGluZyBvbmx5IHZhbGlkIGNsaWVudCBjb25uZWN0aW9ucyBoZXJlLCBpdCBpcyBwb3NzaWJsZSB3ZSBoYXZlbid0IHJlbW92ZWQgYSBkaXNjb25uZWN0ZWQgY2xpZW50IGZyb20gdGhlIG1hcCB5ZXRcblx0ICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIGVuc3VyZSB3ZSBkb24ndCBkaXNwYXRjaCB0byBhbnkgZGlzY29ubmVjdGVkIGNsaWVudFxuXHQgICAgICAgIC8vIFRPRE86IFRha2UgYSBsb29rIGF0IG91ciBjbGllbnQgZGlzY29ubmVjdGlvbiBsb2dpYyBhbmQgc2VlIGlmIHdlIGNhbiBoYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3Rpb24gY2xlYW5seVxuXHQgICAgICAgIGNvbnN0IGNsaWVudHNUb0Rpc3BhdGNoVG8gPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZENsaWVudHMoKTtcblx0ICAgICAgICBjb25zdCBkaXNwYXRjaFByb21pc2VzID0gY2xpZW50c1RvRGlzcGF0Y2hUby5tYXAoYXN5bmMgKG90aGVyQ2xpZW50U3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eTogeyBlbmRwb2ludElkOiBvdGhlckNsaWVudEVuZHBvaW50SWQgfSwgb25EaXNjb25uZWN0SGFuZGxlcklkIH0gPSBvdGhlckNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICBpZiAob3RoZXJDbGllbnRFbmRwb2ludElkICE9PSBlbmRwb2ludElkICYmIG9uRGlzY29ubmVjdEhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChvdGhlckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LCBvbkRpc2Nvbm5lY3RIYW5kbGVySWQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoZGlzcGF0Y2hQcm9taXNlcyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBQcm9ibGVtIHdoZW4gYXR0ZW1wdGluZyB0byBkaXNwYXRjaCB0byBvbkRpc2Nvbm5lY3RIYW5kbGVycy4gRXJyb3I6ICR7ZXJyb3J9IERpc2Nvbm5lY3RpbmcgQ2xpZW50OiB1dWlkOiAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkubmFtZX0uIGVuZHBvaW50SWQ6ICR7ZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5LmVuZHBvaW50SWR9YCk7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgdW5zdWJzY3JpYmVBbGwoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB7IGVuZHBvaW50SWQgfSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5jbGllbnRzLmdldChlbmRwb2ludElkKTtcblx0ICAgICAgICBpZiAoc3RhdGUpIHtcblx0ICAgICAgICAgICAgY29uc3QgY29udGV4dFR5cGVIYW5kbGVySWRzID0gQXJyYXkuZnJvbShzdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMudmFsdWVzKCkpLmZsYXQoKTtcblx0ICAgICAgICAgICAgY29uc3QgZ2xvYmFsSGFuZGxlcklkID0gc3RhdGUuZ2xvYmFsSGFuZGxlcjtcblx0ICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlSGFuZGxlcklkcy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB1bnN1YlByb21pc2VzID0gY29udGV4dFR5cGVIYW5kbGVySWRzLm1hcChhc3luYyAoaGFuZGxlcklkKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dEhhbmRsZXJSZW1vdmVkKHsgaGFuZGxlcklkIH0sIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh1bnN1YlByb21pc2VzKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGdsb2JhbEhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmNvbnRleHRIYW5kbGVyUmVtb3ZlZCh7IGhhbmRsZXJJZDogZ2xvYmFsSGFuZGxlcklkIH0sIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBhc3luYyBoYW5kbGVDbGllbnREaXNjb25uZWN0aW5nKGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGF3YWl0IHRoaXMudW5zdWJzY3JpYmVBbGwoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KTtcblx0ICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGF3YWl0IHRoaXMuZmlyZU9uRGlzY29ubmVjdEZvck90aGVyQ2xpZW50cyhkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgcmVnaXN0ZXJOZXdDbGllbnQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBpZiAoIXRoaXMuY2xpZW50cy5oYXMoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCkpIHtcblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eSxcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJZHNCeUNvbnRleHRUeXBlczogbmV3IE1hcCgpLFxuXHQgICAgICAgICAgICAgICAgZ2xvYmFsSGFuZGxlcjogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICAgICAgb25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQ6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgICAgIG9uVW5zdWJzY3JpYmVIYW5kbGVySWQ6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgICAgIG9uRGlzY29ubmVjdEhhbmRsZXJJZDogdW5kZWZpbmVkXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIHRoaXMuY2xpZW50cy5zZXQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCwgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIGdldENvbm5lY3RlZENsaWVudHMoKSB7XG5cdCAgICAgICAgY29uc3QgYWxsQ2xpZW50SW5mbyA9IGF3YWl0IHRoaXMucHJvdmlkZXIuZ2V0QWxsQ2xpZW50SW5mbygpO1xuXHQgICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuY2xpZW50cy52YWx1ZXMoKSkuZmlsdGVyKChjbGllbnRTdGF0ZSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5O1xuXHQgICAgICAgICAgICByZXR1cm4gYWxsQ2xpZW50SW5mby5zb21lKChjbGllbnRJbmZvKSA9PiB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gY2xpZW50SW5mby5uYW1lICYmIHV1aWQgPT09IGNsaWVudEluZm8udXVpZDtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBzdGF0aWMgaW5pdChjaGFubmVsUHJvdmlkZXIsIGlkKSB7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyKGNoYW5uZWxQcm92aWRlciwgaWQpO1xuXHQgICAgfVxuXHR9O1xuXHRQcml2YXRlQ2hhbm5lbFByb3ZpZGVyLlByaXZhdGVDaGFubmVsUHJvdmlkZXIgPSBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyJDE7XG5cdHJldHVybiBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xufVxuXG52YXIgaGFzUmVxdWlyZWRJbnRlcm9wQnJva2VyO1xuXG5mdW5jdGlvbiByZXF1aXJlSW50ZXJvcEJyb2tlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEludGVyb3BCcm9rZXIpIHJldHVybiBJbnRlcm9wQnJva2VyO1xuXHRoYXNSZXF1aXJlZEludGVyb3BCcm9rZXIgPSAxO1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xuXHR9O1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG5cdCAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG5cdCAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG5cdH07XG5cdHZhciBfX2ltcG9ydERlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnREZWZhdWx0KSB8fCBmdW5jdGlvbiAobW9kKSB7XG5cdCAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcblx0fTtcblx0dmFyIF9JbnRlcm9wQnJva2VyX2ZkYzNJbmZvLCBfSW50ZXJvcEJyb2tlcl9jb250ZXh0R3JvdXBzLCBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2U7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnRlcm9wQnJva2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW50ZXJvcEJyb2tlci5JbnRlcm9wQnJva2VyID0gdm9pZCAwO1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZVNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXIoKSk7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHRjb25zdCBpc0VxdWFsXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMyk7XG5cdGNvbnN0IFByaXZhdGVDaGFubmVsUHJvdmlkZXJfMSA9IHJlcXVpcmVQcml2YXRlQ2hhbm5lbFByb3ZpZGVyKCk7XG5cdGNvbnN0IGxhenlfMSA9IGxhenk7XG5cdGNvbnN0IGRlZmF1bHRDb250ZXh0R3JvdXBzID0gW1xuXHQgICAge1xuXHQgICAgICAgIGlkOiAnZ3JlZW4nLFxuXHQgICAgICAgIGRpc3BsYXlNZXRhZGF0YToge1xuXHQgICAgICAgICAgICBjb2xvcjogJyMwMENDODgnLFxuXHQgICAgICAgICAgICBuYW1lOiAnZ3JlZW4nXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3B1cnBsZScsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnIzhDNjFGRicsXG5cdCAgICAgICAgICAgIG5hbWU6ICdwdXJwbGUnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ29yYW5nZScsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnI0ZGOEM0QycsXG5cdCAgICAgICAgICAgIG5hbWU6ICdvcmFuZ2UnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3JlZCcsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnI0ZGNUU2MCcsXG5cdCAgICAgICAgICAgIG5hbWU6ICdyZWQnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3BpbmsnLFxuXHQgICAgICAgIGRpc3BsYXlNZXRhZGF0YToge1xuXHQgICAgICAgICAgICBjb2xvcjogJyNGRjhGQjgnLFxuXHQgICAgICAgICAgICBuYW1lOiAncGluaydcblx0ICAgICAgICB9XG5cdCAgICB9LFxuXHQgICAge1xuXHQgICAgICAgIGlkOiAneWVsbG93Jyxcblx0ICAgICAgICBkaXNwbGF5TWV0YWRhdGE6IHtcblx0ICAgICAgICAgICAgY29sb3I6ICcjRTlGRjhGJyxcblx0ICAgICAgICAgICAgbmFtZTogJ3llbGxvdydcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdF07XG5cdC8qKlxuXHQgKiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2VuYWJsZS1jb2xvci1saW5raW5nfVxuXHQgKlxuXHQgKiBUaGUgSW50ZXJvcCBCcm9rZXIgaXMgcmVzcG9uc2libGUgZm9yIGtlZXBpbmcgdHJhY2sgb2YgdGhlIEludGVyb3Agc3RhdGUgb2YgdGhlIFBsYXRmb3JtLCBhbmQgZm9yIGRpcmVjdGluZyBtZXNzYWdlcyB0byB0aGUgcHJvcGVyIGxvY2F0aW9ucy5cblx0ICpcblx0ICogQHJlbWFya3MgVGhpcyBjbGFzcyBjb250YWlucyBzb21lIHR5cGVzIHJlbGF0ZWQgdG8gRkRDMyB0aGF0IGFyZSBzcGVjaWZpYyB0byBPcGVuRmluLiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2ZkYzMtc3VwcG9ydC1pbi1vcGVuZmluIE9wZW5GaW4ncyBGREMzIHN1cHBvcnR9IGlzIGZvcndhcmQtIGFuZCBiYWNrd2FyZC1jb21wYXRpYmxlLlxuXHQgKiBTdGFuZGFyZCB0eXBlcyBmb3Ige0BsaW5rIGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvIEZEQzN9IGRvIG5vdCBhcHBlYXIgaW4gT3BlbkZpbuKAmXMgQVBJIGRvY3VtZW50YXRpb24sIHRvIGF2b2lkIGR1cGxpY2F0aW9uLlxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogVGhlcmUgYXJlIDIgd2F5cyB0byBpbmplY3QgY3VzdG9tIGZ1bmN0aW9uYWxpdHkgaW50byB0aGUgSW50ZXJvcCBCcm9rZXI6XG5cdCAqXG5cdCAqICoqMS4gQ29uZmlndXJhdGlvbioqXG5cdCAqXG5cdCAqIEF0IHRoZSBtb21lbnQsIHlvdSBjYW4gY29uZmlndXJlIHRoZSBkZWZhdWx0IGNvbnRleHQgZ3JvdXBzIGZvciB0aGUgSW50ZXJvcCBCcm9rZXIgd2l0aG91dCBoYXZpbmcgdG8gb3ZlcnJpZGUgaXQuIFRvIGRvIHNvLCBpbmNsdWRlIHRoZSBgaW50ZXJvcEJyb2tlckNvbmZpZ3VyYXRpb25gIGBjb250ZXh0R3JvdXBzYCBvcHRpb24gaW4geW91ciBgcGxhdGZvcm1gIG9wdGlvbnMgaW4geW91ciBtYW5pZmVzdC4gVGhpcyBpcyB0aGUgcHJlZmVycmVkIG1ldGhvZC5cblx0ICogYGBganNcblx0ICoge1xuXHQgKiAgICAgIFwicnVudGltZVwiOiB7XG5cdCAqICAgICAgICAgIFwiYXJndW1lbnRzXCI6IFwiLS12PTEgLS1pbnNwZWN0XCIsXG5cdCAqICAgICAgICAgIFwidmVyc2lvblwiOiBcImFscGhhLXYxOVwiXG5cdCAqICAgICAgfSxcblx0ICogICAgICBcInBsYXRmb3JtXCI6IHtcblx0ICogICAgICAgICAgXCJ1dWlkXCI6IFwicGxhdGZvcm1fY3VzdG9taXphdGlvbl9sb2NhbFwiLFxuXHQgKiAgICAgICAgICBcImFwcGxpY2F0aW9uSWNvblwiOiBcImh0dHBzOi8vb3BlbmZpbi5naXRodWIuaW8vZ29sZGVuLXByb3RvdHlwZS9mYXZpY29uLmljb1wiLFxuXHQgKiAgICAgICAgICBcImF1dG9TaG93XCI6IGZhbHNlLFxuXHQgKiAgICAgICAgICBcInByb3ZpZGVyVXJsXCI6IFwiaHR0cDovL2xvY2FsaG9zdDo1NTU1L3Byb3ZpZGVyLmh0bWxcIixcblx0ICogICAgICAgICAgXCJpbnRlcm9wQnJva2VyQ29uZmlndXJhdGlvblwiOiB7XG5cdCAqICAgICAgICAgICAgICBcImNvbnRleHRHcm91cHNcIjogW1xuXHQgKiAgICAgICAgICAgICAgICAgIHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiBcImdyZWVuXCIsXG5cdCAqICAgICAgICAgICAgICAgICAgICAgIFwiZGlzcGxheU1ldGFkYXRhXCI6IHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29sb3JcIjogXCIjMDBDQzg4XCIsXG5cdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJncmVlblwiXG5cdCAqICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICogICAgICAgICAgICAgICAgICB9LFxuXHQgKiAgICAgICAgICAgICAgICAgIHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiBcInB1cnBsZVwiLFxuXHQgKiAgICAgICAgICAgICAgICAgICAgICBcImRpc3BsYXlNZXRhZGF0YVwiOiB7XG5cdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiIzhDNjFGRlwiLFxuXHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwicHVycGxlXCJcblx0ICogICAgICAgICAgICAgICAgICAgICAgfVxuXHQgKiAgICAgICAgICAgICAgICAgIH0sXG5cdCAqICAgICAgICAgICAgICBdXG5cdCAqICAgICAgICAgIH1cblx0ICogICAgICB9XG5cdCAqIH1cblx0ICogYGBgXG5cdCAqXG5cdCAqIEJ5IGRlZmF1bHQgdGhlIEludGVyb3AgQnJva2VyIGxvZ3MgYWxsIGFjdGlvbnMgdG8gdGhlIGNvbnNvbGUuIFlvdSBjYW4gZGlzYWJsZSB0aGlzIGJ5IHVzaW5nIHRoZSBsb2dnaW5nIG9wdGlvbiBpbiBgaW50ZXJvcEJyb2tlckNvbmZpZ3VyYXRpb25gOlxuXHQgKiBgYGBqc1xuXHQgKiB7XG5cdCAqICAgICAgXCJydW50aW1lXCI6IHtcblx0ICogICAgICAgICAgXCJhcmd1bWVudHNcIjogXCItLXY9MSAtLWluc3BlY3RcIixcblx0ICogICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiYWxwaGEtdjE5XCJcblx0ICogICAgICB9LFxuXHQgKiAgICAgIFwicGxhdGZvcm1cIjoge1xuXHQgKiAgICAgICAgICBcInV1aWRcIjogXCJwbGF0Zm9ybV9jdXN0b21pemF0aW9uX2xvY2FsXCIsXG5cdCAqICAgICAgICAgIFwiYXBwbGljYXRpb25JY29uXCI6IFwiaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9nb2xkZW4tcHJvdG90eXBlL2Zhdmljb24uaWNvXCIsXG5cdCAqICAgICAgICAgIFwiYXV0b1Nob3dcIjogZmFsc2UsXG5cdCAqICAgICAgICAgIFwicHJvdmlkZXJVcmxcIjogXCJodHRwOi8vbG9jYWxob3N0OjU1NTUvcHJvdmlkZXIuaHRtbFwiLFxuXHQgKlx0XHQgICAgXCJpbnRlcm9wQnJva2VyQ29uZmlndXJhdGlvblwiOiB7XG5cdCAqICAgICAgIFx0XHRcImxvZ2dpbmdcIjoge1xuXHQgKiAgIFx0XHRcdFx0XCJiZWZvcmVBY3Rpb25cIjoge1xuXHQgKiAgIFx0XHRcdFx0XHRcImVuYWJsZWRcIjogZmFsc2Vcblx0ICogICBcdFx0XHRcdH0sXG5cdCAqICAgXHRcdFx0XHRcImFmdGVyQWN0aW9uXCI6IHtcblx0ICogICBcdFx0XHRcdFx0XCJlbmFibGVkXCI6IGZhbHNlXG5cdCAqICAgXHRcdFx0XHR9XG5cdCAqICAgXHRcdFx0fVxuXHQgKlx0XHQgICAgfVxuXHQgKiAgICAgIH1cblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogLS0tXG5cdCAqICoqMi4gT3ZlcnJpZGluZyoqXG5cdCAqXG5cdCAqIFNpbWlsYXJseSB0byBob3cge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvcGxhdGZvcm0tY3VzdG9taXphdGlvbiNzZWN0aW9uLWN1c3RvbWl6aW5nLXBsYXRmb3JtLWJlaGF2aW9yIFBsYXRmb3JtIE92ZXJyaWRpbmd9IHdvcmtzLCB5b3UgY2FuIG92ZXJyaWRlIGZ1bmN0aW9ucyBpbiB0aGUgSW50ZXJvcCBCcm9rZXIgaW4gYGZpbi5QbGF0Zm9ybS5pbml0YC4gQW4gZXhhbXBsZSBvZiB0aGF0IGlzIHNob3duIGJlbG93LiBPdmVycmlkaW5nIGBpc0Nvbm5lY3Rpb25BdXRob3JpemVkYCBhbmQgYGlzQWN0aW9uQXV0aG9yaXplZGAgd2lsbCBhbGxvdyB5b3UgdG8gY29udHJvbCBhbGxvd2VkIGNvbm5lY3Rpb25zIGFuZCBhbGxvd2VkIGFjdGlvbnMuXG5cdCAqXG5cdCAqIEhvd2V2ZXIsIGlmIHRoZXJlIGlzIGN1c3RvbSBmdW5jdGlvbmFsaXR5IHlvdSB3aXNoIHRvIGluY2x1ZGUgaW4gdGhlIEludGVyb3AgQnJva2VyLCBwbGVhc2UgbGV0IHVzIGtub3cuIFdlIHdvdWxkIGxpa2UgdG8gcHJvdmlkZSBiZXR0ZXIgY29uZmlndXJhdGlvbiBvcHRpb25zIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gY29udGludWFsbHkgbWFpbnRhaW4geW91ciBvd24gb3ZlcnJpZGUgY29kZS5cblx0ICpcblx0ICogYGBganNcblx0ICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgKiAgICAgb3ZlcnJpZGVDYWxsYmFjazogYXN5bmMgKFByb3ZpZGVyKSA9PiB7XG5cdCAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBQcm92aWRlciB7XG5cdCAqICAgICAgICAgICAgIGFzeW5jIGdldFNuYXBzaG90KCkge1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2JlZm9yZSBnZXRTbmFwc2hvdCcpXG5cdCAqICAgICAgICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHN1cGVyLmdldFNuYXBzaG90KCk7XG5cdCAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYWZ0ZXIgZ2V0U25hcHNob3QnKVxuXHQgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHNuYXBzaG90O1xuXHQgKiAgICAgICAgICAgICB9XG5cdCAqXG5cdCAqICAgICAgICAgICAgIGFzeW5jIGFwcGx5U25hcHNob3QoeyBzbmFwc2hvdCwgb3B0aW9ucyB9KSB7XG5cdCAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYmVmb3JlIGFwcGx5U25hcHNob3QnKVxuXHQgKiAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxQcm9taXNlID0gc3VwZXIuYXBwbHlTbmFwc2hvdCh7IHNuYXBzaG90LCBvcHRpb25zIH0pO1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2FmdGVyIGFwcGx5U25hcHNob3QnKVxuXHQgKlxuXHQgKiAgICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZTtcblx0ICogICAgICAgICAgICAgfVxuXHQgKiAgICAgICAgIH07XG5cdCAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgKiAgICAgfSxcblx0ICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgKiAgICAgICAgICAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKGNoYW5uZWxOYW1lID0gJ2RlZmF1bHQnLCB0YXJnZXQpIHtcblx0ICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdiZWZvcmUgc3VwZXIgam9pbkNvbnRleHRHcm91cCcpXG5cdCAqICAgICAgICAgICAgICAgICBzdXBlci5qb2luQ29udGV4dEdyb3VwKGNoYW5uZWxOYW1lLCB0YXJnZXQpO1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2FmdGVyIHN1cGVyIGpvaW5Db250ZXh0R3JvdXAnKVxuXHQgKiAgICAgICAgICAgICB9XG5cdCAqICAgICAgICAgfVxuXHQgKlxuXHQgKiAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKCk7XG5cdCAqICAgfVxuXHQgKiB9KTtcblx0ICogYGBgXG5cdCAqXG5cdCAqIC0tLVxuXHQgKlxuXHQgKi9cblx0bGV0IEludGVyb3BCcm9rZXIkMSA9IGNsYXNzIEludGVyb3BCcm9rZXIgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICovXG5cdCAgICBjb25zdHJ1Y3Rvcih3aXJlLCBjcmVhdGVQcm92aWRlciwgb3B0aW9ucykge1xuXHQgICAgICAgIC8vIFRpcCBmcm9tIFBpZXJyZSBhbmQgTWljaGFlbCBmcm9tIHRoZSBvdmVycmlkZUNoZWNrIHdvcms6IERvbid0IHVzZSBib3VuZCBtZXRob2RzIGZvciBvdmVycmlkZWFibGUgSW50ZXJvcEJyb2tlciBmdW5jdGlvbnMuXG5cdCAgICAgICAgc3VwZXIod2lyZSk7XG5cdCAgICAgICAgX0ludGVyb3BCcm9rZXJfZmRjM0luZm8uc2V0KHRoaXMsIHZvaWQgMCk7XG5cdCAgICAgICAgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3Vwcy5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2Uuc2V0KHRoaXMsIHZvaWQgMCk7XG5cdCAgICAgICAgdGhpcy5nZXRQcm92aWRlciA9ICgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfcHJvdmlkZXJQcm9taXNlLCBcImZcIikuZ2V0VmFsdWUoKTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMuaW50ZXJvcENsaWVudHMgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0R3JvdXBzQnlJZCA9IG5ldyBNYXAoKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQnJva2VyX2NvbnRleHRHcm91cHMsIG9wdGlvbnMuY29udGV4dEdyb3VwcyA/PyBbLi4uZGVmYXVsdENvbnRleHRHcm91cHNdLCBcImZcIik7XG5cdCAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfSW50ZXJvcEJyb2tlcl9mZGMzSW5mbywgb3B0aW9ucy5mZGMzSW5mbywgXCJmXCIpO1xuXHQgICAgICAgIGlmIChvcHRpb25zPy5sb2dnaW5nKSB7XG5cdCAgICAgICAgICAgIHRoaXMubG9nZ2luZyA9IG9wdGlvbnMubG9nZ2luZztcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5pbnRlbnRDbGllbnRNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5sYXN0Q29udGV4dE1hcCA9IG5ldyBNYXAoKTtcblx0ICAgICAgICB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2UsIG5ldyBsYXp5XzEuTGF6eShjcmVhdGVQcm92aWRlciksIFwiZlwiKTtcblx0ICAgICAgICB0aGlzLnNldENvbnRleHRHcm91cE1hcCgpO1xuXHQgICAgICAgIHRoaXMuc2V0dXBDaGFubmVsUHJvdmlkZXIoKTtcblx0ICAgIH1cblx0ICAgIHN0YXRpYyBjcmVhdGVDbG9zZWRDb25zdHJ1Y3RvciguLi5hcmdzKSB7XG5cdCAgICAgICAgcmV0dXJuIGNsYXNzIE92ZXJyaWRlYWJsZUJyb2tlciBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICAgICAgICBjb25zdHJ1Y3RvciguLi51bnVzZWQpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh1bnVzZWQubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgW19pZ25vcmUxLCBpZ25vcmUyLCBvcHRzXSA9IHVudXNlZDtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAob3B0cyAmJiB0eXBlb2Ygb3B0cyA9PT0gJ29iamVjdCcgJiYgISgwLCBpc0VxdWFsXzEuZGVmYXVsdCkob3B0cywgYXJnc1syXSkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdZb3UgaGF2ZSBtb2RpZmllZCB0aGUgcGFyYW1ldGVycyBvZiB0aGUgSW50ZXJvcE92ZXJyaWRlIGNvbnN0cnVjdG9yLiBUaGlzIGJlaGF2aW9yIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLiBZb3UgY2FuIG1vZGlmeSB0aGVzZSBvcHRpb25zIGluIHlvdXIgbWFuaWZlc3QuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIoYXJnc1swXSwgYXJnc1sxXSwgb3B0cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSBhcmUgYXR0ZW1wdGluZyB0byBwYXNzIGFyZ3VtZW50cyB0byB0aGUgSW50ZXJvcE92ZXJyaWRlIGNvbnN0cnVjdG9yLiBUaGlzIGlzIG5vdCBuZWNlc3NhcnksIGFuZCB0aGVzZSBwYXNzZWQgYXJndW1lbnRzIHdpbGwgYmUgaWdub3JlZC4gWW91IGFyZSBsaWtlbHkgdXNpbmcgYW4gb2xkZXIgSW50ZXJvcEJyb2tlciBvdmVycmlkZSBzY2hlbWUuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHN1cGVyKC4uLmFyZ3MpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBDbGllbnQgQVBJXG5cdCAgICAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIGEgY29udGV4dCBmb3IgdGhlIGNvbnRleHQgZ3JvdXAgb2YgdGhlIGluY29taW5nIGN1cnJlbnQgZW50aXR5LlxuXHQgICAgICogQHBhcmFtIHNldENvbnRleHRPcHRpb25zIC0gTmV3IGNvbnRleHQgdG8gc2V0LlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBzZXRDb250ZXh0KHsgY29udGV4dCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1zZXQtY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlICYmIGNsaWVudFN0YXRlLmNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgY29udGV4dEdyb3VwSWQgfSA9IGNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICB0aGlzLnNldENvbnRleHRGb3JHcm91cCh7IGNvbnRleHQgfSwgY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIGlmIChjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBDbGllbnQgaGFzIG5vdCBqb2luZWQgYW55IGNvbnRleHQgZ3JvdXAgYmVoYXZpb3IuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3Qgam9pbiBhIGNvbnRleHQgZ3JvdXAgYmVmb3JlIHlvdSBjYW4gc2V0IGNvbnRleHQuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICAvLyBUaGlzIHNob3VsZG4ndCBnZXQgaGl0LlxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2NsaWVudElkZW50aXR5LnV1aWR9ICR7Y2xpZW50SWRlbnRpdHkubmFtZX0gbm90IGluIENsaWVudCBTdGF0ZSBNYXBgKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNldHMgYSBjb250ZXh0IGZvciB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqIEBwYXJhbSBzZXRDb250ZXh0T3B0aW9ucyAtIE5ldyBjb250ZXh0IHRvIHNldC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0R3JvdXBJZCAtIENvbnRleHQgZ3JvdXAgaWQuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBzZXRDb250ZXh0Rm9yR3JvdXAoeyBjb250ZXh0IH0sIGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtYnJva2VyLXNldC1jb250ZXh0LWZvci1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cFN0YXRlID0gdGhpcy5jb250ZXh0R3JvdXBzQnlJZC5nZXQoY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIGlmICghY29udGV4dEdyb3VwU3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gc2V0IGNvbnRleHQgZm9yIGNvbnRleHQgZ3JvdXAgdGhhdCBpc24ndCBpbiB0aGUgY29udGV4dCBncm91cCBtYXBwaW5nOiAke2NvbnRleHRHcm91cElkfS5gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0ID0gSW50ZXJvcEJyb2tlci5jaGVja0NvbnRleHRJbnRlZ3JpdHkoY29udGV4dCk7XG5cdCAgICAgICAgaWYgKGNvbnRleHRJbnRlZ3JpdHlDaGVja1Jlc3VsdC5pc1ZhbGlkID09PSBmYWxzZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBzZXQgQ29udGV4dCAtIGJhZCBDb250ZXh0LiBSZWFzb246ICR7Y29udGV4dEludGVncml0eUNoZWNrUmVzdWx0LnJlYXNvbn0uIENvbnRleHQ6ICR7SlNPTi5zdHJpbmdpZnkoY29udGV4dCl9YCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IGJyb2FkY2FzdGVkQ29udGV4dFR5cGUgPSBjb250ZXh0LnR5cGU7XG5cdCAgICAgICAgY29udGV4dEdyb3VwU3RhdGUuc2V0KGJyb2FkY2FzdGVkQ29udGV4dFR5cGUsIGNvbnRleHQpO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHRNYXAuc2V0KGNvbnRleHRHcm91cElkLCBicm9hZGNhc3RlZENvbnRleHRUeXBlKTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5TYW1lQ29udGV4dEdyb3VwID0gQXJyYXkuZnJvbSh0aGlzLmludGVyb3BDbGllbnRzLnZhbHVlcygpKS5maWx0ZXIoKGNvbm5lY3RlZENsaWVudCkgPT4gY29ubmVjdGVkQ2xpZW50LmNvbnRleHRHcm91cElkID09PSBjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgY2xpZW50c0luU2FtZUNvbnRleHRHcm91cC5mb3JFYWNoKChjbGllbnQpID0+IHtcblx0ICAgICAgICAgICAgZm9yIChjb25zdCBbLCBoYW5kbGVySW5mb10gb2YgY2xpZW50LmNvbnRleHRIYW5kbGVycykge1xuXHQgICAgICAgICAgICAgICAgaWYgKEludGVyb3BCcm9rZXIuaXNDb250ZXh0VHlwZUNvbXBhdGlibGUoYnJvYWRjYXN0ZWRDb250ZXh0VHlwZSwgaGFuZGxlckluZm8uY29udGV4dFR5cGUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnZva2VDb250ZXh0SGFuZGxlcihjbGllbnQuY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJbmZvLmhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0IGN1cnJlbnQgY29udGV4dCBmb3IgYSBjbGllbnQgc3Vic2NyaWJlZCB0byBhIENvbnRleHQgR3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSXQgdGFrZXMgYW4gb3B0aW9uYWwgQ29udGV4dCBUeXBlIGFyZ3VtZW50IGFuZCByZXR1cm5zIHRoZSBsYXN0IGNvbnRleHQgb2YgdGhhdCB0eXBlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBnZXRDb250ZXh0T3B0aW9ucyAtIE9wdGlvbnMgZm9yIGdldHRpbmcgY29udGV4dFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBnZXRDdXJyZW50Q29udGV4dChnZXRDdXJyZW50Q29udGV4dE9wdGlvbnMsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtYnJva2VyLWdldC1jdXJyZW50LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGlmICghY2xpZW50U3RhdGU/LmNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3QgYmUgYSBtZW1iZXIgb2YgYSBjb250ZXh0IGdyb3VwIHRvIGNhbGwgZ2V0Q3VycmVudENvbnRleHQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgeyBjb250ZXh0R3JvdXBJZCB9ID0gY2xpZW50U3RhdGU7XG5cdCAgICAgICAgY29uc3QgY29udGV4dEdyb3VwU3RhdGUgPSB0aGlzLmNvbnRleHRHcm91cHNCeUlkLmdldChjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgY29uc3QgbGFzdENvbnRleHRUeXBlID0gdGhpcy5sYXN0Q29udGV4dE1hcC5nZXQoY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRUeXBlID0gZ2V0Q3VycmVudENvbnRleHRPcHRpb25zPy5jb250ZXh0VHlwZSA/PyBsYXN0Q29udGV4dFR5cGU7XG5cdCAgICAgICAgcmV0dXJuIGNvbnRleHRHcm91cFN0YXRlICYmIGNvbnRleHRUeXBlID8gY29udGV4dEdyb3VwU3RhdGUuZ2V0KGNvbnRleHRUeXBlKSA6IHVuZGVmaW5lZDtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBQbGF0Zm9ybSBXaW5kb3cgQVBJc1xuXHQgICAgKi9cblx0ICAgIC8vIGpvaW5Db250ZXh0R3JvdXAgYW5kIGFkZENsaWVudFRvQ29udGV4dEdyb3VwIGFyZSBzZXBhcmF0ZSBmdW5jdGlvbnMgaGVyZSwgZm9yIGVhc2llciBvdmVycmlkZXMgYW5kIHNlcGFyYXRpb24gb2YgY29uY2VybnMuXG5cdCAgICAvLyBqb2luQ29udGV4dEdyb3VwIGNoZWNrcyBhbGwgY29ubmVjdGlvbnMgZm9yIG1hdGNoaW5nIGlkZW50aXRpZXMsIGluIGNhc2Ugd2UgaGF2ZSBtdWx0aXBsZSBjb25uZWN0aW9uIGZyb20gYW4gZW50aXR5LlxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFsbCBjb25uZWN0aW9ucyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgKG9yIGp1c3Qgb25lIGlmIGVuZHBvaW50SWQgcHJvdmlkZWQpIHRvIGNvbnRleHQgZ3JvdXAgYGNvbnRleHRHcm91cElkYC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IGFkZHMgdGhlIHNlbmRlciB0byB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqIGpvaW5Db250ZXh0R3JvdXAgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIGNvbm5lY3Rpb25zIGF0IHRoZSBpbmNvbWluZyBpZGVudGl0eS4gSXQgY2FsbHMge0BsaW5rIEludGVyb3BCcm9rZXIjYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAgSW50ZXJvcEJyb2tlci5hZGRDbGllbnRUb0NvbnRleHRHcm91cH0gdG8gYWN0dWFsbHkgZ3JvdXAgdGhlIGNsaWVudC5cblx0ICAgICAqIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gam9pbkNvbnRleHRHcm91cE9wdGlvbnMgLSBJZCBvZiB0aGUgQ29udGV4dCBHcm91cCBhbmQgaWRlbnRpdHkgb2YgdGhlIGVudGl0eSB0byBqb2luIHRvIHRoZSBncm91cC5cblx0ICAgICAqIEBwYXJhbSBzZW5kZXJJZGVudGl0eSAtIElkZW50aXR5IG9mIHRoZSBjbGllbnQgc2VuZGVyLlxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKHsgY29udGV4dEdyb3VwSWQsIHRhcmdldCB9LCBzZW5kZXJJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1qb2luLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAodGhpcy5zZXNzaW9uQ29udGV4dEdyb3VwTWFwLmhhcyhjb250ZXh0R3JvdXBJZCkpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5qb2luU2Vzc2lvbkNvbnRleHRHcm91cFdpdGhKb2luQ29udGV4dEdyb3VwKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKHRhcmdldCkge1xuXHQgICAgICAgICAgICAvLyBJZiBhbiBlbmRwb2ludElkIGlzIHByb3ZpZGVkLCB1c2UgdGhhdC4gVGhpcyB3aWxsIGxpa2VseSBiZSB1c2VkIGJ5IGV4dGVybmFsIGFkYXB0ZXJzLlxuXHQgICAgICAgICAgICBpZiAoSW50ZXJvcEJyb2tlci5oYXNFbmRwb2ludElkKHRhcmdldCkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAoeyBjb250ZXh0R3JvdXBJZCB9LCB0YXJnZXQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIFNhbml0eSBjaGVjayBoZXJlIGluIGNhc2UgYSBzaW5nbGUgYXBwIGhhcyBtdWx0aXBsZSBjb25uZWN0aW9uc1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgYWxsQ29ubmVjdGlvbnMgPSB0aGlzLmNoYW5uZWwuY29ubmVjdGlvbnMuZmlsdGVyKCh4KSA9PiB4LnV1aWQgPT09IHRhcmdldC51dWlkICYmIHgubmFtZSA9PT0gdGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgICAgICAgICAgaWYgKCFhbGxDb25uZWN0aW9ucy5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdpdmVuIElkZW50aXR5ICR7dGFyZ2V0LnV1aWR9ICR7dGFyZ2V0Lm5hbWV9IGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhlIEludGVyb3AgQnJva2VyLmApO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgaWYgKGFsbENvbm5lY3Rpb25zLmxlbmd0aCA+IDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTaG91bGQgZmlndXJlIG91dCBob3cgd2Ugd2FudCB0byBoYW5kbGUgdGhpcyBzaXR1YXRpb24uIEluIHRoZSBtZWFudGltZSwganVzdCBjaGFuZ2UgY29udGV4dCBncm91cCBmb3IgYWxsIGNvbm5lY3Rpb25zLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgTW9yZSB0aGFuIG9uZSBjb25uZWN0aW9uIGZvdW5kIGZvciBpZGVudGl0eSAke3RhcmdldC51dWlkfSAke3RhcmdldC5uYW1lfWApO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblx0ICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBhbGxDb25uZWN0aW9ucykge1xuXHQgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5hZGRDbGllbnRUb0NvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0sIGNvbm5lY3Rpb24pKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIC8vIE5vIHRhcmdldCBwcm92aWRlZCwgYWRkIHRoZSBzZW5kZXIgdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAoeyBjb250ZXh0R3JvdXBJZCB9LCBzZW5kZXJJZGVudGl0eSk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAgZG9lcyB0aGUgYWN0dWFsIGFkZGl0aW9uIG9mIHRoZSBjbGllbnQgdG8gdGhlIENvbnRleHQgR3JvdXBcblx0ICAgIC8qKlxuXHQgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciB7QGxpbmsgSW50ZXJvcEJyb2tlciNqb2luQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIuam9pbkNvbnRleHRHcm91cH0uIERvZXMgdGhlIHdvcmsgb2YgYWN0dWFsbHkgYWRkaW5nIHRoZSBjbGllbnQgdG8gdGhlIENvbnRleHQgR3JvdXAuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGFkZENsaWVudFRvQ29udGV4dEdyb3VwT3B0aW9ucyAtIENvbnRhaW5zIHRoZSBjb250ZXh0R3JvdXBJZFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGFkZENsaWVudFRvQ29udGV4dEdyb3VwKHsgY29udGV4dEdyb3VwSWQgfSwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItYWRkLWNsaWVudC10by1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWNsaWVudFN1YnNjcmlwdGlvblN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0gJHtjbGllbnRJZGVudGl0eS5uYW1lfSBub3QgaW4gQ2xpZW50IFN0YXRlIE1hcGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoIXRoaXMuZ2V0Q29udGV4dEdyb3VwcygpLmZpbmQoKGNvbnRleHRHcm91cEluZm8pID0+IGNvbnRleHRHcm91cEluZm8uaWQgPT09IGNvbnRleHRHcm91cElkKSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEF0dGVtcHRpbmcgdG8gam9pbiBhIGNvbnRleHQgZ3JvdXAgdGhhdCBkb2VzIG5vdCBleGlzdDogJHtjb250ZXh0R3JvdXBJZH0uIFlvdSBtYXkgb25seSBqb2luIGV4aXN0aW5nIGNvbnRleHQgZ3JvdXBzLmApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCBvbGRDb250ZXh0R3JvdXBJZCA9IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlLmNvbnRleHRHcm91cElkO1xuXHQgICAgICAgIGlmIChvbGRDb250ZXh0R3JvdXBJZCAhPT0gY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEdyb3VwSWQgPSBjb250ZXh0R3JvdXBJZDtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRDdXJyZW50Q29udGV4dEdyb3VwSW5DbGllbnRPcHRpb25zKGNsaWVudElkZW50aXR5LCBjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cE1hcCA9IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuZ2V0KGNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgZm9yIChjb25zdCBbLCBoYW5kbGVySW5mb10gb2YgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEhhbmRsZXJzKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRUeXBlLCBoYW5kbGVySWQgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTZW5kIHRoaXMgc2luZ2xlIGhhbmRsZXIgYWxsIG9mIHRoZSBjb250ZXh0LCBiZWNhdXNlIGl0IGFjY2VwdHMgYWxsLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnRleHRHcm91cE1hcC5mb3JFYWNoKChjb250ZXh0LCBfKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZXh0R3JvdXBNYXAuaGFzKGNvbnRleHRUeXBlKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRleHRGb3JUeXBlID0gY29udGV4dEdyb3VwTWFwLmdldChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRGb3JUeXBlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dEZvclR5cGUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIFJlbW92ZXMgdGhlIHRhcmdldCBmcm9tIGl0cyBjb250ZXh0IGdyb3VwLiBTaW1pbGFyIHN0cnVjdHVyZSB0byBqb2luQ29udGV4dEdyb3VwLlxuXHQgICAgLyoqXG5cdCAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGZyb20gYSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogSWYgbm8gdGFyZ2V0IGlzIHNwZWNpZmllZCwgaXQgcmVtb3ZlcyB0aGUgc2VuZGVyIGZyb20gdGhlaXIgY29udGV4dCBncm91cC5cblx0ICAgICAqIHJlbW92ZUZyb21Db250ZXh0R3JvdXAgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIGNvbm5lY3Rpb25zIGF0IHRoZSBpbmNvbWluZyBpZGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBJdCBjYWxscyB7QGxpbmsgSW50ZXJvcEJyb2tlciNyZW1vdmVDbGllbnRGcm9tQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIucmVtb3ZlQ2xpZW50RnJvbUNvbnRleHRHcm91cH0gdG8gYWN0dWFsbHkgdW5ncm91cFxuXHQgICAgICogdGhlIGNsaWVudC4gVXNlZCBieSBQbGF0Zm9ybSBXaW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSByZW1vdmVGcm9tQ29udGV4dEdyb3VwT3B0aW9ucyAtIENvbnRhaW5zIHRoZSB0YXJnZXQgaWRlbnRpdHkgdG8gcmVtb3ZlLlxuXHQgICAgICogQHBhcmFtIHNlbmRlcklkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHJlbW92ZUZyb21Db250ZXh0R3JvdXAoeyB0YXJnZXQgfSwgc2VuZGVySWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItcmVtb3ZlLWZyb20tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICh0YXJnZXQpIHtcblx0ICAgICAgICAgICAgLy8gSWYgYW4gZW5kcG9pbnRJZCBpcyBwcm92aWRlZCwgdXNlIHRoYXQuIFRoaXMgd2lsbCBsaWtlbHkgYmUgdXNlZCBieSBleHRlcm5hbCBhZGFwdGVycy5cblx0ICAgICAgICAgICAgaWYgKEludGVyb3BCcm9rZXIuaGFzRW5kcG9pbnRJZCh0YXJnZXQpKSB7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAodGFyZ2V0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2FuaXR5IGNoZWNrIGhlcmUgaW4gY2FzZSBhIHNpbmdsZSBhcHAgaGFzIG11bHRpcGxlIGNvbm5lY3Rpb25zXG5cdCAgICAgICAgICAgICAgICBjb25zdCBhbGxDb25uZWN0aW9ucyA9IHRoaXMuY2hhbm5lbC5jb25uZWN0aW9ucy5maWx0ZXIoKHgpID0+IHgudXVpZCA9PT0gdGFyZ2V0LnV1aWQgJiYgeC5uYW1lID09PSB0YXJnZXQubmFtZSk7XG5cdCAgICAgICAgICAgICAgICBpZiAoIWFsbENvbm5lY3Rpb25zLmxlbmd0aCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gY29ubmVjdGlvbiBmb3VuZCBmb3IgZ2l2ZW4gSWRlbnRpdHkgJHt0YXJnZXQudXVpZH0gJHt0YXJnZXQubmFtZX1gKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChhbGxDb25uZWN0aW9ucy5sZW5ndGggPiAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBNb3JlIHRoYW4gb25lIGNvbm5lY3Rpb24gZm91bmQgZm9yIGlkZW50aXR5ICR7dGFyZ2V0LnV1aWR9ICR7dGFyZ2V0Lm5hbWV9YCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuXHQgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGFsbENvbm5lY3Rpb25zKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAoY29ubmVjdGlvbikpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgLy8gTm8gdGFyZ2V0IHByb3ZpZGVkLCByZW1vdmUgdGhlIHNlbmRlciBmcm9tIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAoc2VuZGVySWRlbnRpdHkpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIHJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAgZG9lcyB0aGUgYWN0dWFsIHJlbW92ZSBvZiB0aGUgY2xpZW50IGZyb20gdGhlIENvbnRleHQgR3JvdXBcblx0ICAgIC8qKlxuXHQgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciB7QGxpbmsgSW50ZXJvcEJyb2tlciNyZW1vdmVGcm9tQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIucmVtb3ZlRnJvbUNvbnRleHRHcm91cH0uIERvZXMgdGhlIHdvcmsgb2YgYWN0dWFsbHkgcmVtb3ZpbmcgdGhlIGNsaWVudCBmcm9tIHRoZSBDb250ZXh0IEdyb3VwLlxuXHQgICAgICogVXNlZCBieSBQbGF0Zm9ybSBXaW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7IENsaWVudElkZW50aXR5IH0gY2xpZW50SWRlbnRpdHkgLSBJZGVudGl0eSBvZiB0aGUgY2xpZW50IHNlbmRlci5cblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmVtb3ZlQ2xpZW50RnJvbUNvbnRleHRHcm91cChjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1yZW1vdmUtY2xpZW50LWZyb20tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGNsaWVudFN0YXRlLmNvbnRleHRHcm91cElkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhd2FpdCB0aGlzLnNldEN1cnJlbnRDb250ZXh0R3JvdXBJbkNsaWVudE9wdGlvbnMoY2xpZW50SWRlbnRpdHksIG51bGwpO1xuXHQgICAgfVxuXHQgICAgLy8gVXNlZCBieSBwbGF0Zm9ybSB3aW5kb3dzIHRvIGtub3cgd2hhdCBjbGllbnQgZ3JvdXBzIHRoZSBwcm92aWRlciBoYXMgZGVjbGFyZWQuIEFsc28gdXNlZCBpbnRlcm5hbGx5IHRvIGFjY2VzcyBjb250ZXh0IGdyb3Vwcy4gT3ZlcnJpZGVhYmxlIHNvIHRoYXQgdGhlIHBsYXRmb3JtIGRldmVsb3BlciBjYW4gbW9kaWZ5IGl0LlxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBJbnRlcm9wLUJyb2tlci1kZWZpbmVkIGNvbnRleHQgZ3JvdXBzIGF2YWlsYWJsZSBmb3IgYW4gZW50aXR5IHRvIGpvaW4uIEJlY2F1c2UgdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIHRoZSByZXN0IG9mIHRoZSBJbnRlcm9wIEJyb2tlciB0byBmZXRjaCB0aGUgQ29udGV4dCBHcm91cHMsIG92ZXJyaWRpbmcgdGhpcyBhbGxvd3MgeW91IHRvIGN1c3RvbWl6ZSB0aGUgQ29udGV4dCBHcm91cHMgZm9yIHRoZSBJbnRlcm9wIEJyb2tlci4gSG93ZXZlciwgd2UgcmVjb21tZW5kIGN1c3RvbWl6aW5nIHRoZSBjb250ZXh0IGdyb3VwcyB0aHJvdWdoIGNvbmZpZ3VyYXRpb24gaW5zdGVhZC5cblx0ICAgICAqIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBnZXRDb250ZXh0R3JvdXBzKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1nZXQtY29udGV4dC1ncm91cHMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvLyBDcmVhdGUgY29weSBmb3IgaW1tdXRhYmlsaXR5XG5cdCAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3VwcywgXCJmXCIpLm1hcCgoY29udGV4dEdyb3VwKSA9PiB7XG5cdCAgICAgICAgICAgIHJldHVybiB7IC4uLmNvbnRleHRHcm91cCB9O1xuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgLy8gVXNlZCB0byBieSBwbGF0Zm9ybSB3aW5kb3dzIHRvIGdldCBkaXNwbGF5IG1ldGFkYXRhIGZvciBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAvKipcblx0ICAgICAqIEdldHMgZGlzcGxheSBpbmZvIGZvciBhIGNvbnRleHQgZ3JvdXBcblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGdldEluZm9Gb3JDb250ZXh0R3JvdXBPcHRpb25zIC0gQ29udGFpbnMgY29udGV4dEdyb3VwSWQsIHRoZSBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBkaXNwbGF5IGluZm8gZm9yLlxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0pIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItZ2V0LWluZm8tZm9yLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5nZXRDb250ZXh0R3JvdXBzKCkuZmluZCgoY29udGV4dEdyb3VwKSA9PiBjb250ZXh0R3JvdXAuaWQgPT09IGNvbnRleHRHcm91cElkKTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgYnkgcGxhdGZvcm0gd2luZG93cyB0byBnZXQgYWxsIGNsaWVudHMgZm9yIGEgY29udGV4dCBncm91cC5cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBhbGwgY2xpZW50cyBmb3IgYSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzICoqVGhpcyBpcyBwcmltYXJpbHkgdXNlZCBmb3IgcGxhdGZvcm0gd2luZG93cy4gVmlld3Mgd2l0aGluIGEgcGxhdGZvcm0gc2hvdWxkIG5vdCBoYXZlIHRvIHVzZSB0aGlzIEFQSS4qKlxuXHQgICAgICogUmV0dXJucyB0aGUgSW50ZXJvcC1Ccm9rZXItZGVmaW5lZCBjb250ZXh0IGdyb3VwcyBhdmFpbGFibGUgZm9yIGFuIGVudGl0eSB0byBqb2luLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBnZXRBbGxDbGllbnRzSW5Db250ZXh0R3JvdXBPcHRpb25zIC0gQ29udGFpbnMgY29udGV4dEdyb3VwSWQsIHRoZSBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBjbGllbnRzIGZvci5cblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0pIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItZ2V0LWFsbC1jbGllbnRzLWluLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5Db250ZXh0R3JvdXAgPSBBcnJheS5mcm9tKHRoaXMuaW50ZXJvcENsaWVudHMudmFsdWVzKCkpXG5cdCAgICAgICAgICAgIC5maWx0ZXIoKGNvbm5lY3RlZENsaWVudCkgPT4gY29ubmVjdGVkQ2xpZW50LmNvbnRleHRHcm91cElkID09PSBjb250ZXh0R3JvdXBJZClcblx0ICAgICAgICAgICAgLm1hcCgoc3Vic2NyaXB0aW9uU3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvblN0YXRlLmNsaWVudElkZW50aXR5O1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBjbGllbnRzSW5Db250ZXh0R3JvdXA7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciBsYXVuY2hpbmcgb2YgYXBwbGljYXRpb25zIHRoYXQgY2FuIGhhbmRsZSBhIGdpdmVuIGludGVudCwgYW5kIGRlbGVnYXRpb24gb2YgaW50ZW50cyB0byB0aG9zZSBhcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gbWFrZSB0aGlzIGNhbGwgRkRDMy1Db21wbGlhbnQgaXQgd291bGQgbmVlZCB0byByZXR1cm4gYW4gSW50ZW50UmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogaW50ZXJmYWNlIEludGVudFJlc29sdXRpb24ge1xuXHQgICAgICogICBzb3VyY2U6IFRhcmdldEFwcDtcblx0ICAgICAqICAgLy8gZGVwcmVjYXRlZCwgbm90IGFzc2lnbmFibGUgZnJvbSBpbnRlbnQgbGlzdGVuZXJzXG5cdCAgICAgKiAgIGRhdGE/OiBvYmplY3Q7XG5cdCAgICAgKiAgIHZlcnNpb246IHN0cmluZztcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIE1vcmUgaW5mb3JtYXRpb24gb24gdGhlIEludGVudFJlc29sdXRpb24gdHlwZSBjYW4gYmUgZm91bmQgaW4gdGhlIFtGREMzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL0ludGVudFJlc29sdXRpb24pLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgVGhlIGNvbWJpbmF0aW9uIG9mIGFuIGFjdGlvbiBhbmQgYSBjb250ZXh0IHRoYXQgaXMgcGFzc2VkIHRvIGFuIGFwcGxpY2F0aW9uIGZvciByZXNvbHV0aW9uLlxuXHQgICAgICogQHBhcmFtICBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIC8vIG92ZXJyaWRlIGNhbGwgc28gd2Ugc2V0IGludGVudCB0YXJnZXQgYW5kIGNyZWF0ZSB2aWV3IHRoYXQgd2lsbCBoYW5kbGUgaXRcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudChpbnRlbnQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBzdXBlci5zZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB7IHV1aWQ6ICdwbGF0Zm9ybS11dWlkJywgbmFtZTogJ2ludGVudC12aWV3JyB9KTtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyBuYW1lOiAnZm9vJywgdXVpZDogJ3BsYXRmb3JtLXV1aWQnIH0pO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRWaWV3ID0gYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh7IHVybDogJ2h0dHA6Ly9vcGVuZmluLmNvJywgbmFtZTogJ2ludGVudC12aWV3JyB9LCB3aW4uaWRlbnRpdHkpO1xuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIHJldHVybiBuZXcgT3ZlcnJpZGUoKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuXHQgICAgYXN5bmMgaGFuZGxlRmlyZWRJbnRlbnQoaW50ZW50LCBjbGllbnRJZGVudGl0eSAvLyBUT0RPKENPUkUtODExKTogcmVtb3ZlIGlubGluZSBpbnRlcnNlY3RlZCB0eXBlXG5cdCAgICApIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLnJhaXNlSW50ZW50JywgJ0ludGVyb3BCcm9rZXIuaGFuZGxlRmlyZWRJbnRlbnQnLCBjbGllbnRJZGVudGl0eSwgJ2ludGVyb3BDbGllbnQuZmlyZUludGVudCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG91bGQgYmUgY2FsbGVkIGluIHtAbGluayBJbnRlcm9wQnJva2VyI2hhbmRsZUZpcmVkSW50ZW50IEludGVyb3BCcm9rZXIuaGFuZGxlRmlyZWRJbnRlbnR9LlxuXHQgICAgICogV2hpbGUgaGFuZGxlRmlyZWRJbnRlbnQgaXMgcmVzcG9uc2libGUgZm9yIGxhdW5jaGluZyBhcHBsaWNhdGlvbnMsIHNldEludGVudFRhcmdldCBpcyB1c2VkIHRvIHRlbGwgdGhlIEludGVyb3BCcm9rZXIgd2hpY2ggYXBwbGljYXRpb24gc2hvdWxkIHJlY2VpdmUgdGhlIGludGVudCB3aGVuIGl0IGlzIHJlYWR5LlxuXHQgICAgICogQHBhcmFtIGludGVudCBUaGUgY29tYmluYXRpb24gb2YgYW4gYWN0aW9uIGFuZCBhIGNvbnRleHQgdGhhdCBpcyBwYXNzZWQgdG8gYW4gYXBwbGljYXRpb24gZm9yIHJlc29sdXRpb24uXG5cdCAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gSWRlbnRpdHkgb2YgdGhlIHRhcmdldCB0aGF0IHdpbGwgaGFuZGxlIHRoZSBpbnRlbnQuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB0YXJnZXQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItc2V0LWludGVudC10YXJnZXQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIHRoaXMgaXMgb25seSBmb3IgYXBpIGFuYWx5dGljcyBwdXJwb3Nlc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQodGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgIGNvbnN0IGhhbmRsZXJJZCA9IGBpbnRlbnQtaGFuZGxlci0ke2ludGVudC5uYW1lfWA7XG5cdCAgICAgICAgaWYgKCF0YXJnZXRJbmZvKSB7XG5cdCAgICAgICAgICAgIHRoaXMuaW50ZW50Q2xpZW50TWFwLnNldCh0YXJnZXQubmFtZSwgbmV3IE1hcCgpKTtcblx0ICAgICAgICAgICAgY29uc3QgbmV3SGFuZGxlckluZm9NYXAgPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQodGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgICAgICBpZiAobmV3SGFuZGxlckluZm9NYXApIHtcblx0ICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJJbmZvTWFwLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogZmFsc2UsIHBlbmRpbmdJbnRlbnRzOiBbaW50ZW50XSB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY29uc3QgaGFuZGxlckluZm8gPSB0YXJnZXRJbmZvLmdldChoYW5kbGVySWQpO1xuXHQgICAgICAgICAgICBpZiAoIWhhbmRsZXJJbmZvKSB7XG5cdCAgICAgICAgICAgICAgICB0YXJnZXRJbmZvLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogZmFsc2UsIHBlbmRpbmdJbnRlbnRzOiBbaW50ZW50XSB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJbmZvLnBlbmRpbmdJbnRlbnRzLnB1c2goaW50ZW50KTtcblx0ICAgICAgICAgICAgICAgIGlmIChoYW5kbGVySW5mby5jbGllbnRJZGVudGl0eSAmJiBoYW5kbGVySW5mby5pc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgcGVuZGluZ0ludGVudHMgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVudFRvU2VuZCA9IHBlbmRpbmdJbnRlbnRzW3BlbmRpbmdJbnRlbnRzLmxlbmd0aCAtIDFdO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmludm9rZUludGVudEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgaW50ZW50VG9TZW5kKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8ucGVuZGluZ0ludGVudHMgPSBbXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGludGVudCBoYW5kbGVyIGZvciBjbGllbnQgJHtjbGllbnRJZGVudGl0eS51dWlkfS8ke2NsaWVudElkZW50aXR5Lm5hbWV9LyR7Y2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH1gKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8uaXNSZWFkeSA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJldHVybmluZyBpbmZvcm1hdGlvbiBvbiBhIHBhcnRpY3VsYXIgSW50ZW50LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdoZW5ldmVyIEludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCBpcyBjYWxsZWQgdGhpcyBmdW5jdGlvbiB3aWxsIGZpcmUuIFRoZSBvcHRpb25zIGFyZ3VtZW50IGdpdmVzIHlvdVxuXHQgICAgICogYWNjZXNzIHRvIHRoZSBpbnRlbnQgbmFtZSBhbmQgYW55IG9wdGlvbmFsIGNvbnRleHQgdGhhdCB3YXMgcGFzc2VkIGFuZCBjbGllbnRJZGVudGl0eSBpcyB0aGUgaWRlbnRpdHkgb2YgdGhlIGNsaWVudFxuXHQgICAgICogdGhhdCBtYWRlIHRoZSBjYWxsLiBJZGVhbGx5IGhlcmUgeW91IHdvdWxkIGZldGNoIHRoZSBpbmZvIGZvciB0aGUgaW50ZW50IGFuZCByZXR1cm4gaXQgd2l0aCB0aGUgc2hhcGUgdGhhdCB0aGVcblx0ICAgICAqIEludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCBjYWxsIGlzIGV4cGVjdGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBBcHAgSW50ZW50OlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogTW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgQXBwSW50ZW50IHR5cGUgY2FuIGJlIGZvdW5kIGluIHRoZSBbRkRDMyBkb2N1bWVudGF0aW9uXShodHRwczovL2ZkYzMuZmlub3Mub3JnL2RvY3MvYXBpL3JlZi9BcHBJbnRlbnQpLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHkgSWRlbnRpdHkgb2YgdGhlIENsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdCAgICAgKiAgICAgaW50ZXJvcE92ZXJyaWRlOiBhc3luYyAoSW50ZXJvcEJyb2tlcikgPT4ge1xuXHQgICAgICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICogICAgICAgICAgICAgYXN5bmMgaGFuZGxlSW5mb0ZvckludGVudChvcHRpb25zLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIFlvdXIgY29kZSBnb2VzIGhlcmUuXG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBoYW5kbGVJbmZvRm9ySW50ZW50KG9wdGlvbnMsIGNsaWVudElkZW50aXR5IC8vIFRPRE8oQ09SRS04MTEpOiByZW1vdmUgaW5saW5lIGludGVyc2VjdGVkIHR5cGVcblx0ICAgICkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZmluZEludGVudCcsICdJbnRlcm9wQnJva2VyLmhhbmRsZUluZm9Gb3JJbnRlbnQnLCBjbGllbnRJZGVudGl0eSwgJ2ludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXNwb25zaWJsZSBmb3IgcmV0dXJuaW5nIGluZm9ybWF0aW9uIG9uIHdoaWNoIEludGVudHMgYXJlIG1lYW50IHRvIGhhbmRsZSBhIHNwZWNpZmljIENvbnRleHQuXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgUmVzcG9uc2libGUgZm9yIHJldHVybmluZyBpbmZvcm1hdGlvbiBvbiB3aGljaCBJbnRlbnRzIGFyZSBtZWFudCB0byBoYW5kbGUgYSBzcGVjaWZpYyBDb250ZXh0LiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogV2hlbmV2ZXIgSW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBpcyBjYWxsZWQgdGhpcyBmdW5jdGlvbiB3aWxsIGZpcmUuIFRoZSBjb250ZXh0IGFyZ3VtZW50IGdpdmVzIHlvdSBhY2Nlc3MgdG8gdGhlIGNvbnRleHQgdGhhdCB0aGUgY2xpZW50IHdhbnRzIGluZm9ybWF0aW9uIG9uIGFuZCBjbGllbnRJZGVudGl0eSBpcyB0aGUgaWRlbnRpdHkgb2YgdGhlIGNsaWVudCB0aGF0IG1hZGUgdGhlIGNhbGwuIElkZWFsbHkgaGVyZSB5b3Ugd291bGQgZmV0Y2ggdGhlIGluZm8gZm9yIGFueSBpbnRlbnQgdGhhdCBjYW4gaGFuZGxlIGFuZCByZXR1cm4gaXQgd2l0aCB0aGUgc2hhcGUgdGhhdCB0aGUgSW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBjYWxsIGlzIGV4cGVjdGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBhcnJheSBvZiBBcHBJbnRlbnRzOlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyBbe1xuXHQgICAgICogLy8gICAgIGludGVudDogeyBuYW1lOiBcIlN0YXJ0Q2FsbFwiLCBkaXNwbGF5TmFtZTogXCJDYWxsXCIgfSxcblx0ICAgICAqIC8vICAgICBhcHBzOiBbeyBuYW1lOiBcIlNreXBlXCIgfV1cblx0ICAgICAqIC8vIH0sXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfV07XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBNb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBBcHBJbnRlbnQgdHlwZSBjYW4gYmUgZm91bmQgaW4gdGhlIFtGREMzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL0FwcEludGVudCkuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgRGF0YSBwYXNzZWQgYmV0d2VlbiBlbnRpdGllcyBhbmQgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IElkZW50aXR5IG9mIHRoZSBDbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgLy8gWW91ciBjb2RlIGdvZXMgaGVyZS5cblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKCk7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIGNsaWVudElkZW50aXR5IC8vIFRPRE8oQ09SRS04MTEpOiByZW1vdmUgaW5saW5lIGludGVyc2VjdGVkIHR5cGVcblx0ICAgICkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZmluZEludGVudHNCeUNvbnRleHQnLCAnSW50ZXJvcEJyb2tlci5oYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcsIGNsaWVudElkZW50aXR5LCAnaW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBhbiBJbnRlbnQgYmFzZWQgb24gYSBzcGVjaWZpYyBDb250ZXh0LlxuXHQgICAgICogTXVzdCBiZSBvdmVycmlkZGVuLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdoZW5ldmVyIEludGVyb3BDbGllbnQuZmlyZUludGVudEZvckNvbnRleHQgaXMgY2FsbGVkIHRoaXMgZnVuY3Rpb24gd2lsbCBmaXJlLiBUaGUgY29udGV4dEZvckludGVudCBhcmd1bWVudFxuXHQgICAgICogZ2l2ZXMgeW91IGFjY2VzcyB0byB0aGUgY29udGV4dCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgdG8gYW4gaW50ZW50LiBJdCBhbHNvIGNhbiBvcHRpb25hbGx5IGNvbnRhaW4gYW55IG1ldGFkYXRhIHJlbGV2YW50XG5cdCAgICAgKiB0byByZXNvbHZpbmcgaXQsIGxpa2UgYSBzcGVjaWZpYyBhcHAgdGhlIGNsaWVudCB3YW50cyB0aGUgY29udGV4dCB0byBiZSBoYW5kbGVkIGJ5LiBUaGUgY2xpZW50SWRlbnRpdHkgaXMgdGhlIGlkZW50aXR5XG5cdCAgICAgKiBvZiB0aGUgY2xpZW50IHRoYXQgbWFkZSB0aGUgY2FsbC5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBJbnRlbnRSZXNvbHV0aW9uOlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogTW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgSW50ZW50UmVzb2x1dGlvbiB0eXBlIGNhbiBiZSBmb3VuZCBpbiB0aGUgW0ZEQzMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9mZGMzLmZpbm9zLm9yZy9kb2NzL2FwaS9yZWYvTWV0YWRhdGEjaW50ZW50cmVzb2x1dGlvbikuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRGb3JJbnRlbnQgRGF0YSBwYXNzZWQgYmV0d2VlbiBlbnRpdGllcyBhbmQgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IElkZW50aXR5IG9mIHRoZSBDbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGhhbmRsZUZpcmVkSW50ZW50Rm9yQ29udGV4dChjb250ZXh0Rm9ySW50ZW50LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIFlvdXIgY29kZSBnb2VzIGhlcmUuXG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQoY29udGV4dEZvckludGVudCwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLnJhaXNlSW50ZW50Rm9yQ29udGV4dCcsICdJbnRlcm9wQnJva2VyLmhhbmRsZUZpcmVkSW50ZW50Rm9yQ29udGV4dCcsIGNsaWVudElkZW50aXR5LCAnaW50ZXJvcENsaWVudC5maXJlSW50ZW50Rm9yQ29udGV4dCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnRGb3JDb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJvdmlkZXMgdGhlIGlkZW50aXR5IG9mIGFueSBJbnRlcm9wIENsaWVudCB0aGF0IGRpc2Nvbm5lY3RzIGZyb20gdGhlIEludGVyb3AgQnJva2VyLiBJdCBpcyBtZWFudCB0byBiZSBvdmVycmlkZW4uXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHlcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBjbGllbnREaXNjb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDbGllbnQgd2l0aCBpZGVudGl0eSAke3V1aWR9LyR7bmFtZX0gaGFzIGJlZW4gZGlzY29ubmVjdGVkYCk7XG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBjbGllbnREaXNjb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiBjaGFubmVsLm9uRGlzY29ubmVjdGlvbi5cblx0ICAgICAgICAvLyBJdCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIHRvIGluZm9ybSB3aGVuIGFuIEludGVyb3AgQ2xpZW50IGhhcyBiZWVuIGRpc2Nvbm5lY3RlZC5cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBhbiBmZGMzLm9wZW4gY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlbi5cblx0ICAgICAqIEBwYXJhbSBmZGMzT3Blbk9wdGlvbnMgZmRjMy5vcGVuIG9wdGlvbnNcblx0ICAgICAqIEBwYXJhbSBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGZkYzNIYW5kbGVPcGVuKHsgYXBwLCBjb250ZXh0IH0sIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3Qgd2FybmluZyA9ICgwLCB1dGlsc18xLmdlbmVyYXRlT3ZlcnJpZGVXYXJuaW5nKSgnZmRjMy5vcGVuJywgJ0ludGVyb3BCcm9rZXIuZmRjM0hhbmRsZU9wZW4nLCBjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcpO1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcih1dGlsc18xLkJST0tFUl9FUlJPUlMuZmRjM09wZW4pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIHRoZSBmZGMzLmZpbmRJbnN0YW5jZXMgY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlblxuXHQgICAgICogQHBhcmFtIGFwcCBBcHBJZGVudGlmaWVyIHRoYXQgd2FzIHBhc3NlZCB0byBmZGMzLmZpbmRJbnN0YW5jZXNcblx0ICAgICAqIEBwYXJhbSBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGZkYzNIYW5kbGVGaW5kSW5zdGFuY2VzKGFwcCwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLm9wZW4nLCAnSW50ZXJvcEJyb2tlci5mZGMzSGFuZGxlRmluZEluc3RhbmNlcycsIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjb25zb2xlLndhcm4od2FybmluZyk7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5mZGMzRmluZEluc3RhbmNlcyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgdGhlIGZkYzMuZ2V0QXBwTWV0YWRhdGEgY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlblxuXHQgICAgICogQHBhcmFtIGFwcCBBcHBJZGVudGlmaWVyIHRoYXQgd2FzIHBhc3NlZCB0byBmZGMzLmdldEFwcE1ldGFkYXRhXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHkgSWRlbnRpdHkgb2YgdGhlIENsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBmZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEoYXBwLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZ2V0QXBwTWV0YWRhdGEnLCAnSW50ZXJvcEJyb2tlci5mZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEnLCBjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcpO1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcih1dGlsc18xLkJST0tFUl9FUlJPUlMuZmRjM0dldEFwcE1ldGFkYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIEludGVyb3AgQnJva2VyIHdoZW5ldmVyIGEgQ29udGV4dCBoYW5kbGVyIHdvdWxkIGZpcmUuXG5cdCAgICAgKiBGb3IgRkRDMyAyLjAgeW91IHdvdWxkIG5lZWQgdG8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBhbmQgYWRkIHRoZSBjb250ZXh0TWV0YWRhdGEgYXNcblx0ICAgICAqIHBhcnQgb2YgdGhlIENvbnRleHQgb2JqZWN0LiBUaGVuIHdvdWxkIHlvdSBuZWVkIHRvIGNhbGxcblx0ICAgICAqIHN1cGVyLmludm9rZUNvbnRleHRIYW5kbGVyIHBhc3NpbmcgaXQgdGhpcyBuZXcgQ29udGV4dCBvYmplY3QgYWxvbmcgd2l0aCB0aGUgY2xpZW50SWRlbnRpdHkgYW5kIGhhbmRsZXJJZFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5XG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlcklkXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAuLi5jb250ZXh0LFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICBjb250ZXh0TWV0YWRhdGE6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZToge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcElkOiAnb3BlbmZpbi1hcHAnLFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6ICczRDU0RDQ1NkQ5SFQwJ1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpIHtcblx0ICAgICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIoKTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBhd2FpdCBwcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGNvbnRleHQgaGFuZGxlciAke2hhbmRsZXJJZH0gZm9yIGNvbnRleHQgdHlwZSAke2NvbnRleHQudHlwZX0gaW4gY2xpZW50ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0vJHtjbGllbnRJZGVudGl0eS5uYW1lfS8ke2NsaWVudElkZW50aXR5LmVuZHBvaW50SWR9YCwgZXJyb3IpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIEludGVyb3AgQnJva2VyIHdoZW5ldmVyIGFuIEludGVudCBoYW5kbGVyIHdvdWxkIGZpcmUuXG5cdCAgICAgKiBGb3IgRkRDMyAyLjAgeW91IHdvdWxkIG5lZWQgdG8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBhbmQgYWRkIHRoZSBjb250ZXh0TWV0YWRhdGEgYXNcblx0ICAgICAqIHBhcnQgb2YgdGhlIENvbnRleHQgb2JqZWN0IGluc2lkZSB0aGUgSW50ZW50IG9iamVjdC4gVGhlbiB3b3VsZCB5b3UgbmVlZCB0byBjYWxsXG5cdCAgICAgKiBzdXBlci5pbnZva2VJbnRlbnRIYW5kbGVyIHBhc3NpbmcgaXQgdGhpcyBuZXcgSW50ZW50IG9iamVjdCBhbG9uZyB3aXRoIHRoZSBjbGllbnRJZGVudGl0eSBhbmQgaGFuZGxlcklkXG5cdCAgICAgKiBAcGFyYW0gQ2xpZW50SWRlbnRpdHlcblx0ICAgICAqIEBwYXJhbSBoYW5kbGVySWRcblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdCAgICAgKiAgICAgaW50ZXJvcE92ZXJyaWRlOiBhc3luYyAoSW50ZXJvcEJyb2tlcikgPT4ge1xuXHQgICAgICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICogICAgICAgICAgICAgYXN5bmMgaW52b2tlSW50ZW50SGFuZGxlcihjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KSB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgY29uc3QgeyBjb250ZXh0IH0gPSBpbnRlbnQ7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmludm9rZUludGVudEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAuLi5pbnRlbnQsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmNvbnRleHQsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0TWV0YWRhdGE6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwSWQ6ICdvcGVuZmluLWFwcCcsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6ICczRDU0RDQ1NkQ5SFQwJ1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIHJldHVybiBuZXcgT3ZlcnJpZGUoKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBpbnZva2VJbnRlbnRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudCkge1xuXHQgICAgICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgdGhpcy5nZXRQcm92aWRlcigpO1xuXHQgICAgICAgIGF3YWl0IHByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgZmRjMy5nZXRJbmZvIGZvciBGREMzIDIuMFxuXHQgICAgICogV291bGQgbmVlZCB0byByZXR1cm4gdGhlIG9wdGlvbmFsRmVhdHVyZXMgYW5kIGFwcE1ldGFkYXRhIGZvciB0aGUge0BsaW5rIGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL01ldGFkYXRhI2ltcGxlbWVudGF0aW9ubWV0YWRhdGEgSW1wbGVtZW50YXRpb25NZXRhZGF0YX0uXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHlcblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBmZGMzSGFuZGxlR2V0SW5mbyhwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgZmRjM1ZlcnNpb24gfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgZmRjM1ZlcnNpb24sXG5cdCAgICAgICAgICAgIC4uLl9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfZmRjM0luZm8sIFwiZlwiKSxcblx0ICAgICAgICAgICAgb3B0aW9uYWxGZWF0dXJlczoge1xuXHQgICAgICAgICAgICAgICAgT3JpZ2luYXRpbmdBcHBNZXRhZGF0YTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBVc2VyQ2hhbm5lbE1lbWJlcnNoaXBBUElzOiB0cnVlXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGFwcE1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgICAgICBhcHBJZDogJycsXG5cdCAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiAnJ1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBpbmZvIGZvciBlYWNoIEludGVyb3AgQ2xpZW50IGNvbm5lY3RlZCB0byB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKlxuXHQgICAgICogRkRDMyAyLjA6IFVzZSB0aGUgZW5kcG9pbnRJZCBpbiB0aGUgQ2xpZW50SW5mbyBhcyB0aGUgaW5zdGFuY2VJZCB3aGVuIGdlbmVyYXRpbmdcblx0ICAgICAqIGFuIEFwcElkZW50aWZpZXIuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgRkRDMyAyLjAgTm90ZTogV2hlbiBuZWVkaW5nIGFuIGluc3RhbmNlSWQgdG8gZ2VuZXJhdGUgYW4gQXBwSWRlbnRpZmllciB1c2UgdGhpcyBjYWxsIHRvXG5cdCAgICAgKiBnZXQgdGhlIGVuZHBvaW50SWQgYW5kIHVzZSBpdCBhcyB0aGUgaW5zdGFuY2VJZC4gSW4gdGhlIEV4YW1wbGUgYmVsb3cgd2Ugb3ZlcnJpZGUgaGFuZGxlRmlyZWRJbnRlbnRcblx0ICAgICAqIGFuZCB0aGVuIGNhbGwgc3VwZXIuZ2V0QWxsQ2xpZW50SW5mbyB0byBnZW5lcmF0ZSB0aGUgQXBwSWRlbnRpZmllciBmb3IgdGhlIEludGVudFJlc29sdXRpb24uXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogLy8gRkRDMyAyLjAgRXhhbXBsZTpcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyLCAuLi5hcmdzKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudChpbnRlbnQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBzdXBlci5zZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB7IHV1aWQ6ICdwbGF0Zm9ybS11dWlkJywgbmFtZTogJ2ludGVudC12aWV3JyB9KTtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyBuYW1lOiAnZm9vJywgdXVpZDogJ3BsYXRmb3JtLXV1aWQnIH0pO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRWaWV3ID0gYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh7IHVybDogJ2h0dHA6Ly9vcGVuZmluLmNvJywgbmFtZTogJ2ludGVudC12aWV3JyB9LCB3aW4uaWRlbnRpdHkpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBhbGxDbGllbnRJbmZvID0gYXdhaXQgc3VwZXIuZ2V0QWxsQ2xpZW50SW5mbygpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBpbmZvRm9yVGFyZ2V0ID0gYWxsQ2xpZW50SW5mby5maW5kKChjbGllbnRJbmZvKSA9PiB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRJbmZvLnV1aWQgPT09ICdwbGF0Zm9ybS11dWlkJyAmJiBjbGllbnRJbmZvLm5hbWUgPT09ICdpbnRlbnQtdmlldyc7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgKlxuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgYXBwSWQ6ICdpbnRlbnQtdmlldycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6IGluZm9Gb3JUYXJnZXQuZW5kcG9pbnRJZFxuXHQgICAgICogICAgICAgICAgICAgICAgIH1cblx0ICAgICAqXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgc291cmNlLFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICBpbnRlbnQ6IGludGVudC5uYW1lXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKC4uLmFyZ3MpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEFsbENsaWVudEluZm8oKSB7XG5cdCAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCB0aGlzLmdldFByb3ZpZGVyKCk7XG5cdCAgICAgICAgcmV0dXJuIHByb3ZpZGVyLmdldEFsbENsaWVudEluZm8oKTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBTbmFwc2hvdCBBUElzXG5cdCAgICAqL1xuXHQgICAgLy8gVXNlZCB0byBzYXZlIGludGVyb3AgYnJva2VyIHN0YXRlIGluIHNuYXBzaG90c1xuXHQgICAgZGVjb3JhdGVTbmFwc2hvdChzbmFwc2hvdCkge1xuXHQgICAgICAgIHJldHVybiB7IC4uLnNuYXBzaG90LCBpbnRlcm9wU25hcHNob3REZXRhaWxzOiB7IGNvbnRleHRHcm91cFN0YXRlczogdGhpcy5nZXRDb250ZXh0R3JvdXBTdGF0ZXMoKSB9IH07XG5cdCAgICB9XG5cdCAgICAvLyBVc2VkIHRvIHJlc3RvcmUgaW50ZXJvcCBicm9rZXIgc3RhdGUgaW4gc25hcHNob3RzLlxuXHQgICAgYXBwbHlTbmFwc2hvdChzbmFwc2hvdCwgb3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cFN0YXRlcyA9IHNuYXBzaG90Py5pbnRlcm9wU25hcHNob3REZXRhaWxzPy5jb250ZXh0R3JvdXBTdGF0ZXM7XG5cdCAgICAgICAgaWYgKGNvbnRleHRHcm91cFN0YXRlcykge1xuXHQgICAgICAgICAgICBpZiAoIW9wdGlvbnM/LmNsb3NlRXhpc3RpbmdXaW5kb3dzKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUV4aXN0aW5nQ2xpZW50cyhjb250ZXh0R3JvdXBTdGF0ZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMucmVoeWRyYXRlQ29udGV4dEdyb3VwU3RhdGVzKGNvbnRleHRHcm91cFN0YXRlcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgdXBkYXRlRXhpc3RpbmdDbGllbnRzKGNvbnRleHRHcm91cFN0YXRlcykge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmludGVyb3BDbGllbnRzO1xuXHQgICAgICAgIGNsaWVudHMuZm9yRWFjaCgoc3ViU3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgY29udGV4dEdyb3VwSWQsIGNvbnRleHRIYW5kbGVycyB9ID0gc3ViU3RhdGU7XG5cdCAgICAgICAgICAgIGlmIChjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBDb250ZXh0cyA9IGNvbnRleHRHcm91cFN0YXRlc1tjb250ZXh0R3JvdXBJZF07XG5cdCAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFssIGNvbnRleHRdIG9mIE9iamVjdC5lbnRyaWVzKGdyb3VwQ29udGV4dHMpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzLmZvckVhY2goKGNvbnRleHRIYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9ID0gY29udGV4dEhhbmRsZXI7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJbnRlcm9wQnJva2VyLmlzQ29udGV4dFR5cGVDb21wYXRpYmxlKGNvbnRleHQudHlwZSwgY29udGV4dFR5cGUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgdG8gc3RvcmUgY29udGV4dCBncm91cCBzdGF0ZSBpbiBzbmFwc2hvdHNcblx0ICAgIGdldENvbnRleHRHcm91cFN0YXRlcygpIHtcblx0ICAgICAgICByZXR1cm4gSW50ZXJvcEJyb2tlci50b09iamVjdCh0aGlzLmNvbnRleHRHcm91cHNCeUlkKTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgdG8gcmVoeWRyYXRlIHRoZSBjb250ZXh0IHN0YXRlIGZyb20gYSBzbmFwc2hvdFxuXHQgICAgcmVoeWRyYXRlQ29udGV4dEdyb3VwU3RhdGVzKGluY29taW5nQ29udGV4dEdyb3VwU3RhdGVzKSB7XG5cdCAgICAgICAgY29uc3QgY29udGV4dEdyb3VwU3RhdGVzID0gT2JqZWN0LmVudHJpZXMoaW5jb21pbmdDb250ZXh0R3JvdXBTdGF0ZXMpO1xuXHQgICAgICAgIGZvciAoY29uc3QgW2NvbnRleHRHcm91cElkLCBjb250ZXh0c10gb2YgY29udGV4dEdyb3VwU3RhdGVzKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRPYmplY3RzID0gT2JqZWN0LmVudHJpZXMoY29udGV4dHMpO1xuXHQgICAgICAgICAgICBmb3IgKGNvbnN0IFtjb250ZXh0VHlwZSwgY29udGV4dF0gb2YgY29udGV4dE9iamVjdHMpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHRHcm91cHNCeUlkLmhhcyhjb250ZXh0R3JvdXBJZCkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dEdyb3VwU3RhdGUgPSB0aGlzLmNvbnRleHRHcm91cHNCeUlkLmdldChjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbnRleHRHcm91cFN0YXRlLnNldChjb250ZXh0VHlwZSwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGxvZ2ljIHdpbGwgY2hhbmdlIHdoZW4gZHluYW1pYyBjb250ZXh0IGdyb3VwIGNyZWF0aW9uIGNvbWVzIGluLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQXR0ZW1wdGluZyB0byBzZXQgYSBjb250ZXh0IGdyb3VwIHRoYXQgaXNuJ3QgaW4gdGhlIGNvbnRleHQgZ3JvdXAgbWFwcGluZy4gU2tpcHBpbmcgY29udGV4dCBncm91cCByZWh5ZHJhdGlvbiBmb3I6ICR7Y29udGV4dEdyb3VwSWR9YCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKlxuXHQgICAgSW50ZXJuYWwgQ29udGV4dCBIYW5kbGVyIEFQSXNcblx0ICAgICovXG5cdCAgICAvLyBVc2VkIHRvIGdpdmUgY29udGV4dCB0byBhIGNsaWVudCB0aGF0IGhhcyByZWdpc3RlcmVkIHRoZWlyIGNvbnRleHQgaGFuZGxlclxuXHQgICAgY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkKHsgY29udGV4dFR5cGUsIGhhbmRsZXJJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGhhbmRsZXJJbmZvID0geyBjb250ZXh0VHlwZSwgaGFuZGxlcklkIH07XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjbGllbnRTdGF0ZT8uY29udGV4dEhhbmRsZXJzLnNldChoYW5kbGVySWQsIGhhbmRsZXJJbmZvKTtcblx0ICAgICAgICBpZiAoY2xpZW50U3RhdGUgJiYgY2xpZW50U3RhdGUuY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjb250ZXh0R3JvdXBJZCB9ID0gY2xpZW50U3RhdGU7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cE1hcCA9IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuZ2V0KGNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNlbmQgdGhpcyBzaW5nbGUgaGFuZGxlciBhbGwgb2YgdGhlIGNvbnRleHQsIGJlY2F1c2UgaXQgYWNjZXB0cyBhbGwuXG5cdCAgICAgICAgICAgICAgICBjb250ZXh0R3JvdXBNYXAuZm9yRWFjaCgoY29udGV4dCwgXykgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIGlmIChjb250ZXh0R3JvdXBNYXAuaGFzKGNvbnRleHRUeXBlKSkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dEZvclR5cGUgPSBjb250ZXh0R3JvdXBNYXAuZ2V0KGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgICAgIGlmIChjb250ZXh0Rm9yVHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dEZvclR5cGUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGludGVudEhhbmRsZXJSZWdpc3RlcmVkKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgY29uc3QgY2xpZW50SW50ZW50SW5mbyA9IHRoaXMuaW50ZW50Q2xpZW50TWFwLmdldChjbGllbnRJZGVudGl0eS5uYW1lKTtcblx0ICAgICAgICBjb25zdCBoYW5kbGVySW5mbyA9IGNsaWVudEludGVudEluZm8/LmdldChoYW5kbGVySWQpO1xuXHQgICAgICAgIGlmICghY2xpZW50SW50ZW50SW5mbykge1xuXHQgICAgICAgICAgICB0aGlzLmludGVudENsaWVudE1hcC5zZXQoY2xpZW50SWRlbnRpdHkubmFtZSwgbmV3IE1hcCgpKTtcblx0ICAgICAgICAgICAgY29uc3QgbmV3SGFuZGxlckluZm9NYXAgPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQoY2xpZW50SWRlbnRpdHkubmFtZSk7XG5cdCAgICAgICAgICAgIGlmIChuZXdIYW5kbGVySW5mb01hcCkge1xuXHQgICAgICAgICAgICAgICAgbmV3SGFuZGxlckluZm9NYXAuc2V0KGhhbmRsZXJJZCwgeyBpc1JlYWR5OiB0cnVlLCBwZW5kaW5nSW50ZW50czogW10sIGNsaWVudElkZW50aXR5IH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2UgaWYgKCFoYW5kbGVySW5mbykge1xuXHQgICAgICAgICAgICBjbGllbnRJbnRlbnRJbmZvLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogdHJ1ZSwgcGVuZGluZ0ludGVudHM6IFtdLCBjbGllbnRJZGVudGl0eSB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgcGVuZGluZ0ludGVudHMgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICBoYW5kbGVySW5mby5jbGllbnRJZGVudGl0eSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICAgICAgICBoYW5kbGVySW5mby5pc1JlYWR5ID0gdHJ1ZTtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nSW50ZW50cy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZW50VG9TZW5kID0gcGVuZGluZ0ludGVudHNbcGVuZGluZ0ludGVudHMubGVuZ3RoIC0gMV07XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5pbnZva2VJbnRlbnRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudFRvU2VuZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8ucGVuZGluZ0ludGVudHMgPSBbXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGludGVudCBoYW5kbGVyOiAke2hhbmRsZXJJZH0gZm9yIGNsaWVudCAke2NsaWVudElkZW50aXR5LnV1aWR9LyR7Y2xpZW50SWRlbnRpdHkubmFtZX0vJHtjbGllbnRJZGVudGl0eS5lbmRwb2ludElkfWApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gVXNlZCB0byByZW1vdmUgYSBjb250ZXh0IGhhbmRsZXIgZm9yIGEgY2xpZW50XG5cdCAgICByZW1vdmVDb250ZXh0SGFuZGxlcih7IGhhbmRsZXJJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGNsaWVudFN0YXRlLmNvbnRleHRIYW5kbGVycy5kZWxldGUoaGFuZGxlcklkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBoYW5kbGVKb2luU2Vzc2lvbkNvbnRleHRHcm91cCh7IHNlc3Npb25Db250ZXh0R3JvdXBJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGlmICghc2Vzc2lvbkNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBqb2luIHNlc3Npb24gY29udGV4dCBncm91cDogbXVzdCBzcGVjaWZ5IGdyb3VwIGlkLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNvbnN0IHNlc3Npb25Db250ZXh0R3JvdXAgPSB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAuZ2V0KHNlc3Npb25Db250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgIGlmIChzZXNzaW9uQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICBzZXNzaW9uQ29udGV4dEdyb3VwLnJlZ2lzdGVyTmV3Q2xpZW50KGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb25Db250ZXh0R3JvdXBCcm9rZXIgPSBuZXcgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcl8xLmRlZmF1bHQodGhpcy5jaGFubmVsLCBzZXNzaW9uQ29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgICAgICAgICAgbmV3U2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlci5yZWdpc3Rlck5ld0NsaWVudChjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAuc2V0KHNlc3Npb25Db250ZXh0R3JvdXBJZCwgbmV3U2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIHsgaGFzQ29uZmxpY3Q6IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuaGFzKHNlc3Npb25Db250ZXh0R3JvdXBJZCkgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLypcblx0ICAgIEludGVybmFsIFV0aWx0aWVzXG5cdCAgICAqL1xuXHQgICAgLy8gR2V0dGVyIGZvciBpbnRlcm9wIGluZm8gZm9yIGEgY2xpZW50LlxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm9wQ2xpZW50cy5nZXQoaWQuZW5kcG9pbnRJZCk7XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIGZvciBnZXRDb250ZXh0R3JvdXBTdGF0ZXMuIFNlcmlhbGl6ZXMgdGhlIGNvbnRleHRHcm91cFN0YXRlcyBvYmplY3Qgc28gd2UgY2FuIHN0b3JlIGl0LlxuXHQgICAgc3RhdGljIHRvT2JqZWN0KG1hcCkge1xuXHQgICAgICAgIGNvbnN0IG9iamVjdEZyb21NYXAgPSBPYmplY3QuZnJvbUVudHJpZXMobWFwKTtcblx0ICAgICAgICBjb25zdCBuZXdPYmplY3QgPSB7fTtcblx0ICAgICAgICBPYmplY3QuZW50cmllcyhvYmplY3RGcm9tTWFwKS5mb3JFYWNoKChbY29udGV4dEdyb3VwSWQsIGNvbnRleHRNYXBdKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHRPYmplY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoY29udGV4dE1hcCk7XG5cdCAgICAgICAgICAgIG5ld09iamVjdFtjb250ZXh0R3JvdXBJZF0gPSBuZXdDb250ZXh0T2JqZWN0O1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBuZXdPYmplY3Q7XG5cdCAgICB9XG5cdCAgICBzdGF0aWMgY2hlY2tDb250ZXh0SW50ZWdyaXR5KGNvbnRleHQpIHtcblx0ICAgICAgICBpZiAoIWNvbnRleHQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ05vIGNvbnRleHQgc3VwcGxpZWQnIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ0NvbnRleHQgbXVzdCBiZSBhbiBPYmplY3QnIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICghY29udGV4dC50eXBlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCByZWFzb246ICdDb250ZXh0IG11c3QgaGF2ZSBhIHR5cGUgcHJvcGVydHknIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0LmlkICYmIHR5cGVvZiBjb250ZXh0LmlkICE9PSAnb2JqZWN0Jykge1xuXHQgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICByZWFzb246ICdDb250ZXh0IGlkIG11c3QgYmUgYW4gT2JqZWN0IHBvcHVsYXRlZCB3aXRoIGtleS12YWx1ZSBpZGVudGlmaWVycyAoaWYgc2V0KSdcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGNvbnRleHQuaWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBpZCB9ID0gY29udGV4dDtcblx0ICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGlkKTtcblx0ICAgICAgICAgICAgbGV0IGZvdW5kQmFkSWRlbnRpZmllciA9IGZhbHNlO1xuXHQgICAgICAgICAgICBpZiAoIWtleXMubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4geyBpc1ZhbGlkOiBmYWxzZSwgcmVhc29uOiAnQ29udGV4dCBpZCBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGtleS12YWx1ZSBpZGVudGlmaWVyJyB9O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycgfHwgdHlwZW9mIGlkW2tleV0gIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZm91bmRCYWRJZGVudGlmaWVyID0gdHJ1ZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGlmIChmb3VuZEJhZElkZW50aWZpZXIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCByZWFzb246ICdDb250ZXh0IGlkIGtleS12YWx1ZSBpZGVudGlmaWVycyBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nJyB9O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0Lm5hbWUgJiYgdHlwZW9mIGNvbnRleHQubmFtZSAhPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ0NvbnRleHQgbmFtZSBtdXN0IGJlIG9mIHN0cmluZyB0eXBlIChpZiBzZXQpJyB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlIH07XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIHRvIGNoZWNrIGEgY2xpZW50IGlkZW50aXR5LlxuXHQgICAgc3RhdGljIGhhc0VuZHBvaW50SWQodGFyZ2V0KSB7XG5cdCAgICAgICAgcmV0dXJuIHRhcmdldC5lbmRwb2ludElkICE9PSB1bmRlZmluZWQ7XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIHRvIGNoZWNrIGlmIHdlIHNob3VsZCBzZW5kIGEgY29udGV4dCB0byBhIGhhbmRsZXIuXG5cdCAgICBzdGF0aWMgaXNDb250ZXh0VHlwZUNvbXBhdGlibGUoY29udGV4dFR5cGUsIHJlZ2lzdGVyZWRDb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgcmVnaXN0ZXJlZENvbnRleHRUeXBlID09PSAndW5kZWZpbmVkJyB8fCBjb250ZXh0VHlwZSA9PT0gcmVnaXN0ZXJlZENvbnRleHRUeXBlO1xuXHQgICAgfVxuXHQgICAgLy8gU2V0dXAgZnVuY3Rpb24gZm9yIHN0YXRlIG1hcHBpbmdcblx0ICAgIHNldENvbnRleHRHcm91cE1hcCgpIHtcblx0ICAgICAgICAvLyBUaGlzIHdheSwgaWYgYSB1c2VyIG92ZXJyaWRlcyB0aGlzLmdldENvbnRleHRHcm91cHMsIGl0J3MgcmVmbGVjdGVkIGluIHRoZSBjb250ZXh0R3JvdXBNYXBwaW5nLlxuXHQgICAgICAgIGZvciAoY29uc3QgY29udGV4dEdyb3VwSW5mbyBvZiB0aGlzLmdldENvbnRleHRHcm91cHMoKSkge1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHRHcm91cHNCeUlkLnNldChjb250ZXh0R3JvdXBJbmZvLmlkLCBuZXcgTWFwKCkpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIHNldEN1cnJlbnRDb250ZXh0R3JvdXBJbkNsaWVudE9wdGlvbnMoY2xpZW50SWRlbnRpdHksIGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3QgZW50aXR5SW5mbyA9IGF3YWl0IHRoaXMuZmluLlN5c3RlbS5nZXRFbnRpdHlJbmZvKGNsaWVudElkZW50aXR5LnV1aWQsIGNsaWVudElkZW50aXR5Lm5hbWUpO1xuXHQgICAgICAgICAgICBsZXQgZW50aXR5O1xuXHQgICAgICAgICAgICBpZiAoZW50aXR5SW5mby5lbnRpdHlUeXBlID09PSAndmlldycpIHtcblx0ICAgICAgICAgICAgICAgIGVudGl0eSA9IGF3YWl0IHRoaXMuZmluLlZpZXcud3JhcChjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgZWxzZSBpZiAoZW50aXR5SW5mby5lbnRpdHlUeXBlID09PSAnd2luZG93Jykge1xuXHQgICAgICAgICAgICAgICAgZW50aXR5ID0gYXdhaXQgdGhpcy5maW4uV2luZG93LndyYXAoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChlbnRpdHkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IGVudGl0eS51cGRhdGVPcHRpb25zKHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnRlcm9wOiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDb250ZXh0R3JvdXA6IGNvbnRleHRHcm91cElkXG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIC8vICBNYXkgZmlsZSBpbiBpbnRlcm9wXG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgc2V0dXBDaGFubmVsUHJvdmlkZXIoKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIoKTtcblx0ICAgICAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcblx0ICAgICAgICAgICAgdGhpcy53aXJlQ2hhbm5lbChjaGFubmVsKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3Igc2V0dGluZyB1cCBJbnRlcm9wIEJyb2tlciBDaGFubmVsIFByb3ZpZGVyOiAke2Vycm9yfWApO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIFNldHVwIENoYW5uZWwgQ29ubmVjdGlvbiBMb2dpY1xuXHQgICAgd2lyZUNoYW5uZWwoY2hhbm5lbCkge1xuXHQgICAgICAgIGNoYW5uZWwub25Db25uZWN0aW9uKGFzeW5jIChjbGllbnRJZGVudGl0eSwgLy8gVE9ETyhDT1JFLTgxMSk6IHJlbW92ZSBpbmxpbmUgaW50ZXJzZWN0ZWQgdHlwZVxuXHQgICAgICAgIHBheWxvYWQpID0+IHtcblx0ICAgICAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5pc0Nvbm5lY3Rpb25BdXRob3JpemVkKGNsaWVudElkZW50aXR5LCBwYXlsb2FkKSkpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBub3QgYXV0aG9yaXplZCBmb3IgJHtjbGllbnRJZGVudGl0eS51dWlkfSwgJHtjbGllbnRJZGVudGl0eS5uYW1lfWApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmICghY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZXJzaW9uIHRvbyBvbGQgdG8gYmUgY29tcGF0aWJsZSB3aXRoIEludGVyb3AuIFBsZWFzZSB1cGdyYWRlIHlvdXIgcnVudGltZSB0byBhIG1vcmUgcmVjZW50IHZlcnNpb24uJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjb250ZXh0R3JvdXBJZDogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzOiBuZXcgTWFwKCksXG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICAvLyBPbmx5IGFsbG93IHRoZSBjbGllbnQgdG8gam9pbiBhIGNvbnRleHRHcm91cCB0aGF0IGFjdHVhbGx5IGV4aXN0cy5cblx0ICAgICAgICAgICAgaWYgKHBheWxvYWQ/LmN1cnJlbnRDb250ZXh0R3JvdXAgJiYgdGhpcy5jb250ZXh0R3JvdXBzQnlJZC5oYXMocGF5bG9hZC5jdXJyZW50Q29udGV4dEdyb3VwKSkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEdyb3VwSWQgPSBwYXlsb2FkPy5jdXJyZW50Q29udGV4dEdyb3VwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuaW50ZXJvcENsaWVudHMuc2V0KGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQsIGNsaWVudFN1YnNjcmlwdGlvblN0YXRlKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjaGFubmVsLm9uRGlzY29ubmVjdGlvbigoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgdGhpcy5pbnRlcm9wQ2xpZW50cy5kZWxldGUoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCk7XG5cdCAgICAgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQoY2xpZW50SWRlbnRpdHkubmFtZSk7XG5cdCAgICAgICAgICAgIGlmICh0YXJnZXRJbmZvICYmIGNsaWVudElkZW50aXR5LnV1aWQgPT09IHRoaXMuZmluLm1lLnV1aWQpIHtcblx0ICAgICAgICAgICAgICAgIHRhcmdldEluZm8uZm9yRWFjaCgoaGFuZGxlcikgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuaXNSZWFkeSA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5zZXNzaW9uQ29udGV4dEdyb3VwTWFwLmZvckVhY2goKHNlc3Npb25Db250ZXh0R3JvdXApID0+IHtcblx0ICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXAub25EaXNjb25uZWN0aW9uKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIHRoaXMuY2xpZW50RGlzY29ubmVjdGVkKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjaGFubmVsLmJlZm9yZUFjdGlvbihhc3luYyAoYWN0aW9uLCBwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkgPT4ge1xuXHQgICAgICAgICAgICBpZiAoIShhd2FpdCB0aGlzLmlzQWN0aW9uQXV0aG9yaXplZChhY3Rpb24sIHBheWxvYWQsIGNsaWVudElkZW50aXR5KSkpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQWN0aW9uICgke2FjdGlvbn0pIG5vdCBhdXRob3JpemVkIGZvciAke2NsaWVudElkZW50aXR5LnV1aWR9LCAke2NsaWVudElkZW50aXR5Lm5hbWV9YCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9nZ2luZz8uYmVmb3JlQWN0aW9uPy5lbmFibGVkKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhhY3Rpb24sIHBheWxvYWQsIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNoYW5uZWwuYWZ0ZXJBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9nZ2luZz8uYWZ0ZXJBY3Rpb24/LmVuYWJsZWQpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGFjdGlvbiwgcGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy8gQ2xpZW50IGZ1bmN0aW9uc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ3NldENvbnRleHQnLCB0aGlzLnNldENvbnRleHQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZmlyZUludGVudCcsIHRoaXMuaGFuZGxlRmlyZWRJbnRlbnQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZ2V0Q3VycmVudENvbnRleHQnLCB0aGlzLmdldEN1cnJlbnRDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEluZm9Gb3JJbnRlbnQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZ2V0SW5mb0ZvckludGVudHNCeUNvbnRleHQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ZpcmVJbnRlbnRGb3JDb250ZXh0JywgdGhpcy5oYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gUGxhdGZvcm0gd2luZG93IGZ1bmN0aW9uc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldENvbnRleHRHcm91cHMnLCB0aGlzLmdldENvbnRleHRHcm91cHMuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3Rlcignam9pbkNvbnRleHRHcm91cCcsIHRoaXMuam9pbkNvbnRleHRHcm91cC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdyZW1vdmVGcm9tQ29udGV4dEdyb3VwJywgdGhpcy5yZW1vdmVGcm9tQ29udGV4dEdyb3VwLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCcsIHRoaXMuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEluZm9Gb3JDb250ZXh0R3JvdXAnLCB0aGlzLmdldEluZm9Gb3JDb250ZXh0R3JvdXAuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gSW50ZXJuYWwgbWV0aG9kc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2NvbnRleHRIYW5kbGVyUmVnaXN0ZXJlZCcsIHRoaXMuY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ludGVudEhhbmRsZXJSZWdpc3RlcmVkJywgdGhpcy5pbnRlbnRIYW5kbGVyUmVnaXN0ZXJlZC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdyZW1vdmVDb250ZXh0SGFuZGxlcicsIHRoaXMucmVtb3ZlQ29udGV4dEhhbmRsZXIuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3Rlcignc2Vzc2lvbkNvbnRleHRHcm91cDpjcmVhdGVJZk5lZWRlZCcsIHRoaXMuaGFuZGxlSm9pblNlc3Npb25Db250ZXh0R3JvdXAuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gZmRjMyBvbmx5IG1ldGhvZHNcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzT3BlbicsIHRoaXMuZmRjM0hhbmRsZU9wZW4uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZmRjM3YyRmluZEludGVudHNCeUNvbnRleHQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ZkYzNGaW5kSW5zdGFuY2VzJywgdGhpcy5mZGMzSGFuZGxlRmluZEluc3RhbmNlcy5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzR2V0QXBwTWV0YWRhdGEnLCB0aGlzLmZkYzNIYW5kbGVHZXRBcHBNZXRhZGF0YS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzdjJHZXRJbmZvJywgYXN5bmMgKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSA9PiB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmZkYzNIYW5kbGVHZXRJbmZvLmJpbmQodGhpcykocGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2NyZWF0ZVByaXZhdGVDaGFubmVsUHJvdmlkZXInLCBhc3luYyAocGF5bG9hZCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IGNoYW5uZWxJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICAgICAgY29uc3QgY2hhbm5lbFByb3ZpZGVyID0gYXdhaXQgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShjaGFubmVsSWQpO1xuXHQgICAgICAgICAgICBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyXzEuUHJpdmF0ZUNoYW5uZWxQcm92aWRlci5pbml0KGNoYW5uZWxQcm92aWRlciwgY2hhbm5lbElkKTtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2FuIGJlIHVzZWQgdG8gY29tcGxldGVseSBwcmV2ZW50IGEgY29ubmVjdGlvbi4gUmV0dXJuIGZhbHNlIHRvIHByZXZlbnQgY29ubmVjdGlvbnMuIEFsbG93cyBhbGwgY29ubmVjdGlvbnMgYnkgZGVmYXVsdC5cblx0ICAgICAqIEBwYXJhbSBfaWQgdGhlIGlkZW50aXR5IHRyeWluYyB0byBjb25uZWN0XG5cdCAgICAgKiBAcGFyYW0gX2Nvbm5lY3Rpb25QYXlsb2FkIG9wdGlvbmFsIHBheWxvYWQgdG8gdXNlIGluIGN1c3RvbSBpbXBsZW1lbnRhdGlvbnMsIHdpbGwgYmUgdW5kZWZpbmVkIGJ5IGRlZmF1bHRcblx0ICAgICAqL1xuXHQgICAgaXNDb25uZWN0aW9uQXV0aG9yaXplZChfaWQsIF9jb25uZWN0aW9uUGF5bG9hZCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1pcy1jb25uZWN0aW9uLWF1dGhvcml6ZWQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDYWxsZWQgYmVmb3JlIGV2ZXJ5IGFjdGlvbiB0byBjaGVjayBpZiB0aGlzIGVudGl0eSBzaG91bGQgYmUgYWxsb3dlZCB0byB0YWtlIHRoZSBhY3Rpb24uXG5cdCAgICAgKiBSZXR1cm4gZmFsc2UgdG8gcHJldmVudCB0aGUgYWN0aW9uXG5cdCAgICAgKiBAcGFyYW0gX2FjdGlvbiB0aGUgc3RyaW5nIGFjdGlvbiB0byBhdXRob3JpemUgaW4gY2FtZWwgY2FzZVxuXHQgICAgICogQHBhcmFtIF9wYXlsb2FkIHRoZSBkYXRhIGJlaW5nIHNlbnQgZm9yIHRoaXMgYWN0aW9uXG5cdCAgICAgKiBAcGFyYW0gX2lkZW50aXR5IHRoZSBjb25uZWN0aW9uIGF0dGVtcHRpbmcgdG8gZGlzcGF0Y2ggdGhpcyBhY3Rpb25cblx0ICAgICAqL1xuXHQgICAgaXNBY3Rpb25BdXRob3JpemVkKF9hY3Rpb24sIF9wYXlsb2FkLCBfaWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItaXMtYWN0aW9uLWF1dGhvcml6ZWQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXHQgICAgfVxuXHR9O1xuXHRJbnRlcm9wQnJva2VyLkludGVyb3BCcm9rZXIgPSBJbnRlcm9wQnJva2VyJDE7XG5cdF9JbnRlcm9wQnJva2VyX2ZkYzNJbmZvID0gbmV3IFdlYWtNYXAoKSwgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3VwcyA9IG5ldyBXZWFrTWFwKCksIF9JbnRlcm9wQnJva2VyX3Byb3ZpZGVyUHJvbWlzZSA9IG5ldyBXZWFrTWFwKCk7XG5cdHJldHVybiBJbnRlcm9wQnJva2VyO1xufVxuXG52YXIgSW50ZXJvcENsaWVudCA9IHt9O1xuXG52YXIgU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxID0ge307XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMiA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2U7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbnN0IGJhc2VfMSQyID0gYmFzZTtcbmNvbnN0IHV0aWxzXzEkMiA9IHV0aWxzJDM7XG5jbGFzcyBTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50IGV4dGVuZHMgYmFzZV8xJDIuQmFzZSB7XG4gICAgY29uc3RydWN0b3Iod2lyZSwgY2xpZW50LCBpZCkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZS5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDIodGhpcywgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSwgY2xpZW50LCBcImZcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgYSBjb250ZXh0IGZvciB0aGUgc2Vzc2lvbiBjb250ZXh0IGdyb3VwLlxuICAgICAqIEBwYXJhbSBjb250ZXh0IC0gTmV3IGNvbnRleHQgdG8gc2V0LlxuICAgICAqXG4gICAgICogQHR1dG9yaWFsIGludGVyb3Auc2V0Q29udGV4dFxuICAgICAqL1xuICAgIGFzeW5jIHNldENvbnRleHQoY29udGV4dCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1zZXNzaW9uLWNvbnRleHQtZ3JvdXAtc2V0LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDIodGhpcywgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKGBzZXNzaW9uQ29udGV4dEdyb3VwOnNldENvbnRleHQtJHt0aGlzLmlkfWAsIHtcbiAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXBJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0KHR5cGUpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3Atc2Vzc2lvbi1jb250ZXh0LWdyb3VwLWdldC1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQyKHRoaXMsIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaChgc2Vzc2lvbkNvbnRleHRHcm91cDpnZXRDb250ZXh0LSR7dGhpcy5pZH1gLCB7XG4gICAgICAgICAgICBzZXNzaW9uQ29udGV4dEdyb3VwSWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICB0eXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBhZGRDb250ZXh0SGFuZGxlcihjb250ZXh0SGFuZGxlciwgY29udGV4dFR5cGUpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3Atc2Vzc2lvbi1jb250ZXh0LWdyb3VwLWFkZC1oYW5kbGVyJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0SGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm9uLWZ1bmN0aW9uIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZmlyc3QgcGFyYW1ldGVyICdoYW5kbGVyJy4gQmUgYXdhcmUgdGhhdCB0aGUgYXJndW1lbnQgb3JkZXIgZG9lcyBub3QgbWF0Y2ggdGhlIEZEQzMgc3RhbmRhcmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMih0aGlzLCBfU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG4gICAgICAgIGxldCBoYW5kbGVySWQ7XG4gICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYHNlc3Npb25Db250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfS0ke2NvbnRleHRUeXBlfS0keygwLCB1dGlsc18xJDIuZ2VuZXJhdGVJZCkoKX1gO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYHNlc3Npb25Db250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfWA7XG4gICAgICAgIH1cbiAgICAgICAgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgKDAsIHV0aWxzXzEkMi53cmFwQ29udGV4dEhhbmRsZXIpKGNvbnRleHRIYW5kbGVyLCBoYW5kbGVySWQpKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKGBzZXNzaW9uQ29udGV4dEdyb3VwOmhhbmRsZXJBZGRlZC0ke3RoaXMuaWR9YCwgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0pO1xuICAgICAgICByZXR1cm4geyB1bnN1YnNjcmliZTogYXdhaXQgdGhpcy5jcmVhdGVVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlVW5zdWJzY3JpYmVDYihoYW5kbGVySWQpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQyKHRoaXMsIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcbiAgICAgICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaChgc2Vzc2lvbkNvbnRleHRHcm91cDpoYW5kbGVyUmVtb3ZlZC0ke3RoaXMuaWR9YCwgeyBoYW5kbGVySWQgfSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldFVzZXJJbnN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICAgICAgc2V0Q29udGV4dDogKDAsIHV0aWxzXzEkMi53cmFwSW5UcnlDYXRjaCkodGhpcy5zZXRDb250ZXh0LmJpbmQodGhpcyksICdGYWlsZWQgdG8gc2V0IGNvbnRleHQ6ICcpLFxuICAgICAgICAgICAgZ2V0Q3VycmVudENvbnRleHQ6ICgwLCB1dGlsc18xJDIud3JhcEluVHJ5Q2F0Y2gpKHRoaXMuZ2V0Q3VycmVudENvbnRleHQuYmluZCh0aGlzKSwgJ0ZhaWxlZCB0byBnZXQgY29udGV4dDogJyksXG4gICAgICAgICAgICBhZGRDb250ZXh0SGFuZGxlcjogKDAsIHV0aWxzXzEkMi53cmFwSW5UcnlDYXRjaCkodGhpcy5hZGRDb250ZXh0SGFuZGxlci5iaW5kKHRoaXMpLCAnRmFpbGVkIHRvIGFkZCBjb250ZXh0IGhhbmRsZXI6ICcpXG4gICAgICAgIH07XG4gICAgfVxufVxuU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxLmRlZmF1bHQgPSBTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50O1xuX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBmZGMzMV8yID0ge307XG5cbnZhciBmZGMzQ29tbW9uID0ge307XG5cbnZhciB1dGlscyQyID0ge307XG5cbnZhciBQcml2YXRlQ2hhbm5lbENsaWVudCQxID0ge307XG5cbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jcmVhdGVCaW5kaW5nKSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG4gICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIG9bazJdID0gbVtrXTtcbn0pKTtcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xufSkgOiBmdW5jdGlvbihvLCB2KSB7XG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xufSk7XG52YXIgX19pbXBvcnRTdGFyID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0U3RhcikgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFByaXZhdGVDaGFubmVsQ2xpZW50JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuUHJpdmF0ZUNoYW5uZWxDbGllbnQkMS5Qcml2YXRlQ2hhbm5lbENsaWVudCA9IHZvaWQgMDtcbmNvbnN0IHV0aWxzJDEgPSBfX2ltcG9ydFN0YXIodXRpbHMkMyk7XG5jbGFzcyBQcml2YXRlQ2hhbm5lbENsaWVudCB7XG4gICAgY29uc3RydWN0b3IoY2xpZW50LCBpZCkge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgYXN5bmMgYnJvYWRjYXN0KGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmRpc3BhdGNoKCdicm9hZGNhc3QnLCB7IGNvbnRleHQgfSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0KGNvbnRleHRUeXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5kaXNwYXRjaCgnZ2V0Q3VycmVudENvbnRleHQnLCB7IGNvbnRleHRUeXBlIH0pO1xuICAgIH1cbiAgICBhc3luYyBhZGRDb250ZXh0TGlzdGVuZXIoY29udGV4dFR5cGUsIGhhbmRsZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb24tZnVuY3Rpb24gYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBzZWNvbmQgcGFyYW1ldGVyICdoYW5kbGVyJy4gQmUgYXdhcmUgdGhhdCB0aGUgYXJndW1lbnQgb3JkZXIgZG9lcyBub3QgbWF0Y2ggdGhlIEZEQzMgc3RhbmRhcmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBoYW5kbGVySWQ7XG4gICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYGNvbnRleHRIYW5kbGVyOmludm9rZS0ke3RoaXMuaWR9LSR7Y29udGV4dFR5cGV9LSR7dXRpbHMkMS5nZW5lcmF0ZUlkKCl9YDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhhbmRsZXJJZCA9IGBjb250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfS0ke3V0aWxzJDEuZ2VuZXJhdGVJZCgpfWA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGllbnQucmVnaXN0ZXIoaGFuZGxlcklkLCB1dGlscyQxLndyYXBDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBoYW5kbGVySWQpKTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB7IHVuc3Vic2NyaWJlOiBhd2FpdCB0aGlzLmNyZWF0ZUNvbnRleHRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICBhd2FpdCB0aGlzLmNsaWVudC5kaXNwYXRjaChgY29udGV4dEhhbmRsZXJBZGRlZGAsIHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuICAgIH1cbiAgICBjcmVhdGVOb25TdGFuZGFyZFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ25vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQnLCB7IGhhbmRsZXJJZCB9KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY3JlYXRlQ29udGV4dFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ2NvbnRleHRIYW5kbGVyUmVtb3ZlZCcsIHsgaGFuZGxlcklkIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBvbkFkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJJZCA9IGBvbkNvbnRleHRIYW5kbGVyQWRkZWQ6aW52b2tlLSR7dGhpcy5pZH0tJHt1dGlscyQxLmdlbmVyYXRlSWQoKX1gO1xuICAgICAgICB0aGlzLmNsaWVudC5yZWdpc3RlcihoYW5kbGVySWQsIGhhbmRsZXIpO1xuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHsgdW5zdWJzY3JpYmU6IHRoaXMuY3JlYXRlTm9uU3RhbmRhcmRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICB0aGlzLmNsaWVudC5kaXNwYXRjaChgb25BZGRDb250ZXh0SGFuZGxlckFkZGVkYCwgeyBoYW5kbGVySWQgfSk7XG4gICAgICAgIHJldHVybiBsaXN0ZW5lcjtcbiAgICB9XG4gICAgb25EaXNjb25uZWN0KGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYG9uRGlzY29ubmVjdDppbnZva2UtJHt0aGlzLmlkfS0ke3V0aWxzJDEuZ2VuZXJhdGVJZCgpfWA7XG4gICAgICAgIHRoaXMuY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgaGFuZGxlcik7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyID0geyB1bnN1YnNjcmliZTogdGhpcy5jcmVhdGVOb25TdGFuZGFyZFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB9O1xuICAgICAgICB0aGlzLmxpc3RlbmVycy5zZXQoaGFuZGxlcklkLCBsaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuY2xpZW50LmRpc3BhdGNoKGBvbkRpc2Nvbm5lY3RIYW5kbGVyQWRkZWRgLCB7IGhhbmRsZXJJZCB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuICAgIH1cbiAgICBvblVuc3Vic2NyaWJlKGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYG9uVW5zdWJzY3JpYmU6aW52b2tlLSR7dGhpcy5pZH0tJHt1dGlscyQxLmdlbmVyYXRlSWQoKX1gO1xuICAgICAgICB0aGlzLmNsaWVudC5yZWdpc3RlcihoYW5kbGVySWQsIGhhbmRsZXIpO1xuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHsgdW5zdWJzY3JpYmU6IHRoaXMuY3JlYXRlTm9uU3RhbmRhcmRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICB0aGlzLmNsaWVudC5kaXNwYXRjaChgb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZGAsIHsgaGFuZGxlcklkIH0pO1xuICAgICAgICByZXR1cm4gbGlzdGVuZXI7XG4gICAgfVxuICAgIGFzeW5jIGNsZWFuVXBBbGxTdWJzKCkge1xuICAgICAgICBjb25zdCBsaXN0ZW5lclVuc3Vic2NyaWJlcnMgPSBBcnJheS5mcm9tKHRoaXMubGlzdGVuZXJzLmtleXMoKSk7XG4gICAgICAgIGxpc3RlbmVyVW5zdWJzY3JpYmVycy5mb3JFYWNoKChoYW5kbGVySWQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xpZW50LnJlbW92ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMuZGVsZXRlKGhhbmRsZXJJZCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBkaXNjb25uZWN0KCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ2NsaWVudERpc2Nvbm5lY3RpbmcnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xlYW5VcEFsbFN1YnMoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblByaXZhdGVDaGFubmVsQ2xpZW50JDEuUHJpdmF0ZUNoYW5uZWxDbGllbnQgPSBQcml2YXRlQ2hhbm5lbENsaWVudDtcblxuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdHZhciBfX2ltcG9ydERlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnREZWZhdWx0KSB8fCBmdW5jdGlvbiAobW9kKSB7XG5cdCAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLmdldEludGVudFJlc29sdXRpb24gPSBleHBvcnRzLmlzQ2hhbm5lbCA9IGV4cG9ydHMuaXNDb250ZXh0ID0gZXhwb3J0cy5jb25uZWN0UHJpdmF0ZUNoYW5uZWwgPSBleHBvcnRzLmJ1aWxkQXBwQ2hhbm5lbE9iamVjdCA9IGV4cG9ydHMuYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdCA9IGV4cG9ydHMuQ2hhbm5lbEVycm9yID0gZXhwb3J0cy5SZXN1bHRFcnJvciA9IGV4cG9ydHMuVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IgPSBleHBvcnRzLmdldFVuc3VwcG9ydGVkQ2hhbm5lbEFwaXMgPSB2b2lkIDA7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHRjb25zdCBQcml2YXRlQ2hhbm5lbENsaWVudF8xID0gUHJpdmF0ZUNoYW5uZWxDbGllbnQkMTtcblx0Y29uc3QgaXNFcXVhbF8xID0gX19pbXBvcnREZWZhdWx0KHJlcXVpcmUkJDMpO1xuXHRjb25zdCBnZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzID0gKGNoYW5uZWxUeXBlKSA9PiB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICAgIGFkZENvbnRleHRMaXN0ZW5lcjogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IoJ0NoYW5uZWwuYWRkQ29udGV4dExpc3RlbmVyJywgY2hhbm5lbFR5cGUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgYnJvYWRjYXN0OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZENoYW5uZWxBcGlFcnJvcignQ2hhbm5lbC5icm9hZGNhc3QnLCBjaGFubmVsVHlwZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXRDdXJyZW50Q29udGV4dDogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IoJ0NoYW5uZWwuZ2V0Q3VycmVudENvbnRleHQnLCBjaGFubmVsVHlwZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy5nZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzID0gZ2V0VW5zdXBwb3J0ZWRDaGFubmVsQXBpcztcblx0Y2xhc3MgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdCAgICBjb25zdHJ1Y3RvcihhcGlOYW1lLCBjaGFubmVsVHlwZSA9ICdTeXN0ZW0nKSB7XG5cdCAgICAgICAgc3VwZXIoYXBpTmFtZSk7XG5cdCAgICAgICAgdGhpcy5tZXNzYWdlID0gYENhbGxpbmcgJHthcGlOYW1lfSBvbiBhbiBpbnN0YW5jZSBvZiBhICR7Y2hhbm5lbFR5cGV9IENoYW5uZWwgcmV0dXJuZWQgYnkgZmRjMy5nZXQke2NoYW5uZWxUeXBlfUNoYW5uZWxzIGlzIG5vdCBzdXBwb3J0ZWQuIElmIHlvdSB3b3VsZCBsaWtlIHRvIHVzZSBhICR7Y2hhbm5lbFR5cGV9IENoYW5uZWwsIHBsZWFzZSB1c2UgZmRjMy5qb2luQ2hhbm5lbCwgZmRjMy5hZGRDb250ZXh0TGlzdGVuZXIsIGFuZCBmZGMzLmJyb2FkY2FzdCBpbnN0ZWFkLmA7XG5cdCAgICB9XG5cdH1cblx0ZXhwb3J0cy5VbnN1cHBvcnRlZENoYW5uZWxBcGlFcnJvciA9IFVuc3VwcG9ydGVkQ2hhbm5lbEFwaUVycm9yO1xuXHR2YXIgUmVzdWx0RXJyb3I7XG5cdChmdW5jdGlvbiAoUmVzdWx0RXJyb3IpIHtcblx0ICAgIC8qKiBSZXR1cm5lZCBpZiB0aGUgYEludGVudEhhbmRsZXJgIGV4aXRlZCB3aXRob3V0IHJldHVybmluZyBhIFByb21pc2Ugb3IgdGhhdFxuXHQgICAgICogIFByb21pc2Ugd2FzIG5vdCByZXNvbHZlZCB3aXRoIGEgQ29udGV4dCBvciBDaGFubmVsIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgUmVzdWx0RXJyb3JbXCJOb1Jlc3VsdFJldHVybmVkXCJdID0gXCJOb1Jlc3VsdFJldHVybmVkXCI7XG5cdCAgICAvKiogUmV0dXJuZWQgaWYgdGhlIGBJbnRlbnRIYW5kbGVyYCBmdW5jdGlvbiBwcm9jZXNzaW5nIHRoZSByYWlzZWQgaW50ZW50XG5cdCAgICAgKiAgdGhyb3dzIGFuIGVycm9yIG9yIHJlamVjdHMgdGhlIFByb21pc2UgaXQgcmV0dXJuZWQuXG5cdCAgICAgKi9cblx0ICAgIFJlc3VsdEVycm9yW1wiSW50ZW50SGFuZGxlclJlamVjdGVkXCJdID0gXCJJbnRlbnRIYW5kbGVyUmVqZWN0ZWRcIjtcblx0fSkoUmVzdWx0RXJyb3IgPSBleHBvcnRzLlJlc3VsdEVycm9yIHx8IChleHBvcnRzLlJlc3VsdEVycm9yID0ge30pKTtcblx0KGZ1bmN0aW9uIChDaGFubmVsRXJyb3IpIHtcblx0ICAgIC8qKiBSZXR1cm5lZCBpZiB0aGUgc3BlY2lmaWVkIGNoYW5uZWwgaXMgbm90IGZvdW5kIHdoZW4gYXR0ZW1wdGluZyB0byBqb2luIGFcblx0ICAgICAqICBjaGFubmVsIHZpYSB0aGUgYGpvaW5Vc2VyQ2hhbm5lbGAgZnVuY3Rpb24gb2YgdGhlIERlc2t0b3BBZ2VudCAoYGZkYzNgKS5cblx0ICAgICAqL1xuXHQgICAgQ2hhbm5lbEVycm9yW1wiTm9DaGFubmVsRm91bmRcIl0gPSBcIk5vQ2hhbm5lbEZvdW5kXCI7XG5cdCAgICAvKiogU0hPVUxEIGJlIHJldHVybmVkIHdoZW4gYSByZXF1ZXN0IHRvIGpvaW4gYSB1c2VyIGNoYW5uZWwgb3IgdG8gYSByZXRyaWV2ZVxuXHQgICAgICogIGEgQ2hhbm5lbCBvYmplY3QgdmlhIHRoZSBgam9pblVzZXJDaGFubmVsYCBvciBgZ2V0T3JDcmVhdGVDaGFubmVsYCBtZXRob2RzXG5cdCAgICAgKiAgb2YgdGhlIERlc2t0b3BBZ2VudCAoYGZkYzNgKSBvYmplY3QgaXMgZGVuaWVkLlxuXHQgICAgICovXG5cdCAgICBDaGFubmVsRXJyb3JbXCJBY2Nlc3NEZW5pZWRcIl0gPSBcIkFjY2Vzc0RlbmllZFwiO1xuXHQgICAgLyoqIFNIT1VMRCBiZSByZXR1cm5lZCB3aGVuIGEgY2hhbm5lbCBjYW5ub3QgYmUgY3JlYXRlZCBvciByZXRyaWV2ZWQgdmlhIHRoZVxuXHQgICAgICogIGBnZXRPckNyZWF0ZUNoYW5uZWxgIG1ldGhvZCBvZiB0aGUgRGVza3RvcEFnZW50IChgZmRjM2ApLlxuXHQgICAgICovXG5cdCAgICBDaGFubmVsRXJyb3JbXCJDcmVhdGlvbkZhaWxlZFwiXSA9IFwiQ3JlYXRpb25GYWlsZWRcIjtcblx0fSkoZXhwb3J0cy5DaGFubmVsRXJyb3IgfHwgKGV4cG9ydHMuQ2hhbm5lbEVycm9yID0ge30pKTtcblx0Y29uc3QgYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdCA9IChwcml2YXRlQ2hhbm5lbENsaWVudCkgPT4ge1xuXHQgICAgbGV0IGNsaWVudERpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuXHQgICAgY29uc3QgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCA9ICgpID0+IHtcblx0ICAgICAgICBpZiAoY2xpZW50RGlzY29ubmVjdGVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUHJpdmF0ZSBDaGFubmVsIENsaWVudCBoYXMgYmVlbiBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgUHJpdmF0ZSBDaGFubmVsJyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgaWQ6IHByaXZhdGVDaGFubmVsQ2xpZW50LmlkLFxuXHQgICAgICAgIHR5cGU6ICdwcml2YXRlJyxcblx0ICAgICAgICBicm9hZGNhc3Q6IGFzeW5jIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50LmJyb2FkY2FzdChjb250ZXh0KTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldEN1cnJlbnRDb250ZXh0OiBhc3luYyAoY29udGV4dFR5cGUpID0+IHtcblx0ICAgICAgICAgICAgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCgpO1xuXHQgICAgICAgICAgICByZXR1cm4gcHJpdmF0ZUNoYW5uZWxDbGllbnQuZ2V0Q3VycmVudENvbnRleHQoY29udGV4dFR5cGUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUT0RPIFtDT1JFLTE1MjRdXG5cdCAgICAgICAgYWRkQ29udGV4dExpc3RlbmVyOiBhc3luYyAoY29udGV4dFR5cGUsIGhhbmRsZXIpID0+IHtcblx0ICAgICAgICAgICAgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCgpO1xuXHQgICAgICAgICAgICBsZXQgaGFuZGxlckluVXNlID0gaGFuZGxlcjtcblx0ICAgICAgICAgICAgbGV0IGNvbnRleHRUeXBlSW5Vc2UgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJblVzZSA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICAgICAgY29udGV4dFR5cGVJblVzZSA9IG51bGw7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBwcml2YXRlQ2hhbm5lbENsaWVudC5hZGRDb250ZXh0TGlzdGVuZXIoY29udGV4dFR5cGVJblVzZSwgaGFuZGxlckluVXNlKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgb25BZGRDb250ZXh0TGlzdGVuZXI6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uQWRkQ29udGV4dExpc3RlbmVyKGhhbmRsZXIpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZGlzY29ubmVjdDogYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjaGVja0lmQ2xpZW50RGlzY29ubmVjdGVkKCk7XG5cdCAgICAgICAgICAgIGNsaWVudERpc2Nvbm5lY3RlZCA9IHRydWU7XG5cdCAgICAgICAgICAgIHJldHVybiBwcml2YXRlQ2hhbm5lbENsaWVudC5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBvbkRpc2Nvbm5lY3Q6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uRGlzY29ubmVjdChoYW5kbGVyKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uVW5zdWJzY3JpYmU6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uVW5zdWJzY3JpYmUoaGFuZGxlcik7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy5idWlsZFByaXZhdGVDaGFubmVsT2JqZWN0ID0gYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdDtcblx0Y29uc3QgYnVpbGRBcHBDaGFubmVsT2JqZWN0ID0gKHNlc3Npb25Db250ZXh0R3JvdXApID0+IHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgaWQ6IHNlc3Npb25Db250ZXh0R3JvdXAuaWQsXG5cdCAgICAgICAgdHlwZTogJ2FwcCcsXG5cdCAgICAgICAgYnJvYWRjYXN0OiBzZXNzaW9uQ29udGV4dEdyb3VwLnNldENvbnRleHQsXG5cdCAgICAgICAgZ2V0Q3VycmVudENvbnRleHQ6IGFzeW5jIChjb250ZXh0VHlwZSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgc2Vzc2lvbkNvbnRleHRHcm91cC5nZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgIHJldHVybiBjb250ZXh0ID09PSB1bmRlZmluZWQgPyBudWxsIDogY29udGV4dDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETyBbQ09SRS0xNTI0XVxuXHQgICAgICAgIGFkZENvbnRleHRMaXN0ZW5lcjogKGNvbnRleHRUeXBlLCBoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGxldCByZWFsSGFuZGxlcjtcblx0ICAgICAgICAgICAgbGV0IHJlYWxUeXBlO1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2FkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGFkZENvbnRleHRMaXN0ZW5lcihudWxsLCBoYW5kbGVyKScpO1xuXHQgICAgICAgICAgICAgICAgcmVhbEhhbmRsZXIgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJlYWxIYW5kbGVyID0gaGFuZGxlcjtcblx0ICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVhbFR5cGUgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IChhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCBzZXNzaW9uQ29udGV4dEdyb3VwLmdldEN1cnJlbnRDb250ZXh0KHJlYWxUeXBlKTtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRIYW5kbGVyID0gKGNvbnRleHQsIGNvbnRleHRNZXRhZGF0YSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKDAsIGlzRXF1YWxfMS5kZWZhdWx0KShjdXJyZW50Q29udGV4dCwgY29udGV4dCkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhbEhhbmRsZXIoY29udGV4dCwgY29udGV4dE1ldGFkYXRhKTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc2Vzc2lvbkNvbnRleHRHcm91cC5hZGRDb250ZXh0SGFuZGxlcih3cmFwcGVkSGFuZGxlciwgcmVhbFR5cGUpO1xuXHQgICAgICAgICAgICB9KSgpO1xuXHQgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgLi4ubGlzdGVuZXIsXG5cdCAgICAgICAgICAgICAgICB1bnN1YnNjcmliZTogKCkgPT4gbGlzdGVuZXIudGhlbigobCkgPT4gbC51bnN1YnNjcmliZSgpKVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdH07XG5cdGV4cG9ydHMuYnVpbGRBcHBDaGFubmVsT2JqZWN0ID0gYnVpbGRBcHBDaGFubmVsT2JqZWN0O1xuXHRjb25zdCBjb25uZWN0UHJpdmF0ZUNoYW5uZWwgPSBhc3luYyAoY2hhbm5lbElkKSA9PiB7XG5cdCAgICB0cnkge1xuXHQgICAgICAgIGNvbnN0IGNoYW5uZWxDbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbElkKTtcblx0ICAgICAgICBjb25zdCBwcml2YXRlQ2hhbm5lbENsaWVudCA9IG5ldyBQcml2YXRlQ2hhbm5lbENsaWVudF8xLlByaXZhdGVDaGFubmVsQ2xpZW50KGNoYW5uZWxDbGllbnQsIGNoYW5uZWxJZCk7XG5cdCAgICAgICAgcmV0dXJuICgwLCBleHBvcnRzLmJ1aWxkUHJpdmF0ZUNoYW5uZWxPYmplY3QpKHByaXZhdGVDaGFubmVsQ2xpZW50KTtcblx0ICAgIH1cblx0ICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJpdmF0ZSBDaGFubmVsIHdpdGggaWQ6ICR7Y2hhbm5lbElkfSBkb2Vzbid0IGV4aXN0YCk7XG5cdCAgICB9XG5cdH07XG5cdGV4cG9ydHMuY29ubmVjdFByaXZhdGVDaGFubmVsID0gY29ubmVjdFByaXZhdGVDaGFubmVsO1xuXHRjb25zdCBpc0NvbnRleHQgPSAoY29udGV4dCkgPT4ge1xuXHQgICAgaWYgKGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiBjb250ZXh0KSB7XG5cdCAgICAgICAgY29uc3QgeyB0eXBlIH0gPSBjb250ZXh0O1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZyc7XG5cdCAgICB9XG5cdCAgICByZXR1cm4gZmFsc2U7XG5cdH07XG5cdGV4cG9ydHMuaXNDb250ZXh0ID0gaXNDb250ZXh0O1xuXHRjb25zdCBpc0NoYW5uZWwgPSAoY2hhbm5lbCkgPT4ge1xuXHQgICAgaWYgKGNoYW5uZWwgJiYgdHlwZW9mIGNoYW5uZWwgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiBjaGFubmVsICYmICdpZCcgaW4gY2hhbm5lbCkge1xuXHQgICAgICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGNoYW5uZWw7XG5cdCAgICAgICAgcmV0dXJuIHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmICh0eXBlID09PSAnYXBwJyB8fCB0eXBlID09PSAncHJpdmF0ZScpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIGZhbHNlO1xuXHR9O1xuXHRleHBvcnRzLmlzQ2hhbm5lbCA9IGlzQ2hhbm5lbDtcblx0Y29uc3QgZ2V0SW50ZW50UmVzb2x1dGlvbiA9IGFzeW5jIChpbnRlcm9wTW9kdWxlLCBjb250ZXh0LCBhcHAsIGludGVudCkgPT4ge1xuXHQgICAgLy8gR2VuZXJhdGUgYW4gSUQgdG8gbWFrZSBhIHNlc3Npb24gY29udGV4dCBncm91cCB3aXRoLiBXZSB3aWxsIHBhc3MgdGhhdCBJRCB0byB0aGUgQnJva2VyLlxuXHQgICAgLy8gVGhlIGJyb2tlciB3aWxsIHRoZW4gc2V0Q29udGV4dCBvbiB0aGF0IHNlc3Npb24gY29udGV4dCBncm91cCBsYXRlciB3aXRoIG91ciBJbnRlbnQgUmVzdWx0LFxuXHQgICAgY29uc3QgZ3VpZCA9ICgwLCB1dGlsc18xLmdlbmVyYXRlSWQpKCk7IC8vIFRPRE8gbWFrZSB0aGlzIHVuZGVmaW5lZCBpbiB3ZWJcblx0ICAgIC8vIFByb21pc2Ugd2UnbGwgdXNlIGluIGdldFJlc3VsdFxuXHQgICAgY29uc3QgZ2V0UmVzdWx0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0ICAgICAgICBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5zdWJzY3JpYmUoeyB1dWlkOiAnKicgfSwgZ3VpZCwgKGludGVudFJlc3VsdCkgPT4ge1xuXHQgICAgICAgICAgICByZXNvbHZlKGludGVudFJlc3VsdCk7XG5cdCAgICAgICAgfSkuY2F0Y2goKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignZ2V0UmVzdWx0IGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudCcpKSk7XG5cdCAgICB9KTtcblx0ICAgIC8vIEFkZGluZyB0aGUgaW50ZW50UmVzb2x1dGlvblJlc3VsdElkIHRvIHRoZSBpbnRlbnRPYmouIEJlY2F1c2UgZmlyZUludGVudCBvbmx5IGFjY2VwdHMgYSBzaW5nbGUgYXJnLCB3ZSBoYXZlIHRvIHNsYXAgaXQgaW4gaGVyZS5cblx0ICAgIGNvbnN0IG1ldGFkYXRhID0gYXBwID8geyB0YXJnZXQ6IGFwcCwgaW50ZW50UmVzb2x1dGlvblJlc3VsdElkOiBndWlkIH0gOiB7IGludGVudFJlc29sdXRpb25SZXN1bHRJZDogZ3VpZCB9O1xuXHQgICAgY29uc3QgaW50ZW50T2JqID0gaW50ZW50ID8geyBuYW1lOiBpbnRlbnQsIGNvbnRleHQsIG1ldGFkYXRhIH0gOiB7IC4uLmNvbnRleHQsIG1ldGFkYXRhIH07XG5cdCAgICAvLyBTZXQgdXAgdGhlIGdldFJlc3VsdCBjYWxsLlxuXHQgICAgY29uc3QgZ2V0UmVzdWx0ID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgIGxldCBpbnRlbnRSZXN1bHQgPSBhd2FpdCBnZXRSZXN1bHRQcm9taXNlO1xuXHQgICAgICAgIGlmICghaW50ZW50UmVzdWx0IHx8IHR5cGVvZiBpbnRlbnRSZXN1bHQgIT09ICdvYmplY3QnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihSZXN1bHRFcnJvci5Ob1Jlc3VsdFJldHVybmVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgeyBlcnJvciB9ID0gaW50ZW50UmVzdWx0O1xuXHQgICAgICAgIGlmIChlcnJvcikge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoUmVzdWx0RXJyb3IuSW50ZW50SGFuZGxlclJlamVjdGVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCgwLCBleHBvcnRzLmlzQ2hhbm5lbCkoaW50ZW50UmVzdWx0KSkge1xuXHQgICAgICAgICAgICBjb25zdCB7IGlkLCB0eXBlIH0gPSBpbnRlbnRSZXN1bHQ7XG5cdCAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuXHQgICAgICAgICAgICAgICAgY2FzZSAncHJpdmF0ZSc6IHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnRlbnRSZXN1bHQgPSBhd2FpdCAoMCwgZXhwb3J0cy5jb25uZWN0UHJpdmF0ZUNoYW5uZWwpKGlkKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhc2UgJ2FwcCc6IHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uQ29udGV4dEdyb3VwID0gYXdhaXQgaW50ZXJvcE1vZHVsZS5qb2luU2Vzc2lvbkNvbnRleHRHcm91cChpZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gKDAsIGV4cG9ydHMuYnVpbGRBcHBDaGFubmVsT2JqZWN0KShzZXNzaW9uQ29udGV4dEdyb3VwKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIGlmICghKDAsIGV4cG9ydHMuaXNDb250ZXh0KShpbnRlbnRSZXN1bHQpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihSZXN1bHRFcnJvci5Ob1Jlc3VsdFJldHVybmVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGludGVudFJlc3VsdDtcblx0ICAgIH07XG5cdCAgICAvLyBGaW5hbGx5IGZpcmUgdGhlIGludGVudC5cblx0ICAgIGNvbnN0IGludGVudFJlc29sdXRpb25JbmZvRnJvbUJyb2tlciA9IGludGVudFxuXHQgICAgICAgID8gYXdhaXQgaW50ZXJvcE1vZHVsZS5maXJlSW50ZW50KGludGVudE9iailcblx0ICAgICAgICA6IGF3YWl0IGludGVyb3BNb2R1bGUuZmlyZUludGVudEZvckNvbnRleHQoaW50ZW50T2JqKTtcblx0ICAgIGlmICh0eXBlb2YgaW50ZW50UmVzb2x1dGlvbkluZm9Gcm9tQnJva2VyICE9PSAnb2JqZWN0Jykge1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHNvdXJjZToge1xuXHQgICAgICAgICAgICAgICAgYXBwSWQ6ICcnLFxuXHQgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogJydcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgaW50ZW50OiAnJyxcblx0ICAgICAgICAgICAgdmVyc2lvbjogJzIuMCcsXG5cdCAgICAgICAgICAgIGdldFJlc3VsdFxuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICByZXR1cm4geyAuLi5pbnRlbnRSZXNvbHV0aW9uSW5mb0Zyb21Ccm9rZXIsIGdldFJlc3VsdCB9O1xuXHR9O1xuXHRleHBvcnRzLmdldEludGVudFJlc29sdXRpb24gPSBnZXRJbnRlbnRSZXNvbHV0aW9uOyBcbn0gKHV0aWxzJDIpKTtcblxudmFyIGhhc1JlcXVpcmVkRmRjM0NvbW1vbjtcblxuZnVuY3Rpb24gcmVxdWlyZUZkYzNDb21tb24gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGZGMzQ29tbW9uKSByZXR1cm4gZmRjM0NvbW1vbjtcblx0aGFzUmVxdWlyZWRGZGMzQ29tbW9uID0gMTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xuXHR9O1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xuXHR9O1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdHZhciBfRkRDM01vZHVsZUJhc2VfcHJvZHVjZXI7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmZGMzQ29tbW9uLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0ZmRjM0NvbW1vbi5GREMzTW9kdWxlQmFzZSA9IHZvaWQgMDtcblx0Y29uc3QgdXRpbHNfMSA9IHV0aWxzJDI7XG5cdGNvbnN0IHV0aWxzXzIgPSB1dGlscyQzO1xuXHRjb25zdCBJbnRlcm9wQ2xpZW50XzEgPSByZXF1aXJlSW50ZXJvcENsaWVudCgpO1xuXHRjb25zdCBpc0VxdWFsXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMyk7XG5cdGNsYXNzIEZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIGdldCBjbGllbnQoKSB7XG5cdCAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLCBcImZcIikuY2FsbCh0aGlzKTtcblx0ICAgIH1cblx0ICAgIGdldCBmaW4oKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5nZXRGaW4oKTtcblx0ICAgIH1cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNvbnN0cnVjdG9yXG5cdCAgICBjb25zdHJ1Y3Rvcihwcm9kdWNlciwgd2lyZSkge1xuXHQgICAgICAgIHRoaXMud2lyZSA9IHdpcmU7XG5cdCAgICAgICAgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLnNldCh0aGlzLCB2b2lkIDApO1xuXHQgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLCBwcm9kdWNlciwgXCJmXCIpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBCcm9hZGNhc3RzIGEgY29udGV4dCBmb3IgdGhlIGNoYW5uZWwgb2YgdGhlIGN1cnJlbnQgZW50aXR5LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgLSBOZXcgY29udGV4dCB0byBzZXQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYnJvYWRjYXN0XG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGJyb2FkY2FzdChjb250ZXh0KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYnJvYWRjYXN0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LnNldENvbnRleHQoY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIExhdW5jaGVzIGFuIGFwcCB3aXRoIHRhcmdldCBpbmZvcm1hdGlvbiwgd2hpY2ggY2FuIGVpdGhlciBiZSBhIHN0cmluZyBvciBhbiBBcHBNZXRhZGF0YSBvYmplY3QuXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLm9wZW5cblx0ICAgICAqL1xuXHQgICAgYXN5bmMgX29wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtb3BlbicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCBJbnRlcm9wQ2xpZW50XzEuSW50ZXJvcENsaWVudC5mZXJyeUZkYzNDYWxsKHRoaXMuY2xpZW50LCAnZmRjM09wZW4nLCB7IGFwcCwgY29udGV4dCB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGVycm9yVG9UaHJvdyA9IGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzIuQlJPS0VSX0VSUk9SUy5mZGMzT3BlbiA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIF9nZXRDaGFubmVscygpIHtcblx0ICAgICAgICBjb25zdCBjaGFubmVscyA9IGF3YWl0IHRoaXMuY2xpZW50LmdldENvbnRleHRHcm91cHMoKTtcblx0ICAgICAgICAvLyBmZGMzIGltcGxlbWVudGF0aW9uIG9mIGdldFN5c3RlbUNoYW5uZWxzIHJldHVybnMgYW4gYXJyYXkgb2YgY2hhbm5lbHMsIGhhdmUgdG8gZGVjb3JhdGUgb3ZlclxuXHQgICAgICAgIC8vIHRoaXMgc28gcGVvcGxlIGtub3cgdGhhdCB0aGVzZSBBUElzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdCAgICAgICAgcmV0dXJuIGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4geyAuLi5jaGFubmVsLCB0eXBlOiAnc3lzdGVtJywgLi4uKDAsIHV0aWxzXzEuZ2V0VW5zdXBwb3J0ZWRDaGFubmVsQXBpcykoKSB9O1xuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIGEgQ2hhbm5lbCBvYmplY3QgZm9yIHRoZSBzcGVjaWZpZWQgY2hhbm5lbCwgY3JlYXRpbmcgaXQgYXMgYW4gQXBwIENoYW5uZWwgaWYgaXQgZG9lcyBub3QgZXhpc3QuXG5cdCAgICAgKiBAcGFyYW0gY2hhbm5lbElkXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZ2V0T3JDcmVhdGVDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldE9yQ3JlYXRlQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtb3ItY3JlYXRlLWNoYW5uZWwnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBzeXN0ZW1DaGFubmVscyA9IGF3YWl0IHRoaXMuX2dldENoYW5uZWxzKCk7XG5cdCAgICAgICAgY29uc3QgdXNlckNoYW5uZWwgPSBzeXN0ZW1DaGFubmVscy5maW5kKChjaGFubmVsKSA9PiBjaGFubmVsLmlkID09PSBjaGFubmVsSWQpO1xuXHQgICAgICAgIGlmICh1c2VyQ2hhbm5lbCkge1xuXHQgICAgICAgICAgICByZXR1cm4geyAuLi51c2VyQ2hhbm5lbCwgdHlwZTogJ3N5c3RlbScsIC4uLigwLCB1dGlsc18xLmdldFVuc3VwcG9ydGVkQ2hhbm5lbEFwaXMpKCkgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkNvbnRleHRHcm91cCA9IGF3YWl0IHRoaXMuY2xpZW50LmpvaW5TZXNzaW9uQ29udGV4dEdyb3VwKGNoYW5uZWxJZCk7XG5cdCAgICAgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMS5idWlsZEFwcENoYW5uZWxPYmplY3QpKHNlc3Npb25Db250ZXh0R3JvdXApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQ2hhbm5lbEVycm9yLkNyZWF0aW9uRmFpbGVkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIEludGVyb3AtQnJva2VyLWRlZmluZWQgY29udGV4dCBncm91cHMgYXZhaWxhYmxlIGZvciBhbiBlbnRpdHkgdG8gam9pbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRTeXN0ZW1DaGFubmVsc1xuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRTeXN0ZW1DaGFubmVscygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtc3lzdGVtLWNoYW5uZWxzJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxzKCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEpvaW4gYWxsIEludGVyb3AgQ2xpZW50cyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgdG8gY29udGV4dCBncm91cCBgY29udGV4dEdyb3VwSWRgLlxuXHQgICAgICogSWYgbm8gdGFyZ2V0IGlzIHNwZWNpZmllZCwgaXQgYWRkcyB0aGUgc2VuZGVyIHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogQmVjYXVzZSBtdWx0aXBsZSBDaGFubmVsIGNvbm5lY3Rpb25zL0ludGVyb3AgQ2xpZW50cyBjYW4gcG90ZW50aWFsbHkgZXhpc3QgYXQgYSBgdXVpZGAvYG5hbWVgIGNvbWJvLCB3ZSBjdXJyZW50bHkgam9pbiBhbGwgQ2hhbm5lbCBjb25uZWN0aW9ucy9JbnRlcm9wIENsaWVudHMgYXQgdGhlIGdpdmVuIGlkZW50aXR5IHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogSWYgYW4gYGVuZHBvaW50SWRgIGlzIHByb3ZpZGVkICh3aGljaCBpcyB1bmxpa2VseSwgdW5sZXNzIHRoZSBjYWxsIGlzIGNvbWluZyBmcm9tIGFuIGV4dGVybmFsIGFkYXB0ZXIpLCB0aGVuIHdlIG9ubHkgam9pbiB0aGF0IHNpbmdsZSBjb25uZWN0aW9uIHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogRm9yIGFsbCBpbnRlbnRzIGFuZCBwdXJwb3NlcywgdGhlcmUgd2lsbCBvbmx5IGJlIDEgY29ubmVjdGlvbiBwcmVzZW50IGluIFBsYXRmb3JtIGFuZCBCcm93c2VyIGltcGxlbWVudGF0aW9ucywgc28gdGhpcyBwb2ludCBpcyBtb3JlLW9yLWxlc3MgbW9vdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWQgLSBJZCBvZiB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5qb2luQ2hhbm5lbFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1qb2luLWNoYW5uZWwnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuam9pbkNvbnRleHRHcm91cChjaGFubmVsSWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzIuQlJPS0VSX0VSUk9SUy5qb2luU2Vzc2lvbkNvbnRleHRHcm91cFdpdGhKb2luQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgQ2hhbm5lbCB5b3UgaGF2ZSB0cmllZCB0byBqb2luIGlzIGFuIEFwcCBDaGFubmVsLiBDdXN0b20gQ2hhbm5lbHMgY2FuIG9ubHkgYmUgZGVmaW5lZCBieSB0aGUgSW50ZXJvcCBCcm9rZXIgdGhyb3VnaCBjb2RlIG9yIG1hbmlmZXN0IGNvbmZpZ3VyYXRpb24uIFBsZWFzZSB1c2UgZ2V0T3JDcmVhdGVDaGFubmVsLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZS5zdGFydHNXaXRoKCdBdHRlbXB0aW5nIHRvIGpvaW4gYSBjb250ZXh0IGdyb3VwIHRoYXQgZG9lcyBub3QgZXhpc3QnKSkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQ2hhbm5lbEVycm9yLk5vQ2hhbm5lbEZvdW5kKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5DaGFubmVsRXJyb3IuQWNjZXNzRGVuaWVkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIENoYW5uZWwgdGhhdCB0aGUgZW50aXR5IGlzIHN1YnNjcmliZWQgdG8uIFJldHVybnMgbnVsbCBpZiBub3Qgam9pbmVkIHRvIGEgY2hhbm5lbC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRDdXJyZW50Q2hhbm5lbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRDdXJyZW50Q2hhbm5lbCgpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtY3VycmVudC1jaGFubmVsJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY3VycmVudENvbnRleHRHcm91cEluZm8gPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKCk7XG5cdCAgICAgICAgaWYgKCFjdXJyZW50Q29udGV4dEdyb3VwSW5mbykge1xuXHQgICAgICAgICAgICByZXR1cm4gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRDaGFubmVsT2JqZWN0KGN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHRhcmdldCBmcm9tIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IHJlbW92ZXMgdGhlIHNlbmRlciBmcm9tIHRoZWlyIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMubGVhdmVDdXJyZW50Q2hhbm5lbFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBsZWF2ZUN1cnJlbnRDaGFubmVsKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWxlYXZlLWN1cnJlbnQtY2hhbm5lbCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5yZW1vdmVGcm9tQ29udGV4dEdyb3VwKCk7XG5cdCAgICB9XG5cdCAgICAvLyB1dGlsc1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKCkge1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cHMgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRDb250ZXh0R3JvdXBzKCk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50c0luQ3R4R3JvdXBzUHJvbWlzZSA9IGNvbnRleHRHcm91cHMubWFwKGFzeW5jIChjdHhHcm91cCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKGN0eEdyb3VwLmlkKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5DdHhHcm91cHMgPSBhd2FpdCBQcm9taXNlLmFsbChjbGllbnRzSW5DdHhHcm91cHNQcm9taXNlKTtcblx0ICAgICAgICBjb25zdCBjbGllbnRJZHggPSBjbGllbnRzSW5DdHhHcm91cHMuZmluZEluZGV4KChjbGllbnRJZGVudGl0eUFycikgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xpZW50SWRlbnRpdHlBcnIuc29tZSgoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gY2xpZW50SWRlbnRpdHk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLm1lLnV1aWQgPT09IHV1aWQgJiYgdGhpcy53aXJlLm1lLm5hbWUgPT09IG5hbWU7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBjb250ZXh0R3JvdXBzW2NsaWVudElkeF07XG5cdCAgICB9XG5cdCAgICBhc3luYyBidWlsZENoYW5uZWxPYmplY3QoY3VycmVudENvbnRleHRHcm91cEluZm8pIHtcblx0ICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLi4uY3VycmVudENvbnRleHRHcm91cEluZm8sXG5cdCAgICAgICAgICAgIHR5cGU6ICdzeXN0ZW0nLFxuXHQgICAgICAgICAgICBhZGRDb250ZXh0TGlzdGVuZXI6ICguLi5bY29udGV4dFR5cGUsIGhhbmRsZXJdKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBsZXQgcmVhbEhhbmRsZXI7XG5cdCAgICAgICAgICAgICAgICBsZXQgcmVhbFR5cGU7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgICAgICAgICByZWFsSGFuZGxlciA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVhbEhhbmRsZXIgPSBoYW5kbGVyO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxUeXBlID0gY29udGV4dFR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRDdXJyZW50Q29udGV4dChyZWFsVHlwZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZEhhbmRsZXIgPSAoY29udGV4dCwgY29udGV4dE1ldGFkYXRhKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoMCwgaXNFcXVhbF8xLmRlZmF1bHQpKGN1cnJlbnRDb250ZXh0LCBjb250ZXh0KSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWxIYW5kbGVyKGNvbnRleHQsIGNvbnRleHRNZXRhZGF0YSk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIsIHJlYWxUeXBlKTtcblx0ICAgICAgICAgICAgICAgIH0pKCk7XG5cdCAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgICAgICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgICAgICAgICAgLi4ubGlzdGVuZXIsXG5cdCAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IGxpc3RlbmVyLnRoZW4oKGwpID0+IGwudW5zdWJzY3JpYmUoKSlcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGJyb2FkY2FzdDogdGhpcy5icm9hZGNhc3QuYmluZCh0aGlzKSxcblx0ICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUeXBlc2NyaXB0IGZhaWxzIHRvIGluZmVyIHRoZSByZXR1cm50eXBlIGlzIGEgUHJvbWlzZVxuXHQgICAgICAgICAgICBnZXRDdXJyZW50Q29udGV4dDogYXN5bmMgKGNvbnRleHRUeXBlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0Q3VycmVudENvbnRleHQoY29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUeXBlc2NyaXB0IGZhaWxzIHRvIGluZmVyIHRoZSByZXR1cm50eXBlIGlzIGEgUHJvbWlzZVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb250ZXh0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0fVxuXHRmZGMzQ29tbW9uLkZEQzNNb2R1bGVCYXNlID0gRkRDM01vZHVsZUJhc2U7XG5cdF9GREMzTW9kdWxlQmFzZV9wcm9kdWNlciA9IG5ldyBXZWFrTWFwKCk7XG5cdHJldHVybiBmZGMzQ29tbW9uO1xufVxuXG52YXIgaGFzUmVxdWlyZWRGZGMzMV8yO1xuXG5mdW5jdGlvbiByZXF1aXJlRmRjMzFfMiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZkYzMxXzIpIHJldHVybiBmZGMzMV8yO1xuXHRoYXNSZXF1aXJlZEZkYzMxXzIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZmRjMzFfMiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdGZkYzMxXzIuRmRjM01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgdXRpbHNfMSA9IHV0aWxzJDM7XG5cdGNvbnN0IGZkYzNfY29tbW9uXzEgPSByZXF1aXJlRmRjM0NvbW1vbigpO1xuXHQvKipcblx0ICogQHZlcnNpb24gMS4yXG5cdCAqIFRoZSBGREMzIENsaWVudCBMaWJyYXJ5IHByb3ZpZGVzIGEgc2V0IEFQSXMgdG8gYmUgdXNlZCBmb3IgRkRDMyBjb21wbGlhbmNlLFxuXHQgKiB3aGlsZSB1c2luZyBvdXIgSW50ZXJvcCBBUEkgdW5kZXIgdGhlIGhvb2QuIEluIG9yZGVyIHRvIHVzZSB0aGlzIHNldCBvZiBBUElzXG5cdCAqIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHVwIHlvdXIgb3duIHtAbGluayBJbnRlcm9wQnJva2VyIEludGVyb3BCcm9rZXJ9IG9yIHVzZSBhIFBsYXRmb3JtIGFwcGxpY2F0aW9uLCB3aGljaCBkb2VzIHRoZSBzZXR1cCBmb3IgeW91LiBSZWZlciB0byBvdXIgZG9jdW1lbnRhdGlvbiBvblxuXHQgKiBvdXIge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL29mLWRvY3MvZG9jcy9lbmFibGUtY29sb3ItbGlua2luZyBJbnRlcm9wIEFQSX0uXG5cdCAqXG5cdCAqIFRvIGVuYWJsZSB0aGUgRkRDMyBBUElzIGluIGEge0BsaW5rIFdpbmRvdyBXaW5kb3d9IG9yIHtAbGluayBWaWV3IFZpZXd9LCBhZGQgdGhlIGZkYzNJbnRlcm9wQXBpXG5cdCAqIHByb3BlcnR5IHRvIGl0cyBvcHRpb25zOlxuXHQgKlxuXHQgKiBgYGBqc1xuXHQgKiB7XG5cdCAqICAgICBhdXRvU2hvdzogZmFsc2UsXG5cdCAqICAgICBzYXZlV2luZG93U3RhdGU6IHRydWUsXG5cdCAqICAgICB1cmw6ICdodHRwczovL29wZW5maW4uY28nLFxuXHQgKiAgICAgZmRjM0ludGVyb3BBcGk6ICcxLjInXG5cdCAqIH1cblx0ICogYGBgXG5cdCAqXG5cdCAqIElmIHVzaW5nIGEge0BsaW5rIFBsYXRmb3JtIFBsYXRmb3JtIH0gYXBwbGljYXRpb24sIHlvdSBjYW4gc2V0IHRoaXMgcHJvcGVydHkgaW4gZGVmYXVsdFdpbmRvd09wdGlvbnMgYW5kIGRlZmF1bHRWaWV3T3B0aW9ucy5cblx0ICpcblx0ICogSW4gb3JkZXIgdG8gZW5zdXJlIHRoYXQgdGhlIEZEQzMgQXBpIGlzIHJlYWR5IGJlZm9yZSB1c2UsIHlvdSBjYW4gdXNlIHRoZSAnZmRjM1JlYWR5JyBldmVudCBmaXJlZCBvbiB0aGUgRE9NIFdpbmRvdyBvYmplY3Q6XG5cdCAqXG5cdCAqIGBgYGpzXG5cdCAqIGZ1bmN0aW9uIGZkYzNBY3Rpb24oKSB7XG5cdCAqICAgICAvLyBNYWtlIHNvbWUgZmRjMyBBUEkgY2FsbHMgaGVyZVxuXHQgKiB9XG5cdCAqXG5cdCAqIGlmICh3aW5kb3cuZmRjMykge1xuXHQgKiAgICBmZGMzQWN0aW9uKCk7XG5cdCAqIH0gZWxzZSB7XG5cdCAqICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdmZGMzUmVhZHknLCBmZGMzQWN0aW9uKTtcblx0ICogfVxuXHQgKiBgYGBcblx0ICovXG5cdGNsYXNzIEZkYzNNb2R1bGUgZXh0ZW5kcyBmZGMzX2NvbW1vbl8xLkZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIGFzeW5jIG9wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgYXdhaXQgc3VwZXIuX29wZW4oYXBwLCBjb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkIGEgY29udGV4dCBoYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LiBJZiBhbiBlbnRpdHkgaXMgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAsIGFuZCB0aGVuIHNldHMgaXRzIGNvbnRleHQgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuIElmIHlvdSB3aXNoIHRvIGxpc3RlbiBmb3IgYWxsIGluY29taW5nIGNvbnRleHRzLCBwYXNzIGBudWxsYCBmb3IgdGhlIGNvbnRleHRUeXBlIGFyZ3VtZW50LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlIC0gVGhlIHR5cGUgb2YgY29udGV4dCB5b3Ugd2lzaCB0byBoYW5kbGUuXG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlciAtIEhhbmRsZXIgZm9yIGluY29taW5nIGNvbnRleHQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYWRkQ29udGV4dExpc3RlbmVyXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKi9cblx0ICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETyBbQ09SRS0xNTI0XVxuXHQgICAgYWRkQ29udGV4dExpc3RlbmVyKGNvbnRleHRUeXBlLCBoYW5kbGVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYWRkLWNvbnRleHQtbGlzdGVuZXInKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBsZXQgbGlzdGVuZXI7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2FkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGFkZENvbnRleHRMaXN0ZW5lcihudWxsLCBoYW5kbGVyKScpO1xuXHQgICAgICAgICAgICBsaXN0ZW5lciA9IHRoaXMuY2xpZW50LmFkZENvbnRleHRIYW5kbGVyKGNvbnRleHRUeXBlKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGxpc3RlbmVyID0gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlciwgY29udGV4dFR5cGUgPT09IG51bGwgPyB1bmRlZmluZWQgOiBjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIC4uLmxpc3RlbmVyLFxuXHQgICAgICAgICAgICB1bnN1YnNjcmliZTogKCkgPT4gbGlzdGVuZXIudGhlbigobCkgPT4gbC51bnN1YnNjcmliZSgpKVxuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmb3IgaW5jb21pbmcgSW50ZW50cy5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgLSBOYW1lIG9mIHRoZSBJbnRlbnRcblx0ICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gSGFuZGxlciBmb3IgaW5jb21pbmcgSW50ZW50XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYWRkSW50ZW50TGlzdGVuZXJcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqL1xuXHQgICAgYWRkSW50ZW50TGlzdGVuZXIoaW50ZW50LCBoYW5kbGVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYWRkLWludGVudC1saXN0ZW5lcicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRIYW5kbGVyID0gKHJhaXNlZEludGVudCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHQsIG1ldGFkYXRhOiBpbnRlbnRNZXRhZGF0YSB9ID0gcmFpc2VkSW50ZW50O1xuXHQgICAgICAgICAgICBjb25zdCB7IG1ldGFkYXRhIH0gPSBjb250ZXh0O1xuXHQgICAgICAgICAgICBjb25zdCBpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQgPSBpbnRlbnRNZXRhZGF0YT8uaW50ZW50UmVzb2x1dGlvblJlc3VsdElkIHx8IG1ldGFkYXRhPy5pbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQ7XG5cdCAgICAgICAgICAgIGlmIChpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMucHVibGlzaChpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQsIG51bGwpLmNhdGNoKCgpID0+IG51bGwpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGhhbmRsZXIocmFpc2VkSW50ZW50LmNvbnRleHQpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB0aGlzLmNsaWVudC5yZWdpc3RlckludGVudEhhbmRsZXIoY29udGV4dEhhbmRsZXIsIGludGVudCwge1xuXHQgICAgICAgICAgICBmZGMzVmVyc2lvbjogJzEuMidcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAuLi5saXN0ZW5lcixcblx0ICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IGxpc3RlbmVyLnRoZW4oKGwpID0+IGwudW5zdWJzY3JpYmUoKSlcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSYWlzZXMgYSBzcGVjaWZpYyBpbnRlbnQuXG5cdCAgICAgKiBAcGFyYW0gaW50ZW50IE5hbWUgb2YgdGhlIEludGVudC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSBJbnRlbnQuXG5cdCAgICAgKiBAcGFyYW0gIGFwcCBBcHAgdGhhdCB3aWxsIHJlc29sdmUgdGhlIEludGVudC4gVGhpcyBpcyBhZGRlZCBhcyBtZXRhZGF0YSB0byB0aGUgSW50ZW50LiBDYW4gYmUgYWNjZXNzZWQgYnkgdGhlIGFwcCBwcm92aWRlciBpbiB7QGxpbmsgSW50ZXJvcEJyb2tlciNoYW5kbGVGaXJlZEludGVudCBJbnRlcm9wQnJva2VyLmhhbmRsZUZpcmVkSW50ZW50fS5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5yYWlzZUludGVudFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyByYWlzZUludGVudChpbnRlbnQsIGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGludGVudE9iaiA9IGFwcFxuXHQgICAgICAgICAgICA/IHsgbmFtZTogaW50ZW50LCBjb250ZXh0LCBtZXRhZGF0YTogeyB0YXJnZXQ6IGFwcCB9IH1cblx0ICAgICAgICAgICAgOiB7IG5hbWU6IGludGVudCwgY29udGV4dCB9O1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5maXJlSW50ZW50KGludGVudE9iaik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmluZCBvdXQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBhIHBhcnRpY3VsYXIgaW50ZW50IGJ5IHBhc3NpbmcgaXRzIG5hbWUsIGFuZCBvcHRpb25hbGx5IGl0cyBjb250ZXh0LlxuXHQgICAgICogQHBhcmFtIGludGVudCBOYW1lIG9mIHRoZSBJbnRlbnRcblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZmluZEludGVudFxuXHQgICAgICovXG5cdCAgICBhc3luYyBmaW5kSW50ZW50KGludGVudCwgY29udGV4dCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWZpbmQtaW50ZW50JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmdldEluZm9Gb3JJbnRlbnQoeyBuYW1lOiBpbnRlbnQsIGNvbnRleHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZ2V0SW5mb0ZvckludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmluZCBhbGwgdGhlIGF2YWlsYWJsZSBpbnRlbnRzIGZvciBhIHBhcnRpY3VsYXIgY29udGV4dC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZmluZEludGVudHNCeUNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZmluZEludGVudHNCeUNvbnRleHQoY29udGV4dCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWZpbmQtaW50ZW50cy1ieS1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0ID8gJ1Jlc29sdmVyVW5hdmFpbGFibGUnIDogZXJyb3IubWVzc2FnZTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yVG9UaHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBGaW5kcyBhbmQgcmFpc2VzIGFuIGludGVudCBhZ2FpbnN0IGEgdGFyZ2V0IGFwcCBiYXNlZCBwdXJlbHkgb24gY29udGV4dCBkYXRhLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRcblx0ICAgICAqIEBwYXJhbSBhcHBcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5yYWlzZUludGVudEZvckNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmFpc2VJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudC1mb3ItY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5maXJlSW50ZW50Rm9yQ29udGV4dCh7IC4uLmNvbnRleHQsIG1ldGFkYXRhOiB7IHRhcmdldDogYXBwIH0gfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudEZvckNvbnRleHQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBDaGFubmVsIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFubmVsLCBjcmVhdGluZyBpdCBhcyBhbiBBcHAgQ2hhbm5lbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRPckNyZWF0ZUNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0T3JDcmVhdGVDaGFubmVsKGNoYW5uZWxJZCkge1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRPckNyZWF0ZUNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBtZXRhZGF0YSByZWxhdGluZyB0byB0aGUgRkRDMyBvYmplY3QgYW5kIGl0cyBwcm92aWRlciwgaW5jbHVkaW5nIHRoZSBzdXBwb3J0ZWQgdmVyc2lvbiBvZiB0aGUgRkRDMyBzcGVjaWZpY2F0aW9uIGFuZCB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgb2YgdGhlIGltcGxlbWVudGF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldEluZm9cblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mbygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtaW5mbycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0QWRhcHRlclZlcnNpb25TeW5jKCk7XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgcHJvdmlkZXJWZXJzaW9uOiB2ZXJzaW9uLFxuXHQgICAgICAgICAgICBwcm92aWRlcjogYG9wZW5maW4tJHt0aGlzLndpcmUubWUudXVpZH1gLFxuXHQgICAgICAgICAgICBmZGMzVmVyc2lvbjogJzEuMidcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHR9XG5cdGZkYzMxXzIuRmRjM01vZHVsZSA9IEZkYzNNb2R1bGU7XG5cdHJldHVybiBmZGMzMV8yO1xufVxuXG52YXIgZmRjMzJfMCA9IHt9O1xuXG52YXIgaGFzUmVxdWlyZWRGZGMzMl8wO1xuXG5mdW5jdGlvbiByZXF1aXJlRmRjMzJfMCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZkYzMyXzApIHJldHVybiBmZGMzMl8wO1xuXHRoYXNSZXF1aXJlZEZkYzMyXzAgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZmRjMzJfMCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdGZkYzMyXzAuRmRjM01vZHVsZTIgPSB2b2lkIDA7XG5cdGNvbnN0IGZkYzNfY29tbW9uXzEgPSByZXF1aXJlRmRjM0NvbW1vbigpO1xuXHRjb25zdCB1dGlsc18xID0gdXRpbHMkMztcblx0Y29uc3QgSW50ZXJvcENsaWVudF8xID0gcmVxdWlyZUludGVyb3BDbGllbnQoKTtcblx0Y29uc3QgdXRpbHNfMiA9IHV0aWxzJDI7XG5cdGNvbnN0IFByaXZhdGVDaGFubmVsQ2xpZW50XzEgPSBQcml2YXRlQ2hhbm5lbENsaWVudCQxO1xuXHQvKipcblx0ICogQHZlcnNpb24gMi4wXG5cdCAqIFRoZSBGREMzIENsaWVudCBMaWJyYXJ5IHByb3ZpZGVzIGEgc2V0IEFQSXMgdG8gYmUgdXNlZCBmb3IgRkRDMyBjb21wbGlhbmNlLFxuXHQgKiB3aGlsZSB1c2luZyBvdXIgSW50ZXJvcCBBUEkgdW5kZXIgdGhlIGhvb2QuIEluIG9yZGVyIHRvIHVzZSB0aGlzIHNldCBvZiBBUElzXG5cdCAqIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHVwIHlvdXIgb3duIHtAbGluayBJbnRlcm9wQnJva2VyIEludGVyb3BCcm9rZXJ9IG9yIHVzZSBhIFBsYXRmb3JtIGFwcGxpY2F0aW9uLCB3aGljaCBkb2VzIHRoZSBzZXR1cCBmb3IgeW91LiBSZWZlciB0byBvdXIgZG9jdW1lbnRhdGlvbiBvblxuXHQgKiBvdXIge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL29mLWRvY3MvZG9jcy9lbmFibGUtY29udGV4dC1zaGFyaW5nIEludGVyb3AgQVBJfS5cblx0ICpcblx0ICogVG8gZW5hYmxlIHRoZSBGREMzIEFQSXMgaW4gYSB7QGxpbmsgV2luZG93IFdpbmRvd30gb3Ige0BsaW5rIFZpZXcgVmlld30sIGFkZCB0aGUgZmRjM0ludGVyb3BBcGlcblx0ICogcHJvcGVydHkgdG8gaXRzIG9wdGlvbnM6XG5cdCAqXG5cdCAqIGBgYGpzXG5cdCAqIHtcblx0ICogICAgIGF1dG9TaG93OiBmYWxzZSxcblx0ICogICAgIHNhdmVXaW5kb3dTdGF0ZTogdHJ1ZSxcblx0ICogICAgIHVybDogJ2h0dHBzOi8vb3BlbmZpbi5jbycsXG5cdCAqICAgICBmZGMzSW50ZXJvcEFwaTogJzIuMCdcblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogSWYgdXNpbmcgYSB7QGxpbmsgUGxhdGZvcm0gUGxhdGZvcm0gfSBhcHBsaWNhdGlvbiwgeW91IGNhbiBzZXQgdGhpcyBwcm9wZXJ0eSBpbiBkZWZhdWx0V2luZG93T3B0aW9ucyBhbmQgZGVmYXVsdFZpZXdPcHRpb25zLlxuXHQgKlxuXHQgKiBJbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUgRkRDMyBBcGkgaXMgcmVhZHkgYmVmb3JlIHVzZSwgeW91IGNhbiB1c2UgdGhlICdmZGMzUmVhZHknIGV2ZW50IGZpcmVkIG9uIHRoZSBET00gV2luZG93IG9iamVjdDpcblx0ICpcblx0ICogYGBganNcblx0ICogZnVuY3Rpb24gZmRjM0FjdGlvbigpIHtcblx0ICogICAgIC8vIE1ha2Ugc29tZSBmZGMzIEFQSSBjYWxscyBoZXJlXG5cdCAqIH1cblx0ICpcblx0ICogaWYgKHdpbmRvdy5mZGMzKSB7XG5cdCAqICAgIGZkYzNBY3Rpb24oKTtcblx0ICogfSBlbHNlIHtcblx0ICogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2ZkYzNSZWFkeScsIGZkYzNBY3Rpb24pO1xuXHQgKiB9XG5cdCAqIGBgYFxuXHQgKi9cblx0Y2xhc3MgRmRjM01vZHVsZTIgZXh0ZW5kcyBmZGMzX2NvbW1vbl8xLkZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIC8qKlxuXHQgICAgICogTGF1bmNoZXMgYW4gYXBwLCBzcGVjaWZpZWQgdmlhIGFuIEFwcElkZW50aWZpZXIgb2JqZWN0LlxuXHQgICAgICogQHBhcmFtIGFwcFxuXHQgICAgICogQHBhcmFtIGNvbnRleHRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5vcGVuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIG9wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBhcHAgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFzc2luZyBhIHN0cmluZyBhcyB0aGUgYXBwIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGFuIEFwcElkZW50aWZpZXIgKHsgYXBwSWQ6IHN0cmluZzsgaW5zdGFuY2VJZD86IHN0cmluZyB9KS4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgcmV0dXJuIHN1cGVyLl9vcGVuKGFwcCwgY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmQgYWxsIHRoZSBhdmFpbGFibGUgaW5zdGFuY2VzIGZvciBhIHBhcnRpY3VsYXIgYXBwbGljYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5maW5kSW5zdGFuY2VzXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnN0YW5jZXMoYXBwKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtZmluZC1pbnN0YW5jZXMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgSW50ZXJvcENsaWVudF8xLkludGVyb3BDbGllbnQuZmVycnlGZGMzQ2FsbCh0aGlzLmNsaWVudCwgJ2ZkYzNGaW5kSW5zdGFuY2VzJywgYXBwKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGVycm9yVG9UaHJvdyA9IGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5mZGMzRmluZEluc3RhbmNlcyA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIHRoZSBBcHBNZXRhZGF0YSBmb3IgYW4gQXBwSWRlbnRpZmllciwgd2hpY2ggcHJvdmlkZXMgYWRkaXRpb25hbCBtZXRhZGF0YSAoc3VjaCBhcyBpY29ucywgYSB0aXRsZSBhbmQgZGVzY3JpcHRpb24pIGZyb20gdGhlIEFwcCBEaXJlY3RvcnkgcmVjb3JkIGZvciB0aGUgYXBwbGljYXRpb24sIHRoYXQgbWF5IGJlIHVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRBcHBNZXRhZGF0YVxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRBcHBNZXRhZGF0YShhcHApIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtYXBwLW1ldGFkYXRhJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzR2V0QXBwTWV0YWRhdGEnLCBhcHApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmZkYzNHZXRBcHBNZXRhZGF0YSA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkIGEgY29udGV4dCBoYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LiBJZiBhbiBlbnRpdHkgaXMgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAsIGFuZCB0aGVuIHNldHMgaXRzIGNvbnRleHQgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuIElmIHlvdSB3aXNoIHRvIGxpc3RlbiBmb3IgYWxsIGluY29taW5nIGNvbnRleHRzLCBwYXNzIGBudWxsYCBmb3IgdGhlIGNvbnRleHRUeXBlIGFyZ3VtZW50LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlXG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlclxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmFkZENvbnRleHRMaXN0ZW5lclxuXHQgICAgICovXG5cdCAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgIGFzeW5jIGFkZENvbnRleHRMaXN0ZW5lcihjb250ZXh0VHlwZSwgaGFuZGxlcikge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWFkZC1jb250ZXh0LWxpc3RlbmVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy8gVGhlIEZEQzMgQ29udGV4dEhhbmRsZXIgb25seSBleHBlY3RzIHRoZSBjb250ZXh0IGFuZCBvcHRpb25hbCBDb250ZXh0TWV0YWRhdGEsIHNvIHdlIHdyYXAgdGhlIGhhbmRsZXJcblx0ICAgICAgICAvLyBoZXJlIHNvIGl0IG9ubHkgZ2V0cyBwYXNzZWQgdGhlc2UgcGFyYW1ldGVyc1xuXHQgICAgICAgIGNvbnN0IGdldFdyYXBwZWRIYW5kbGVyID0gKGhhbmRsZXJUb1dyYXApID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRNZXRhZGF0YSwgLi4ucmVzdCB9ID0gY29udGV4dDtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBjb250ZXh0TWV0YWRhdGEgPyBbeyAuLi5yZXN0IH0sIGNvbnRleHRNZXRhZGF0YV0gOiBbY29udGV4dCwgbnVsbF07XG5cdCAgICAgICAgICAgICAgICBoYW5kbGVyVG9XcmFwKC4uLmFyZ3MpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgbGV0IGFjdHVhbEhhbmRsZXIgPSBoYW5kbGVyO1xuXHQgICAgICAgIGxldCB3cmFwcGVkSGFuZGxlciA9IGdldFdyYXBwZWRIYW5kbGVyKGFjdHVhbEhhbmRsZXIpO1xuXHQgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgYWN0dWFsSGFuZGxlciA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICB3cmFwcGVkSGFuZGxlciA9IGdldFdyYXBwZWRIYW5kbGVyKGFjdHVhbEhhbmRsZXIpO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIsIGNvbnRleHRUeXBlID09PSBudWxsID8gdW5kZWZpbmVkIDogY29udGV4dFR5cGUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBGaW5kIG91dCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGEgcGFydGljdWxhciBpbnRlbnQgYnkgcGFzc2luZyBpdHMgbmFtZSwgYW5kIG9wdGlvbmFsbHkgaXRzIGNvbnRleHQgYW5kIHJlc3VsdFR5cGUuXG5cdCAgICAgKiBAcGFyYW0gaW50ZW50IE5hbWUgb2YgdGhlIEludGVudFxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgQ29udGV4dFxuXHQgICAgICogQHBhcmFtIHJlc3VsdFR5cGUgVGhlIHR5cGUgb2YgcmVzdWx0IHJldHVybmVkIGZvciBhbnkgaW50ZW50IHNwZWNpZmllZCBkdXJpbmcgcmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5maW5kSW50ZW50XG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnRlbnQoaW50ZW50LCBjb250ZXh0LCByZXN1bHRUeXBlKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtZmluZC1pbnRlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuZ2V0SW5mb0ZvckludGVudCh7IG5hbWU6IGludGVudCwgY29udGV4dCwgbWV0YWRhdGE6IHsgcmVzdWx0VHlwZSB9IH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmQgYWxsIHRoZSBhdmFpbGFibGUgaW50ZW50cyBmb3IgYSBwYXJ0aWN1bGFyIGNvbnRleHQuXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICogQHBhcmFtIHJlc3VsdFR5cGUgVGhlIHR5cGUgb2YgcmVzdWx0IHJldHVybmVkIGZvciBhbnkgaW50ZW50IHNwZWNpZmllZCBkdXJpbmcgcmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjM3YyLmZpbmRJbnRlbnRzQnlDb250ZXh0XG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIHJlc3VsdFR5cGUpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1maW5kLWludGVudHMtYnktY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHBheWxvYWQgPSByZXN1bHRUeXBlID8geyBjb250ZXh0LCBtZXRhZGF0YTogeyByZXN1bHRUeXBlIH0gfSA6IGNvbnRleHQ7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzdjJGaW5kSW50ZW50c0J5Q29udGV4dCcsIHBheWxvYWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0ID8gJ1Jlc29sdmVyVW5hdmFpbGFibGUnIDogZXJyb3IubWVzc2FnZTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yVG9UaHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSYWlzZXMgYSBzcGVjaWZpYyBpbnRlbnQgZm9yIHJlc29sdXRpb24gYWdhaW5zdCBhcHBzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgZGVza3RvcCBhZ2VudC5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgTmFtZSBvZiB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCBDb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5yYWlzZUludGVudFxuXHQgICAgICovXG5cdCAgICBhc3luYyByYWlzZUludGVudChpbnRlbnQsIGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgYXBwID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQYXNzaW5nIGEgc3RyaW5nIGFzIHRoZSBhcHAgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYW4gQXBwSWRlbnRpZmllciAoeyBhcHBJZDogc3RyaW5nOyBpbnN0YW5jZUlkPzogc3RyaW5nIH0pLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMi5nZXRJbnRlbnRSZXNvbHV0aW9uKSh0aGlzLmNsaWVudCwgY29udGV4dCwgYXBwLCBpbnRlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmRzIGFuZCByYWlzZXMgYW4gaW50ZW50IGFnYWluc3QgYXBwcyByZWdpc3RlcmVkIHdpdGggdGhlIGRlc2t0b3AgYWdlbnQgYmFzZWQgcHVyZWx5IG9uIHRoZSB0eXBlIG9mIHRoZSBjb250ZXh0IGRhdGEuXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCBDb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5yYWlzZUludGVudEZvckNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmFpc2VJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIC8vIFRPRE86IFdlIGhhdmUgdG8gZG8gdGhlIHNhbWUgdGhpbmcgd2UgZG8gZm9yIHJhaXNlSW50ZW50IGhlcmUgYXMgd2VsbC5cblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1yYWlzZS1pbnRlbnQtZm9yLWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGFwcCA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFzc2luZyBhIHN0cmluZyBhcyB0aGUgYXBwIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGFuIEFwcElkZW50aWZpZXIgKHsgYXBwSWQ6IHN0cmluZzsgaW5zdGFuY2VJZD86IHN0cmluZyB9KS4nKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICByZXR1cm4gKDAsIHV0aWxzXzIuZ2V0SW50ZW50UmVzb2x1dGlvbikodGhpcy5jbGllbnQsIGNvbnRleHQsIGFwcCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkcyBhIGxpc3RlbmVyIGZvciBpbmNvbWluZyBpbnRlbnRzLlxuXHQgICAgICogQHBhcmFtIGludGVudCAgTmFtZSBvZiB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlciBBIGNhbGxiYWNrIHRoYXQgaGFuZGxlcyBhIGNvbnRleHQgZXZlbnQgYW5kIG1heSByZXR1cm4gYSBwcm9taXNlIG9mIGEgQ29udGV4dCBvciBDaGFubmVsIG9iamVjdCB0byBiZSByZXR1cm5lZCB0byB0aGUgYXBwbGljYXRpb24gdGhhdCByYWlzZWQgdGhlIGludGVudC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5hZGRJbnRlbnRMaXN0ZW5lclxuXHQgICAgICovXG5cdCAgICBhc3luYyBhZGRJbnRlbnRMaXN0ZW5lcihpbnRlbnQsIGhhbmRsZXIpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1hZGQtaW50ZW50LWxpc3RlbmVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBpbnRlbnQgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBJbnRlbnQgbmFtZScpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvLyBUaGUgRkRDMyBJbnRlbnRlciBoYW5kbGVyIG9ubHkgZXhwZWN0cyB0aGUgY29udGV4dCBhbmQgY29udGV4dE1ldGFkYXRhIHRvIGJlIHBhc3NlZCB0byB0aGUgaGFuZGxlcixcblx0ICAgICAgICAvLyBzbyB3ZSB3cmFwIGl0IGhlcmUgYW5kIG9ubHkgcGFzcyB0aG9zZSBwYXJhbWF0ZXJzLlxuXHQgICAgICAgIGNvbnN0IGNvbnRleHRIYW5kbGVyID0gYXN5bmMgKHJhaXNlZEludGVudCkgPT4ge1xuXHQgICAgICAgICAgICBsZXQgaW50ZW50UmVzdWx0O1xuXHQgICAgICAgICAgICBsZXQgaW50ZW50UmVzdWx0VG9TZW5kO1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHQsIG1ldGFkYXRhOiBpbnRlbnRNZXRhZGF0YSB9ID0gcmFpc2VkSW50ZW50O1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRNZXRhZGF0YSwgbWV0YWRhdGEsIC4uLnJlc3QgfSA9IGNvbnRleHQ7XG5cdCAgICAgICAgICAgIGNvbnN0IGludGVudFJlc29sdXRpb25SZXN1bHRJZCA9IGludGVudE1ldGFkYXRhPy5pbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQgfHwgbWV0YWRhdGE/LmludGVudFJlc29sdXRpb25SZXN1bHRJZDtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSBtZXRhZGF0YSA/IHsgbWV0YWRhdGEsIC4uLnJlc3QgfSA6IHsgLi4ucmVzdCB9O1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gYXdhaXQgaGFuZGxlcihuZXdDb250ZXh0LCBjb250ZXh0TWV0YWRhdGEpO1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0VG9TZW5kID0gaW50ZW50UmVzdWx0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gZXJyb3I7XG5cdCAgICAgICAgICAgICAgICBpbnRlbnRSZXN1bHRUb1NlbmQgPSB7IGVycm9yOiB0cnVlIH07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGludGVudFJlc29sdXRpb25SZXN1bHRJZCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5wdWJsaXNoKGludGVudFJlc29sdXRpb25SZXN1bHRJZCwgaW50ZW50UmVzdWx0VG9TZW5kKS5jYXRjaCgoKSA9PiBudWxsKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoaW50ZW50UmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihpbnRlbnRSZXN1bHQubWVzc2FnZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIGludGVudFJlc3VsdDtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5yZWdpc3RlckludGVudEhhbmRsZXIoY29udGV4dEhhbmRsZXIsIGludGVudCwgeyBmZGMzVmVyc2lvbjogJzIuMCcgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBDaGFubmVsIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFubmVsLCBjcmVhdGluZyBpdCBhcyBhbiBBcHAgQ2hhbm5lbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRPckNyZWF0ZUNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0T3JDcmVhdGVDaGFubmVsKGNoYW5uZWxJZCkge1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRPckNyZWF0ZUNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIENoYW5uZWwgd2l0aCBhbiBhdXRvLWdlbmVyYXRlZCBpZGVudGl0eSB0aGF0IGlzIGludGVuZGVkIGZvciBwcml2YXRlIGNvbW11bmljYXRpb24gYmV0d2VlbiBhcHBsaWNhdGlvbnMuIFByaW1hcmlseSB1c2VkIHRvIGNyZWF0ZSBjaGFubmVscyB0aGF0IHdpbGwgYmUgcmV0dXJuZWQgdG8gb3RoZXIgYXBwbGljYXRpb25zIHZpYSBhbiBJbnRlbnRSZXNvbHV0aW9uIGZvciBhIHJhaXNlZCBpbnRlbnQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5jcmVhdGVQcml2YXRlQ2hhbm5lbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjcmVhdGVQcml2YXRlQ2hhbm5lbCgpIHtcblx0ICAgICAgICBjb25zdCBjaGFubmVsSWQgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZUlkKSgpO1xuXHQgICAgICAgIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdjcmVhdGVQcml2YXRlQ2hhbm5lbFByb3ZpZGVyJywgeyBjaGFubmVsSWQgfSk7XG5cdCAgICAgICAgY29uc3QgY2hhbm5lbENsaWVudCA9IGF3YWl0IHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxJZCk7XG5cdCAgICAgICAgY29uc3QgbmV3UHJpdmF0ZUNoYW5uZWxDbGllbnQgPSBuZXcgUHJpdmF0ZUNoYW5uZWxDbGllbnRfMS5Qcml2YXRlQ2hhbm5lbENsaWVudChjaGFubmVsQ2xpZW50LCBjaGFubmVsSWQpO1xuXHQgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMi5idWlsZFByaXZhdGVDaGFubmVsT2JqZWN0KShuZXdQcml2YXRlQ2hhbm5lbENsaWVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdGhlIFVzZXIgQ2hhbm5lbHMgYXZhaWxhYmxlIGZvciB0aGUgYXBwIHRvIGpvaW4uXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRVc2VyQ2hhbm5lbHNcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0VXNlckNoYW5uZWxzKCkge1xuXHQgICAgICAgIGNvbnN0IGNoYW5uZWxzID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0Q29udGV4dEdyb3VwcygpO1xuXHQgICAgICAgIC8vIGZkYzMgaW1wbGVtZW50YXRpb24gb2YgZ2V0VXNlckNoYW5uZWxzIHJldHVybnMgb24gYXJyYXkgb2YgY2hhbm5lbHMsIGhhdmUgdG8gZGVjb3JhdGUgb3ZlclxuXHQgICAgICAgIC8vIHRoaXMgc28gcGVvcGxlIGtub3cgdGhhdCB0aGVzZSBBUElzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdCAgICAgICAgcmV0dXJuIGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuXHQgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgICAgICAgICAgcmV0dXJuIHsgLi4uY2hhbm5lbCwgdHlwZTogJ3VzZXInLCAuLi4oMCwgdXRpbHNfMi5nZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzKSgnVXNlcicpIH07XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdGhlIFVzZXIgQ2hhbm5lbHMgYXZhaWxhYmxlIGZvciB0aGUgYXBwIHRvIGpvaW4uXG5cdCAgICAgKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgUGxlYXNlIHVzZSB7QGxpbmsgZmRjMy5nZXRVc2VyQ2hhbm5lbHMgZmRjMy5nZXRVc2VyQ2hhbm5lbHN9IGluc3RlYWRcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldFN5c3RlbUNoYW5uZWxzXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldFN5c3RlbUNoYW5uZWxzKCkge1xuXHQgICAgICAgIGNvbnNvbGUud2FybignVGhpcyBBUEkgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBmZGMzLmdldFVzZXJDaGFubmVscyBpbnN0ZWFkLicpO1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRTeXN0ZW1DaGFubmVscygpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFuIGFwcCB0byBhIHNwZWNpZmllZCBVc2VyIGNoYW5uZWwuXG5cdCAgICAgKiBAcGFyYW0gY2hhbm5lbElkIENoYW5uZWwgbmFtZVxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzdjIuam9pblVzZXJDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGpvaW5Vc2VyQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICByZXR1cm4gc3VwZXIuam9pbkNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSm9pbiBhbiBhcHAgdG8gYSBzcGVjaWZpZWQgVXNlciBjaGFubmVsLlxuXHQgICAgICogQHBhcmFtIGNoYW5uZWxJZCBDaGFubmVsIG5hbWVcblx0ICAgICAqIEBkZXByZWNhdGVkIFBsZWFzZSB1c2Uge0BsaW5rIGZkYzMuam9pblVzZXJDaGFubmVsIGZkYzMuam9pblVzZXJDaGFubmVsfSBpbnN0ZWFkXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuam9pbkNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgam9pbkNoYW5uZWwoY2hhbm5lbElkKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdUaGlzIEFQSSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGZkYzMuam9pblVzZXJDaGFubmVsIGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHN1cGVyLmpvaW5DaGFubmVsKGNoYW5uZWxJZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIENoYW5uZWwgb2JqZWN0IGZvciB0aGUgY3VycmVudCBVc2VyIGNoYW5uZWwgbWVtYmVyc2hpcFxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldEN1cnJlbnRDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEN1cnJlbnRDaGFubmVsKCkge1xuXHQgICAgICAgIGNvbnN0IGN1cnJlbnRDaGFubmVsID0gYXdhaXQgc3VwZXIuZ2V0Q3VycmVudENoYW5uZWwoKTtcblx0ICAgICAgICBpZiAoIWN1cnJlbnRDaGFubmVsKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAuLi5jdXJyZW50Q2hhbm5lbCxcblx0ICAgICAgICAgICAgdHlwZTogJ3VzZXInLFxuXHQgICAgICAgICAgICBicm9hZGNhc3Q6IHRoaXMuYnJvYWRjYXN0LmJpbmQodGhpcylcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIEZEQzMgaW1wbGVtZW50YXRpb24sIGluY2x1ZGluZyB0aGUgc3VwcG9ydGVkIHZlcnNpb24gb2YgdGhlIEZEQzMgc3BlY2lmaWNhdGlvbiwgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIG9mIHRoZSBpbXBsZW1lbnRhdGlvbiwgaXRzIG93biB2ZXJzaW9uIG51bWJlciwgZGV0YWlscyBvZiB3aGV0aGVyIG9wdGlvbmFsIEFQSSBmZWF0dXJlcyBhcmUgaW1wbGVtZW50ZWQgYW5kIHRoZSBtZXRhZGF0YSBvZiB0aGUgY2FsbGluZyBhcHBsaWNhdGlvbiBhY2NvcmRpbmcgdG8gdGhlIGRlc2t0b3AgYWdlbnQuXG5cdCAgICAgKiBmZGMzSGFuZGxlR2V0SW5mbyBtdXN0IGJlIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3BCcm9rZXIgc28gdGhhdCB0aGUgSW1wbGVtZW50YXRpb25NZXRhZGF0YSB3aWxsIGhhdmUgdGhlIGFwcE1ldGFkYXRhIGluZm8uXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRJbmZvXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEluZm8oKSB7XG5cdCAgICAgICAgcmV0dXJuIEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzdjJHZXRJbmZvJywgeyBmZGMzVmVyc2lvbjogJzIuMCcgfSk7XG5cdCAgICB9XG5cdH1cblx0ZmRjMzJfMC5GZGMzTW9kdWxlMiA9IEZkYzNNb2R1bGUyO1xuXHRyZXR1cm4gZmRjMzJfMDtcbn1cblxudmFyIGhhc1JlcXVpcmVkSW50ZXJvcENsaWVudDtcblxuZnVuY3Rpb24gcmVxdWlyZUludGVyb3BDbGllbnQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRJbnRlcm9wQ2xpZW50KSByZXR1cm4gSW50ZXJvcENsaWVudDtcblx0aGFzUmVxdWlyZWRJbnRlcm9wQ2xpZW50ID0gMTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcblx0ICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcblx0ICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcblx0ICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcblx0fTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xuXHR9O1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdHZhciBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3Vwcztcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEludGVyb3BDbGllbnQsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRJbnRlcm9wQ2xpZW50LkludGVyb3BDbGllbnQgPSB2b2lkIDA7XG5cdGNvbnN0IGJhc2VfMSA9IGJhc2U7XG5cdGNvbnN0IFNlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfMSA9IF9faW1wb3J0RGVmYXVsdChTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50JDEpO1xuXHRjb25zdCBmZGMzXzFfMl8xID0gcmVxdWlyZUZkYzMxXzIoKTtcblx0Y29uc3QgZmRjM18yXzBfMSA9IHJlcXVpcmVGZGMzMl8wKCk7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHQvKipcblx0ICogVGhlIEludGVyb3AgQ2xpZW50IEFQSSBpcyBicm9rZW4gdXAgaW50byB0d28gZ3JvdXBzOlxuXHQgKlxuXHQgKiAqKkNvbnRlbnQgRmFjaW5nIEFQSXMqKiAtIEZvciBBcHBsaWNhdGlvbiBEZXZlbG9wZXJzIHB1dHRpbmcgVmlld3MgaW50byBhIFBsYXRmb3JtIFdpbmRvdywgd2hvIGNhcmUgYWJvdXQgQ29udGV4dC4gVGhlc2UgYXJlIEFQSXMgdGhhdCBzZW5kIG91dCBhbmQgcmVjZWl2ZSB0aGUgQ29udGV4dCBkYXRhIHRoYXQgZmxvd3MgYmV0d2VlbiBhcHBsaWNhdGlvbnMuIFRoaW5rIG9mIHRoaXMgYXMgdGhlIFdhdGVyIGluIHRoZSBJbnRlcm9wIFBpcGVzLlxuXHQgKlxuXHQgKiAqKkNvbnRleHQgR3JvdXBpbmcgQVBJcyoqIC0gRm9yIFBsYXRmb3JtIERldmVsb3BlcnMsIHRvIGFkZCBhbmQgcmVtb3ZlIFZpZXdzIHRvIGFuZCBmcm9tIENvbnRleHQgR3JvdXBzLiBUaGVzZSBBUElzIGFyZSB1dGlsaXplZCB1bmRlci10aGUtaG9vZCBpbiBQbGF0Zm9ybXMsIHNvIHRoZXkgZG9uJ3QgbmVlZCB0byBiZSB1c2VkIHRvIHBhcnRpY2lwYXRlIGluIEludGVyb3AuIFRoZXNlIGFyZSB0aGUgQVBJcyB0aGF0IGRlY2lkZSB3aGljaCBlbnRpdGllcyB0aGUgY29udGV4dCBkYXRhIGZsb3dzIGJldHdlZW4uIFRoaW5rIG9mIHRoZXNlIGFzIHRoZSB2YWx2ZXMgb3IgcGlwZXMgdGhhdCBjb250cm9sIHRoZSBmbG93IG9mIENvbnRleHQgRGF0YSBmb3IgSW50ZXJvcC5cblx0ICpcblx0ICogLS0tXG5cdCAqXG5cdCAqIEFsbCBBUElzIGFyZSBhdmFpbGFibGUgYXQgdGhlIGBmaW4ubWUuaW50ZXJvcGAgbmFtZXNwYWNlLlxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogKipZb3Ugb25seSBuZWVkIDIgdGhpbmdzIHRvIHBhcnRpY2lwYXRlIGluIEludGVyb3AgQ29udGV4dCBHcm91cGluZzoqKlxuXHQgKiAqIEEgQ29udGV4dCBIYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0OiB7QGxpbmsgSW50ZXJvcENsaWVudCNhZGRDb250ZXh0SGFuZGxlciBhZGRDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBjb250ZXh0VHlwZT8pfVxuXHQgKiAqIENhbGwgc2V0Q29udGV4dCBvbiB5b3VyIGNvbnRleHQgZ3JvdXAgd2hlbiB5b3Ugd2FudCB0byBzaGFyZSBjb250ZXh0IHdpdGggb3RoZXIgZ3JvdXAgbWVtYmVyczoge0BsaW5rIEludGVyb3BDbGllbnQjc2V0Q29udGV4dCBzZXRDb250ZXh0KGNvbnRleHQpfVxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogIyMjIyMgQ29uc3RydWN0b3Jcblx0ICogUmV0dXJuZWQgYnkge0BsaW5rIEludGVyb3AuY29ubmVjdFN5bmMgSW50ZXJvcC5jb25uZWN0U3luY30uXG5cdCAqXG5cdCAqIC0tLVxuXHQgKlxuXHQgKiAjIyMjIyBJbnRlcm9wIG1ldGhvZHMgaW50ZW5kZWQgZm9yIFZpZXdzXG5cdCAqXG5cdCAqXG5cdCAqICoqQ29udGV4dCBHcm91cHMgQVBJKipcblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjYWRkQ29udGV4dEhhbmRsZXIgYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlciwgY29udGV4dFR5cGU/KX1cblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjc2V0Q29udGV4dCBzZXRDb250ZXh0KGNvbnRleHQpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNnZXRDdXJyZW50Q29udGV4dCBnZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZT8pfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNqb2luU2Vzc2lvbkNvbnRleHRHcm91cCBqb2luU2Vzc2lvbkNvbnRleHRHcm91cChzZXNzaW9uQ29udGV4dEdyb3VwSWQpfVxuXHQgKlxuXHQgKlxuXHQgKiAqKkludGVudHMgQVBJKipcblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjZmlyZUludGVudCBmaXJlSW50ZW50KGludGVudCl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I3JlZ2lzdGVySW50ZW50SGFuZGxlciByZWdpc3RlckludGVudEhhbmRsZXIoaW50ZW50SGFuZGxlciwgaW50ZW50TmFtZSl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JJbnRlbnQgZ2V0SW5mb0ZvckludGVudChpbmZvRm9ySW50ZW50T3B0aW9ucyl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0IGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNmaXJlSW50ZW50Rm9yQ29udGV4dCBmaXJlSW50ZW50Rm9yQ29udGV4dChjb250ZXh0Rm9ySW50ZW50KX1cblx0ICpcblx0ICogIyMjIyMgSW50ZXJvcCBtZXRob2RzIGludGVuZGVkIGZvciBXaW5kb3dzXG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldENvbnRleHRHcm91cHMgZ2V0Q29udGV4dEdyb3VwcygpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNqb2luQ29udGV4dEdyb3VwIGpvaW5Db250ZXh0R3JvdXAoY29udGV4dEdyb3VwSWQsIHRhcmdldD8pfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNyZW1vdmVGcm9tQ29udGV4dEdyb3VwIHJlbW92ZUZyb21Db250ZXh0R3JvdXAodGFyZ2V0Pyl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JDb250ZXh0R3JvdXAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cChjb250ZXh0R3JvdXBJZCl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCBnZXRBbGxDbGllbnRzSW5Db250ZXh0R3JvdXAoY29udGV4dEdyb3VwSWQpfVxuXHQgKlxuXHQgKi9cblx0bGV0IEludGVyb3BDbGllbnQkMSA9IGNsYXNzIEludGVyb3BDbGllbnQgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICovXG5cdCAgICBjb25zdHJ1Y3Rvcih3aXJlLCBjbGllbnRQcm9taXNlKSB7XG5cdCAgICAgICAgc3VwZXIod2lyZSk7XG5cdCAgICAgICAgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZS5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3Vwcy5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X3Nlc3Npb25Db250ZXh0R3JvdXBzLCBuZXcgTWFwKCksIFwiZlwiKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIGNsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBDbGllbnQgQVBJc1xuXHQgICAgKi9cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBhIGNvbnRleHQgZm9yIHRoZSBjb250ZXh0IGdyb3VwIG9mIHRoZSBjdXJyZW50IGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBUaGUgZW50aXR5IG11c3QgYmUgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAgaW4gb3JkZXIgc2V0IGEgY29udGV4dC5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCAtIE5ldyBjb250ZXh0IHRvIHNldC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIHNldEluc3RydW1lbnRDb250ZXh0ID0gYXN5bmMgKHRpY2tlcikgPT4ge1xuXHQgICAgICogICAgIGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoe3R5cGU6ICdpbnN0cnVtZW50JywgaWQ6IHt0aWNrZXJ9fSlcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiAvLyBUaGUgdXNlciBjbGlja3MgYW4gaW5zdHJ1bWVudCBvZiBpbnRlcmVzdC4gV2Ugd2FudCB0byBzZXQgdGhhdCBJbnN0cnVtZW50IGNvbnRleHQgc28gdGhhdCB0aGUgcmVzdCBvZiBvdXIgd29ya2Zsb3cgdXBkYXRlcyB3aXRoIGluZm9ybWF0aW9uIGZvciB0aGF0IGluc3RydW1lbnRcblx0ICAgICAqIGluc3RydW1lbnRFbGVtZW50Lm9uKCdjbGljaycsIChldnQpID0+IHtcblx0ICAgICAqICAgICBzZXRJbnN0cnVtZW50Q29udGV4dChldnQudGlja2VyKVxuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtc2V0LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdzZXRDb250ZXh0JywgeyBjb250ZXh0IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBZGQgYSBjb250ZXh0IGhhbmRsZXIgZm9yIGluY29taW5nIGNvbnRleHQuIElmIGFuIGVudGl0eSBpcyBwYXJ0IG9mIGEgY29udGV4dCBncm91cCwgYW5kIHRoZW4gc2V0cyBpdHMgY29udGV4dCBoYW5kbGVyLFxuXHQgICAgICogaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGhhbmRsZXIgLSBIYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlIC0gVGhlIHR5cGUgb2YgY29udGV4dCB5b3Ugd2lzaCB0byBoYW5kbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmdW5jdGlvbiBoYW5kbGVJbmNvbWluZ0NvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBzd2l0Y2ggKHR5cGUpIHtcblx0ICAgICAqICAgICAgICAgY2FzZSAnaW5zdHJ1bWVudCc6XG5cdCAgICAgKiAgICAgICAgICAgICBoYW5kbGVJbnN0cnVtZW50Q29udGV4dChjb250ZXh0SW5mbyk7XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqICAgICAgICAgY2FzZSAnY291bnRyeSc6XG5cdCAgICAgKiAgICAgICAgICAgICBoYW5kbGVDb3VudHJ5Q29udGV4dChjb250ZXh0SW5mbyk7XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqXG5cdCAgICAgKiAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIGZ1bmN0aW9uIGhhbmRsZUluc3RydW1lbnRDb250ZXh0KGNvbnRleHRJbmZvKSB7XG5cdCAgICAgKiAgICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gY29udGV4dEluZm87XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coJ2NvbnRleHRJbmZvIGZvciBpbnN0cnVtZW50JywgY29udGV4dEluZm8pXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZnVuY3Rpb24gaGFuZGxlQ291bnRyeUNvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygnY29udGV4dEluZm8gZm9yIGNvdW50cnknLCBjb250ZXh0SW5mbylcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5hZGRDb250ZXh0SGFuZGxlcihoYW5kbGVJbmNvbWluZ0NvbnRleHQpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIFBhc3NpbmcgaW4gYSBjb250ZXh0IHR5cGUgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgd2lsbCBjYXVzZSB0aGUgaGFuZGxlciB0byBvbmx5IGJlIGludm9rZWQgd2l0aCB0aGF0IGNvbnRleHQgdHlwZS5cblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZnVuY3Rpb24gaGFuZGxlSW5zdHJ1bWVudENvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygnY29udGV4dEluZm8gZm9yIGluc3RydW1lbnQnLCBjb250ZXh0SW5mbylcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBmdW5jdGlvbiBoYW5kbGVDb3VudHJ5Q29udGV4dChjb250ZXh0SW5mbykge1xuXHQgICAgICogICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGNvbnRleHRJbmZvO1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKCdjb250ZXh0SW5mbyBmb3IgY291bnRyeScsIGNvbnRleHRJbmZvKVxuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5hZGRDb250ZXh0SGFuZGxlcihoYW5kbGVJbnN0cnVtZW50Q29udGV4dCwgJ2luc3RydW1lbnQnKVxuXHQgICAgICogZmluLm1lLmludGVyb3AuYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlQ291bnRyeUNvbnRleHQsICdjb3VudHJ5Jylcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBhZGRDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBjb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1hZGQtY29udGV4dC1oYW5kbGVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vbi1mdW5jdGlvbiBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZpcnN0IHBhcmFtZXRlciAnaGFuZGxlcicuIEJlIGF3YXJlIHRoYXQgdGhlIGFyZ3VtZW50IG9yZGVyIGRvZXMgbm90IG1hdGNoIHRoZSBGREMzIHN0YW5kYXJkLlwiKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgbGV0IGhhbmRsZXJJZDtcblx0ICAgICAgICBpZiAoY29udGV4dFR5cGUpIHtcblx0ICAgICAgICAgICAgaGFuZGxlcklkID0gYGludm9rZUNvbnRleHRIYW5kbGVyLSR7Y29udGV4dFR5cGV9LSR7KDAsIHV0aWxzXzEuZ2VuZXJhdGVJZCkoKX1gO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgaGFuZGxlcklkID0gJ2ludm9rZUNvbnRleHRIYW5kbGVyJztcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3Qgd3JhcHBlZEhhbmRsZXIgPSAoMCwgdXRpbHNfMS53cmFwQ29udGV4dEhhbmRsZXIpKGhhbmRsZXIsIGhhbmRsZXJJZCk7XG5cdCAgICAgICAgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgd3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkJywgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0pO1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHVuc3Vic2NyaWJlOiBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjbGllbnQucmVtb3ZlKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlbW92ZUNvbnRleHRIYW5kbGVyJywgeyBoYW5kbGVySWQgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLypcblx0ICAgIFBsYXRmb3JtIFdpbmRvdyBBUElzXG5cdCAgICAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBJbnRlcm9wLUJyb2tlci1kZWZpbmVkIGNvbnRleHQgZ3JvdXBzIGF2YWlsYWJsZSBmb3IgYW4gZW50aXR5IHRvIGpvaW4uXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5nZXRDb250ZXh0R3JvdXBzKClcblx0ICAgICAqICAgICAgICAgLnRoZW4oY29udGV4dEdyb3VwcyA9PiB7XG5cdCAgICAgKiAgICAgICAgICAgICBjb250ZXh0R3JvdXBzLmZvckVhY2goY29udGV4dEdyb3VwID0+IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhjb250ZXh0R3JvdXAuZGlzcGxheU1ldGFkYXRhLm5hbWUpXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwLmRpc3BsYXlNZXRhZGF0YS5jb2xvcilcblx0ICAgICAqICAgICAgICAgICAgIH0pXG5cdCAgICAgKiAgICAgICAgIH0pXG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0Q29udGV4dEdyb3VwcygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZ2V0LWNvbnRleHQtZ3JvdXBzJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0Q29udGV4dEdyb3VwcycpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFsbCBJbnRlcm9wIENsaWVudHMgYXQgdGhlIGdpdmVuIGlkZW50aXR5IHRvIGNvbnRleHQgZ3JvdXAgYGNvbnRleHRHcm91cElkYC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IGFkZHMgdGhlIHNlbmRlciB0byB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBCZWNhdXNlIG11bHRpcGxlIENoYW5uZWwgY29ubmVjdGlvbnMvSW50ZXJvcCBDbGllbnRzIGNhbiBwb3RlbnRpYWxseSBleGlzdCBhdCBhIGB1dWlkYC9gbmFtZWAgY29tYm8sIHdlIGN1cnJlbnRseSBqb2luIGFsbCBDaGFubmVsIGNvbm5lY3Rpb25zL0ludGVyb3AgQ2xpZW50cyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBJZiBhbiBgZW5kcG9pbnRJZGAgaXMgcHJvdmlkZWQgKHdoaWNoIGlzIHVubGlrZWx5LCB1bmxlc3MgdGhlIGNhbGwgaXMgY29taW5nIGZyb20gYW4gZXh0ZXJuYWwgYWRhcHRlciksIHRoZW4gd2Ugb25seSBqb2luIHRoYXQgc2luZ2xlIGNvbm5lY3Rpb24gdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBGb3IgYWxsIGludGVudHMgYW5kIHB1cnBvc2VzLCB0aGVyZSB3aWxsIG9ubHkgYmUgMSBjb25uZWN0aW9uIHByZXNlbnQgaW4gUGxhdGZvcm0gYW5kIEJyb3dzZXIgaW1wbG1lbnRhdGlvbnMsIHNvIHRoaXMgcG9pbnQgaXMgbW9yZS1vci1sZXNzIG1vb3QuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRHcm91cElkIC0gSWQgb2YgdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gSWRlbnRpdHkgb2YgdGhlIGVudGl0eSB5b3Ugd2lzaCB0byBqb2luIHRvIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGpvaW5WaWV3VG9Db250ZXh0R3JvdXAgPSBhc3luYyAoY29udGV4dEdyb3VwSWQsIHZpZXcpID0+IHtcblx0ICAgICAqICAgICBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkLCB2aWV3KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRMYXN0Rm9jdXNlZFZpZXcoKVxuXHQgICAgICogICAgIC50aGVuKGxhc3RGb2N1c2VkVmlld0lkZW50aXR5ID0+IHtcblx0ICAgICAqICAgICAgICAgam9pblZpZXdUb0NvbnRleHRHcm91cCgncmVkJywgbGFzdEZvY3VzZWRWaWV3SWRlbnRpdHkpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkLCB0YXJnZXQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtam9pbi1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgaWYgKCFjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbnRleHRHcm91cElkIHNwZWNpZmllZCBmb3Igam9pbkNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnam9pbkNvbnRleHRHcm91cCcsIHsgY29udGV4dEdyb3VwSWQsIHRhcmdldCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHRhcmdldCBmcm9tIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IHJlbW92ZXMgdGhlIHNlbmRlciBmcm9tIHRoZWlyIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHRhcmdldCAtIElkZW50aXR5IG9mIHRoZSBlbnRpdHkgeW91IHdpc2ggdG8gam9pbiB0byBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiByZW1vdmVWaWV3RnJvbUNvbnRleHRHcm91cCA9IGFzeW5jICh2aWV3KSA9PiB7XG5cdCAgICAgKiAgICAgYXdhaXQgZmluLm1lLmludGVyb3AucmVtb3ZlRnJvbUNvbnRleHRHcm91cCh2aWV3KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRMYXN0Rm9jdXNlZFZpZXcoKVxuXHQgICAgICogICAgIC50aGVuKGxhc3RGb2N1c2VkVmlld0lkZW50aXR5ID0+IHtcblx0ICAgICAqICAgICAgICAgcmVtb3ZlVmlld0Zyb21Db250ZXh0R3JvdXAobGFzdEZvY3VzZWRWaWV3SWRlbnRpdHkpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyByZW1vdmVGcm9tQ29udGV4dEdyb3VwKHRhcmdldCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1yZW1vdmUtZnJvbS1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgncmVtb3ZlRnJvbUNvbnRleHRHcm91cCcsIHsgdGFyZ2V0IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGFsbCBjbGllbnRzIGZvciBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgKipUaGlzIGlzIHByaW1hcmlseSB1c2VkIGZvciBwbGF0Zm9ybSB3aW5kb3dzLiBWaWV3cyB3aXRoaW4gYSBwbGF0Zm9ybSBzaG91bGQgbm90IGhhdmUgdG8gdXNlIHRoaXMgQVBJLioqXG5cdCAgICAgKlxuXHQgICAgICogUmV0dXJucyB0aGUgSW50ZXJvcC1Ccm9rZXItZGVmaW5lZCBjb250ZXh0IGdyb3VwcyBhdmFpbGFibGUgZm9yIGFuIGVudGl0eSB0byBqb2luLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRHcm91cElkIC0gVGhlIGlkIG9mIGNvbnRleHQgZ3JvdXAgeW91IHdpc2ggdG8gZ2V0IGNsaWVudHMgZm9yLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLm1lLmludGVyb3AuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKCdyZWQnKVxuXHQgICAgICogICAgIC50aGVuKGNsaWVudHNJbkNvbnRleHRHcm91cCA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGNsaWVudHNJbkNvbnRleHRHcm91cClcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cChjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1nZXQtYWxsLWNsaWVudHMtaW4tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuXHQgICAgICAgIGlmICghY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb250ZXh0R3JvdXBJZCBzcGVjaWZpZWQgZm9yIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwJywgeyBjb250ZXh0R3JvdXBJZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBkaXNwbGF5IGluZm8gZm9yIGEgY29udGV4dCBncm91cFxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0R3JvdXBJZCAtIFRoZSBpZCBvZiBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBkaXNwbGF5IGluZm8gZm9yLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLm1lLmludGVyb3AuZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgncmVkJylcblx0ICAgICAqICAgICAudGhlbihjb250ZXh0R3JvdXBJbmZvID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mby5kaXNwbGF5TWV0YWRhdGEubmFtZSlcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mby5kaXNwbGF5TWV0YWRhdGEuY29sb3IpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRJbmZvRm9yQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWdldC1pbmZvLWZvci1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgaWYgKCFjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbnRleHRHcm91cElkIHNwZWNpZmllZCBmb3IgZ2V0SW5mb0ZvckNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0SW5mb0ZvckNvbnRleHRHcm91cCcsIHsgY29udGV4dEdyb3VwSWQgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNlbmRzIGFuIGludGVudCB0byB0aGUgSW50ZXJvcCBCcm9rZXIgdG8gcmVzb2x2ZS5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgLSBUaGUgY29tYmluYXRpb24gb2YgYW4gYWN0aW9uIGFuZCBhIGNvbnRleHQgdGhhdCBpcyBwYXNzZWQgdG8gYW4gYXBwbGljYXRpb24gZm9yIHJlc29sdXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyBWaWV3IHdhbnRzIHRvIGZpcmUgYW4gSW50ZW50IGFmdGVyIGEgdXNlciBjbGlja3Mgb24gYSB0aWNrZXJcblx0ICAgICAqIHRpY2tlckVsZW1lbnQub24oJ2NsaWNrJywgKGVsZW1lbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB0aWNrZXIgPSBlbGVtZW50LmlubmVyVGV4dDtcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnQgPSB7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdWaWV3Q2hhcnQnLFxuXHQgICAgICogICAgICAgICBjb250ZXh0OiB7dHlwZTogJ2ZkYzMuaW5zdHJ1bWVudCcsIGlkOiB7IHRpY2tlciB9fVxuXHQgICAgICogICAgIH1cblx0ICAgICAqXG5cdCAgICAgKiAgICAgZmluLm1lLmludGVyb3AuZmlyZUludGVudChpbnRlbnQpO1xuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBmaXJlSW50ZW50KGludGVudCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1maXJlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgdGhpcyBpcyBvbmx5IGZvciBhcGkgYW5hbHl0aWNzIHB1cnBvc2VzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZmlyZUludGVudCcsIGludGVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEFkZHMgYW4gaW50ZW50IGhhbmRsZXIgZm9yIGluY29taW5nIGludGVudHMuIFRoZSBsYXN0IGludGVudCBzZW50IG9mIHRoZSBuYW1lIHN1YnNjcmliZWQgdG8gd2lsbCBiZSByZWNlaXZlZC5cblx0ICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gUmVnaXN0ZXJlZCBmdW5jdGlvbiBtZWFudCB0byBoYW5kbGUgYSBzcGVjaWZpYyBpbnRlbnQgdHlwZS5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnROYW1lIC0gVGhlIG5hbWUgb2YgYW4gaW50ZW50LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgaW50ZW50SGFuZGxlciA9IChpbnRlbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB7IGNvbnRleHQgfSA9IGludGVudDtcblx0ICAgICAqICAgICBteVZpZXdDaGFydEhhbmRsZXIoY29udGV4dCk7XG5cdCAgICAgKiB9O1xuXHQgICAgICpcblx0ICAgICAqIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLnJlZ2lzdGVySW50ZW50SGFuZGxlcihpbnRlbnRIYW5kbGVyLCAnVmlld0NoYXJ0Jyk7XG5cdCAgICAgKlxuXHQgICAgICogZnVuY3Rpb24gbXlBcHBDbG9zZVNlcXVlbmNlKCkge1xuXHQgICAgICogICAgIC8vIHRvIHVuc3Vic2NyaWJlIHRoZSBoYW5kbGVyLCBzaW1wbHkgY2FsbDpcblx0ICAgICAqICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyByZWdpc3RlckludGVudEhhbmRsZXIoaGFuZGxlciwgaW50ZW50TmFtZSwgb3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1yZWdpc3Rlci1pbnRlbnQtaGFuZGxlcicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgdGhpcyBpcyBvbmx5IGZvciBhcGkgYW5hbHl0aWNzIHB1cnBvc2VzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYGludGVudC1oYW5kbGVyLSR7aW50ZW50TmFtZX1gO1xuXHQgICAgICAgIGNvbnN0IHdyYXBwZWRIYW5kbGVyID0gKDAsIHV0aWxzXzEud3JhcEludGVudEhhbmRsZXIpKGhhbmRsZXIsIGhhbmRsZXJJZCk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgd3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ2ludGVudEhhbmRsZXJSZWdpc3RlcmVkJywgeyBoYW5kbGVySWQsIC4uLm9wdGlvbnMgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byByZWdpc3RlciBpbnRlbnQgaGFuZGxlcicpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICB1bnN1YnNjcmliZTogYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50LnJlbW92ZShoYW5kbGVySWQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgbGFzdCBjb250ZXh0IG9mIHRoZSBDb250ZXh0IEdyb3VwIGN1cnJlbnRseSBzdWJzY3JpYmVkIHRvLiBJdCB0YWtlcyBhbiBvcHRpb25hbCBDb250ZXh0IFR5cGUgYW5kIHJldHVybnMgdGhlXG5cdCAgICAgKiBsYXN0IGNvbnRleHQgb2YgdGhhdCB0eXBlLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKCd5ZWxsb3cnKTtcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoeyB0eXBlOiAnaW5zdHJ1bWVudCcsIGlkOiB7IHRpY2tlcjogJ0ZPTycgfX0pO1xuXHQgICAgICogY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCBmaW4ubWUuaW50ZXJvcC5nZXRDdXJyZW50Q29udGV4dCgpO1xuXHQgICAgICpcblx0ICAgICAqIC8vIHdpdGggYSBzcGVjaWZpYyBjb250ZXh0XG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKCd5ZWxsb3cnKTtcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoeyB0eXBlOiAnY291bnRyeScsIGlkOiB7IElTT0FMUEhBMzogJ1VTJyB9fSk7XG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5zZXRDb250ZXh0KHsgdHlwZTogJ2luc3RydW1lbnQnLCBpZDogeyB0aWNrZXI6ICdGT08nIH19KTtcblx0ICAgICAqIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gYXdhaXQgZmluLm1lLmludGVyb3AuZ2V0Q3VycmVudENvbnRleHQoJ2NvdW50cnknKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1nZXQtY3VycmVudC1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0Q3VycmVudENvbnRleHQnLCB7IGNvbnRleHRUeXBlIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXQgaW5mb3JtYXRpb24gZm9yIGEgcGFydGljdWxhciBJbnRlbnQgZnJvbSB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVJbmZvRm9ySW50ZW50IGlzIG1lYW50IHRvIGJlIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3AgQnJva2VyLlxuXHQgICAgICogVGhlIGZvcm1hdCBmb3IgdGhlIHJlc3BvbnNlIHdpbGwgYmUgZGV0ZXJtaW5lZCBieSB0aGUgQXBwIFByb3ZpZGVyIG92ZXJyaWRpbmcgdGhlIGZ1bmN0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBpbnRlbnRJbmZvID0gYXdhaXQgZmluLm1lLmludGVyb3AuZ2V0SW5mb0ZvckludGVudCgnVmlld0NoYXJ0Jyk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0SW5mb0ZvckludGVudChvcHRpb25zKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWdldC1pbmZvLWZvci1pbnRlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXRJbmZvRm9ySW50ZW50Jywgb3B0aW9ucyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdldCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBJbnRlcm9wIEJyb2tlciBvbiBhbGwgSW50ZW50cyB0aGF0IGFyZSBtZWFudCB0byBoYW5kbGUgYSBwYXJ0aWN1bGFyIGNvbnRleHQuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIGluIHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoZSBmb3JtYXQgZm9yIHRoZSByZXNwb25zZSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIEFwcCBQcm92aWRlciBvdmVycmlkaW5nIHRoZSBmdW5jdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogdGlja2VyRWxlbWVudC5vbignY2xpY2snLCAoZWxlbWVudCkgPT4ge1xuXHQgICAgICogICAgIGNvbnN0IHRpY2tlciA9IGVsZW1lbnQuaW5uZXJUZXh0O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBjb250ZXh0ID0ge1xuXHQgICAgICogICAgICAgICB0eXBlOiAnZmRjMy5pbnN0cnVtZW50Jyxcblx0ICAgICAqICAgICAgICAgaWQ6IHtcblx0ICAgICAqICAgICAgICAgICAgIHRpY2tlclxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnRzSW5mbyA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLmdldEluZm9Gb3JJbnRlbnRCeUNvbnRleHQoY29udGV4dCk7XG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZ2V0LWluZm8tZm9yLWludGVudHMtYnktY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuXHQgICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2dldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0JywgY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNlbmRzIGEgQ29udGV4dCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgdG8gYW4gSW50ZW50IGJ5IHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoaXMgY29udGV4dCBhY2NlcHRzIGEgbWV0YWRhdGEgcHJvcGVydHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVGaXJlZEludGVudEJ5Q29udGV4dCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIGluIHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoZSBmb3JtYXQgZm9yIHRoZSByZXNwb25zZSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIEFwcCBQcm92aWRlciBvdmVycmlkaW5nIHRoZSBmdW5jdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogdGlja2VyRWxlbWVudC5vbignY2xpY2snLCAoZWxlbWVudCkgPT4ge1xuXHQgICAgICogICAgIGNvbnN0IHRpY2tlciA9IGVsZW1lbnQuaW5uZXJUZXh0O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBjb250ZXh0ID0ge1xuXHQgICAgICogICAgICAgICB0eXBlOiAnZmRjMy5pbnN0cnVtZW50Jyxcblx0ICAgICAqICAgICAgICAgaWQ6IHtcblx0ICAgICAqICAgICAgICAgICAgIHRpY2tlclxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnRSZXNvbHV0aW9uID0gYXdhaXQgZmluLm1lLmludGVyb3AuZmlyZUludGVudEZvckNvbnRleHQoY29udGV4dCk7XG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpcmVJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZmlyZS1pbnRlbnQtZm9yLWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdmaXJlSW50ZW50Rm9yQ29udGV4dCcsIGNvbnRleHQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIHRoZSBjdXJyZW50IGVudGl0eSB0byBzZXNzaW9uIGNvbnRleHQgZ3JvdXAgYHNlc3Npb25Db250ZXh0R3JvdXBJZGAgYW5kIHJldHVybiBhIHNlc3Npb25Db250ZXh0R3JvdXAgaW5zdGFuY2UuXG5cdCAgICAgKiBJZiB0aGUgc2Vzc2lvbkNvbnRleHRHcm91cCBkb2Vzbid0IGV4aXN0LCBvbmUgd2lsbCBnZXQgY3JlYXRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBTZXNzaW9uIENvbnRleHQgR3JvdXBzIGRvIG5vdCBwZXJzaXN0IGJldHdlZW4gcnVucyBhbmQgYXJlbid0IHByZXNlbnQgb24gc25hcHNob3RzLlxuXHQgICAgICogQHBhcmFtIHNlc3Npb25Db250ZXh0R3JvdXBJZCAtIElkIG9mIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBTYXkgd2Ugd2FudCB0byBoYXZlIGEgU2Vzc2lvbiBDb250ZXh0IEdyb3VwIHRoYXQgaG9sZHMgVUkgdGhlbWUgaW5mb3JtYXRpb24gZm9yIGFsbCBhcHBzIHRvIGNvbnN1bWU6XG5cdCAgICAgKlxuXHQgICAgICogTXkgY29sb3ItcGlja2VyIFZpZXc6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogICAgIGNvbnN0IHRoZW1lU2Vzc2lvbkNvbnRleHRHcm91cCA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLmpvaW5TZXNzaW9uQ29udGV4dEdyb3VwKCd0aGVtZScpO1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBteUNvbG9yUGlja2VyRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb2xvci1wYWxldHRlLXBpY2tlcicpO1xuXHQgICAgICogICAgIG15Q29sb3JQaWNrZXJFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGV2ZW50ID0+IHtcblx0ICAgICAqICAgICAgICAgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwLnNldENvbnRleHQoeyB0eXBlOiAnY29sb3ItcGFsZXR0ZScsIHNlbGVjdGlvbjogZXZlbnQudmFsdWUgfSk7XG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBJbiBvdGhlciB2aWV3czpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgY29uc3QgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwID0gYXdhaXQgZmluLm1lLmludGVyb3Auam9pblNlc3Npb25Db250ZXh0R3JvdXAoJ3RoZW1lJyk7XG5cdCAgICAgKlxuXHQgICAgICogICAgIGNvbnN0IGNoYW5nZUNvbG9yUGFsZXR0ZSA9ICh7IHNlbGVjdGlvbiB9KSA9PiB7XG5cdCAgICAgKiAgICAgICAgIC8vIGNoYW5nZSB0aGUgY29sb3IgcGFsZXR0ZSB0byB0aGUgc2VsZWN0aW9uXG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqXG5cdCAgICAgKiAgICAgLy8gSWYgdGhlIGNvbnRleHQgaXMgYWxyZWFkeSBzZXQgYnkgdGhlIHRpbWUgdGhlIGhhbmRsZXIgd2FzIHNldCwgdGhlIGhhbmRsZXIgd2lsbCBnZXQgaW52b2tlZCBpbW1lZGlhdGVseSB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQuXG5cdCAgICAgKiAgICAgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwLmFkZENvbnRleHRIYW5kbGVyKGNoYW5nZUNvbG9yUGFsZXR0ZSwgJ2NvbG9yLXBhbGV0dGUnKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luU2Vzc2lvbkNvbnRleHRHcm91cChzZXNzaW9uQ29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50U2Vzc2lvbkNvbnRleHRHcm91cCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfc2Vzc2lvbkNvbnRleHRHcm91cHMsIFwiZlwiKS5nZXQoc2Vzc2lvbkNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgaWYgKGN1cnJlbnRTZXNzaW9uQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFNlc3Npb25Db250ZXh0R3JvdXAuZ2V0VXNlckluc3RhbmNlKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgaGFzQ29uZmxpY3QgfSA9IGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnc2Vzc2lvbkNvbnRleHRHcm91cDpjcmVhdGVJZk5lZWRlZCcsIHtcblx0ICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXBJZFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgaWYgKGhhc0NvbmZsaWN0KSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEEgKG5vbi1zZXNzaW9uKSBjb250ZXh0IGdyb3VwIHdpdGggdGhlIG5hbWUgXCIke3Nlc3Npb25Db250ZXh0R3JvdXBJZH1cIiBhbHJlYWR5IGV4aXN0cy4gSWYgeW91IGFyZSB0cnlpbmcgdG8gam9pbiBhIENvbnRleHQgR3JvdXAsIGNhbGwgam9pbkNvbnRleHRHcm91cCBpbnN0ZWFkLmApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb25Db250ZXh0R3JvdXAgPSBuZXcgU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudF8xLmRlZmF1bHQodGhpcy53aXJlLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKSwgc2Vzc2lvbkNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3VwcywgXCJmXCIpLnNldChzZXNzaW9uQ29udGV4dEdyb3VwSWQsIG5ld1Nlc3Npb25Db250ZXh0R3JvdXApO1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3U2Vzc2lvbkNvbnRleHRHcm91cC5nZXRVc2VySW5zdGFuY2UoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHRocm93biB0cnlpbmcgdG8gY3JlYXRlIFNlc3Npb24gQ29udGV4dCBHcm91cCB3aXRoIGlkIFwiJHtzZXNzaW9uQ29udGV4dEdyb3VwSWR9XCI6ICR7ZXJyb3J9YCk7XG5cdCAgICAgICAgICAgIHRocm93IGVycm9yO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBJbnRlcm9wIENsaWVudCBoYXMgYmVlbiBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKiBPbmx5IG9uZSBsaXN0ZW5lciBwZXIgSW50ZXJvcCBDbGllbnQgY2FuIGJlIHNldC5cblx0ICAgICAqIEBwYXJhbSBsaXN0ZW5lclxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgbGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIHRvcGljLCBicm9rZXJOYW1lfSA9IGV2ZW50O1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKGBEaXNjb25uZWN0ZWQgZnJvbSBJbnRlcm9wIEJyb2tlciAke2Jyb2tlck5hbWV9IGApO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLm9uRGlzY29ubmVjdGlvbihsaXN0ZW5lcik7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgb25EaXNjb25uZWN0aW9uKGxpc3RlbmVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWFkZC1vbmRpc2Nvbm5lY3Rpb24tbGlzdGVuZXInKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50Lm9uRGlzY29ubmVjdGlvbigoZXZlbnQpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyB1dWlkIH0gPSBldmVudDtcblx0ICAgICAgICAgICAgbGlzdGVuZXIoeyB0eXBlOiAnaW50ZXJvcC1icm9rZXInLCB0b3BpYzogJ2Rpc2Nvbm5lY3RlZCcsIGJyb2tlck5hbWU6IHV1aWQgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBnZXRGREMzU3luYyh2ZXJzaW9uKSB7XG5cdCAgICAgICAgc3dpdGNoICh2ZXJzaW9uKSB7XG5cdCAgICAgICAgICAgIGNhc2UgJzEuMic6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGZkYzNfMV8yXzEuRmRjM01vZHVsZSgoKSA9PiB0aGlzLCB0aGlzLndpcmUpO1xuXHQgICAgICAgICAgICBjYXNlICcyLjAnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBmZGMzXzJfMF8xLkZkYzNNb2R1bGUyKCgpID0+IHRoaXMsIHRoaXMud2lyZSk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgRkRDMyB2ZXJzaW9uIHByb3ZpZGVkOiAke3ZlcnNpb259LiBNdXN0IGJlICcxLjInIG9yICcyLjAnYCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgZ2V0RkRDMyh2ZXJzaW9uKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RkRDM1N5bmModmVyc2lvbik7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICpcblx0ICAgICAqIFVzZWQgdG8gZmVycnkgZmRjMy1vbmx5IGNhbGxzIGZyb20gdGhlIGZkYzMgc2hpbSB0byB0aGUgSW50ZXJvcCBCcm9rZXJcblx0ICAgICAqL1xuXHQgICAgc3RhdGljIGFzeW5jIGZlcnJ5RmRjM0NhbGwoaW50ZXJvcENsaWVudCwgYWN0aW9uLCBwYXlsb2FkKSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldChpbnRlcm9wQ2xpZW50LCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaChhY3Rpb24sIHBheWxvYWQgfHwgbnVsbCk7XG5cdCAgICB9XG5cdH07XG5cdEludGVyb3BDbGllbnQuSW50ZXJvcENsaWVudCA9IEludGVyb3BDbGllbnQkMTtcblx0X0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSA9IG5ldyBXZWFrTWFwKCksIF9JbnRlcm9wQ2xpZW50X3Nlc3Npb25Db250ZXh0R3JvdXBzID0gbmV3IFdlYWtNYXAoKTtcblx0cmV0dXJuIEludGVyb3BDbGllbnQ7XG59XG5cbnZhciBvdmVycmlkZUNoZWNrID0ge307XG5cbnZhciBoYXNSZXF1aXJlZE92ZXJyaWRlQ2hlY2s7XG5cbmZ1bmN0aW9uIHJlcXVpcmVPdmVycmlkZUNoZWNrICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkT3ZlcnJpZGVDaGVjaykgcmV0dXJuIG92ZXJyaWRlQ2hlY2s7XG5cdGhhc1JlcXVpcmVkT3ZlcnJpZGVDaGVjayA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvdmVycmlkZUNoZWNrLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0b3ZlcnJpZGVDaGVjay5vdmVycmlkZUNoZWNrID0gb3ZlcnJpZGVDaGVjay5jaGVja0ZEQzMyT3ZlcnJpZGVzID0gb3ZlcnJpZGVDaGVjay5nZXREZWZhdWx0Vmlld0ZkYzNWZXJzaW9uRnJvbUFwcEluZm8gPSB2b2lkIDA7XG5cdGNvbnN0IEludGVyb3BCcm9rZXJfMSA9IHJlcXVpcmVJbnRlcm9wQnJva2VyKCk7XG5cdGZ1bmN0aW9uIGdldERlZmF1bHRWaWV3RmRjM1ZlcnNpb25Gcm9tQXBwSW5mbyh7IG1hbmlmZXN0LCBpbml0aWFsT3B0aW9ucyB9KSB7XG5cdCAgICBjb25zdCBzZXRWZXJzaW9uID0gbWFuaWZlc3Q/LnBsYXRmb3JtPy5kZWZhdWx0Vmlld09wdGlvbnM/LmZkYzNJbnRlcm9wQXBpID8/IGluaXRpYWxPcHRpb25zLmRlZmF1bHRWaWV3T3B0aW9ucz8uZmRjM0ludGVyb3BBcGk7XG5cdCAgICByZXR1cm4gWycxLjInLCAnMi4wJ10uaW5jbHVkZXMoc2V0VmVyc2lvbiA/PyAnJykgPyBzZXRWZXJzaW9uIDogdW5kZWZpbmVkO1xuXHR9XG5cdG92ZXJyaWRlQ2hlY2suZ2V0RGVmYXVsdFZpZXdGZGMzVmVyc2lvbkZyb21BcHBJbmZvID0gZ2V0RGVmYXVsdFZpZXdGZGMzVmVyc2lvbkZyb21BcHBJbmZvO1xuXHRmdW5jdGlvbiBjaGVja0ZEQzMyT3ZlcnJpZGVzKG92ZXJyaWRkZW5Ccm9rZXIpIHtcblx0ICAgIC8vIFRoZXNlIGFyZSB0aGUgQVBJcyB0aGF0IG11c3QgYmUgb3ZlcnJpZGRlbiBmb3IgRkRDMyAyLjAgY29tcGxpYW5jZVxuXHQgICAgY29uc3QgbXVzdE92ZXJyaWRlQVBJcyA9IFtcblx0ICAgICAgICAnZmRjM0hhbmRsZUZpbmRJbnN0YW5jZXMnLFxuXHQgICAgICAgICdoYW5kbGVJbmZvRm9ySW50ZW50Jyxcblx0ICAgICAgICAnaGFuZGxlSW5mb0ZvckludGVudHNCeUNvbnRleHQnLFxuXHQgICAgICAgICdmZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEnLFxuXHQgICAgICAgICdmZGMzSGFuZGxlR2V0SW5mbycsXG5cdCAgICAgICAgJ2ZkYzNIYW5kbGVPcGVuJyxcblx0ICAgICAgICAnaGFuZGxlRmlyZWRJbnRlbnQnLFxuXHQgICAgICAgICdoYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQnXG5cdCAgICBdO1xuXHQgICAgcmV0dXJuIG11c3RPdmVycmlkZUFQSXMuZmlsdGVyKChhcGkpID0+IHtcblx0ICAgICAgICByZXR1cm4gb3ZlcnJpZGRlbkJyb2tlclthcGldID09PSBJbnRlcm9wQnJva2VyXzEuSW50ZXJvcEJyb2tlci5wcm90b3R5cGVbYXBpXTtcblx0ICAgIH0pO1xuXHR9XG5cdG92ZXJyaWRlQ2hlY2suY2hlY2tGREMzMk92ZXJyaWRlcyA9IGNoZWNrRkRDMzJPdmVycmlkZXM7XG5cdGZ1bmN0aW9uIG92ZXJyaWRlQ2hlY2skMShvdmVycmlkZGVuQnJva2VyLCBmZGMzSW50ZXJvcEFwaSkge1xuXHQgICAgaWYgKGZkYzNJbnRlcm9wQXBpICYmIGZkYzNJbnRlcm9wQXBpID09PSAnMi4wJykge1xuXHQgICAgICAgIGNvbnN0IG5vdE92ZXJyaWRkZW4gPSBjaGVja0ZEQzMyT3ZlcnJpZGVzKG92ZXJyaWRkZW5Ccm9rZXIpO1xuXHQgICAgICAgIGlmIChub3RPdmVycmlkZGVuLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKGBXQVJOSU5HOiBGREMzIDIuMCBoYXMgYmVlbiBzZXQgYXMgYSBkZWZhdWx0IG9wdGlvbiBmb3IgVmlld3MgaW4gdGhpcyBQbGF0Zm9ybSwgYnV0IHRoZSByZXF1aXJlZCBJbnRlcm9wQnJva2VyIEFQSXMgZm9yIEZEQzMgMi4wIGNvbXBsaWFuY2UgaGF2ZSBub3QgYWxsIGJlZW4gb3ZlcnJpZGRlbi5cXG5UaGUgZm9sbG93aW5nIEFQSXMgbmVlZCB0byBiZSBvdmVycmlkZGVuOlxcbiR7bm90T3ZlcnJpZGRlbi5qb2luKCdcXG4nKX1gKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdH1cblx0b3ZlcnJpZGVDaGVjay5vdmVycmlkZUNoZWNrID0gb3ZlcnJpZGVDaGVjayQxO1xuXHRyZXR1cm4gb3ZlcnJpZGVDaGVjaztcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeTtcblxuZnVuY3Rpb24gcmVxdWlyZUZhY3RvcnkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGYWN0b3J5KSByZXR1cm4gRmFjdG9yeSQxO1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkgPSAxO1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDEuSW50ZXJvcE1vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgY2xvbmVEZWVwXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMCQxKTtcblx0Y29uc3QgaW5hY2Nlc3NpYmxlT2JqZWN0XzEgPSBpbmFjY2Vzc2libGVPYmplY3Q7XG5cdGNvbnN0IGJhc2VfMSA9IGJhc2U7XG5cdGNvbnN0IEludGVyb3BCcm9rZXJfMSA9IHJlcXVpcmVJbnRlcm9wQnJva2VyKCk7XG5cdGNvbnN0IEludGVyb3BDbGllbnRfMSA9IHJlcXVpcmVJbnRlcm9wQ2xpZW50KCk7XG5cdGNvbnN0IG92ZXJyaWRlQ2hlY2tfMSA9IHJlcXVpcmVPdmVycmlkZUNoZWNrKCk7XG5cdGNvbnN0IGNvbW1vbl91dGlsc18xID0gY29tbW9uVXRpbHM7XG5cdGNvbnN0IGRlZmF1bHRPdmVycmlkZSA9IChDbGFzcykgPT4gbmV3IENsYXNzKCk7XG5cdGNvbnN0IEJyb2tlclBhcmFtQWNjZXNzRXJyb3IgPSAnWW91IGhhdmUgYXR0ZW1wdGVkIHRvIHVzZSBvciBtb2RpZnkgSW50ZXJvcEJyb2tlciBwYXJhbWV0ZXJzLCB3aGljaCBpcyBub3QgYWxsb3dlZC4gWW91IGFyZSBsaWtlbHkgdXNpbmcgYW4gb2xkZXIgSW50ZXJvcEJyb2tlciBvdmVycmlkZSBzY2hlbWUuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nO1xuXHQvKipcblx0ICogTWFuYWdlcyBjcmVhdGlvbiBvZiBJbnRlcm9wIEJyb2tlcnMgYW5kIEludGVyb3AgQ2xpZW50cy4gVGhlc2UgQVBJcyBhcmUgY2FsbGVkIHVuZGVyLXRoZS1ob29kIGluIFBsYXRmb3Jtcy5cblx0ICpcblx0ICovXG5cdGNsYXNzIEludGVyb3BNb2R1bGUgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEluaXRpYWxpemVzIGFuIEludGVyb3AgQnJva2VyLiBUaGlzIGlzIGNhbGxlZCB1bmRlci10aGUtaG9vZCBmb3IgUGxhdGZvcm1zLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIEZvciBQbGF0Zm9ybXMsIHRoaXMgaXMgc2V0IHVwIGF1dG9tYXRpY2FsbHkuIFdlIGFkdmlzZSB0byBvbmx5IGNyZWF0ZSB5b3VyIG93biBJbnRlcm9wIEJyb2tlclxuXHQgICAgICogd2hlbiBub3QgdXNpbmcgYSBQbGF0Zm9ybSBhcHAuIFlvdSBjYW4gb3ZlcnJpZGUgZnVuY3Rpb25zIGluIHRoZSBJbnRlcm9wIEJyb2tlci4gTW9yZSBpbmZvIHtAbGluayBJbnRlcm9wQnJva2VyIGhlcmV9LlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBuYW1lIC0gTmFtZSBvZiB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKiBAcGFyYW0gb3ZlcnJpZGUgLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGNhbGxiYWNrIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGV4dGVuZCBvciByZXBsYWNlIGRlZmF1bHQgSW50ZXJvcCBCcm9rZXIgYmVoYXZpb3IuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYCBqc1xuXHQgICAgICogY29uc3QgaW50ZXJvcEJyb2tlciA9IGF3YWl0IGZpbi5JbnRlcm9wLmluaXQoJ29wZW5maW4nKTtcblx0ICAgICAqIGNvbnN0IGNvbnRleHRHcm91cHMgPSBhd2FpdCBpbnRlcm9wQnJva2VyLmdldENvbnRleHRHcm91cHMoKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKGNvbnRleHRHcm91cHMpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGluaXQobmFtZSwgb3ZlcnJpZGUgPSBkZWZhdWx0T3ZlcnJpZGUpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1pbml0JykuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvLyBBbGxvd3MgZm9yIG1hbmlmZXN0LWxldmVsIGNvbmZpZ3VyYXRpb24sIHdpdGhvdXQgaGF2aW5nIHRvIG92ZXJyaWRlLiAoZS5nLiBzcGVjaWZ5aW5nIGN1c3RvbSBjb250ZXh0IGdyb3Vwcylcblx0ICAgICAgICBjb25zdCBvcHRpb25zID0gYXdhaXQgdGhpcy53aXJlLmVudmlyb25tZW50LmdldEludGVyb3BJbmZvKHRoaXMud2lyZS5nZXRGaW4oKSk7XG5cdCAgICAgICAgY29uc3Qgb2JqZWN0VGhhdFRocm93cyA9ICgwLCBpbmFjY2Vzc2libGVPYmplY3RfMS5jcmVhdGVVbnVzYWJsZU9iamVjdCkoQnJva2VyUGFyYW1BY2Nlc3NFcnJvcik7XG5cdCAgICAgICAgY29uc3Qgd2FybmluZ09wdHNDbG9uZSA9ICgwLCBpbmFjY2Vzc2libGVPYmplY3RfMS5jcmVhdGVXYXJuaW5nT2JqZWN0KShCcm9rZXJQYXJhbUFjY2Vzc0Vycm9yLCAoMCwgY2xvbmVEZWVwXzEuZGVmYXVsdCkob3B0aW9ucykpO1xuXHQgICAgICAgIGNvbnN0IGdldFByb3ZpZGVyID0gKCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShgaW50ZXJvcC1icm9rZXItJHtuYW1lfWApO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgdGhyb3dpbmdHZXRQcm92aWRlciA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEJyb2tlclBhcmFtQWNjZXNzRXJyb3IpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgT3ZlcnJpZGVhYmxlQnJva2VyID0gSW50ZXJvcEJyb2tlcl8xLkludGVyb3BCcm9rZXIuY3JlYXRlQ2xvc2VkQ29uc3RydWN0b3IodGhpcy53aXJlLCBnZXRQcm92aWRlciwgb3B0aW9ucyk7XG5cdCAgICAgICAgbGV0IGJyb2tlcjtcblx0ICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvdmVycmlkZSkpIHtcblx0ICAgICAgICAgICAgY29uc3QgQnJva2VyQ29uc3RydWN0b3IgPSAoMCwgY29tbW9uX3V0aWxzXzEub3ZlcnJpZGVGcm9tQ29tcG9zYWJsZXMpKC4uLm92ZXJyaWRlKShPdmVycmlkZWFibGVCcm9rZXIpO1xuXHQgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHVzZSB0aGVzZSBvYmplY3RzIGJlY2F1c2UgcmVtb3ZpbmcgdGhlbSBlbnRpcmVseSB3b3VsZCBiZSBhIGJyZWFraW5nIGNoYW5nZSBhbmQgd2Ugd2FudCBhbiBpbmZvcm1hdGl2ZSBlcnJvclxuXHQgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG5cdCAgICAgICAgICAgIGJyb2tlciA9IG5ldyBCcm9rZXJDb25zdHJ1Y3RvcihvYmplY3RUaGF0VGhyb3dzLCB0aHJvd2luZ0dldFByb3ZpZGVyLCB3YXJuaW5nT3B0c0Nsb25lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gdXNlIHRoZXNlIG9iamVjdHMgYmVjYXVzZSByZW1vdmluZyB0aGVtIGVudGlyZWx5IHdvdWxkIGJlIGEgYnJlYWtpbmcgY2hhbmdlIGFuZCB3ZSB3YW50IGFuIGluZm9ybWF0aXZlIGVycm9yXG5cdCAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3Jcblx0ICAgICAgICAgICAgYnJva2VyID0gYXdhaXQgb3ZlcnJpZGUoT3ZlcnJpZGVhYmxlQnJva2VyLCBvYmplY3RUaGF0VGhyb3dzLCB0aHJvd2luZ0dldFByb3ZpZGVyLCB3YXJuaW5nT3B0c0Nsb25lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgKDAsIG92ZXJyaWRlQ2hlY2tfMS5vdmVycmlkZUNoZWNrKShicm9rZXIsIG9wdGlvbnMuZmRjM1ZlcnNpb24pO1xuXHQgICAgICAgIHJldHVybiBicm9rZXI7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENvbm5lY3RzIGEgY2xpZW50IHRvIGFuIEludGVyb3AgYnJva2VyLiBUaGlzIGlzIGNhbGxlZCB1bmRlci10aGUtaG9vZCBmb3IgVmlld3MgaW4gYSBQbGF0Zm9ybS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrc1xuXHQgICAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgSW50ZXJvcCBCcm9rZXIgdG8gY29ubmVjdCB0by4gRm9yIFBsYXRmb3JtcywgdGhpcyB3aWxsIGRlZmF1bHQgdG8gdGhlIHV1aWQgb2YgdGhlIFBsYXRmb3JtLlxuXHQgICAgICogQHBhcmFtIGludGVyb3BDb25maWcgLSBJbmZvcm1hdGlvbiByZWxldmFudCB0byB0aGUgSW50ZXJvcCBCcm9rZXIuIFR5cGljYWxseSBhIGRlY2xhcmF0aW9uIG9mXG5cdCAgICAgKiB3aGF0IGNvbnRleHQocykgdGhlIGVudGl0eSB3YW50cyB0byBzdWJzY3JpYmUgdG8sIGFuZCB0aGUgY3VycmVudCBDb250ZXh0IEdyb3VwIG9mIHRoZSBlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBpbnRlcm9wQ29uZmlnID0ge1xuXHQgICAgICogICAgIGN1cnJlbnRDb250ZXh0R3JvdXA6ICdncmVlbidcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjb25zdCBpbnRlcm9wQnJva2VyID0gYXdhaXQgZmluLkludGVyb3AuaW5pdCgnb3BlbmZpbicpO1xuXHQgICAgICogY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyb3AuY29ubmVjdFN5bmMoJ29wZW5maW4nLCBpbnRlcm9wQ29uZmlnKTtcblx0ICAgICAqIGNvbnN0IGNvbnRleHRHcm91cEluZm8gPSBhd2FpdCBjbGllbnQuZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpO1xuXHQgICAgICogY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mbyk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY29ubmVjdFN5bmMobmFtZSwgaW50ZXJvcENvbmZpZykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNvbm5lY3Qtc3luYycpLmNhdGNoKCgpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm9wQ2xpZW50XzEuSW50ZXJvcENsaWVudCh0aGlzLndpcmUsIHRoaXMud2lyZS5lbnZpcm9ubWVudC53aGVuUmVhZHkoKS50aGVuKCgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGBpbnRlcm9wLWJyb2tlci0ke25hbWV9YCwge1xuXHQgICAgICAgICAgICAgICAgcGF5bG9hZDogaW50ZXJvcENvbmZpZ1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9KSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQxLkludGVyb3BNb2R1bGUgPSBJbnRlcm9wTW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQxO1xufVxuXG52YXIgaGFzUmVxdWlyZWRJbnRlcm9wO1xuXG5mdW5jdGlvbiByZXF1aXJlSW50ZXJvcCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEludGVyb3ApIHJldHVybiBpbnRlcm9wO1xuXHRoYXNSZXF1aXJlZEludGVyb3AgPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYEludGVyb3BgIEFQSSAoYGZpbi5JbnRlcm9wYCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBJbnRlcm9wTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEludGVyb3BgIEFQSSAoYXZhaWxhYmxlIHVuZGVyIGBmaW4uSW50ZXJvcGApXG5cdFx0ICogKiB7QGxpbmsgSW50ZXJvcENsaWVudH0gYW5kIHtAbGluayBJbnRlcm9wQnJva2VyfSBkb2N1bWVudCBpbnN0YW5jZXMgb2YgdGhlaXIgcmVzcGVjdGl2ZSBjbGFzc2VzLlxuXHRcdCAqXG5cdFx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdFx0ICovXG5cdFx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdFx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdFx0ICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcblx0XHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0XHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHRcdCAgICB9XG5cdFx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdFx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgb1trMl0gPSBtW2tdO1xuXHRcdH0pKTtcblx0XHR2YXIgX19leHBvcnRTdGFyID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fZXhwb3J0U3RhcikgfHwgZnVuY3Rpb24obSwgZXhwb3J0cykge1xuXHRcdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdFx0fTtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFx0X19leHBvcnRTdGFyKHJlcXVpcmVGYWN0b3J5KCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW50ZXJvcENsaWVudCgpLCBleHBvcnRzKTtcblx0XHRfX2V4cG9ydFN0YXIocmVxdWlyZUludGVyb3BCcm9rZXIoKSwgZXhwb3J0cyk7IFxuXHR9IChpbnRlcm9wKSk7XG5cdHJldHVybiBpbnRlcm9wO1xufVxuXG52YXIgc25hcHNob3RTb3VyY2UgPSB7fTtcblxudmFyIEZhY3RvcnkgPSB7fTtcblxudmFyIEluc3RhbmNlID0ge307XG5cbnZhciB1dGlscyA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodXRpbHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudXRpbHMuZ2V0U25hcHNob3RTb3VyY2VDaGFubmVsTmFtZSA9IHZvaWQgMDtcbmNvbnN0IGNoYW5uZWxQcmVmaXggPSAnc25hcHNob3Qtc291cmNlLXByb3ZpZGVyLSc7XG5jb25zdCBnZXRTbmFwc2hvdFNvdXJjZUNoYW5uZWxOYW1lID0gKGlkKSA9PiBgJHtjaGFubmVsUHJlZml4fSR7aWQudXVpZH1gO1xudXRpbHMuZ2V0U25hcHNob3RTb3VyY2VDaGFubmVsTmFtZSA9IGdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWU7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9TbmFwc2hvdFNvdXJjZV9pZGVudGl0eSwgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIF9TbmFwc2hvdFNvdXJjZV9nZXRDbGllbnQsIF9TbmFwc2hvdFNvdXJjZV9zdGFydENvbm5lY3Rpb24sIF9TbmFwc2hvdFNvdXJjZV9zZXRVcENvbm5lY3Rpb25MaXN0ZW5lcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZS5TbmFwc2hvdFNvdXJjZSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cbmNvbnN0IGJhc2VfMSQxID0gYmFzZTtcbmNvbnN0IHV0aWxzXzEkMSA9IHV0aWxzO1xuY29uc3QgY29ubmVjdGlvbk1hcCA9IG5ldyBNYXAoKTtcbi8qKlxuICogRW5hYmxlcyBjb25maWd1cmluZyBhIFNuYXBzaG90U291cmNlIHdpdGggY3VzdG9tIGdldFNuYXBzaG90IGFuZCBhcHBseVNuYXBzaG90IG1ldGhvZHMuXG4gKlxuICogQHR5cGVQYXJhbSBTbmFwc2hvdCBJbXBsZW1lbnRhdGlvbi1kZWZpbmVkIHNoYXBlIG9mIGFuIGFwcGxpY2F0aW9uIHNuYXBzaG90LiAgQWxsb3dzXG4gKiBjdXN0b20gc25hcHNob3QgaW1wbGVtZW50YXRpb25zIGZvciBsZWdhY3kgYXBwbGljYXRpb25zIHRvIGRlZmluZSB0aGVpciBvd24gc25hcHNob3QgZm9ybWF0LlxuICovXG5jbGFzcyBTbmFwc2hvdFNvdXJjZSBleHRlbmRzIGJhc2VfMSQxLkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIGlkKSB7XG4gICAgICAgIHN1cGVyKHdpcmUpO1xuICAgICAgICBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHkuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWNvbm5lY3Rpb25NYXAuaGFzKHRoaXMuaWRlbnRpdHkudXVpZCkpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uTWFwLnNldCh0aGlzLmlkZW50aXR5LnV1aWQsIHsgZXZlbnRGaXJlZDogbnVsbCwgY2xpZW50UHJvbWlzZTogbnVsbCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb25uZWN0aW9uTWFwLmdldCh0aGlzLmlkZW50aXR5LnV1aWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgX1NuYXBzaG90U291cmNlX2dldENsaWVudC5zZXQodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmNsaWVudFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmNsaWVudFByb21pc2UgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLCBcImZcIikuY2FsbCh0aGlzKS5jbGllbnRQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbi5zZXQodGhpcywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSAoMCwgdXRpbHNfMSQxLmdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWUpKHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX3NldFVwQ29ubmVjdGlvbkxpc3RlbmVyLCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbE5hbWUsIHsgd2FpdDogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgY2xpZW50Lm9uRGlzY29ubmVjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuY2xpZW50UHJvbWlzZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLCBcImZcIikuY2FsbCh0aGlzKS5jbGllbnRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgdGFyZ2V0ZWQgU25hcHNob3RTb3VyY2UgaXMgbm90IGN1cnJlbnRseSBpbml0aWFsaXplZC4gQXdhaXQgdGhpcyBvYmplY3QncyByZWFkeSgpIG1ldGhvZC5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfU25hcHNob3RTb3VyY2Vfc2V0VXBDb25uZWN0aW9uTGlzdGVuZXIuc2V0KHRoaXMsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gKDAsIHV0aWxzXzEkMS5nZXRTbmFwc2hvdFNvdXJjZUNoYW5uZWxOYW1lKSh0aGlzLmlkZW50aXR5KTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlO1xuICAgICAgICAgICAgbGV0IHJlamVjdDtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RmlyZWQgPSBuZXcgUHJvbWlzZSgoeSwgbikgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUgPSB5O1xuICAgICAgICAgICAgICAgIHJlamVjdCA9IG47XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCA9IGV2ZW50RmlyZWQ7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUuY2hhbm5lbE5hbWUgPT09IGNoYW5uZWxOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwucmVtb3ZlTGlzdGVuZXIoJ2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwub24oJ2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHksIGlkLCBcImZcIik7XG4gICAgfVxuICAgIGdldCBpZGVudGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHksIFwiZlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRvIGRldGVybWluZSBpZiB0aGUgU25hcHNob3RTb3VyY2UgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBVc2Ugd2hlbiB0aGUgcGFyZW50IGFwcGxpY2F0aW9uIGlzIHN0YXJ0aW5nIHVwIHRvIGVuc3VyZSB0aGUgU25hcHNob3RTb3VyY2UgaXMgYWJsZSB0byBhY2NlcHQgYW5kXG4gICAgICogYXBwbHkgYSBzbmFwc2hvdCB1c2luZyB0aGUge0BsaW5rIFNuYXBzaG90U291cmNlI2FwcGx5U25hcHNob3QgYXBwbHlTbmFwc2hvdH0gbWV0aG9kLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCBzbmFwc2hvdFNvdXJjZSA9IGZpbi5TbmFwc2hvdFNvdXJjZS53cmFwU3luYyhmaW4ubWUpO1xuICAgICAqXG4gICAgICogY29uc3Qgc25hcHNob3RQcm92aWRlciA9IHtcbiAgICAgKiAgICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7IHJldHVybiAnZm9vJyB9LFxuICAgICAqICAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICogICAgICAgY29uc29sZS5sb2coc25hcHNob3QpO1xuICAgICAqICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICogICAgIH1cbiAgICAgKiB9XG4gICAgICogYXdhaXQgZmluLlNuYXBzaG90U291cmNlLmluaXQoc25hcHNob3RQcm92aWRlcik7XG4gICAgICpcbiAgICAgKiB0cnkge1xuICAgICAqICAgYXdhaXQgc25hcHNob3RTb3VyY2UucmVhZHkoKTtcbiAgICAgKiAgIGF3YWl0IHNuYXBzaG90U291cmNlLmFwcGx5U25hcHNob3QoJ2ZvbycpO1xuICAgICAqIH0gY2F0Y2ggKGVycikge1xuICAgICAqICAgY29uc29sZS5sb2coZXJyKVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyByZWFkeSgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NuYXBzaG90LXNvdXJjZS1yZWFkeScpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBJZiBnZXRDbGllbnQgd2FzIGFscmVhZHkgY2FsbGVkIGJlZm9yZSB0aGlzLCBkbyB3ZSBoYXZlIGEgdGltaW5nIGlzc3VlIHdoZXJlIHRoZSBjaGFubmVsIG1pZ2h0IGhhdmUgYmVlbiBjcmVhdGVkIGJ1dCB3ZSBtaXNzZWQgdGhlIGV2ZW50IGJ1dCB0aGlzIHN0aWxsIGZhaWxzP1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDbGllbnQsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBpdCB3YXMgbm90IHJ1bm5pbmcuXG4gICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmV2ZW50RmlyZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbCB0aGUgU25hcHNob3RTb3VyY2UncyBnZXRTbmFwc2hvdCBtZXRob2QgZGVmaW5lZCBieSB7QGxpbmsgU25hcHNob3RTb3VyY2UuU25hcHNob3RTb3VyY2VNb2R1bGUjaW5pdCBpbml0fS5cbiAgICAgKlxuICAgICAqL1xuICAgIGFzeW5jIGdldFNuYXBzaG90KCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLWdldC1zbmFwc2hvdCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q2xpZW50LCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdnZXQtc25hcHNob3QnKSk7XG4gICAgICAgIHJldHVybiAoYXdhaXQgcmVzcG9uc2UpLnNuYXBzaG90O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoZSBTbmFwc2hvdFNvdXJjZSdzIGFwcGx5U25hcHNob3QgbWV0aG9kIGRlZmluZWQgYnkge0BsaW5rIFNuYXBzaG90U291cmNlLlNuYXBzaG90U291cmNlTW9kdWxlI2luaXQgaW5pdH0uXG4gICAgICpcbiAgICAgKi9cbiAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzbmFwc2hvdC1zb3VyY2UtYXBwbHktc25hcHNob3QnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENsaWVudCwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2FwcGx5LXNuYXBzaG90JywgeyBzbmFwc2hvdCB9KTtcbiAgICB9XG59XG5JbnN0YW5jZS5TbmFwc2hvdFNvdXJjZSA9IFNuYXBzaG90U291cmNlO1xuX1NuYXBzaG90U291cmNlX2lkZW50aXR5ID0gbmV3IFdlYWtNYXAoKSwgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24gPSBuZXcgV2Vha01hcCgpLCBfU25hcHNob3RTb3VyY2VfZ2V0Q2xpZW50ID0gbmV3IFdlYWtNYXAoKSwgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9TbmFwc2hvdFNvdXJjZV9zZXRVcENvbm5lY3Rpb25MaXN0ZW5lciA9IG5ldyBXZWFrTWFwKCk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbkZhY3RvcnkuU25hcHNob3RTb3VyY2VNb2R1bGUgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEgPSBiYXNlO1xuY29uc3QgSW5zdGFuY2VfMSA9IEluc3RhbmNlO1xuY29uc3QgdXRpbHNfMSA9IHV0aWxzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIFNuYXBzaG90U291cmNlfSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uU25hcHNob3RTb3VyY2VgLlxuICovXG5jbGFzcyBTbmFwc2hvdFNvdXJjZU1vZHVsZSBleHRlbmRzIGJhc2VfMS5CYXNlIHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhIFNuYXBzaG90U291cmNlIHdpdGggdGhlIGdldFNuYXBzaG90IGFuZCBhcHBseVNuYXBzaG90IG1ldGhvZHMgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIEB0eXBlUGFyYW0gU25hcHNob3QgSW1wbGVtZW50YXRpb24tZGVmaW5lZCBzaGFwZSBvZiBhbiBhcHBsaWNhdGlvbiBzbmFwc2hvdC4gIEFsbG93c1xuICAgICAqIGN1c3RvbSBzbmFwc2hvdCBpbXBsZW1lbnRhdGlvbnMgZm9yIGxlZ2FjeSBhcHBsaWNhdGlvbnMgdG8gZGVmaW5lIHRoZWlyIG93biBzbmFwc2hvdCBmb3JtYXQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgc25hcHNob3RQcm92aWRlciA9IHtcbiAgICAgKiAgICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7XG4gICAgICogICAgICAgY29uc3QgYm91bmRzID0gYXdhaXQgZmluLm1lLmdldEJvdW5kcygpO1xuICAgICAqICAgICAgIHJldHVybiBib3VuZHM7XG4gICAgICogICAgICB9LFxuICAgICAqICAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICogICAgICAgYXdhaXQgZmluLm1lLnNldEJvdW5kcyhzbmFwc2hvdCk7XG4gICAgICogICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgKiAgICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGF3YWl0IGZpbi5TbmFwc2hvdFNvdXJjZS5pbml0KHNuYXBzaG90UHJvdmlkZXIpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICovXG4gICAgYXN5bmMgaW5pdChwcm92aWRlcikge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLWluaXQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZW9mIHByb3ZpZGVyICE9PSAnb2JqZWN0JyB8fFxuICAgICAgICAgICAgdHlwZW9mIHByb3ZpZGVyLmdldFNuYXBzaG90ICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICAgICB0eXBlb2YgcHJvdmlkZXIuYXBwbHlTbmFwc2hvdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd5b3UgbXVzdCBwYXNzIGluIGEgdmFsaWQgU25hcHNob3RQcm92aWRlcicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCgwLCB1dGlsc18xLmdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWUpKHRoaXMuZmluLm1lKSk7XG4gICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldC1zbmFwc2hvdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcHJvdmlkZXIuZ2V0U25hcHNob3QoKTtcbiAgICAgICAgICAgIHJldHVybiB7IHNuYXBzaG90IH07XG4gICAgICAgIH0pO1xuICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdhcHBseS1zbmFwc2hvdCcsICh7IHNuYXBzaG90IH0pID0+IHByb3ZpZGVyLmFwcGx5U25hcHNob3Qoc25hcHNob3QpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgU25hcHNob3RTb3VyY2Ugb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBTbmFwc2hvdFNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBzbmFwc2hvdFNvdXJjZSA9IGZpbi5TbmFwc2hvdFNvdXJjZS53cmFwU3luYyhmaW4ubWUpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlJ3MgZ2V0U25hcHNob3QgbWV0aG9kLCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc25hcHNob3RTb3VyY2UuZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLXdyYXAtc3luYycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMS5TbmFwc2hvdFNvdXJjZSh0aGlzLndpcmUsIGlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIFNuYXBzaG90U291cmNlIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgU25hcHNob3RTb3VyY2UuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgc25hcHNob3RTb3VyY2UgPSBhd2FpdCBmaW4uU25hcHNob3RTb3VyY2Uud3JhcChmaW4ubWUpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlJ3MgZ2V0U25hcHNob3QgbWV0aG9kLCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc25hcHNob3RTb3VyY2UuZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cmFwKGlkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzbmFwc2hvdC1zb3VyY2Utd3JhcCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBTeW5jKGlkZW50aXR5KTtcbiAgICB9XG59XG5GYWN0b3J5LlNuYXBzaG90U291cmNlTW9kdWxlID0gU25hcHNob3RTb3VyY2VNb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgU25hcHNob3RTb3VyY2VgIEFQSSAoYGZpbi5TbmFwc2hvdFNvdXJjZWApLlxuXHQgKlxuXHQgKiAqIHtAbGluayBTbmFwc2hvdFNvdXJjZU1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBTbmFwc2hvdFNvdXJjZWAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5TbmFwc2hvdFNvdXJjZWAuXG5cdCAqICoge0BsaW5rIFNuYXBzaG90U291cmNlfSBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gT3BlbkZpbiBTbmFwc2hvdFNvdXJjZSwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlNuYXBzaG90U291cmNlLndyYXBgLlxuXHQgKlxuXHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnksIGV4cG9ydHMpO1xuXHRfX2V4cG9ydFN0YXIoSW5zdGFuY2UsIGV4cG9ydHMpOyBcbn0gKHNuYXBzaG90U291cmNlKSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShmaW4kMiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRmluXzEgPSBmaW4kMi5GaW4gPSB2b2lkIDA7XG5jb25zdCBldmVudHNfMSQzID0gcmVxdWlyZSQkMDtcbi8vIEltcG9ydCBmcm9tIHRoZSBmaWxlIHJhdGhlciB0aGFuIHRoZSBkaXJlY3RvcnkgaW4gY2FzZSBzb21lb25lIGNvbnN1bWluZyB0eXBlcyBpcyB1c2luZyBtb2R1bGUgcmVzb2x1dGlvbiBvdGhlciB0aGFuIFwibm9kZVwiXG5jb25zdCBpbmRleF8xID0gc3lzdGVtO1xuY29uc3QgaW5kZXhfMiA9IHJlcXVpcmVXaW5kb3coKTtcbmNvbnN0IGluZGV4XzMgPSByZXF1aXJlQXBwbGljYXRpb24oKTtcbmNvbnN0IGluZGV4XzQgPSBpbnRlcmFwcGJ1cztcbmNvbnN0IGluZGV4XzUgPSBjbGlwYm9hcmQ7XG5jb25zdCBpbmRleF82ID0gZXh0ZXJuYWxBcHBsaWNhdGlvbjtcbmNvbnN0IGluZGV4XzcgPSBmcmFtZTtcbmNvbnN0IGluZGV4XzggPSBnbG9iYWxIb3RrZXk7XG5jb25zdCBpbmRleF85ID0gcmVxdWlyZVZpZXcoKTtcbmNvbnN0IGluZGV4XzEwID0gcGxhdGZvcm07XG5jb25zdCBtZV8xJDIgPSBtZTtcbmNvbnN0IGludGVyb3BfMSA9IHJlcXVpcmVJbnRlcm9wKCk7XG5jb25zdCBzbmFwc2hvdF9zb3VyY2VfMSA9IHNuYXBzaG90U291cmNlO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgRmluIGV4dGVuZHMgZXZlbnRzXzEkMy5FdmVudEVtaXR0ZXIge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy53aXJlID0gd2lyZTtcbiAgICAgICAgdGhpcy5TeXN0ZW0gPSBuZXcgaW5kZXhfMS5TeXN0ZW0od2lyZSk7XG4gICAgICAgIHRoaXMuV2luZG93ID0gbmV3IGluZGV4XzIuX1dpbmRvd01vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5BcHBsaWNhdGlvbiA9IG5ldyBpbmRleF8zLkFwcGxpY2F0aW9uTW9kdWxlKHdpcmUpO1xuICAgICAgICB0aGlzLkludGVyQXBwbGljYXRpb25CdXMgPSBuZXcgaW5kZXhfNC5JbnRlckFwcGxpY2F0aW9uQnVzKHdpcmUpO1xuICAgICAgICB0aGlzLkNsaXBib2FyZCA9IG5ldyBpbmRleF81LkNsaXBib2FyZCh3aXJlKTtcbiAgICAgICAgdGhpcy5FeHRlcm5hbEFwcGxpY2F0aW9uID0gbmV3IGluZGV4XzYuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5GcmFtZSA9IG5ldyBpbmRleF83Ll9GcmFtZU1vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5HbG9iYWxIb3RrZXkgPSBuZXcgaW5kZXhfOC5HbG9iYWxIb3RrZXkod2lyZSk7XG4gICAgICAgIHRoaXMuUGxhdGZvcm0gPSBuZXcgaW5kZXhfMTAuUGxhdGZvcm1Nb2R1bGUod2lyZSwgdGhpcy5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwpO1xuICAgICAgICB0aGlzLlZpZXcgPSBuZXcgaW5kZXhfOS5WaWV3TW9kdWxlKHdpcmUpO1xuICAgICAgICB0aGlzLkludGVyb3AgPSBuZXcgaW50ZXJvcF8xLkludGVyb3BNb2R1bGUod2lyZSk7XG4gICAgICAgIHRoaXMuU25hcHNob3RTb3VyY2UgPSBuZXcgc25hcHNob3Rfc291cmNlXzEuU25hcHNob3RTb3VyY2VNb2R1bGUod2lyZSk7XG4gICAgICAgIHdpcmUucmVnaXN0ZXJGaW4odGhpcyk7XG4gICAgICAgIHRoaXMubWUgPSAoMCwgbWVfMSQyLmdldE1lKSh3aXJlKTtcbiAgICAgICAgLy8gSGFuZGxlIGRpc2Nvbm5lY3QgZXZlbnRzXG4gICAgICAgIHdpcmUub24oJ2Rpc2Nvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdGVkJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbkZpbl8xID0gZmluJDIuRmluID0gRmluO1xuXG52YXIgdHJhbnNwb3J0ID0ge307XG5cbnZhciB3aXJlID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aXJlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbndpcmUuaXNJbnRlcm5hbENvbm5lY3RDb25maWcgPSB3aXJlLmlzUG9ydERpc2NvdmVyeUNvbmZpZyA9IHdpcmUuaXNOZXdDb25uZWN0Q29uZmlnID0gd2lyZS5pc0NvbmZpZ1dpdGhSZWNlaXZlciA9IHdpcmUuaXNSZW1vdGVDb25maWcgPSB3aXJlLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnID0gd2lyZS5pc0V4dGVybmFsQ29uZmlnID0gdm9pZCAwO1xuZnVuY3Rpb24gaXNFeHRlcm5hbENvbmZpZyhjb25maWcpIHtcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5tYW5pZmVzdFVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbndpcmUuaXNFeHRlcm5hbENvbmZpZyA9IGlzRXh0ZXJuYWxDb25maWc7XG5mdW5jdGlvbiBpc0V4aXN0aW5nQ29ubmVjdENvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaGFzVXVpZChjb25maWcpICYmIHR5cGVvZiBjb25maWcuYWRkcmVzcyA9PT0gJ3N0cmluZyc7XG59XG53aXJlLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnID0gaXNFeGlzdGluZ0Nvbm5lY3RDb25maWc7XG5mdW5jdGlvbiBpc1JlbW90ZUNvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaXNFeGlzdGluZ0Nvbm5lY3RDb25maWcoY29uZmlnKSAmJiB0eXBlb2YgY29uZmlnLnRva2VuID09PSAnc3RyaW5nJztcbn1cbndpcmUuaXNSZW1vdGVDb25maWcgPSBpc1JlbW90ZUNvbmZpZztcbmZ1bmN0aW9uIGlzQ29uZmlnV2l0aFJlY2VpdmVyKGNvbmZpZykge1xuICAgIHJldHVybiB0eXBlb2YgY29uZmlnLnJlY2VpdmVyID09PSAnb2JqZWN0JyAmJiBpc1JlbW90ZUNvbmZpZyh7IC4uLmNvbmZpZywgYWRkcmVzczogJycgfSk7XG59XG53aXJlLmlzQ29uZmlnV2l0aFJlY2VpdmVyID0gaXNDb25maWdXaXRoUmVjZWl2ZXI7XG5mdW5jdGlvbiBoYXNVdWlkKGNvbmZpZykge1xuICAgIHJldHVybiB0eXBlb2YgY29uZmlnLnV1aWQgPT09ICdzdHJpbmcnO1xufVxuZnVuY3Rpb24gaGFzUnVudGltZVZlcnNpb24oY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ydW50aW1lICYmIHR5cGVvZiBjb25maWcucnVudGltZS52ZXJzaW9uID09PSAnc3RyaW5nJztcbn1cbmZ1bmN0aW9uIGlzTmV3Q29ubmVjdENvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaGFzVXVpZChjb25maWcpICYmIGhhc1J1bnRpbWVWZXJzaW9uKGNvbmZpZyk7XG59XG53aXJlLmlzTmV3Q29ubmVjdENvbmZpZyA9IGlzTmV3Q29ubmVjdENvbmZpZztcbmZ1bmN0aW9uIGlzUG9ydERpc2NvdmVyeUNvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gKGlzRXh0ZXJuYWxDb25maWcoY29uZmlnKSAmJiBoYXNSdW50aW1lVmVyc2lvbihjb25maWcpKSB8fCBpc05ld0Nvbm5lY3RDb25maWcoY29uZmlnKTtcbn1cbndpcmUuaXNQb3J0RGlzY292ZXJ5Q29uZmlnID0gaXNQb3J0RGlzY292ZXJ5Q29uZmlnO1xuZnVuY3Rpb24gaXNJbnRlcm5hbENvbm5lY3RDb25maWcoY29uZmlnKSB7XG4gICAgcmV0dXJuIGlzRXhpc3RpbmdDb25uZWN0Q29uZmlnKGNvbmZpZykgfHwgaXNOZXdDb25uZWN0Q29uZmlnKGNvbmZpZyk7XG59XG53aXJlLmlzSW50ZXJuYWxDb25uZWN0Q29uZmlnID0gaXNJbnRlcm5hbENvbm5lY3RDb25maWc7XG5cbnZhciBldmVudEFnZ3JlZ2F0b3IgPSB7fTtcblxudmFyIGVtaXR0ZXJNYXAgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVtaXR0ZXJNYXAsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZW1pdHRlck1hcC5FbWl0dGVyTWFwID0gdm9pZCAwO1xuY29uc3QgZXZlbnRzXzEkMiA9IHJlcXVpcmUkJDA7XG5jbGFzcyBFbWl0dGVyTWFwIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yYWdlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICAgIGhhc2hLZXlzKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaGVkID0ga2V5cy5tYXAobm9ybWFsaXplU3RyaW5nKTtcbiAgICAgICAgcmV0dXJuIGhhc2hlZC5qb2luKCcvJyk7XG4gICAgfVxuICAgIGdldE9yQ3JlYXRlKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaEtleXMoa2V5cyk7XG4gICAgICAgIGlmICghdGhpcy5zdG9yYWdlLmhhcyhoYXNoKSkge1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnNldChoYXNoLCBuZXcgZXZlbnRzXzEkMi5FdmVudEVtaXR0ZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2Ugc2V0IGl0IGFib3ZlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KGhhc2gpO1xuICAgIH1cbiAgICBoYXMoa2V5cykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmhhcyh0aGlzLmhhc2hLZXlzKGtleXMpKTtcbiAgICB9XG4gICAgZGVsZXRlKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaEtleXMoa2V5cyk7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZGVsZXRlKGhhc2gpO1xuICAgIH1cbn1cbmVtaXR0ZXJNYXAuRW1pdHRlck1hcCA9IEVtaXR0ZXJNYXA7XG5mdW5jdGlvbiBub3JtYWxpemVTdHJpbmcocykge1xuICAgIGNvbnN0IGIgPSBCdWZmZXIuZnJvbShzKTtcbiAgICByZXR1cm4gYi50b1N0cmluZygnYmFzZTY0Jyk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShldmVudEFnZ3JlZ2F0b3IsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgZW1pdHRlck1hcF8xID0gZW1pdHRlck1hcDtcbmZ1bmN0aW9uIGlzRXZlbnRNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbWVzc2FnZS5hY3Rpb24gPT09ICdwcm9jZXNzLWRlc2t0b3AtZXZlbnQnO1xufVxuZnVuY3Rpb24gbWFwS2V5RnJvbUV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgeyB0b3BpYyB9ID0gZXZlbnQ7XG4gICAgaWYgKHRvcGljID09PSAnZnJhbWUnIHx8IHRvcGljID09PSAnd2luZG93JyB8fCB0b3BpYyA9PT0gJ3ZpZXcnKSB7XG4gICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gZXZlbnQ7XG4gICAgICAgIHJldHVybiBbdG9waWMsIHV1aWQsIG5hbWVdO1xuICAgIH1cbiAgICBpZiAodG9waWMgPT09ICdhcHBsaWNhdGlvbicpIHtcbiAgICAgICAgY29uc3QgeyB1dWlkIH0gPSBldmVudDtcbiAgICAgICAgcmV0dXJuIFt0b3BpYywgdXVpZF07XG4gICAgfVxuICAgIHJldHVybiBbdG9waWNdO1xufVxuY2xhc3MgRXZlbnRBZ2dyZWdhdG9yIGV4dGVuZHMgZW1pdHRlck1hcF8xLkVtaXR0ZXJNYXAge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQgPSAobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzRXZlbnRNZXNzYWdlKG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBtZXNzYWdlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc29yID0gbWFwS2V5RnJvbUV2ZW50KHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhcyhhY2Nlc3NvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckNyZWF0ZShhY2Nlc3NvcikuZW1pdChwYXlsb2FkLnR5cGUsIHBheWxvYWQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfVxufVxuZXZlbnRBZ2dyZWdhdG9yLmRlZmF1bHQgPSBFdmVudEFnZ3JlZ2F0b3I7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgXCJkZWZhdWx0XCI6IG1vZCB9O1xufTtcbnZhciBfVHJhbnNwb3J0X3dpcmUsIF9UcmFuc3BvcnRfZmluO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHRyYW5zcG9ydCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgVHJhbnNwb3J0XzEgPSB0cmFuc3BvcnQuVHJhbnNwb3J0ID0gdm9pZCAwO1xuY29uc3QgZXZlbnRzXzEkMSA9IHJlcXVpcmUkJDA7XG5jb25zdCB3aXJlXzEgPSB3aXJlO1xuY29uc3QgdHJhbnNwb3J0X2Vycm9yc18xID0gdHJhbnNwb3J0RXJyb3JzO1xuY29uc3QgZXZlbnRBZ2dyZWdhdG9yXzEgPSBfX2ltcG9ydERlZmF1bHQoZXZlbnRBZ2dyZWdhdG9yKTtcbmNvbnN0IG1lXzEkMSA9IG1lO1xuY29uc3QgZXJyb3JzXzEgPSBlcnJvcnM7XG5jbGFzcyBUcmFuc3BvcnQgZXh0ZW5kcyBldmVudHNfMSQxLkV2ZW50RW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IoV2lyZVR5cGUsIGVudmlyb25tZW50LCBjb25maWcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy53aXJlTGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLnRvcGljUmVmTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLmV2ZW50QWdncmVnYXRvciA9IG5ldyBldmVudEFnZ3JlZ2F0b3JfMS5kZWZhdWx0KCk7XG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXJzID0gW3RoaXMuZXZlbnRBZ2dyZWdhdG9yLmRpc3BhdGNoRXZlbnRdO1xuICAgICAgICBfVHJhbnNwb3J0X3dpcmUuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8vIFR5cGluZyBhcyB1bmtub3duIHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHNob3VsZCBub3QgYmUgdXNlZCBkaXJlY3RseS5cbiAgICAgICAgX1RyYW5zcG9ydF9maW4uc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIHRoaXMuY29ubmVjdFN5bmMgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3aXJlID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKTtcbiAgICAgICAgICAgIHdpcmUuY29ubmVjdFN5bmMoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IHVzZWQgaW4gb3VyIHRlc3RzLlxuICAgICAgICB0aGlzLmdldFBvcnQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3aXJlID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKTtcbiAgICAgICAgICAgIHJldHVybiB3aXJlLmdldFBvcnQoKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIG5ldyBXaXJlVHlwZSh0aGlzLm9ubWVzc2FnZS5iaW5kKHRoaXMpKSwgXCJmXCIpO1xuICAgICAgICB0aGlzLmVudmlyb25tZW50ID0gZW52aXJvbm1lbnQ7XG4gICAgICAgIHRoaXMuc2VuZFJhdyA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIikuc2VuZC5iaW5kKF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIikpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5oYW5kbGVNZXNzYWdlLmJpbmQodGhpcykpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpLm9uKCdkaXNjb25uZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFssIHsgaGFuZGxlTmFjayB9XSBvZiB0aGlzLndpcmVMaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVOYWNrKHsgcmVhc29uOiAnUmVtb3RlIGNvbm5lY3Rpb24gaGFzIGNsb3NlZCcgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndpcmVMaXN0ZW5lcnMuY2xlYXIoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdGVkJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNvbmZpZztcbiAgICAgICAgY29uc3QgZW50aXR5VHlwZSA9IHRoaXMuZW52aXJvbm1lbnQuZ2V0Q3VycmVudEVudGl0eVR5cGUoKTtcbiAgICAgICAgdGhpcy5tZSA9ICgwLCBtZV8xJDEuZ2V0QmFzZU1lKShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKTtcbiAgICB9XG4gICAgZ2V0RmluKCkge1xuICAgICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIFwiZlwiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBGaW4gb2JqZWN0IHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHJhbnNwb3J0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIFwiZlwiKTtcbiAgICB9XG4gICAgcmVnaXN0ZXJGaW4oX2Zpbikge1xuICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X2ZpbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpbiBvYmplY3QgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGZvciB0aGlzIHRyYW5zcG9ydCcpO1xuICAgICAgICB9XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIF9maW4sIFwiZlwiKTtcbiAgICB9XG4gICAgc2h1dGRvd24oKSB7XG4gICAgICAgIGNvbnN0IHdpcmUgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpO1xuICAgICAgICByZXR1cm4gd2lyZS5zaHV0ZG93bigpO1xuICAgIH1cbiAgICBhc3luYyBjb25uZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoKDAsIHdpcmVfMS5pc0NvbmZpZ1dpdGhSZWNlaXZlcikoY29uZmlnKSkge1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKS5jb25uZWN0KGNvbmZpZy5yZWNlaXZlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdXRob3JpemUoY29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKDAsIHdpcmVfMS5pc1JlbW90ZUNvbmZpZykoY29uZmlnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdFJlbW90ZShjb25maWcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoMCwgd2lyZV8xLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnKShjb25maWcpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0QnlQb3J0KGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCgwLCB3aXJlXzEuaXNOZXdDb25uZWN0Q29uZmlnKShjb25maWcpKSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0ID0gYXdhaXQgdGhpcy5lbnZpcm9ubWVudC5yZXRyaWV2ZVBvcnQoY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RCeVBvcnQoeyAuLi5jb25maWcsIGFkZHJlc3M6IGB3czovL2xvY2FsaG9zdDoke3BvcnR9YCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBhc3luYyBjb25uZWN0UmVtb3RlKGNvbmZpZykge1xuICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpLmNvbm5lY3QobmV3ICh0aGlzLmVudmlyb25tZW50LmdldFdzQ29uc3RydWN0b3IoKSkoY29uZmlnLmFkZHJlc3MpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aG9yaXplKGNvbmZpZyk7XG4gICAgfVxuICAgIGFzeW5jIGNvbm5lY3RCeVBvcnQoY29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHsgYWRkcmVzcywgdXVpZCB9ID0gY29uZmlnO1xuICAgICAgICBjb25zdCByZXFBdXRoUGF5bG9hZCA9IHsgLi4uY29uZmlnLCB0eXBlOiAnZmlsZS10b2tlbicgfTtcbiAgICAgICAgY29uc3Qgd2lyZSA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIik7XG4gICAgICAgIGF3YWl0IHdpcmUuY29ubmVjdChuZXcgKHRoaXMuZW52aXJvbm1lbnQuZ2V0V3NDb25zdHJ1Y3RvcigpKShjb25maWcuYWRkcmVzcykpO1xuICAgICAgICBjb25zdCByZXF1ZXN0RXh0QXV0aFJldCA9IGF3YWl0IHRoaXMuc2VuZEFjdGlvbigncmVxdWVzdC1leHRlcm5hbC1hdXRob3JpemF0aW9uJywge1xuICAgICAgICAgICAgdXVpZCxcbiAgICAgICAgICAgIHR5cGU6ICdmaWxlLXRva2VuJ1xuICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgaWYgKHJlcXVlc3RFeHRBdXRoUmV0LmFjdGlvbiAhPT0gJ2V4dGVybmFsLWF1dGhvcml6YXRpb24tcmVzcG9uc2UnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgdHJhbnNwb3J0X2Vycm9yc18xLlVuZXhwZWN0ZWRBY3Rpb25FcnJvcihyZXF1ZXN0RXh0QXV0aFJldC5hY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuZW52aXJvbm1lbnQud3JpdGVUb2tlbihyZXF1ZXN0RXh0QXV0aFJldC5wYXlsb2FkLmZpbGUsIHJlcXVlc3RFeHRBdXRoUmV0LnBheWxvYWQudG9rZW4pO1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRob3JpemUocmVxQXV0aFBheWxvYWQpO1xuICAgIH1cbiAgICBhc3luYyBhdXRob3JpemUocmVxQXV0aFBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdEF1dGhSZXQgPSBhd2FpdCB0aGlzLnNlbmRBY3Rpb24oJ3JlcXVlc3QtYXV0aG9yaXphdGlvbicsIHJlcUF1dGhQYXlsb2FkLCB0cnVlKTtcbiAgICAgICAgaWYgKHJlcXVlc3RBdXRoUmV0LmFjdGlvbiAhPT0gJ2F1dGhvcml6YXRpb24tcmVzcG9uc2UnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgdHJhbnNwb3J0X2Vycm9yc18xLlVuZXhwZWN0ZWRBY3Rpb25FcnJvcihyZXF1ZXN0QXV0aFJldC5hY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJlcXVlc3RBdXRoUmV0LnBheWxvYWQuc3VjY2VzcyAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5SdW50aW1lRXJyb3IocmVxdWVzdEF1dGhSZXQucGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2VuZEFjdGlvbihhY3Rpb24sIHBheWxvYWQgPSB7fSwgdW5jb3JyZWxhdGVkID0gZmFsc2VcbiAgICAvLyBzcGVjaWFsUmVzcG9uc2UgdHlwZSBpcyBvbmx5IHVzZWQgZm9yICdyZXF1ZXN0QXV0aG9yaXphdGlvbidcbiAgICApIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICAgICAgICBsZXQgY2FuY2VsID0gKCkgPT4geyB9O1xuICAgICAgICAvLyBXZSB3YW50IHRoZSBjYWxsc2l0ZSBmcm9tIHRoZSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiwgbm90IGZyb20gaGVyZS5cbiAgICAgICAgY29uc3QgY2FsbFNpdGVzID0gdHJhbnNwb3J0X2Vycm9yc18xLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgxKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZUlkID0gdGhpcy5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCk7XG4gICAgICAgIGNvbnN0IHByb20gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjYW5jZWwgPSByZWplY3Q7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgd2lyZSA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIik7XG4gICAgICAgICAgICB0aGlzLmFkZFdpcmVMaXN0ZW5lcihtZXNzYWdlSWQsIHJlc29sdmUsIChwYXlsb2FkKSA9PiB0aGlzLm5hY2tIYW5kbGVyKHBheWxvYWQsIHJlamVjdCwgY2FsbFNpdGVzKSwgdW5jb3JyZWxhdGVkKTtcbiAgICAgICAgICAgIHJldHVybiB3aXJlLnNlbmQobXNnKS5jYXRjaChyZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocHJvbSwgeyBjYW5jZWwsIG1lc3NhZ2VJZCB9KTtcbiAgICB9XG4gICAgbmFja0hhbmRsZXIocGF5bG9hZE9yTWVzc2FnZSwgcmVqZWN0LCBjYWxsU2l0ZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkT3JNZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gTk9URTogdGhpcyBpcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdG8gc3VwcG9ydCBwbGFpbiBzdHJpbmcgcmVqZWN0aW9uc1xuICAgICAgICAgICAgcmVqZWN0KHBheWxvYWRPck1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyB0cmFuc3BvcnRfZXJyb3JzXzEuUnVudGltZUVycm9yKHBheWxvYWRPck1lc3NhZ2UsIGNhbGxTaXRlcykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZlcnJ5QWN0aW9uKG9yaWdEYXRhKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpO1xuICAgICAgICAgICAgb3JpZ0RhdGEubWVzc2FnZUlkID0gaWQ7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlciA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnBheWxvYWQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHdpcmUgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHdpcmVcbiAgICAgICAgICAgICAgICAuc2VuZChvcmlnRGF0YSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmFkZFdpcmVMaXN0ZW5lcihpZCwgcmVzb2x2ZXIsIChwYXlsb2FkKSA9PiB0aGlzLm5hY2tIYW5kbGVyKHBheWxvYWQsIHJlamVjdCksIGZhbHNlKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gocmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgIH1cbiAgICBhZGRXaXJlTGlzdGVuZXIoaWQsIHJlc29sdmUsIGhhbmRsZU5hY2ssIHVuY29ycmVsYXRlZCkge1xuICAgICAgICBpZiAodW5jb3JyZWxhdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnVuY29ycmVsYXRlZExpc3RlbmVyID0gcmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLndpcmVMaXN0ZW5lcnMuaGFzKGlkKSkge1xuICAgICAgICAgICAgaGFuZGxlTmFjayh7XG4gICAgICAgICAgICAgICAgcmVhc29uOiAnRHVwbGljYXRlIGhhbmRsZXIgaWQnLFxuICAgICAgICAgICAgICAgIGVycm9yOiAoMCwgZXJyb3JzXzEuZXJyb3JUb1BPSk8pKG5ldyB0cmFuc3BvcnRfZXJyb3JzXzEuRHVwbGljYXRlQ29ycmVsYXRpb25FcnJvcihTdHJpbmcoaWQpKSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53aXJlTGlzdGVuZXJzLnNldChpZCwgeyByZXNvbHZlLCBoYW5kbGVOYWNrIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRpbWVvdXQgYW5kIHJlamVjdCgpP1xuICAgIH1cbiAgICAvLyBUaGlzIG1ldGhvZCBleGVjdXRlcyBtZXNzYWdlIGhhbmRsZXJzIHVudGlsIHRoZSBfb25lXyB0aGF0IGhhbmRsZXMgdGhlIG1lc3NhZ2UgKHJldHVybnMgdHJ1dGh5KSBoYXMgcnVuXG4gICAgb25tZXNzYWdlKGRhdGEpIHtcbiAgICAgICAgZm9yIChjb25zdCBoIG9mIHRoaXMubWVzc2FnZUhhbmRsZXJzKSB7XG4gICAgICAgICAgICBoLmNhbGwobnVsbCwgZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlTWVzc2FnZShkYXRhKSB7XG4gICAgICAgIGNvbnN0IGlkID0gZGF0YS5jb3JyZWxhdGlvbklkIHx8IE5hTjtcbiAgICAgICAgaWYgKCEoJ2NvcnJlbGF0aW9uSWQnIGluIGRhdGEpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy51bmNvcnJlbGF0ZWRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMudW5jb3JyZWxhdGVkTGlzdGVuZXIuY2FsbChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudW5jb3JyZWxhdGVkTGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZW1wdHkgYmxvY2tcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRoaXMud2lyZUxpc3RlbmVycy5oYXMoaWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBXZSBqdXN0IGNoZWNrZWQgZm9yIGV4aXN0ZW5jZSBhYm92ZVxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIGNvbnN0IHsgcmVzb2x2ZSwgaGFuZGxlTmFjayB9ID0gdGhpcy53aXJlTGlzdGVuZXJzLmdldChpZCk7XG4gICAgICAgICAgICBpZiAoZGF0YS5hY3Rpb24gIT09ICdhY2snKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlTmFjayh7IHJlYXNvbjogJ0RpZCBub3QgcmVjZWl2ZSBhY2sgYWN0aW9uJywgZXJyb3I6ICgwLCBlcnJvcnNfMS5lcnJvclRvUE9KTykobmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5Ob0Fja0Vycm9yKGRhdGEuYWN0aW9uKSkgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghKCdwYXlsb2FkJyBpbiBkYXRhKSkge1xuICAgICAgICAgICAgICAgIC8vIEknbSBub3Qgc3VyZSB3aGVuIHRoaXMgY29kZSB3b3VsZCBhY3R1YWxseSBydW4sIGJ1dCBwYXNzaW5nIGluIHNvbWV0aGluZyB0aGF0IGRvZWVzbid0IGhhdmUgYSByZWFzb24gdG8gdGhlIHJ1bnRpbWVlcnJvciBjb25zdHJ1Y3RvciB3aWxsIG5vdCBlbmQgd2VsbC5cbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnJlYXNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFjayhkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUmVjZWl2ZWQgaW52YWxpZCByZXNwb25zZSBmcm9tIGNvcmUnLCBkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFjayh7IHJlYXNvbjogJ2ludmFsaWQgcmVzcG9uc2Ugc2hhcGUnIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFkYXRhLnBheWxvYWQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGhhbmRsZU5hY2soZGF0YS5wYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmUuY2FsbChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2lyZUxpc3RlbmVycy5kZWxldGUoaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cblRyYW5zcG9ydF8xID0gdHJhbnNwb3J0LlRyYW5zcG9ydCA9IFRyYW5zcG9ydDtcbl9UcmFuc3BvcnRfd2lyZSA9IG5ldyBXZWFrTWFwKCksIF9UcmFuc3BvcnRfZmluID0gbmV3IFdlYWtNYXAoKTtcblxudmFyIG1vY2tFbnZpcm9ubWVudCA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobW9ja0Vudmlyb25tZW50LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNb2NrRW52aXJvbm1lbnRfMSA9IG1vY2tFbnZpcm9ubWVudC5Nb2NrRW52aXJvbm1lbnQgPSB2b2lkIDA7XG5jb25zdCBtZV8xID0gbWU7XG5jbGFzcyBNb2NrRW52aXJvbm1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAnb3RoZXInO1xuICAgICAgICB0aGlzLmNoaWxkVmlld3MgPSB0cnVlO1xuICAgIH1cbiAgICBnZXRBZGFwdGVyVmVyc2lvblN5bmMoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0SW50ZXJvcEluZm8oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0RGVmYXVsdENoYW5uZWxPcHRpb25zKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGdldFJ0Y1BlZXIoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgbGF5b3V0QWxsb3dlZEluQ29udGV4dChfZmluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgaW5pdExheW91dE1hbmFnZXIoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXBwbHlMYXlvdXRTbmFwc2hvdCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBhc3luYyBjcmVhdGVMYXlvdXQoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXN5bmMgZGVzdHJveUxheW91dCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBhc3luYyByZXNvbHZlTGF5b3V0KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGluaXRQbGF0Zm9ybSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBvYnNlcnZlQm91bmRzKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIHdyaXRlVG9rZW4ocGF0aCwgdG9rZW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICByZXRyaWV2ZVBvcnQoY29uZmlnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0TmV4dE1lc3NhZ2VJZCgpIHtcbiAgICAgICAgcmV0dXJuIGBtb2NrLW1lc3NhZ2UtaWQtJHtNYXRoLnJhbmRvbSgpfWA7XG4gICAgfVxuICAgIGdldFJhbmRvbUlkKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGNyZWF0ZUNoaWxkQ29udGVudChvcHRpb25zKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0V2ViV2luZG93KGlkZW50aXR5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0Q3VycmVudEVudGl0eUlkZW50aXR5KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGdldEN1cnJlbnRFbnRpdHlUeXBlKCkge1xuICAgICAgICByZXR1cm4gJ3Vua25vd24nO1xuICAgIH1cbiAgICByYWlzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnRBcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0VXJsKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIHdoZW5SZWFkeSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBnZXRXc0NvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gICAgfVxufVxuTW9ja0Vudmlyb25tZW50XzEgPSBtb2NrRW52aXJvbm1lbnQuTW9ja0Vudmlyb25tZW50ID0gTW9ja0Vudmlyb25tZW50O1xuXG52YXIgbW9ja1dpcmUgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vY2tXaXJlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNb2NrV2lyZV8xID0gbW9ja1dpcmUuTW9ja1dpcmUgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IGV2ZW50c18xID0gcmVxdWlyZSQkMDtcbmNsYXNzIE1vY2tXaXJlIGV4dGVuZHMgZXZlbnRzXzEuRXZlbnRFbWl0dGVyIHtcbiAgICBjb25uZWN0KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IHJ1bm5pbmcgaW4gT3BlbkZpbi4nKTtcbiAgICB9XG4gICAgY29ubmVjdFN5bmMoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgcnVubmluZyBpbiBPcGVuRmluLicpO1xuICAgIH1cbiAgICBzZW5kKGRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBydW5uaW5nIGluIE9wZW5GaW4uJyk7XG4gICAgfVxuICAgIHNodXRkb3duKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IHJ1bm5pbmcgaW4gT3BlbkZpbi4nKTtcbiAgICB9XG4gICAgZ2V0UG9ydCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHRyYW5zcG9ydCBoYXMgbm8gcG9ydCcpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1jb25zdHJ1Y3RvclxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cbn1cbk1vY2tXaXJlXzEgPSBtb2NrV2lyZS5Nb2NrV2lyZSA9IE1vY2tXaXJlO1xuXG5jb25zdCBmaW4kMSA9ICgodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Py5maW4pIHx8XG4gICAgKCgpID0+IHtcbiAgICAgICAgY29uc3QgZW52aXJvbm1lbnQgPSBuZXcgTW9ja0Vudmlyb25tZW50XzEoKTtcbiAgICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydF8xKE1vY2tXaXJlXzEsIGVudmlyb25tZW50LCB7XG4gICAgICAgICAgICB1dWlkOiAnJyxcbiAgICAgICAgICAgIG5hbWU6ICcnXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IEZpbl8xKHRyYW5zcG9ydCk7XG4gICAgfSkoKSk7XG5cbmV4cG9ydHMuT3BlbkZpbiA9IE9wZW5GaW4kMTtcbmV4cG9ydHMuZGVmYXVsdCA9IE9wZW5GaW4kMTtcbmV4cG9ydHMuZmluID0gZmluJDE7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShyb290LCAnRGF0YVZpZXcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhVmlldztcbiIsInZhciBoYXNoQ2xlYXIgPSByZXF1aXJlKCcuL19oYXNoQ2xlYXInKSxcbiAgICBoYXNoRGVsZXRlID0gcmVxdWlyZSgnLi9faGFzaERlbGV0ZScpLFxuICAgIGhhc2hHZXQgPSByZXF1aXJlKCcuL19oYXNoR2V0JyksXG4gICAgaGFzaEhhcyA9IHJlcXVpcmUoJy4vX2hhc2hIYXMnKSxcbiAgICBoYXNoU2V0ID0gcmVxdWlyZSgnLi9faGFzaFNldCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBoYXNoIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gSGFzaChlbnRyaWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gIHRoaXMuY2xlYXIoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC5cbkhhc2gucHJvdG90eXBlLmNsZWFyID0gaGFzaENsZWFyO1xuSGFzaC5wcm90b3R5cGVbJ2RlbGV0ZSddID0gaGFzaERlbGV0ZTtcbkhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7XG5IYXNoLnByb3RvdHlwZS5oYXMgPSBoYXNoSGFzO1xuSGFzaC5wcm90b3R5cGUuc2V0ID0gaGFzaFNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoO1xuIiwidmFyIGxpc3RDYWNoZUNsZWFyID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlQ2xlYXInKSxcbiAgICBsaXN0Q2FjaGVEZWxldGUgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVEZWxldGUnKSxcbiAgICBsaXN0Q2FjaGVHZXQgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVHZXQnKSxcbiAgICBsaXN0Q2FjaGVIYXMgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVIYXMnKSxcbiAgICBsaXN0Q2FjaGVTZXQgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGxpc3QgY2FjaGUgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBMaXN0Q2FjaGUoZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgTGlzdENhY2hlYC5cbkxpc3RDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBsaXN0Q2FjaGVDbGVhcjtcbkxpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlO1xuTGlzdENhY2hlLnByb3RvdHlwZS5nZXQgPSBsaXN0Q2FjaGVHZXQ7XG5MaXN0Q2FjaGUucHJvdG90eXBlLmhhcyA9IGxpc3RDYWNoZUhhcztcbkxpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IExpc3RDYWNoZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgTWFwID0gZ2V0TmF0aXZlKHJvb3QsICdNYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXA7XG4iLCJ2YXIgbWFwQ2FjaGVDbGVhciA9IHJlcXVpcmUoJy4vX21hcENhY2hlQ2xlYXInKSxcbiAgICBtYXBDYWNoZURlbGV0ZSA9IHJlcXVpcmUoJy4vX21hcENhY2hlRGVsZXRlJyksXG4gICAgbWFwQ2FjaGVHZXQgPSByZXF1aXJlKCcuL19tYXBDYWNoZUdldCcpLFxuICAgIG1hcENhY2hlSGFzID0gcmVxdWlyZSgnLi9fbWFwQ2FjaGVIYXMnKSxcbiAgICBtYXBDYWNoZVNldCA9IHJlcXVpcmUoJy4vX21hcENhY2hlU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gIHRoaXMuY2xlYXIoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBNYXBDYWNoZWAuXG5NYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyO1xuTWFwQ2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IG1hcENhY2hlRGVsZXRlO1xuTWFwQ2FjaGUucHJvdG90eXBlLmdldCA9IG1hcENhY2hlR2V0O1xuTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzO1xuTWFwQ2FjaGUucHJvdG90eXBlLnNldCA9IG1hcENhY2hlU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcENhY2hlO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBQcm9taXNlID0gZ2V0TmF0aXZlKHJvb3QsICdQcm9taXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgU2V0ID0gZ2V0TmF0aXZlKHJvb3QsICdTZXQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTZXQ7XG4iLCJ2YXIgTWFwQ2FjaGUgPSByZXF1aXJlKCcuL19NYXBDYWNoZScpLFxuICAgIHNldENhY2hlQWRkID0gcmVxdWlyZSgnLi9fc2V0Q2FjaGVBZGQnKSxcbiAgICBzZXRDYWNoZUhhcyA9IHJlcXVpcmUoJy4vX3NldENhY2hlSGFzJyk7XG5cbi8qKlxuICpcbiAqIENyZWF0ZXMgYW4gYXJyYXkgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gU2V0Q2FjaGUodmFsdWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gdmFsdWVzID09IG51bGwgPyAwIDogdmFsdWVzLmxlbmd0aDtcblxuICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHRoaXMuYWRkKHZhbHVlc1tpbmRleF0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBTZXRDYWNoZWAuXG5TZXRDYWNoZS5wcm90b3R5cGUuYWRkID0gU2V0Q2FjaGUucHJvdG90eXBlLnB1c2ggPSBzZXRDYWNoZUFkZDtcblNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhcztcblxubW9kdWxlLmV4cG9ydHMgPSBTZXRDYWNoZTtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBzdGFja0NsZWFyID0gcmVxdWlyZSgnLi9fc3RhY2tDbGVhcicpLFxuICAgIHN0YWNrRGVsZXRlID0gcmVxdWlyZSgnLi9fc3RhY2tEZWxldGUnKSxcbiAgICBzdGFja0dldCA9IHJlcXVpcmUoJy4vX3N0YWNrR2V0JyksXG4gICAgc3RhY2tIYXMgPSByZXF1aXJlKCcuL19zdGFja0hhcycpLFxuICAgIHN0YWNrU2V0ID0gcmVxdWlyZSgnLi9fc3RhY2tTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gU3RhY2soZW50cmllcykge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuXG5TdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuU3RhY2sucHJvdG90eXBlWydkZWxldGUnXSA9IHN0YWNrRGVsZXRlO1xuU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0O1xuU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuU3RhY2sucHJvdG90eXBlLnNldCA9IHN0YWNrU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0YWNrO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIFN5bWJvbCA9IHJvb3QuU3ltYm9sO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN5bWJvbDtcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBVaW50OEFycmF5ID0gcm9vdC5VaW50OEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFVpbnQ4QXJyYXk7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIFdlYWtNYXAgPSBnZXROYXRpdmUocm9vdCwgJ1dlYWtNYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBXZWFrTWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RWFjaDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheUZpbHRlcihhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICByZXNJbmRleCA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUZpbHRlcjtcbiIsInZhciBiYXNlVGltZXMgPSByZXF1aXJlKCcuL19iYXNlVGltZXMnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vX2lzSW5kZXgnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGluaGVyaXRlZCBTcGVjaWZ5IHJldHVybmluZyBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VLZXlzKHZhbHVlLCBpbmhlcml0ZWQpIHtcbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICBpc0J1ZmYgPSAhaXNBcnIgJiYgIWlzQXJnICYmIGlzQnVmZmVyKHZhbHVlKSxcbiAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmICgoaW5oZXJpdGVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgIGtleSA9PSAnbGVuZ3RoJyB8fFxuICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy5cbiAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgaXNJbmRleChrZXksIGxlbmd0aClcbiAgICAgICAgKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlMaWtlS2V5cztcbiIsIi8qKlxuICogQXBwZW5kcyB0aGUgZWxlbWVudHMgb2YgYHZhbHVlc2AgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtvZmZzZXQgKyBpbmRleF0gPSB2YWx1ZXNbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVB1c2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAqIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5U29tZTtcbiIsInZhciBiYXNlQXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19iYXNlQXNzaWduVmFsdWUnKSxcbiAgICBlcSA9IHJlcXVpcmUoJy4vZXEnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBc3NpZ25zIGB2YWx1ZWAgdG8gYGtleWAgb2YgYG9iamVjdGAgaWYgdGhlIGV4aXN0aW5nIHZhbHVlIGlzIG5vdCBlcXVpdmFsZW50XG4gKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gKi9cbmZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XTtcbiAgaWYgKCEoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYgZXEob2JqVmFsdWUsIHZhbHVlKSkgfHxcbiAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NpZ25WYWx1ZTtcbiIsInZhciBlcSA9IHJlcXVpcmUoJy4vZXEnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSBrZXkgVGhlIGtleSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHtcbiAgICAgIHJldHVybiBsZW5ndGg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NvY0luZGV4T2Y7XG4iLCJ2YXIgY29weU9iamVjdCA9IHJlcXVpcmUoJy4vX2NvcHlPYmplY3QnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXNcbiAqIG9yIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25JbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnbkluKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ25JbjtcbiIsInZhciBkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2RlZmluZVByb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGFzc2lnblZhbHVlYCBhbmQgYGFzc2lnbk1lcmdlVmFsdWVgIHdpdGhvdXRcbiAqIHZhbHVlIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgPT0gJ19fcHJvdG9fXycgJiYgZGVmaW5lUHJvcGVydHkpIHtcbiAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIGtleSwge1xuICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAnZW51bWVyYWJsZSc6IHRydWUsXG4gICAgICAndmFsdWUnOiB2YWx1ZSxcbiAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFzc2lnblZhbHVlO1xuIiwidmFyIFN0YWNrID0gcmVxdWlyZSgnLi9fU3RhY2snKSxcbiAgICBhcnJheUVhY2ggPSByZXF1aXJlKCcuL19hcnJheUVhY2gnKSxcbiAgICBhc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Fzc2lnblZhbHVlJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ24nKSxcbiAgICBiYXNlQXNzaWduSW4gPSByZXF1aXJlKCcuL19iYXNlQXNzaWduSW4nKSxcbiAgICBjbG9uZUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQnVmZmVyJyksXG4gICAgY29weUFycmF5ID0gcmVxdWlyZSgnLi9fY29weUFycmF5JyksXG4gICAgY29weVN5bWJvbHMgPSByZXF1aXJlKCcuL19jb3B5U3ltYm9scycpLFxuICAgIGNvcHlTeW1ib2xzSW4gPSByZXF1aXJlKCcuL19jb3B5U3ltYm9sc0luJyksXG4gICAgZ2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2dldEFsbEtleXMnKSxcbiAgICBnZXRBbGxLZXlzSW4gPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzSW4nKSxcbiAgICBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZUFycmF5JyksXG4gICAgaW5pdENsb25lQnlUYWcgPSByZXF1aXJlKCcuL19pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc01hcCA9IHJlcXVpcmUoJy4vaXNNYXAnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKSxcbiAgICBpc1NldCA9IHJlcXVpcmUoJy4vaXNTZXQnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgY2xvbmluZy4gKi9cbnZhciBDTE9ORV9ERUVQX0ZMQUcgPSAxLFxuICAgIENMT05FX0ZMQVRfRkxBRyA9IDIsXG4gICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBzdXBwb3J0ZWQgYnkgYF8uY2xvbmVgLiAqL1xudmFyIGNsb25lYWJsZVRhZ3MgPSB7fTtcbmNsb25lYWJsZVRhZ3NbYXJnc1RhZ10gPSBjbG9uZWFibGVUYWdzW2FycmF5VGFnXSA9XG5jbG9uZWFibGVUYWdzW2FycmF5QnVmZmVyVGFnXSA9IGNsb25lYWJsZVRhZ3NbZGF0YVZpZXdUYWddID1cbmNsb25lYWJsZVRhZ3NbYm9vbFRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGVUYWddID1cbmNsb25lYWJsZVRhZ3NbZmxvYXQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID1cbmNsb25lYWJsZVRhZ3NbaW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9XG5jbG9uZWFibGVUYWdzW251bWJlclRhZ10gPSBjbG9uZWFibGVUYWdzW29iamVjdFRhZ10gPVxuY2xvbmVhYmxlVGFnc1tyZWdleHBUYWddID0gY2xvbmVhYmxlVGFnc1tzZXRUYWddID1cbmNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3ltYm9sVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgYW5kIGBfLmNsb25lRGVlcGAgd2hpY2ggdHJhY2tzXG4gKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gKiAgMSAtIERlZXAgY2xvbmVcbiAqICAyIC0gRmxhdHRlbiBpbmhlcml0ZWQgcHJvcGVydGllc1xuICogIDQgLSBDbG9uZSBzeW1ib2xzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgcGFyZW50IG9iamVjdCBvZiBgdmFsdWVgLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGFuZCB0aGVpciBjbG9uZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgb2JqZWN0LCBzdGFjaykge1xuICB2YXIgcmVzdWx0LFxuICAgICAgaXNEZWVwID0gYml0bWFzayAmIENMT05FX0RFRVBfRkxBRyxcbiAgICAgIGlzRmxhdCA9IGJpdG1hc2sgJiBDTE9ORV9GTEFUX0ZMQUcsXG4gICAgICBpc0Z1bGwgPSBiaXRtYXNrICYgQ0xPTkVfU1lNQk9MU19GTEFHO1xuXG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QsIHN0YWNrKSA6IGN1c3RvbWl6ZXIodmFsdWUpO1xuICB9XG4gIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSk7XG4gIGlmIChpc0Fycikge1xuICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgcmV0dXJuIGNvcHlBcnJheSh2YWx1ZSwgcmVzdWx0KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHRhZyA9IGdldFRhZyh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7XG5cbiAgICBpZiAoaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY2xvbmVCdWZmZXIodmFsdWUsIGlzRGVlcCk7XG4gICAgfVxuICAgIGlmICh0YWcgPT0gb2JqZWN0VGFnIHx8IHRhZyA9PSBhcmdzVGFnIHx8IChpc0Z1bmMgJiYgIW9iamVjdCkpIHtcbiAgICAgIHJlc3VsdCA9IChpc0ZsYXQgfHwgaXNGdW5jKSA/IHt9IDogaW5pdENsb25lT2JqZWN0KHZhbHVlKTtcbiAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgIHJldHVybiBpc0ZsYXRcbiAgICAgICAgICA/IGNvcHlTeW1ib2xzSW4odmFsdWUsIGJhc2VBc3NpZ25JbihyZXN1bHQsIHZhbHVlKSlcbiAgICAgICAgICA6IGNvcHlTeW1ib2xzKHZhbHVlLCBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjbG9uZWFibGVUYWdzW3RhZ10pIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBpc0RlZXApO1xuICAgIH1cbiAgfVxuICAvLyBDaGVjayBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyBhbmQgcmV0dXJuIGl0cyBjb3JyZXNwb25kaW5nIGNsb25lLlxuICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldCh2YWx1ZSk7XG4gIGlmIChzdGFja2VkKSB7XG4gICAgcmV0dXJuIHN0YWNrZWQ7XG4gIH1cbiAgc3RhY2suc2V0KHZhbHVlLCByZXN1bHQpO1xuXG4gIGlmIChpc1NldCh2YWx1ZSkpIHtcbiAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlKSB7XG4gICAgICByZXN1bHQuYWRkKGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3ViVmFsdWUsIHZhbHVlLCBzdGFjaykpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGlzTWFwKHZhbHVlKSkge1xuICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0LnNldChrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBrZXlzRnVuYyA9IGlzRnVsbFxuICAgID8gKGlzRmxhdCA/IGdldEFsbEtleXNJbiA6IGdldEFsbEtleXMpXG4gICAgOiAoaXNGbGF0ID8ga2V5c0luIDoga2V5cyk7XG5cbiAgdmFyIHByb3BzID0gaXNBcnIgPyB1bmRlZmluZWQgOiBrZXlzRnVuYyh2YWx1ZSk7XG4gIGFycmF5RWFjaChwcm9wcyB8fCB2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIGlmIChwcm9wcykge1xuICAgICAga2V5ID0gc3ViVmFsdWU7XG4gICAgICBzdWJWYWx1ZSA9IHZhbHVlW2tleV07XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IHBvcHVsYXRlIGNsb25lIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgYXNzaWduVmFsdWUocmVzdWx0LCBrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNsb25lO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAqIHByb3BlcnRpZXMgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdG8gVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgaWYgKCFpc09iamVjdChwcm90bykpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgaWYgKG9iamVjdENyZWF0ZSkge1xuICAgICAgcmV0dXJuIG9iamVjdENyZWF0ZShwcm90byk7XG4gICAgfVxuICAgIG9iamVjdC5wcm90b3R5cGUgPSBwcm90bztcbiAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDcmVhdGU7XG4iLCJ2YXIgYXJyYXlQdXNoID0gcmVxdWlyZSgnLi9fYXJyYXlQdXNoJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlc1xuICogYGtleXNGdW5jYCBhbmQgYHN5bWJvbHNGdW5jYCB0byBnZXQgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3ltYm9sc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0Z1bmMsIHN5bWJvbHNGdW5jKSB7XG4gIHZhciByZXN1bHQgPSBrZXlzRnVuYyhvYmplY3QpO1xuICByZXR1cm4gaXNBcnJheShvYmplY3QpID8gcmVzdWx0IDogYXJyYXlQdXNoKHJlc3VsdCwgc3ltYm9sc0Z1bmMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldEFsbEtleXM7XG4iLCJ2YXIgU3ltYm9sID0gcmVxdWlyZSgnLi9fU3ltYm9sJyksXG4gICAgZ2V0UmF3VGFnID0gcmVxdWlyZSgnLi9fZ2V0UmF3VGFnJyksXG4gICAgb2JqZWN0VG9TdHJpbmcgPSByZXF1aXJlKCcuL19vYmplY3RUb1N0cmluZycpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJyxcbiAgICB1bmRlZmluZWRUYWcgPSAnW29iamVjdCBVbmRlZmluZWRdJztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICovXG5mdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWRUYWcgOiBudWxsVGFnO1xuICB9XG4gIHJldHVybiAoc3ltVG9TdHJpbmdUYWcgJiYgc3ltVG9TdHJpbmdUYWcgaW4gT2JqZWN0KHZhbHVlKSlcbiAgICA/IGdldFJhd1RhZyh2YWx1ZSlcbiAgICA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0VGFnO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LFxuICovXG5mdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNBcmd1bWVudHM7XG4iLCJ2YXIgYmFzZUlzRXF1YWxEZWVwID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gKiBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAqICAxIC0gVW5vcmRlcmVkIGNvbXBhcmlzb25cbiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gIH1cbiAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzRXF1YWw7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9fZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9fZXF1YWxCeVRhZycpLFxuICAgIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vX2VxdWFsT2JqZWN0cycpLFxuICAgIGdldFRhZyA9IHJlcXVpcmUoJy4vX2dldFRhZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyA9IDE7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZztcbiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihvdGhlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgb2JqSXNBcnIgPSB0cnVlO1xuICAgIG9iaklzT2JqID0gZmFsc2U7XG4gIH1cbiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHtcbiAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICA/IGVxdWFsQXJyYXlzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spXG4gICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgfVxuICBpZiAoIShiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcpKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgZ2V0VGFnID0gcmVxdWlyZSgnLi9fZ2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWFwYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXAodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBtYXBUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzTWFwO1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc01hc2tlZCA9IHJlcXVpcmUoJy4vX2lzTWFza2VkJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgdG9Tb3VyY2UgPSByZXF1aXJlKCcuL190b1NvdXJjZScpO1xuXG4vKipcbiAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGBcbiAqIFtzeW50YXggY2hhcmFjdGVyc10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcGF0dGVybnMpLlxuICovXG52YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZSxcbiAgICBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmdW5jVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSkucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXFxcJCYnKVxuICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbik7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYXRpdmVgIHdpdGhvdXQgYmFkIHNoaW0gY2hlY2tzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICghaXNPYmplY3QodmFsdWUpIHx8IGlzTWFza2VkKHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgcGF0dGVybiA9IGlzRnVuY3Rpb24odmFsdWUpID8gcmVJc05hdGl2ZSA6IHJlSXNIb3N0Q3RvcjtcbiAgcmV0dXJuIHBhdHRlcm4udGVzdCh0b1NvdXJjZSh2YWx1ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc05hdGl2ZTtcbiIsInZhciBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNTZXRgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc2V0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc1NldCh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBnZXRUYWcodmFsdWUpID09IHNldFRhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNTZXQ7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxudHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxudHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzVHlwZWRBcnJheTtcbiIsInZhciBpc1Byb3RvdHlwZSA9IHJlcXVpcmUoJy4vX2lzUHJvdG90eXBlJyksXG4gICAgbmF0aXZlS2V5cyA9IHJlcXVpcmUoJy4vX25hdGl2ZUtleXMnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VLZXlzKG9iamVjdCkge1xuICBpZiAoIWlzUHJvdG90eXBlKG9iamVjdCkpIHtcbiAgICByZXR1cm4gbmF0aXZlS2V5cyhvYmplY3QpO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VLZXlzO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBuYXRpdmVLZXlzSW4gPSByZXF1aXJlKCcuL19uYXRpdmVLZXlzSW4nKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzSW5gIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gYmFzZUtleXNJbihvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIG5hdGl2ZUtleXNJbihvYmplY3QpO1xuICB9XG4gIHZhciBpc1Byb3RvID0gaXNQcm90b3R5cGUob2JqZWN0KSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlS2V5c0luO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50aW1lc2Agd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzXG4gKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUaW1lcyhuLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KG4pO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbikge1xuICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVGltZXM7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuYXJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0b3JpbmcgbWV0YWRhdGEuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlVW5hcnkoZnVuYykge1xuICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVVuYXJ5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gY2FjaGVIYXMoY2FjaGUsIGtleSkge1xuICByZXR1cm4gY2FjaGUuaGFzKGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FjaGVIYXM7XG4iLCJ2YXIgVWludDhBcnJheSA9IHJlcXVpcmUoJy4vX1VpbnQ4QXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYGFycmF5QnVmZmVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYXJyYXlCdWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gY2xvbmVBcnJheUJ1ZmZlcihhcnJheUJ1ZmZlcikge1xuICB2YXIgcmVzdWx0ID0gbmV3IGFycmF5QnVmZmVyLmNvbnN0cnVjdG9yKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpO1xuICBuZXcgVWludDhBcnJheShyZXN1bHQpLnNldChuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lQXJyYXlCdWZmZXI7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbnZhciBmcmVlRXhwb3J0cyA9IHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqL1xudmFyIGZyZWVNb2R1bGUgPSBmcmVlRXhwb3J0cyAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcblxuLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbnZhciBtb2R1bGVFeHBvcnRzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBCdWZmZXIgPSBtb2R1bGVFeHBvcnRzID8gcm9vdC5CdWZmZXIgOiB1bmRlZmluZWQsXG4gICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mICBgYnVmZmVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBUaGUgYnVmZmVyIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIGNsb25lQnVmZmVyKGJ1ZmZlciwgaXNEZWVwKSB7XG4gIGlmIChpc0RlZXApIHtcbiAgICByZXR1cm4gYnVmZmVyLnNsaWNlKCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IGJ1ZmZlci5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBhbGxvY1Vuc2FmZSA/IGFsbG9jVW5zYWZlKGxlbmd0aCkgOiBuZXcgYnVmZmVyLmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgYnVmZmVyLmNvcHkocmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZUJ1ZmZlcjtcbiIsInZhciBjbG9uZUFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fY2xvbmVBcnJheUJ1ZmZlcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgZGF0YVZpZXdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVZpZXcgVGhlIGRhdGEgdmlldyB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgZGF0YSB2aWV3LlxuICovXG5mdW5jdGlvbiBjbG9uZURhdGFWaWV3KGRhdGFWaWV3LCBpc0RlZXApIHtcbiAgdmFyIGJ1ZmZlciA9IGlzRGVlcCA/IGNsb25lQXJyYXlCdWZmZXIoZGF0YVZpZXcuYnVmZmVyKSA6IGRhdGFWaWV3LmJ1ZmZlcjtcbiAgcmV0dXJuIG5ldyBkYXRhVmlldy5jb25zdHJ1Y3RvcihidWZmZXIsIGRhdGFWaWV3LmJ5dGVPZmZzZXQsIGRhdGFWaWV3LmJ5dGVMZW5ndGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lRGF0YVZpZXc7XG4iLCIvKiogVXNlZCB0byBtYXRjaCBgUmVnRXhwYCBmbGFncyBmcm9tIHRoZWlyIGNvZXJjZWQgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUZsYWdzID0gL1xcdyokLztcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHJlZ2V4cGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSByZWdleHAgVGhlIHJlZ2V4cCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCByZWdleHAuXG4gKi9cbmZ1bmN0aW9uIGNsb25lUmVnRXhwKHJlZ2V4cCkge1xuICB2YXIgcmVzdWx0ID0gbmV3IHJlZ2V4cC5jb25zdHJ1Y3RvcihyZWdleHAuc291cmNlLCByZUZsYWdzLmV4ZWMocmVnZXhwKSk7XG4gIHJlc3VsdC5sYXN0SW5kZXggPSByZWdleHAubGFzdEluZGV4O1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lUmVnRXhwO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBzeW1ib2wgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgcmV0dXJuIHN5bWJvbFZhbHVlT2YgPyBPYmplY3Qoc3ltYm9sVmFsdWVPZi5jYWxsKHN5bWJvbCkpIDoge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVTeW1ib2w7XG4iLCJ2YXIgY2xvbmVBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQXJyYXlCdWZmZXInKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHR5cGVkQXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gdHlwZWRBcnJheSBUaGUgdHlwZWQgYXJyYXkgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHR5cGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKHR5cGVkQXJyYXkuYnVmZmVyKSA6IHR5cGVkQXJyYXkuYnVmZmVyO1xuICByZXR1cm4gbmV3IHR5cGVkQXJyYXkuY29uc3RydWN0b3IoYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkubGVuZ3RoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZVR5cGVkQXJyYXk7XG4iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5QXJyYXk7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGJhc2VBc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ25WYWx1ZScpO1xuXG4vKipcbiAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICA/IGN1c3RvbWl6ZXIob2JqZWN0W2tleV0sIHNvdXJjZVtrZXldLCBrZXksIG9iamVjdCwgc291cmNlKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbmV3VmFsdWUgPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gICAgaWYgKGlzTmV3KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5T2JqZWN0O1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKTtcblxuLyoqXG4gKiBDb3BpZXMgb3duIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlTeW1ib2xzKHNvdXJjZSwgb2JqZWN0KSB7XG4gIHJldHVybiBjb3B5T2JqZWN0KHNvdXJjZSwgZ2V0U3ltYm9scyhzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvcHlTeW1ib2xzO1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgZ2V0U3ltYm9sc0luID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9sc0luJyk7XG5cbi8qKlxuICogQ29waWVzIG93biBhbmQgaW5oZXJpdGVkIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlTeW1ib2xzSW4oc291cmNlLCBvYmplY3QpIHtcbiAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzSW4oc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5U3ltYm9sc0luO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbnZhciBjb3JlSnNEYXRhID0gcm9vdFsnX19jb3JlLWpzX3NoYXJlZF9fJ107XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZUpzRGF0YTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgZnVuYyh7fSwgJycsIHt9KTtcbiAgICByZXR1cm4gZnVuYztcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydHk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vX2FycmF5U29tZScpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYGFycmF5YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcsXG4gICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLlxuICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gIH1cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgc2VlbiA9IChiaXRtYXNrICYgQ09NUEFSRV9VTk9SREVSRURfRkxBRykgPyBuZXcgU2V0Q2FjaGUgOiB1bmRlZmluZWQ7XG5cbiAgc3RhY2suc2V0KGFycmF5LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdO1xuXG4gICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIGFyclZhbHVlLCBpbmRleCwgb3RoZXIsIGFycmF5LCBzdGFjaylcbiAgICAgICAgOiBjdXN0b21pemVyKGFyclZhbHVlLCBvdGhWYWx1ZSwgaW5kZXgsIGFycmF5LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNvbXBhcmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoc2Vlbikge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlLCBvdGhJbmRleCkge1xuICAgICAgICAgICAgaWYgKCFjYWNoZUhhcyhzZWVuLCBvdGhJbmRleCkgJiZcbiAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShcbiAgICAgICAgICBhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHxcbiAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICApKSB7XG4gICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpLFxuICAgIFVpbnQ4QXJyYXkgPSByZXF1aXJlKCcuL19VaW50OEFycmF5JyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyksXG4gICAgZXF1YWxBcnJheXMgPSByZXF1aXJlKCcuL19lcXVhbEFycmF5cycpLFxuICAgIG1hcFRvQXJyYXkgPSByZXF1aXJlKCcuL19tYXBUb0FycmF5JyksXG4gICAgc2V0VG9BcnJheSA9IHJlcXVpcmUoJy4vX3NldFRvQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqL1xudmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgKG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IG9iamVjdC5idWZmZXI7XG4gICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjtcblxuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgIWVxdWFsRnVuYyhuZXcgVWludDhBcnJheShvYmplY3QpLCBuZXcgVWludDhBcnJheShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLlxuICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncywgcHJpbWl0aXZlcyBhbmQgb2JqZWN0cyxcbiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmdcbiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcblxuICAgIGNhc2UgbWFwVGFnOlxuICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHO1xuICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIGlmIChzeW1ib2xWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpO1xuICAgICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGdldEFsbEtleXMgPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xudmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgIG9ialByb3BzID0gZ2V0QWxsS2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzUGFydGlhbCA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIHZhciBvYmpTdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBvYmpTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gb2JqZWN0O1xuICB9XG4gIHZhciByZXN1bHQgPSB0cnVlO1xuICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTtcblxuICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICkpIHtcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAocmVzdWx0ICYmICFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsIi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZUdsb2JhbDtcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0QWxsS2V5cztcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9sc0luID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9sc0luJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICovXG5mdW5jdGlvbiBnZXRBbGxLZXlzSW4ob2JqZWN0KSB7XG4gIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNJbiwgZ2V0U3ltYm9sc0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRBbGxLZXlzSW47XG4iLCJ2YXIgaXNLZXlhYmxlID0gcmVxdWlyZSgnLi9faXNLZXlhYmxlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187XG4gIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgOiBkYXRhLm1hcDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXBEYXRhO1xuIiwidmFyIGJhc2VJc05hdGl2ZSA9IHJlcXVpcmUoJy4vX2Jhc2VJc05hdGl2ZScpLFxuICAgIGdldFZhbHVlID0gcmVxdWlyZSgnLi9fZ2V0VmFsdWUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG4iLCJ2YXIgb3ZlckFyZyA9IHJlcXVpcmUoJy4vX292ZXJBcmcnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgZ2V0UHJvdG90eXBlID0gb3ZlckFyZyhPYmplY3QuZ2V0UHJvdG90eXBlT2YsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UHJvdG90eXBlO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC5cbiAqL1xuZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gIHZhciBpc093biA9IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHN5bVRvU3RyaW5nVGFnKSxcbiAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICB0cnkge1xuICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHVuZGVmaW5lZDtcbiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIHZhciByZXN1bHQgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgaWYgKHVubWFza2VkKSB7XG4gICAgaWYgKGlzT3duKSB7XG4gICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB0YWc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UmF3VGFnO1xuIiwidmFyIGFycmF5RmlsdGVyID0gcmVxdWlyZSgnLi9fYXJyYXlGaWx0ZXInKSxcbiAgICBzdHViQXJyYXkgPSByZXF1aXJlKCcuL3N0dWJBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLlxuICovXG52YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9scztcbiIsInZhciBhcnJheVB1c2ggPSByZXF1aXJlKCcuL19hcnJheVB1c2gnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBnZXRTeW1ib2xzID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9scycpLFxuICAgIHN0dWJBcnJheSA9IHJlcXVpcmUoJy4vc3R1YkFycmF5Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVHZXRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAqL1xudmFyIGdldFN5bWJvbHNJbiA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgd2hpbGUgKG9iamVjdCkge1xuICAgIGFycmF5UHVzaChyZXN1bHQsIGdldFN5bWJvbHMob2JqZWN0KSk7XG4gICAgb2JqZWN0ID0gZ2V0UHJvdG90eXBlKG9iamVjdCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9sc0luO1xuIiwidmFyIERhdGFWaWV3ID0gcmVxdWlyZSgnLi9fRGF0YVZpZXcnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBQcm9taXNlID0gcmVxdWlyZSgnLi9fUHJvbWlzZScpLFxuICAgIFNldCA9IHJlcXVpcmUoJy4vX1NldCcpLFxuICAgIFdlYWtNYXAgPSByZXF1aXJlKCcuL19XZWFrTWFwJyksXG4gICAgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICB0b1NvdXJjZSA9IHJlcXVpcmUoJy4vX3RvU291cmNlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICBwcm9taXNlVGFnID0gJ1tvYmplY3QgUHJvbWlzZV0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBtYXBzLCBzZXRzLCBhbmQgd2Vha21hcHMuICovXG52YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXcpLFxuICAgIG1hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShNYXApLFxuICAgIHByb21pc2VDdG9yU3RyaW5nID0gdG9Tb3VyY2UoUHJvbWlzZSksXG4gICAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCksXG4gICAgd2Vha01hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShXZWFrTWFwKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC5cbiAqL1xudmFyIGdldFRhZyA9IGJhc2VHZXRUYWc7XG5cbi8vIEZhbGxiYWNrIGZvciBkYXRhIHZpZXdzLCBtYXBzLCBzZXRzLCBhbmQgd2VhayBtYXBzIGluIElFIDExIGFuZCBwcm9taXNlcyBpbiBOb2RlLmpzIDwgNi5cbmlmICgoRGF0YVZpZXcgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoMSkpKSAhPSBkYXRhVmlld1RhZykgfHxcbiAgICAoTWFwICYmIGdldFRhZyhuZXcgTWFwKSAhPSBtYXBUYWcpIHx8XG4gICAgKFByb21pc2UgJiYgZ2V0VGFnKFByb21pc2UucmVzb2x2ZSgpKSAhPSBwcm9taXNlVGFnKSB8fFxuICAgIChTZXQgJiYgZ2V0VGFnKG5ldyBTZXQpICE9IHNldFRhZykgfHxcbiAgICAoV2Vha01hcCAmJiBnZXRUYWcobmV3IFdlYWtNYXApICE9IHdlYWtNYXBUYWcpKSB7XG4gIGdldFRhZyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLFxuICAgICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICBjdG9yU3RyaW5nID0gQ3RvciA/IHRvU291cmNlKEN0b3IpIDogJyc7XG5cbiAgICBpZiAoY3RvclN0cmluZykge1xuICAgICAgc3dpdGNoIChjdG9yU3RyaW5nKSB7XG4gICAgICAgIGNhc2UgZGF0YVZpZXdDdG9yU3RyaW5nOiByZXR1cm4gZGF0YVZpZXdUYWc7XG4gICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzogcmV0dXJuIG1hcFRhZztcbiAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzogcmV0dXJuIHByb21pc2VUYWc7XG4gICAgICAgIGNhc2Ugc2V0Q3RvclN0cmluZzogcmV0dXJuIHNldFRhZztcbiAgICAgICAgY2FzZSB3ZWFrTWFwQ3RvclN0cmluZzogcmV0dXJuIHdlYWtNYXBUYWc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0VGFnO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0VmFsdWUob2JqZWN0LCBrZXkpIHtcbiAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0VmFsdWU7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKi9cbmZ1bmN0aW9uIGhhc2hDbGVhcigpIHtcbiAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9O1xuICB0aGlzLnNpemUgPSAwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hDbGVhcjtcbiIsIi8qKlxuICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGhhc2guXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIFRoZSBoYXNoIHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBoYXNoRGVsZXRlKGtleSkge1xuICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaERlbGV0ZTtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqL1xudmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEdldHMgdGhlIGhhc2ggdmFsdWUgZm9yIGBrZXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBnZXRcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gaGFzaEdldChrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAobmF0aXZlQ3JlYXRlKSB7XG4gICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSBIQVNIX1VOREVGSU5FRCA/IHVuZGVmaW5lZCA6IHJlc3VsdDtcbiAgfVxuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpID8gZGF0YVtrZXldIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hHZXQ7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgaGFzaCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gKGRhdGFba2V5XSAhPT0gdW5kZWZpbmVkKSA6IGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoSGFzO1xuIiwidmFyIG5hdGl2ZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX25hdGl2ZUNyZWF0ZScpO1xuXG4vKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKlxuICogU2V0cyB0aGUgaGFzaCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIGhhc2hTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7XG4gIGRhdGFba2V5XSA9IChuYXRpdmVDcmVhdGUgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkgPyBIQVNIX1VOREVGSU5FRCA6IHZhbHVlO1xuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoU2V0O1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IG5ldyBhcnJheS5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gIC8vIEFkZCBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgcmVzdWx0LmluZGV4ID0gYXJyYXkuaW5kZXg7XG4gICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVBcnJheTtcbiIsInZhciBjbG9uZUFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fY2xvbmVBcnJheUJ1ZmZlcicpLFxuICAgIGNsb25lRGF0YVZpZXcgPSByZXF1aXJlKCcuL19jbG9uZURhdGFWaWV3JyksXG4gICAgY2xvbmVSZWdFeHAgPSByZXF1aXJlKCcuL19jbG9uZVJlZ0V4cCcpLFxuICAgIGNsb25lU3ltYm9sID0gcmVxdWlyZSgnLi9fY2xvbmVTeW1ib2wnKSxcbiAgICBjbG9uZVR5cGVkQXJyYXkgPSByZXF1aXJlKCcuL19jbG9uZVR5cGVkQXJyYXknKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY2xvbmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE1hcGAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgYFNldGAsIG9yIGBTdHJpbmdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUJ5VGFnKG9iamVjdCwgdGFnLCBpc0RlZXApIHtcbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBhcnJheUJ1ZmZlclRhZzpcbiAgICAgIHJldHVybiBjbG9uZUFycmF5QnVmZmVyKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgIHJldHVybiBjbG9uZURhdGFWaWV3KG9iamVjdCwgaXNEZWVwKTtcblxuICAgIGNhc2UgZmxvYXQzMlRhZzogY2FzZSBmbG9hdDY0VGFnOlxuICAgIGNhc2UgaW50OFRhZzogY2FzZSBpbnQxNlRhZzogY2FzZSBpbnQzMlRhZzpcbiAgICBjYXNlIHVpbnQ4VGFnOiBjYXNlIHVpbnQ4Q2xhbXBlZFRhZzogY2FzZSB1aW50MTZUYWc6IGNhc2UgdWludDMyVGFnOlxuICAgICAgcmV0dXJuIGNsb25lVHlwZWRBcnJheShvYmplY3QsIGlzRGVlcCk7XG5cbiAgICBjYXNlIG1hcFRhZzpcbiAgICAgIHJldHVybiBuZXcgQ3RvcjtcblxuICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKG9iamVjdCk7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVJlZ0V4cChvYmplY3QpO1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVN5bWJvbChvYmplY3QpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX2Jhc2VDcmVhdGUnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBpc1Byb3RvdHlwZSA9IHJlcXVpcmUoJy4vX2lzUHJvdG90eXBlJyk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNQcm90b3R5cGUob2JqZWN0KSlcbiAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpXG4gICAgOiB7fTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCIvKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAodHlwZSA9PSAnbnVtYmVyJyB8fFxuICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAodHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicpXG4gICAgPyAodmFsdWUgIT09ICdfX3Byb3RvX18nKVxuICAgIDogKHZhbHVlID09PSBudWxsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleWFibGU7XG4iLCJ2YXIgY29yZUpzRGF0YSA9IHJlcXVpcmUoJy4vX2NvcmVKc0RhdGEnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbnZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhICYmIGNvcmVKc0RhdGEua2V5cyAmJiBjb3JlSnNEYXRhLmtleXMuSUVfUFJPVE8gfHwgJycpO1xuICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG59KCkpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc01hc2tlZDtcbiIsIi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgcHJvdG8gPSAodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG5cbiAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1Byb3RvdHlwZTtcbiIsIi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gIHRoaXMuX19kYXRhX18gPSBbXTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVDbGVhcjtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBkZWxldGVcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgZGF0YS5wb3AoKTtcbiAgfSBlbHNlIHtcbiAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gIH1cbiAgLS10aGlzLnNpemU7XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZURlbGV0ZTtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZ2V0XG4gKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVHZXQ7XG4iLCJ2YXIgYXNzb2NJbmRleE9mID0gcmVxdWlyZSgnLi9fYXNzb2NJbmRleE9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZUhhcztcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIExpc3RDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICArK3RoaXMuc2l6ZTtcbiAgICBkYXRhLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSBlbHNlIHtcbiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZVNldDtcbiIsInZhciBIYXNoID0gcmVxdWlyZSgnLi9fSGFzaCcpLFxuICAgIExpc3RDYWNoZSA9IHJlcXVpcmUoJy4vX0xpc3RDYWNoZScpLFxuICAgIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpO1xuXG4vKipcbiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICB0aGlzLnNpemUgPSAwO1xuICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgJ21hcCc6IG5ldyAoTWFwIHx8IExpc3RDYWNoZSksXG4gICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVDbGVhcjtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZURlbGV0ZTtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7XG4gIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVHZXQ7XG4iLCJ2YXIgZ2V0TWFwRGF0YSA9IHJlcXVpcmUoJy4vX2dldE1hcERhdGEnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgaGFzXG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZUhhcztcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFNldHMgdGhlIG1hcCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIG1hcENhY2hlU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVTZXQ7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gKi9cbmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcFRvQXJyYXk7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBuYXRpdmVDcmVhdGUgPSBnZXROYXRpdmUoT2JqZWN0LCAnY3JlYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlQ3JlYXRlO1xuIiwidmFyIG92ZXJBcmcgPSByZXF1aXJlKCcuL19vdmVyQXJnJyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVLZXlzID0gb3ZlckFyZyhPYmplY3Qua2V5cywgT2JqZWN0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXRpdmVLZXlzO1xuIiwiLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2VcbiAqIFtgT2JqZWN0LmtleXNgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGV4Y2VwdCB0aGF0IGl0IGluY2x1ZGVzIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIG5hdGl2ZUtleXNJbihvYmplY3QpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBpZiAob2JqZWN0ICE9IG51bGwpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlS2V5c0luO1xuIiwidmFyIGZyZWVHbG9iYWwgPSByZXF1aXJlKCcuL19mcmVlR2xvYmFsJyk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG52YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovXG52YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBwcm9jZXNzYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZVByb2Nlc3MgPSBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwucHJvY2VzcztcblxuLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovXG52YXIgbm9kZVV0aWwgPSAoZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuXG4gICAgdmFyIHR5cGVzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlKCd1dGlsJykudHlwZXM7XG5cbiAgICBpZiAodHlwZXMpIHtcbiAgICAgIHJldHVybiB0eXBlcztcbiAgICB9XG5cbiAgICAvLyBMZWdhY3kgYHByb2Nlc3MuYmluZGluZygndXRpbCcpYCBmb3IgTm9kZS5qcyA8IDEwLlxuICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTtcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gbm9kZVV0aWw7XG4iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvYmplY3RUb1N0cmluZztcbiIsIi8qKlxuICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkge1xuICByZXR1cm4gZnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIGZ1bmModHJhbnNmb3JtKGFyZykpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG92ZXJBcmc7XG4iLCJ2YXIgZnJlZUdsb2JhbCA9IHJlcXVpcmUoJy4vX2ZyZWVHbG9iYWwnKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbnZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmO1xuXG4vKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbnZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJvb3Q7XG4iLCIvKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKlxuICogQWRkcyBgdmFsdWVgIHRvIHRoZSBhcnJheSBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgYWRkXG4gKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAqIEBhbGlhcyBwdXNoXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjYWNoZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBzZXRDYWNoZUFkZCh2YWx1ZSkge1xuICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpO1xuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRDYWNoZUFkZDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTZXRDYWNoZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRDYWNoZUhhcztcbiIsIi8qKlxuICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0VG9BcnJheTtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBTdGFja1xuICovXG5mdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0NsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrRGVsZXRlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrR2V0O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTdGFja1xuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0hhcztcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xudmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbi8qKlxuICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187XG4gICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpO1xuICB9XG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrU2V0O1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZ1bmNUb1N0cmluZyA9IGZ1bmNQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc291cmNlIGNvZGUuXG4gKi9cbmZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHtcbiAgaWYgKGZ1bmMgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZnVuY1RvU3RyaW5nLmNhbGwoZnVuYyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIChmdW5jICsgJycpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvU291cmNlO1xuIiwidmFyIGJhc2VDbG9uZSA9IHJlcXVpcmUoJy4vX2Jhc2VDbG9uZScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBjbG9uaW5nLiAqL1xudmFyIENMT05FX0RFRVBfRkxBRyA9IDEsXG4gICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBjbG9uZXMgYHZhbHVlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmVjdXJzaXZlbHkgY2xvbmUuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gKiBAc2VlIF8uY2xvbmVcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbeyAnYSc6IDEgfSwgeyAnYic6IDIgfV07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAqIGNvbnNvbGUubG9nKGRlZXBbMF0gPT09IG9iamVjdHNbMF0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gY2xvbmVEZWVwKHZhbHVlKSB7XG4gIHJldHVybiBiYXNlQ2xvbmUodmFsdWUsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVEZWVwO1xuIiwiLyoqXG4gKiBQZXJmb3JtcyBhXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGVxdWl2YWxlbnQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9O1xuICpcbiAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoJ2EnLCAnYScpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoTmFOLCBOYU4pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBvdGhlciB8fCAodmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXE7XG4iLCJ2YXIgYmFzZUlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9fYmFzZUlzQXJndW1lbnRzJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQXJndW1lbnRzID0gYmFzZUlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID8gYmFzZUlzQXJndW1lbnRzIDogZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwodmFsdWUsICdjYWxsZWUnKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzXG4gKiBub3QgYSBmdW5jdGlvbiBhbmQgaGFzIGEgYHZhbHVlLmxlbmd0aGAgdGhhdCdzIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIG9yXG4gKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZSgnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhaXNGdW5jdGlvbih2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKSxcbiAgICBzdHViRmFsc2UgPSByZXF1aXJlKCcuL3N0dWJGYWxzZScpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG52YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4vKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xudmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMgPyByb290LkJ1ZmZlciA6IHVuZGVmaW5lZDtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4zLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNCdWZmZXIobmV3IEJ1ZmZlcigyKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0J1ZmZlcihuZXcgVWludDhBcnJheSgyKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNCdWZmZXIgPSBuYXRpdmVJc0J1ZmZlciB8fCBzdHViRmFsc2U7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNCdWZmZXI7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL19iYXNlSXNFcXVhbCcpO1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmVcbiAqIGVxdWl2YWxlbnQuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGNvbXBhcmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLFxuICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICogc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkIGFycmF5cy4gYE9iamVjdGAgb2JqZWN0cyBhcmUgY29tcGFyZWRcbiAqIGJ5IHRoZWlyIG93biwgbm90IGluaGVyaXRlZCwgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLiBGdW5jdGlvbnMgYW5kIERPTVxuICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEgfTtcbiAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gKlxuICogXy5pc0VxdWFsKG9iamVjdCwgb3RoZXIpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIG9iamVjdCA9PT0gb3RoZXI7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VxdWFsKHZhbHVlLCBvdGhlcikge1xuICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VxdWFsO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIHByb3h5VGFnID0gJ1tvYmplY3QgUHJveHldJztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oXyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0Z1bmN0aW9uKC9hYmMvKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIFNhZmFyaSA5IHdoaWNoIHJldHVybnMgJ29iamVjdCcgZm9yIHR5cGVkIGFycmF5cyBhbmQgb3RoZXIgY29uc3RydWN0b3JzLlxuICB2YXIgdGFnID0gYmFzZUdldFRhZyh2YWx1ZSk7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsIi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0xlbmd0aCgzKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzTGVuZ3RoKEluZmluaXR5KTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aCgnMycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsInZhciBiYXNlSXNNYXAgPSByZXF1aXJlKCcuL19iYXNlSXNNYXAnKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzTWFwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNNYXA7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBNYXBgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMy4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTWFwKG5ldyBNYXApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNNYXAobmV3IFdlYWtNYXApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzTWFwID0gbm9kZUlzTWFwID8gYmFzZVVuYXJ5KG5vZGVJc01hcCkgOiBiYXNlSXNNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNNYXA7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0TGlrZTtcbiIsInZhciBiYXNlSXNTZXQgPSByZXF1aXJlKCcuL19iYXNlSXNTZXQnKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzU2V0ID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNTZXQ7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMy4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNldCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU2V0KG5ldyBTZXQpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTZXQobmV3IFdlYWtTZXQpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzU2V0ID0gbm9kZUlzU2V0ID8gYmFzZVVuYXJ5KG5vZGVJc1NldCkgOiBiYXNlSXNTZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTZXQ7XG4iLCJ2YXIgYmFzZUlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vX2Jhc2VJc1R5cGVkQXJyYXknKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVHlwZWRBcnJheTtcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzID0gcmVxdWlyZSgnLi9fYmFzZUtleXMnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy5rZXlzKCdoaScpO1xuICogLy8gPT4gWycwJywgJzEnXVxuICovXG5mdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5cztcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzSW4gPSByZXF1aXJlKCcuL19iYXNlS2V5c0luJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDMuMC4wXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXNJbihuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJywgJ2MnXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBrZXlzSW4ob2JqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5TGlrZShvYmplY3QpID8gYXJyYXlMaWtlS2V5cyhvYmplY3QsIHRydWUpIDogYmFzZUtleXNJbihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBhcnJheS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMTMuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgYXJyYXlzID0gXy50aW1lcygyLCBfLnN0dWJBcnJheSk7XG4gKlxuICogY29uc29sZS5sb2coYXJyYXlzKTtcbiAqIC8vID0+IFtbXSwgW11dXG4gKlxuICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gc3R1YkFycmF5KCkge1xuICByZXR1cm4gW107XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3R1YkFycmF5O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEzLjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRpbWVzKDIsIF8uc3R1YkZhbHNlKTtcbiAqIC8vID0+IFtmYWxzZSwgZmFsc2VdXG4gKi9cbmZ1bmN0aW9uIHN0dWJGYWxzZSgpIHtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0dWJGYWxzZTtcbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0aWQ6IG1vZHVsZUlkLFxuXHRcdGxvYWRlZDogZmFsc2UsXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuXHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIl9fd2VicGFja19yZXF1aXJlX18uZyA9IChmdW5jdGlvbigpIHtcblx0aWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSAnb2JqZWN0JykgcmV0dXJuIGdsb2JhbFRoaXM7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIHRoaXMgfHwgbmV3IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHJldHVybiB3aW5kb3c7XG5cdH1cbn0pKCk7IiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsImltcG9ydCB0eXBlIE9wZW5GaW4gZnJvbSBcIkBvcGVuZmluL2NvcmVcIjtcbmltcG9ydCB7IGZpbiB9IGZyb20gXCJAb3BlbmZpbi9jb3JlXCI7XG5cbmxldCBmaWxlTmFtZTogc3RyaW5nO1xubGV0IGRlYnVnTG9nU3RyOiBzdHJpbmc7XG5sZXQgZGVidWdMb2dGaWxlOiBGaWxlO1xuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBhc3luYyAoKSA9PiB7XG5cdHRyeSB7XG5cdFx0YXdhaXQgaW5pdERvbSgpO1xuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuXHR9XG59KTtcblxuLyoqXG4gKiBQb3B1bGF0ZXMgRE9NIHdpdGggdGhlIFVJIGVsZW1lbnRzIGFuZCBhZGRzIGxpc3RlbmVycyBvYnRhaW5pbmcgc2VsZWN0ZWQvc3VibWl0dGVkIG9wdGlvbnMuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluaXREb20oKTogUHJvbWlzZTx2b2lkPiB7XG5cdGNvbnN0IGxvZ0xpc3RFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MU2VsZWN0RWxlbWVudD4oXCIjbG9nLWxpc3RcIik7XG5cdGlmIChsb2dMaXN0RWxlbWVudCkge1xuXHRcdGF3YWl0IGNyZWF0ZUxvZ0Ryb3BEb3duKGxvZ0xpc3RFbGVtZW50KTtcblx0XHRsb2dMaXN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsIGFzeW5jIChzZWxlY3Rpb25DaGFuZ2VFdmVudCkgPT4ge1xuXHRcdFx0ZmlsZU5hbWUgPSAoc2VsZWN0aW9uQ2hhbmdlRXZlbnQudGFyZ2V0IGFzIEhUTUxPcHRpb25FbGVtZW50KS52YWx1ZTtcblx0XHR9KTtcblx0fVxuXG5cdGNvbnN0IHVwbG9hZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEZvcm1FbGVtZW50PihcIiN1cGxvYWQtZm9ybVwiKTtcblx0aWYgKHVwbG9hZCkge1xuXHRcdHVwbG9hZC5hZGRFdmVudExpc3RlbmVyKFwic3VibWl0XCIsIHVwbG9hZEhhbmRsZXIpO1xuXHR9XG5cdGNvbnN0IHNlbmRBcHBMb2dCdG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxCdXR0b25FbGVtZW50PihcIiNzZW5kLWFwcC1sb2dcIik7XG5cdGlmIChzZW5kQXBwTG9nQnRuKSB7XG5cdFx0c2VuZEFwcExvZ0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgc2VuZEFwcGxpY2F0aW9uTG9ncyk7XG5cdH1cbn1cblxuLyoqXG4gKiBIYW5kbGUgdXBsb2Fkcy5cbiAqIDEuIENyZWF0ZXMgYSBGb3JtRGF0YSBvYmplY3QuXG4gKiAyLiBDcmVhdGVzIGEgRmlsZSBvYmplY3QgZnJvbSB0aGUgc3RyaW5nIG9mIHRoZSBSdW50aW1lIGRlYnVnIGxvZyBmaWxlIGNvbnRlbnRzLlxuICogMy4gUG9wdWxhdGVzIHRoZSBGb3JtRGF0YSBvYmplY3Qgd2l0aCBuZWNlc3NhcnkgcGFyYW1ldGVycyB0byBiZSByZWFkIGJ5IHRoZSBzZXJ2ZXIuXG4gKiA0LiBVcGxvYWRzIHRoZSBjcmVhdGVkIHJ1bnRpbWUgZGVidWcgbG9nIGZpbGUgdG8gYSBzZXJ2ZXIgZW5kcG9pbnQuXG4gKiBAcGFyYW0gc3VibWl0RXZlbnQgVGhlIGV2ZW50IHRvIGhhbmRsZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gdXBsb2FkSGFuZGxlcihzdWJtaXRFdmVudDogRXZlbnQpOiBQcm9taXNlPHZvaWQ+IHtcblx0c3VibWl0RXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0aWYgKCFmaWxlTmFtZSkge1xuXHRcdGZpbGVOYW1lID0gXCJkZWJ1Zy5sb2dcIjtcblx0fVxuXHRjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuXHRkZWJ1Z0xvZ1N0ciA9IGF3YWl0IGdldExvZ0Zyb21OYW1lKGZpbGVOYW1lKTtcblx0ZGVidWdMb2dGaWxlID0gbmV3IEZpbGUoW2RlYnVnTG9nU3RyXSwgZmlsZU5hbWUsIHsgdHlwZTogXCJ0ZXh0L3BsYWluXCIgfSk7XG5cdGZvcm1EYXRhLmFwcGVuZChcImZpbGVcIiwgZGVidWdMb2dGaWxlKTtcblx0Zm9ybURhdGEuYXBwZW5kKFwiZmlsZW5hbWVcIiwgZmlsZU5hbWUpO1xuXHRmb3JtRGF0YS5hcHBlbmQoXCJ1dWlkXCIsIGZpbi5tZS51dWlkKTtcblx0Y29uc3QgdXBsb2FkU3RhdGUgPSBhd2FpdCBmZXRjaChcImh0dHA6Ly9sb2NhbGhvc3Q6NTA1MC91cGxvYWRzXCIsIHtcblx0XHRtZXRob2Q6IFwiUE9TVFwiLFxuXHRcdGJvZHk6IGZvcm1EYXRhXG5cdH0pO1xuXG5cdGNvbnN0IHVwbG9hZFN0YXRlSnNvbiA9IGF3YWl0IHVwbG9hZFN0YXRlLmpzb24oKTtcblx0Y29uc3QgdXBsb2FkU3RhdGVKc29uU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkodXBsb2FkU3RhdGVKc29uLCBudWxsLCA1KTtcblx0Y29uc3QgbG9ncyA9IGAke25ldyBEYXRlKCkudG9Mb2NhbGVUaW1lU3RyaW5nKCl9OiAke3VwbG9hZFN0YXRlSnNvblN0cmluZ31cXG5gO1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHRpZiAobG9nUHJldmlldykge1xuXHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgKz0gbG9ncztcblx0fVxufVxuXG4vKipcbiAqIFNlbmRzIGEgbWVzc2FnZSB0byB0aGUgT3BlbkZpbiBSVk0gdG8gc2VuZCB0aGUgYXBwbGljYXRpb24gbG9ncy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2VuZEFwcGxpY2F0aW9uTG9ncygpOiBQcm9taXNlPHZvaWQ+IHtcblx0dHJ5IHtcblx0XHRjb25zdCBhcHBMb2dSZXNwb25zZSA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpLnNlbmRBcHBsaWNhdGlvbkxvZygpO1xuXHRcdGNvbnNvbGUubG9nKGBMb2cgSUQ6ICR7YXBwTG9nUmVzcG9uc2UubG9nSWR9YCk7XG5cdH0gY2F0Y2gge1xuXHRcdC8vIHN3YWxsb3cgdW5uZWNlc3NhcnkgZXJyb3JzLlxuXHR9XG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBydW50aW1lIGRlYnVnIGxvZyBmcm9tIGEgZmlsZW5hbWUuXG4gKiBAcGFyYW0gbmFtZSBmaWxlIG5hbWUgb2YgdGhlIHJ1bnRpbWUgZGVidWcgbG9nIHRvIHJldHJpZXZlLlxuICogQHJldHVybnMgdGhlIGxvZyBjb250ZW50LlxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRMb2dGcm9tTmFtZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRjb25zdCBsb2cgPSBhd2FpdCBmaW4uU3lzdGVtLmdldExvZyh7IG5hbWUgfSk7XG5cdHJldHVybiBsb2c7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBIVE1MT3B0aW9uRWxlbWVudCBmb3IgZWFjaCBvZiB0aGUgUnVudGltZSBkZWJ1ZyBsb2dzLlxuICogQHBhcmFtIHBhcmVudEVsZW1lbnQgSFRNTCBFbGVtZW50IHRvIGFwcGVuZCB0aGUgbG9nIGZpbGVuYW1lIEhUTUxPcHRpb25FbGVtZW50IHRvLlxuICovXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVMb2dEcm9wRG93bihwYXJlbnRFbGVtZW50OiBIVE1MU2VsZWN0RWxlbWVudCk6IFByb21pc2U8dm9pZD4ge1xuXHRjb25zdCBsb2dMaXN0OiBPcGVuRmluLkxvZ0luZm9bXSA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0TG9nTGlzdCgpO1xuXG5cdGZvciAoY29uc3QgbG9nIG9mIGxvZ0xpc3QpIHtcblx0XHRjb25zdCBsb2dFbGVtZW50OiBIVE1MT3B0aW9uRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIik7XG5cdFx0bG9nRWxlbWVudC5pZCA9IGxvZy5kYXRlO1xuXHRcdGxvZ0VsZW1lbnQudGV4dENvbnRlbnQgPSBsb2cubmFtZTtcblx0XHRsb2dFbGVtZW50LnZhbHVlID0gbG9nLm5hbWU7XG5cdFx0cGFyZW50RWxlbWVudC5hcHBlbmQobG9nRWxlbWVudCk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRUFBbUU7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxzQkFBc0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxzQkFBc0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxzQkFBc0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELHNCQUFzQjtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEVBQThFLFNBQVM7QUFDdkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLFNBQVM7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RCx5QkFBeUI7QUFDaEY7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRkFBb0YsU0FBUztBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsVUFBVTtBQUMzQjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsMENBQTBDO0FBQ25FO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qix5Q0FBeUM7QUFDbEU7QUFDQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRUFBK0UsU0FBUztBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRixTQUFTO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0ZBQWdGLFNBQVM7QUFDekY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELFdBQVc7QUFDM0Q7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxXQUFXO0FBQ3JEO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxpQ0FBaUM7QUFDMUU7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlGQUFpRixTQUFTO0FBQzFGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRSxTQUFTO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLFNBQVM7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RCxTQUFTO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsU0FBUztBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxTQUFTO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxnQkFBZ0I7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0QsS0FBSztBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDRFQUE0RTtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyx5QkFBeUI7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSw0RUFBNEU7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1FQUFtRSxjQUFjO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDRFQUE0RTtBQUNwRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUVBQW1FLGNBQWMsVUFBVSxTQUFTO0FBQ3BHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRSxNQUFNO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSLDhEQUE4RCxtREFBbUQ7QUFDakg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsc0RBQXNEO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixpQkFBaUI7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxrQkFBa0I7QUFDM0QsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELFdBQVc7QUFDcEUsbURBQW1ELFdBQVc7QUFDOUQseURBQXlELFdBQVc7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixxQkFBcUI7QUFDekMsMkRBQTJELGVBQWU7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQsWUFBWTtBQUN0RTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixtRUFBbUU7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsMkRBQTJELFlBQVk7QUFDdkU7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtEQUErRCxXQUFXO0FBQzFFLHlEQUF5RCxXQUFXO0FBQ3BFLCtEQUErRCxXQUFXO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IscUJBQXFCO0FBQzdDLCtEQUErRCxlQUFlO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQsWUFBWTtBQUN6RTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLDhCQUE4QjtBQUMzQyxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLG9CQUFvQjtBQUNqRCxtQ0FBbUMsSUFBSTtBQUN2Qyx1Q0FBdUMsUUFBUTtBQUMvQztBQUNBLHlDQUF5QyxNQUFNO0FBQy9DO0FBQ0EsWUFBWTtBQUNaLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxrRUFBa0UsU0FBUyxVQUFVLFNBQVM7QUFDOUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkVBQTZFLFNBQVM7QUFDdEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsZ0JBQWdCO0FBQ25EO0FBQ0E7QUFDQTtBQUNBLDJFQUEyRSxTQUFTO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixpQkFBaUI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsS0FBSztBQUN6RCx1RUFBdUUsU0FBUztBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELE9BQU87QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksNEZBQTRGO0FBQ3hHO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQiwyRkFBMkY7QUFDckg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRSxNQUFNLFVBQVUsU0FBUztBQUMvRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkMsZUFBZTtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2QixtRUFBbUUsTUFBTSxVQUFVLFNBQVM7QUFDNUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRSxNQUFNLFVBQVUsU0FBUztBQUMvRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3QjtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0UsK0JBQStCO0FBQy9GO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLHNCQUFzQixTQUFTO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRUFBb0UsU0FBUztBQUM3RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsaUNBQWlDLDBCQUEwQjtBQUN4RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRkFBZ0Y7QUFDaEY7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0MsZ0JBQWdCLDBCQUEwQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixpREFBaUQ7QUFDekU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyw0QkFBNEIsR0FBRyxHQUFHO0FBQ3pFLHVDQUF1Qyx1QkFBdUIsR0FBRyxHQUFHO0FBQ3BFLHVDQUF1Qyw0QkFBNEIsR0FBRyxHQUFHO0FBQ3pFLHVDQUF1Qyx5QkFBeUIsR0FBRyxHQUFHO0FBQ3RFLHVDQUF1Qyw0QkFBNEIsR0FBRyxHQUFHO0FBQ3pFLHVDQUF1Qyx5QkFBeUIsR0FBRyxHQUFHO0FBQ3RFO0FBQ0E7QUFDQSwyQkFBMkIsNEJBQTRCLEdBQUcsR0FBRztBQUM3RCwyQkFBMkIsdUJBQXVCLEdBQUcsR0FBRztBQUN4RCw2QkFBNkIsNEJBQTRCLEdBQUcsR0FBRztBQUMvRCw2QkFBNkIseUJBQXlCLEdBQUcsR0FBRztBQUM1RCw2QkFBNkIsNEJBQTRCLEdBQUcsR0FBRztBQUMvRCw2QkFBNkIseUJBQXlCLEdBQUcsR0FBRztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsVUFBVSw0RUFBNEUsYUFBYTtBQUNuSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsWUFBWTtBQUN0Qyx1REFBdUQsWUFBWTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsWUFBWTtBQUNaO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSw4RUFBOEUsU0FBUztBQUN2RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFdBQVcsU0FBUztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQsa0NBQWtDO0FBQzlGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFVBQVU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUEsa0RBQWtELGFBQWE7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQSwrQ0FBK0MsYUFBYTtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQsTUFBTTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsK0VBQStFLGtDQUFrQztBQUNqSDtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRCwwQkFBMEIsaURBQWlELE9BQU87QUFDckk7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCwwQkFBMEIsaURBQWlELE9BQU87QUFDdkk7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSx1REFBdUQsYUFBYTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJGQUEyRiwyQ0FBMkM7QUFDdEk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJGQUEyRiwyQ0FBMkM7QUFDdEk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGdEQUFnRCxhQUFhO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0EseURBQXlELGFBQWE7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsK0NBQStDO0FBQ3ZGO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMseUJBQXlCO0FBQ3pCO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxtSUFBbUkseUJBQXlCO0FBQzVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0VBQStFO0FBQy9FO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFJQUFxSSx5QkFBeUI7QUFDOUo7QUFDQSxnQkFBZ0IsV0FBVztBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7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O0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7O0FBRUEsa0NBQWtDLFFBQVE7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7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QUFhLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDakMsYUFBYSxHQUFHLE1BQU0sOENBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzVFLENBQUM7QUFDRixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVk7SUFDcEIsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0RCxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLFVBQVUsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO0lBQzdCLENBQUM7QUFDRixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvQG9wZW5maW4vY29yZS9vdXQvbW9jay5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fRGF0YVZpZXcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19IYXNoLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fTGlzdENhY2hlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fTWFwQ2FjaGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19Qcm9taXNlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fU2V0Q2FjaGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19TdGFjay5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX1N5bWJvbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX1VpbnQ4QXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19XZWFrTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlFYWNoLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlGaWx0ZXIuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheUxpa2VLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlQdXNoLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlTb21lLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXNzaWduVmFsdWUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19hc3NvY0luZGV4T2YuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlQXNzaWduLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnbkluLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnblZhbHVlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUNsb25lLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUNyZWF0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VHZXRBbGxLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUdldFRhZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0FyZ3VtZW50cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0VxdWFsLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzRXF1YWxEZWVwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTmF0aXZlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzVHlwZWRBcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUtleXNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VUaW1lcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VVbmFyeS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2NhY2hlSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVBcnJheUJ1ZmZlci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lQnVmZmVyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVEYXRhVmlldy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lUmVnRXhwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVTeW1ib2wuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jbG9uZVR5cGVkQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jb3B5QXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jb3B5T2JqZWN0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weVN5bWJvbHMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jb3B5U3ltYm9sc0luLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29yZUpzRGF0YS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2RlZmluZVByb3BlcnR5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxBcnJheXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19lcXVhbEJ5VGFnLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxPYmplY3RzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZnJlZUdsb2JhbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldEFsbEtleXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRBbGxLZXlzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRNYXBEYXRhLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TmF0aXZlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UHJvdG90eXBlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UmF3VGFnLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0U3ltYm9scy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFN5bWJvbHNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFRhZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFZhbHVlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaENsZWFyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaERlbGV0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hHZXQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19oYXNoSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaFNldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2luaXRDbG9uZUFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faW5pdENsb25lQnlUYWcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pbml0Q2xvbmVPYmplY3QuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pc0luZGV4LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faXNLZXlhYmxlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faXNNYXNrZWQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pc1Byb3RvdHlwZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUNsZWFyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlRGVsZXRlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlR2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbGlzdENhY2hlU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVDbGVhci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlRGVsZXRlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVHZXQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZUhhcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwVG9BcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX25hdGl2ZUNyZWF0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX25hdGl2ZUtleXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19uYXRpdmVLZXlzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19ub2RlVXRpbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX29iamVjdFRvU3RyaW5nLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fb3ZlckFyZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3Jvb3QuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zZXRDYWNoZUFkZC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3NldENhY2hlSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0VG9BcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrQ2xlYXIuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja0RlbGV0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrR2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc3RhY2tIYXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja1NldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3RvU291cmNlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9jbG9uZURlZXAuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2VxLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0FyZ3VtZW50cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcnJheUxpa2UuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzQnVmZmVyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0VxdWFsLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0Z1bmN0aW9uLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0xlbmd0aC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNNYXAuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzT2JqZWN0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc09iamVjdExpa2UuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzU2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc1R5cGVkQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2tleXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2tleXNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvc3R1YkFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9zdHViRmFsc2UuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzL3dlYnBhY2svcnVudGltZS9nbG9iYWwiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy93ZWJwYWNrL3J1bnRpbWUvbWFrZSBuYW1lc3BhY2Ugb2JqZWN0Iiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvd2VicGFjay9ydW50aW1lL25vZGUgbW9kdWxlIGRlY29yYXRvciIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4vY2xpZW50L3NyYy9hcHAudHMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgcmVxdWlyZSQkMCA9IHJlcXVpcmUoJ2V2ZW50cycpO1xudmFyIHJlcXVpcmUkJDAkMSA9IHJlcXVpcmUoJ2xvZGFzaC9jbG9uZURlZXAnKTtcbnZhciByZXF1aXJlJCQzID0gcmVxdWlyZSgnbG9kYXNoL2lzRXF1YWwnKTtcblxuZnVuY3Rpb24gX21lcmdlTmFtZXNwYWNlcyhuLCBtKSB7XG5cdG0uZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuXHRcdGUgJiYgdHlwZW9mIGUgIT09ICdzdHJpbmcnICYmICFBcnJheS5pc0FycmF5KGUpICYmIE9iamVjdC5rZXlzKGUpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0XHRcdGlmIChrICE9PSAnZGVmYXVsdCcgJiYgIShrIGluIG4pKSB7XG5cdFx0XHRcdHZhciBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLCBrKTtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG4sIGssIGQuZ2V0ID8gZCA6IHtcblx0XHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZVtrXTsgfVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSk7XG5cdHJldHVybiBPYmplY3QuZnJlZXplKG4pO1xufVxuXG52YXIgY29tbW9uanNHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fTtcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHtcblx0cmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDtcbn1cblxudmFyIE9wZW5GaW4kMiA9IHt9O1xuXG52YXIgZXZlbnRzID0ge307XG5cbnZhciBhcHBsaWNhdGlvbiQxID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgdGhhdCBjYW4gYmUgZW1pdHRlZCBieSBhbiB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbn0uICBJbmNsdWRlcyBldmVudHNcbiAqIHJlLXByb3BhZ2F0ZWQgZnJvbSB0aGUge0BsaW5rIE9wZW5GaW4uV2luZG93fSAoYW5kLCB0cmFuc2l0aXZlbHksIHtAbGluayBPcGVuRmluLlZpZXd9KSBsZXZlbCwgcHJlZml4ZWQgd2l0aCBgd2luZG93LWAgKGFuZCBhbHNvLCBpZiBhcHBsaWNhYmxlLCBgdmlldy1gKS5cbiAqIEZvciBleGFtcGxlLCBhIHZpZXcncyBcImF0dGFjaGVkXCIgZXZlbnQgd2lsbCBmaXJlIGFzICd3aW5kb3ctdmlldy1hdHRhY2hlZCcgYXQgdGhlIGFwcGxpY2F0aW9uIGxldmVsLlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhpcyBuYW1lc3BhY2UgY29udGFpbnMgb25seSBwYXlsb2FkIHNoYXBlcyBmb3IgZXZlbnRzIHRoYXQgYXJlIHVuaXF1ZSB0byBgQXBwbGljYXRpb25gLiAgRXZlbnRzIHRoYXQgcHJvcGFnYXRlIHRvIGBBcHBsaWNhdGlvbmAgZnJvbVxuICogY2hpbGQge0BsaW5rIE9wZW5GaW4uV2luZG93IHdpbmRvd3N9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3IHZpZXdzfSBhcmUgZGVmaW5lZCBpbiB0aGUge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfSBhbmRcbiAqIHtAbGluayBPcGVuRmluLlZpZXdFdmVudHN9IG5hbWVzcGFjZXMuICBGb3IgYSBsaXN0IG9mIHZhbGlkIHN0cmluZyBrZXlzIGZvciAqYWxsKiBhcHBsaWNhdGlvbiBldmVudHMsIHNlZSB7QGxpbmsgQXBwbGljYXRpb24ub24gQXBwbGljYXRpb24ub259LlxuICpcbiAqIHtAbGluayBBcHBsaWNhdGlvblNvdXJjZWRFdmVudCBBcHBsaWNhdGlvbi1zb3VyY2VkIGV2ZW50c30gKGkuZS4gdGhvc2UgdGhhdCBoYXZlIG5vdCBwcm9wYWdhdGVkIGZyb20ge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3c31cbiAqIG9yIHtAbGluayBPcGVuRmluLldpbmRvd0V2ZW50cyBXaW5kb3dzfSByZS1wcm9wYWdhdGUgdG8ge0BsaW5rIE9wZW5GaW4uU3lzdGVtRXZlbnRzIFN5c3RlbX0gd2l0aCB0aGVpciB0eXBlIHN0cmluZyBwcmVmaXhlZCB3aXRoIGBhcHBsaWNhdGlvbi1gLlxuICoge0BsaW5rIEFwcGxpY2F0aW9uV2luZG93RXZlbnQgQXBwbGljYXRpb24gZXZlbnRzIHRoYXQgYXJlIHRpZWQgdG8gV2luZG93cyBidXQgZG8gbm90IHByb3BhZ2F0ZSBmcm9tIHRoZW19XG4gKiBhcmUgcHJvcGFnYXRlZCB0byBgU3lzdGVtYCB3aXRob3V0IGFueSB0eXBlIHN0cmluZyBwcmVmaXhpbmcuXG4gKlxuICogXCJSZXF1ZXN0ZWRcIiBldmVudHMgKGUuZy4ge0BsaW5rIFJ1blJlcXVlc3RlZEV2ZW50fSkgZG8gbm90IHByb3BhZ2F0ZS5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcGxpY2F0aW9uJDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgYmFzZSQxID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBzaGFyZWQgZXZlbnQgcGF5bG9hZHMgYW5kIHV0aWxpdHkgdHlwZXMgY29tbW9uIHRvIGFsbCBldmVudCBlbWl0dGVycy5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGJhc2UkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBleHRlcm5hbEFwcGxpY2F0aW9uJDEgPSB7fTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBiZSB0cmFuc21pdHRlZCBieSBhbiB7QGxpbmsgT3BlbkZpbi5FeHRlcm5hbEFwcGxpY2F0aW9ufS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yIGV4dGVybmFsIGFwcGxpY2F0aW9uIGV2ZW50cywgc2VlIHtAbGluayBFeHRlcm5hbEFwcGxpY2F0aW9uLm9uIEV4dGVybmFsQXBwbGljYXRpb24ub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXh0ZXJuYWxBcHBsaWNhdGlvbiQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIGZyYW1lJDEgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGZyYW1lJDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgZ2xvYmFsSG90a2V5JDEgPSB7fTtcblxuLyoqXG4gKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgdGhhdCBjYW4gYmUgdHJhbnNtaXR0ZWQgYnkge0BsaW5rIEdsb2JhbEhvdGtleS5HbG9iYWxIb3RrZXl9LlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogRm9yIGEgbGlzdCBvZiB2YWxpZCBzdHJpbmcga2V5cyBmb3IgZ2xvYmFsIGhvdGtleSBldmVudHMsIHNlZSB7QGxpbmsgR2xvYmFsSG90a2V5Lkdsb2JhbEhvdGtleS5vbiBHbG9iYWxIb3RrZXkub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsSG90a2V5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgcGxhdGZvcm0kMSA9IHt9O1xuXG4vKipcbiAqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBlbWl0dGVkIGJ5IGEge0BsaW5rIE9wZW5GaW4uUGxhdGZvcm19LlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhlIFBsYXRmb3JtIGBFdmVudEVtaXR0ZXJgIGlzIGEgc3VwZXJzZXQgb2YgdGhlIHtAbGluayBPcGVuRmluLkFwcGxpY2F0aW9ufSBgRXZlbnRFbWl0dGVyYCxcbiAqIG1lYW5pbmcgaXQgY2FuIGxpc3RlbiB0byBhbGwge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb25FdmVudHMgQXBwbGljYXRpb24gZXZlbnRzfSBpbiBhZGRpdGlvbiB0byB0aGVcbiAqIFBsYXRmb3JtLXNwZWNpZmljIGV2ZW50cyBsaXN0ZWQgaGVyZS4gIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIHBsYXRmb3JtIGV2ZW50cywgc2VlXG4gKiB7QGxpbmsgUGxhdGZvcm0ub24gUGxhdGZvcm0ub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkocGxhdGZvcm0kMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBzeXN0ZW0kMSA9IHt9O1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgcnVudGltZS13aWRlIE9wZW5GaW4gZXZlbnRzIGVtaXR0ZWQgYnkge0BsaW5rIFN5c3RlbS5TeXN0ZW19LiAgSW5jbHVkZXMgZXZlbnRzXG4gKiByZS1wcm9wYWdhdGVkIGZyb20ge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259LCB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9LCBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30gKHByZWZpeGVkIHdpdGggYGFwcGxpY2F0aW9uLWAsIGB3aW5kb3ctYCwgYW5kIGB2aWV3LWApLiAgQWxsXG4gKiBldmVudCBwcm9wYWdhdGlvbnMgYXJlIHZpc2libGUgYXQgdGhlIFN5c3RlbSBsZXZlbC4gUHJvcGFnYXRlZCBldmVudHMgZnJvbSBXZWJDb250ZW50cyAod2luZG93cywgdmlld3MsIGZyYW1lcykgdG8gdGhlIEFwcGxpY2F0aW9uIGxldmVsIHdpbGwgKm5vdCpcbiAqIHRyYW5zaXRpdmVseSByZS1wcm9wYWdhdGUgdG8gdGhlIFN5c3RlbSBsZXZlbCwgYmVjYXVzZSB0aGV5IGFyZSBhbHJlYWR5IHZpc2libGUgYXQgdGhlIHN5c3RlbSBsZXZlbCBhbmQgY29udGFpbiB0aGUgaWRlbnRpdHlcbiAqIG9mIHRoZSBhcHBsaWNhdGlvbi4gIEZvciBleGFtcGxlLCBhbiBhcHBsaWNhdGlvbidzIFwiY2xvc2VkXCIgZXZlbnQgd2lsbCBmaXJlIGFzICdhcHBsaWNhdGlvbi1jbG9zZWQnIGF0IHRoZSBzeXN0ZW0gbGV2ZWwuICBBIHZpZXcncyAnc2hvd24nIGV2ZW50XG4gKiB3aWxsIGJlIHZpc2libGUgYXMgJ3ZpZXctc2hvd24nIGF0IHRoZSBzeXN0ZW0gbGV2ZWwsIGJ1dCAqbm90KiBhcyBgYXBwbGljYXRpb24td2luZG93LXZpZXctc2hvd25gLlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhpcyBuYW1lc3BhY2UgY29udGFpbnMgb25seSBwYXlsb2FkIHNoYXBlcyBmb3IgZXZlbnRzIHRoYXQgYXJlIHVuaXF1ZSB0byBgU3lzdGVtYC4gIEV2ZW50cyB0aGF0IHByb3BhZ2F0ZSB0byBgU3lzdGVtYCBmcm9tXG4gKiBjaGlsZCB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbiBhcHBsaWNhdGlvbnN9LCB7QGxpbmsgT3BlbkZpbi5XaW5kb3cgd2luZG93c30sIGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3IHZpZXdzfSBhcmUgZGVmaW5lZCBpbiB0aGVcbiAqIHtAbGluayBPcGVuRmluLkFwcGxpY2F0aW9uRXZlbnRzfSwge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfSwgYW5kIHtAbGluayBPcGVuRmluLlZpZXdFdmVudHN9IG5hbWVzcGFjZXMuICBGb3IgYSBsaXN0IG9mIHZhbGlkIHN0cmluZyBrZXlzIGZvciAqYWxsKlxuICogc3lzdGVtIGV2ZW50cywgc2VlIHtAbGluayBTeXN0ZW0ub24gU3lzdGVtLm9ufS5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN5c3RlbSQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIHZpZXckMSA9IHt9O1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgZXZlbnRzIHRoYXQgY2FuIGJlIGVtaXR0ZWQgYnkgYSB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIFRoaXMgbmFtZXNwYWNlIGNvbnRhaW5zIG9ubHkgcGF5bG9hZCBzaGFwZXMgZm9yIGV2ZW50cyB0aGF0IGFyZSB1bmlxdWUgdG8gYFZpZXdgLiAgRXZlbnRzIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIGFsbCBgV2ViQ29udGVudHNgXG4gKiAoaS5lLiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9LCB7QGxpbmsgT3BlbkZpbi5WaWV3fSkgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHN9LiAgRm9yIGEgbGlzdFxuICogb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIFZpZXcgZXZlbnRzLCBzZWUge0BsaW5rIFZpZXcub24gVmlldy5vbn0uXG4gKlxuICogVmlldyBldmVudHMgcHJvcGFnYXRlIHRvIHRoZWlyIHBhcmVudCB7QGxpbmsgT3BlbkZpbi5XaW5kb3dFdmVudHMgV2luZG93fSwge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb25FdmVudHMgQXBwbGljYXRpb259LFxuICogYW5kIHtAbGluayBPcGVuRmluLlN5c3RlbUV2ZW50cyBTeXN0ZW19IHdpdGggYW4gYWRkZWQgYHZpZXdJZGVudGl0eWAgcHJvcGVydHkgYW5kIHRoZWlyIGV2ZW50IHR5cGVzIHByZWZpeGVkIHdpdGggYCd2aWV3LSdgLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodmlldyQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIHdlYmNvbnRlbnRzID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgc2hhcmVkIGJ5IGFsbCBPcGVuRmluIFdlYkNvbnRlbnRzIGVsZW1lbnRzIChpLmUuIHtAbGluayBPcGVuRmluLldpbmRvd30sXG4gKiB7QGxpbmsgT3BlbkZpbi5WaWV3fSkuXG4gKlxuICogV2ViQ29udGVudHMgZXZlbnRzIHdpbGwgcmUtZW1pdCBvbiBwYXJlbnQgZW50aXRpZXMgLSBlLmcuLCBhIHByb3BhZ2F0aW5nIGV2ZW50IGluIGEgdmlldyB3aWxsIGFsc28gYmUgZW1pdHRlZCBvbiB0aGUgdmlldydzXG4gKiBwYXJlbnQgd2luZG93LCBhbmQgcHJvcGFnYXRpbmcgZXZlbnRzIGluIGEgd2luZG93IHdpbGwgYWxzbyBiZSBlbWl0dGVkIG9uIHRoZSB3aW5kb3cncyBwYXJlbnQge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2ViY29udGVudHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgd2luZG93JDIgPSB7fTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBiZSBlbWl0dGVkIGJ5IGEge0BsaW5rIE9wZW5GaW4uV2luZG93fS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIFRoaXMgbmFtZXNwYWNlIGNvbnRhaW5zIG9ubHkgcGF5bG9hZCBzaGFwZXMgZm9yIGV2ZW50cyB0aGF0IGFyZSB1bmlxdWUgdG8gYFdpbmRvd2AuICBFdmVudHMgdGhhdCBhcmUgc2hhcmVkIGJldHdlZW4gYWxsIGBXZWJDb250ZW50c2BcbiAqIChpLmUuIHtAbGluayBPcGVuRmluLldpbmRvd30sIHtAbGluayBPcGVuRmluLlZpZXd9KSBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50c30uIEV2ZW50cyB0aGF0XG4gKiBwcm9wYWdhdGUgZnJvbSBgVmlld2AgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50c30uIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIFdpbmRvdyBldmVudHMsIHNlZVxuICoge0BsaW5rIFdpbmRvdy5vbiBXaW5kb3cub259XG4gKlxuICoge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzLldpbmRvd1NvdXJjZWRFdmVudCBXaW5kb3ctc291cmNlZCBldmVudHN9IChpLmUuIHRob3NlIHRoYXQgYXJlIG5vdCBwcm9wYWdhdGVkIGZyb20gYVxuICoge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3fSkgcHJvcGFnYXRlIHRvIHRoZWlyIHBhcmVudCB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50cyBBcHBsaWNhdGlvbn0gYW5kXG4gKiB7QGxpbmsgT3BlbkZpbi5TeXN0ZW1FdmVudHMgU3lzdGVtfSB3aXRoIHRoZWlyIGV2ZW50IHR5cGVzIHByZWZpeGVkIHdpdGggYCd3aW5kb3ctJ2ApLlxuICpcbiAqIFwiUmVxdWVzdGVkXCIgZXZlbnRzIChlLmcuIHtAbGluayBBdXRoUmVxdWVzdGVkRXZlbnR9KSBkbyBub3QgcHJvcGFnYXRlIHRvIGBTeXN0ZW0uICBUaGUge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzLldpbmRvd0Nsb3NlUmVxdWVzdGVkRXZlbnR9XG4gKiBkb2VzIG5vdCBwcm9wYWdhdGUgYXQgYWxsLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgT3BlbkZpbiBldmVudCB0eXBlcy4gRWFjaCBlbnRpdHkgdGhhdCBlbWl0cyBPcGVuRmluIGV2ZW50cyBoYXMgaXRzIG93biBzdWItbmFtZXNwYWNlLiBFdmVudCBwYXlsb2Fkc1xuICogdGhlbXNlbHZlcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqXG4gKiAjIyMjIEV2ZW50IGVtaXR0ZXJzXG4gKlxuICogVGhlIGZvbGxvd2luZyBlbnRpdGllcyBlbWl0IE9wZW5GaW4gZXZlbnRzLCBhbmQgaGF2ZSBjb3JyZXNwb25kaW5nIHN1Yi1uYW1lc3BhY2VzOlxuICpcbiAqICoge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259OiB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbn06IHtAbGluayBPcGVuRmluLkV4dGVybmFsQXBwbGljYXRpb25FdmVudHN9XG4gKiAqIHtAbGluayBPcGVuRmluLkZyYW1lfToge0BsaW5rIE9wZW5GaW4uRnJhbWVFdmVudHN9XG4gKiAqIHtAbGluayBPcGVuRmluLkdsb2JhbEhvdGtleX06IHtAbGluayBPcGVuRmluLkdsb2JhbEhvdGtleUV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uUGxhdGZvcm19OiB7QGxpbmsgT3BlbkZpbi5QbGF0Zm9ybUV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uU3lzdGVtfToge0BsaW5rIE9wZW5GaW4uU3lzdGVtRXZlbnRzfVxuICogKiB7QGxpbmsgT3BlbkZpbi5WaWV3fToge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uV2luZG93fToge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfVxuICpcbiAqIFRoZXNlIGBFdmVudEVtaXR0ZXJgIGVudGl0aWVzIHNoYXJlIGEgY29tbW9uIHNldCBvZiBtZXRob2RzIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBPcGVuRmluIGV2ZW50IGJ1cywgd2hpY2ggY2FuIGJlXG4gKiBzZWVuIG9uIHRoZSBpbmRpdmlkdWFsIGRvY3VtZW50YXRpb24gcGFnZXMgZm9yIGVhY2ggZW50aXR5IHR5cGUuXG4gKlxuICogUmVnaXN0ZXJpbmcgZXZlbnQgaGFuZGxlcnMgaXMgYW4gYXN5bmNocm9ub3VzIG9wZXJhdGlvbi4gSXQgaXMgaW1wb3J0YW50IHRvIGVuc3VyZSB0aGF0IHRoZSByZXR1cm5lZCBQcm9taXNlcyBhcmUgYXdhaXRlZCB0byByZWR1Y2UgdGhlXG4gKiByaXNrIG9mIHJhY2UgY29uZGl0aW9ucy5cbiAqXG4gKiBXaGVuIHRoZSBgRXZlbnRFbWl0dGVyYCByZWNlaXZlcyBhbiBldmVudCBmcm9tIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIGVtaXRzIG9uIHRoZSByZW5kZXJlciwgYWxsIG9mIHRoZSBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhhdFxuICogc3BlY2lmaWMgZXZlbnQgYXJlIGNhbGxlZCBzeW5jaHJvbm91c2x5LiBBbnkgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsZWQgbGlzdGVuZXJzIGFyZSBpZ25vcmVkIGFuZCB3aWxsIGJlIGRpc2NhcmRlZC4gIElmIHRoZSB3aW5kb3cgZG9jdW1lbnRcbiAqIGlzIGRlc3Ryb3llZCBieSBwYWdlIG5hdmlnYXRpb24gb3IgcmVsb2FkLCBpdHMgcmVnaXN0ZXJlZCBldmVudCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICpcbiAqIFdlIHJlY29tbWVuZCB1c2luZyBBcnJvdyBGdW5jdGlvbnMgZm9yIGV2ZW50IGxpc3RlbmVycyB0byBlbnN1cmUgdGhlIHRoaXMgc2NvcGUgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBjb250ZXh0LlxuICpcbiAqIEV2ZW50cyByZS1wcm9wYWdhdGUgZnJvbSBzbWFsbGVyL21vcmUtbG9jYWwgc2NvcGVzIHRvIGxhcmdlci9tb3JlLWdsb2JhbCBzY29wZXMuICBGb3IgZXhhbXBsZSwgYW4gZXZlbnQgZW1pdHRlZCBvbiBhIHNwZWNpZmljXG4gKiB2aWV3IHdpbGwgcHJvcGFnYXRlIHRvIHRoZSB3aW5kb3cgaW4gd2hpY2ggdGhlIHZpZXcgaXMgZW1iZWRkZWQsIGFuZCB0aGVuIHRvIHRoZSBhcHBsaWNhdGlvbiBpbiB3aGljaCB0aGUgd2luZG93IGlzIHJ1bm5pbmcsIGFuZFxuICogZmluYWxseSB0byB0aGUgT3BlbkZpbiBydW50aW1lIGl0c2VsZiBhdCB0aGUgXCJzeXN0ZW1cIiBsZXZlbC4gIEZvciBkZXRhaWxzIG9uIHByb3BhZ2F0aW9uIHNlbWFudGljcywgc2VlIHRoZSBuYW1lc3BhY2UgZm9yXG4gKiB0aGUgcHJvcGFnYXRpbmcgKG9yIHByb3BhZ2F0ZWQtdG8pIGVudGl0eS5cbiAqXG4gKiBJZiB5b3UgbmVlZCB0aGUgcGF5bG9hZCB0eXBlIGZvciBhIHNwZWNpZmljIHR5cGUgb2YgZXZlbnQgKGVzcGVjaWFsbHkgcHJvcGFnYXRlZCBldmVudHMpLCB1c2UgdGhlIGVtaXR0aW5nIHRvcGljJ3MgYFBheWxvYWRgIGdlbmVyaWNcbiAqIChlLmcuIHtAbGluayBXaW5kb3dFdmVudHMuUGF5bG9hZH0pIHdpdGggdGhlIGV2ZW50J3MgYHR5cGVgIHN0cmluZy4gIEZvciBleGFtcGxlLCB0aGUgcGF5bG9hZCBvZlxuICogYSB7QGxpbmsgVmlld0V2ZW50cy5DcmVhdGVkRXZlbnR9IGFmdGVyIGl0IGhhcyBwcm9wYWdhdGVkIHRvIGl0cyBwYXJlbnQge0BsaW5rIFdpbmRvd0V2ZW50cyBXaW5kb3d9IGNhbiBiZSBmb3VuZCB3aXRoXG4gKiBgV2luZG93RXZlbnRzLlBheWxvYWQ8J3ZpZXctY3JlYXRlZCc+YC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xudmFyIF9fY3JlYXRlQmluZGluZyQxID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19zZXRNb2R1bGVEZWZhdWx0JDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xufSkgOiBmdW5jdGlvbihvLCB2KSB7XG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xufSk7XG52YXIgX19pbXBvcnRTdGFyJDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnRTdGFyKSB8fCBmdW5jdGlvbiAobW9kKSB7XG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmckMShyZXN1bHQsIG1vZCwgayk7XG4gICAgX19zZXRNb2R1bGVEZWZhdWx0JDEocmVzdWx0LCBtb2QpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV2ZW50cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5ldmVudHMuV2luZG93RXZlbnRzID0gZXZlbnRzLldlYkNvbnRlbnRzRXZlbnRzID0gZXZlbnRzLlZpZXdFdmVudHMgPSBldmVudHMuU3lzdGVtRXZlbnRzID0gZXZlbnRzLlBsYXRmb3JtRXZlbnRzID0gZXZlbnRzLkdsb2JhbEhvdGtleUV2ZW50cyA9IGV2ZW50cy5GcmFtZUV2ZW50cyA9IGV2ZW50cy5FeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzID0gZXZlbnRzLkJhc2VFdmVudHMgPSBldmVudHMuQXBwbGljYXRpb25FdmVudHMgPSB2b2lkIDA7XG5jb25zdCBBcHBsaWNhdGlvbkV2ZW50cyA9IF9faW1wb3J0U3RhciQxKGFwcGxpY2F0aW9uJDEpO1xuZXZlbnRzLkFwcGxpY2F0aW9uRXZlbnRzID0gQXBwbGljYXRpb25FdmVudHM7XG5jb25zdCBCYXNlRXZlbnRzID0gX19pbXBvcnRTdGFyJDEoYmFzZSQxKTtcbmV2ZW50cy5CYXNlRXZlbnRzID0gQmFzZUV2ZW50cztcbmNvbnN0IEV4dGVybmFsQXBwbGljYXRpb25FdmVudHMgPSBfX2ltcG9ydFN0YXIkMShleHRlcm5hbEFwcGxpY2F0aW9uJDEpO1xuZXZlbnRzLkV4dGVybmFsQXBwbGljYXRpb25FdmVudHMgPSBFeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzO1xuY29uc3QgRnJhbWVFdmVudHMgPSBfX2ltcG9ydFN0YXIkMShmcmFtZSQxKTtcbmV2ZW50cy5GcmFtZUV2ZW50cyA9IEZyYW1lRXZlbnRzO1xuY29uc3QgR2xvYmFsSG90a2V5RXZlbnRzID0gX19pbXBvcnRTdGFyJDEoZ2xvYmFsSG90a2V5JDEpO1xuZXZlbnRzLkdsb2JhbEhvdGtleUV2ZW50cyA9IEdsb2JhbEhvdGtleUV2ZW50cztcbmNvbnN0IFBsYXRmb3JtRXZlbnRzID0gX19pbXBvcnRTdGFyJDEocGxhdGZvcm0kMSk7XG5ldmVudHMuUGxhdGZvcm1FdmVudHMgPSBQbGF0Zm9ybUV2ZW50cztcbmNvbnN0IFN5c3RlbUV2ZW50cyA9IF9faW1wb3J0U3RhciQxKHN5c3RlbSQxKTtcbmV2ZW50cy5TeXN0ZW1FdmVudHMgPSBTeXN0ZW1FdmVudHM7XG5jb25zdCBWaWV3RXZlbnRzID0gX19pbXBvcnRTdGFyJDEodmlldyQxKTtcbmV2ZW50cy5WaWV3RXZlbnRzID0gVmlld0V2ZW50cztcbmNvbnN0IFdlYkNvbnRlbnRzRXZlbnRzID0gX19pbXBvcnRTdGFyJDEod2ViY29udGVudHMpO1xuZXZlbnRzLldlYkNvbnRlbnRzRXZlbnRzID0gV2ViQ29udGVudHNFdmVudHM7XG5jb25zdCBXaW5kb3dFdmVudHMgPSBfX2ltcG9ydFN0YXIkMSh3aW5kb3ckMik7XG5ldmVudHMuV2luZG93RXZlbnRzID0gV2luZG93RXZlbnRzO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0LyoqXG5cdCAqIFRvcC1sZXZlbCBuYW1lc3BhY2UgZm9yIHR5cGVzIHJlZmVyZW5jZWQgYnkgdGhlIE9wZW5GaW4gQVBJLiAgQ29udGFpbnM6XG5cdCAqXG5cdCAqICogVGhlIHR5cGUgb2YgdGhlIGdsb2JhbCBgZmluYCBlbnRyeSBwb2ludCAoe0BsaW5rIEZpbkFwaX0pXG5cdCAqICogQ2xhc3NlcyB0aGF0IGFjdCBhcyBzdGF0aWMgbmFtZXNwYWNlcyByZXR1cm5lZCBmcm9tIHRoZSBgZmluYCBnbG9iYWwgKGUuZy4ge0BsaW5rIEFwcGxpY2F0aW9uTW9kdWxlfSwgYWNjZXNzaWJsZSB2aWEgYGZpbi5BcHBsaWNhdGlvbmApXG5cdCAqICogSW5zdGFuY2UgY2xhc3NlcyB0aGF0IGFyZSByZXR1cm5lZCBmcm9tIEFQSSBjYWxscyAoZS5nLiB7QGxpbmsgQXBwbGljYXRpb259LCBhY2Nlc3NpYmxlIHZpYSBgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKClgKVxuXHQgKiAqIFBhcmFtZXRlciBzaGFwZXMgZm9yIEFQSSBtZXRob2RzIChlLmcuIHtAbGluayBBcHBsaWNhdGlvbk9wdGlvbnN9LCB1c2VkIGluIGBmaW4uQXBwbGljYXRpb24uc3RhcnQoKWApXG5cdCAqICogRXZlbnQgbmFtZXNwYWNlcyBhbmQgcGF5bG9hZCB1bmlvbiB0eXBlcyAoZS5nLiB7QGxpbmsgQXBwbGljYXRpb25FdmVudHN9IGFuZCB7QGxpbmsgQXBwbGljYXRpb25FdmVudH0pXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0Ly8gRGVwcmVjYXRlZCBzaGltIHRvIHByZXNlcnZlIHYzMCBuYW1lc3BhY2UgbmFtZXNcblx0X19leHBvcnRTdGFyKGV2ZW50cywgZXhwb3J0cyk7IFxufSAoT3BlbkZpbiQyKSk7XG5cbnZhciBPcGVuRmluID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKE9wZW5GaW4kMik7XG5cbnZhciBPcGVuRmluJDEgPSAvKiNfX1BVUkVfXyovX21lcmdlTmFtZXNwYWNlcyh7XG5cdF9fcHJvdG9fXzogbnVsbCxcblx0ZGVmYXVsdDogT3BlbkZpblxufSwgW09wZW5GaW4kMl0pO1xuXG52YXIgZmluJDIgPSB7fTtcblxudmFyIHN5c3RlbSA9IHt9O1xuXG52YXIgYmFzZSA9IHt9O1xuXG52YXIgcHJvbWlzZXMgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2VzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnByb21pc2VzLnByb21pc2VNYXBTZXJpYWwgPSBwcm9taXNlcy5zZXJpYWwgPSBwcm9taXNlcy5wcm9taXNlTWFwID0gcHJvbWlzZXMucHJvbWlzaWZ5ID0gdm9pZCAwO1xuZnVuY3Rpb24gcHJvbWlzaWZ5KGZ1bmMpIHtcbiAgICByZXR1cm4gKC4uLmFyZ3MpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgZnVuYyguLi5hcmdzLCAoZXJyLCB2YWwpID0+IChlcnIgPyByZWplY3QoZXJyKSA6IHJlc29sdmUodmFsKSkpO1xuICAgIH0pO1xufVxucHJvbWlzZXMucHJvbWlzaWZ5ID0gcHJvbWlzaWZ5O1xuYXN5bmMgZnVuY3Rpb24gcHJvbWlzZU1hcChhcnIsIGFzeW5jRikge1xuICAgIHJldHVybiBQcm9taXNlLmFsbChhcnIubWFwKGFzeW5jRikpO1xufVxucHJvbWlzZXMucHJvbWlzZU1hcCA9IHByb21pc2VNYXA7XG5hc3luYyBmdW5jdGlvbiBzZXJpYWwoYXJyKSB7XG4gICAgY29uc3QgcmV0ID0gW107XG4gICAgZm9yIChjb25zdCBmdW5jIG9mIGFycikge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgICAgICBjb25zdCBuZXh0ID0gYXdhaXQgZnVuYygpO1xuICAgICAgICByZXQucHVzaChuZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cbnByb21pc2VzLnNlcmlhbCA9IHNlcmlhbDtcbmFzeW5jIGZ1bmN0aW9uIHByb21pc2VNYXBTZXJpYWwoYXJyLCBmdW5jKSB7XG4gICAgcmV0dXJuIHNlcmlhbChhcnIubWFwKCh2YWx1ZSwgaW5kZXgsIGFycmF5KSA9PiAoKSA9PiBmdW5jKHZhbHVlLCBpbmRleCwgYXJyYXkpKSk7XG59XG5wcm9taXNlcy5wcm9taXNlTWFwU2VyaWFsID0gcHJvbWlzZU1hcFNlcmlhbDtcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRlID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX0VtaXR0ZXJCYXNlX2VtaXR0ZXJBY2Nlc3Nvcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShiYXNlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmJhc2UuUmVwbHkgPSBiYXNlLkVtaXR0ZXJCYXNlID0gYmFzZS5CYXNlID0gdm9pZCAwO1xuY29uc3QgcHJvbWlzZXNfMSA9IHByb21pc2VzO1xuY2xhc3MgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEBkZXByZWNhdGVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzTm9kZUVudmlyb25tZW50ID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5lbnZpcm9ubWVudC50eXBlID09PSAnbm9kZSc7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAaW50ZXJuYWxcbiAgICAgICAgICogQGRlcHJlY2F0ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNPcGVuRmluRW52aXJvbm1lbnQgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgPT09ICdvcGVuZmluJztcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc0Jyb3dzZXJFbnZpcm9ubWVudCA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQudHlwZSA9PT0gJ290aGVyJztcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy53aXJlID0gd2lyZTtcbiAgICB9XG4gICAgZ2V0IGZpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5nZXRGaW4oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBPcGVuRmluIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IGNvZGUgY29udGV4dCAodXN1YWxseSBhIGRvY3VtZW50XG4gICAgICogc3VjaCBhcyBhIHtAbGluayBPcGVuRmluLlZpZXd9IG9yIHtAbGluayBPcGVuRmluLldpbmRvd30pLCBhcyB3ZWxsIGFzIHRvIHRoZSBjdXJyZW50IGBJbnRlcm9wYCBjb250ZXh0LlxuICAgICAqXG4gICAgICogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgaW4gdGhlIGRldnRvb2xzIGNvbnNvbGUsIHdoZXJlIHRoaXMgd2lsbCBpbnRlbGxpZ2VudGx5IHR5cGUgaXRzZWxmIGJhc2VkXG4gICAgICogb24gdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlIGRldnRvb2xzIHBhbmVsIHdhcyBvcGVuZWQuXG4gICAgICovXG4gICAgZ2V0IG1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLm1lO1xuICAgIH1cbn1cbmJhc2UuQmFzZSA9IEJhc2U7XG4vKipcbiAqIEFuIGVudGl0eSB0aGF0IGVtaXRzIE9wZW5GaW4gZXZlbnRzLlxuICpcbiAqIEByZW1hcmtzIEV2ZW50LWJpbmRpbmcgbWV0aG9kcyBhcmUgYXN5bmNocm9ub3VzIGFzIHRoZXkgbXVzdCBjcm9zcyBwcm9jZXNzIGJvdW5kYXJpZXNcbiAqIGFuZCBzZXR1cCB0aGUgbGlzdGVuZXIgaW4gdGhlIGJyb3dzZXIgcHJvY2Vzcy4gIFdoZW4gdGhlIGBFdmVudEVtaXR0ZXJgIHJlY2VpdmVzIGFuIGV2ZW50IGZyb20gdGhlIGJyb3dzZXIgcHJvY2Vzc1xuICogYW5kIGVtaXRzIG9uIHRoZSByZW5kZXJlciwgYWxsIG9mIHRoZSBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhhdCBzcGVjaWZpYyBldmVudCBhcmUgY2FsbGVkIHN5bmNocm9ub3VzbHkuICBBbnkgdmFsdWVzXG4gKiByZXR1cm5lZCBieSB0aGUgY2FsbGVkIGxpc3RlbmVycyBhcmUgaWdub3JlZCBhbmQgd2lsbCBiZSBkaXNjYXJkZWQuICBJZiB0aGUgZXhlY3V0aW9uIGNvbnRleHQgb2YgdGhlIHdpbmRvdyBpcyBkZXN0cm95ZWRcbiAqIGJ5IHBhZ2UgbmF2aWdhdGlvbiBvciByZWxvYWQsIGFueSBldmVudHMgdGhhdCBoYXZlIGJlZW4gc2V0dXAgaW4gdGhhdCBjb250ZXh0IHdpbGwgYmUgZGVzdHJveWVkLlxuICpcbiAqIEl0IGlzIGltcG9ydGFudCB0byBrZWVwIGluIG1pbmQgdGhhdCB3aGVuIGFuIG9yZGluYXJ5IGxpc3RlbmVyIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhlIHN0YW5kYXJkIGB0aGlzYCBrZXl3b3JkIGlzIGludGVudGlvbmFsbHlcbiAqIHNldCB0byByZWZlcmVuY2UgdGhlIGBFdmVudEVtaXR0ZXJgIGluc3RhbmNlIHRvIHdoaWNoIHRoZSBsaXN0ZW5lciBpcyBhdHRhY2hlZC4gIEl0IGlzIHBvc3NpYmxlIHRvIHVzZSBFUzYgQXJyb3cgRnVuY3Rpb25zIGFzXG4gKiBsaXN0ZW5lcnMsIGhvd2V2ZXIsIHdoZW4gZG9pbmcgc28sIHRoZSBgdGhpc2Aga2V5d29yZCB3aWxsIG5vIGxvbmdlciByZWZlcmVuY2UgdGhlIGBFdmVudEVtaXR0ZXJgIGluc3RhbmNlLlxuICpcbiAqIEV2ZW50cyByZS1wcm9wYWdhdGUgZnJvbSBzbWFsbGVyL21vcmUtbG9jYWwgc2NvcGVzIHRvIGxhcmdlci9tb3JlLWdsb2JhbCBzY29wZXMuICBGb3IgZXhhbXBsZSwgYW4gZXZlbnQgZW1pdHRlZCBvbiBhIHNwZWNpZmljXG4gKiB2aWV3IHdpbGwgcHJvcGFnYXRlIHRvIHRoZSB3aW5kb3cgaW4gd2hpY2ggdGhlIHZpZXcgaXMgZW1iZWRkZWQsIGFuZCB0aGVuIHRvIHRoZSBhcHBsaWNhdGlvbiBpbiB3aGljaCB0aGUgd2luZG93IGlzIHJ1bm5pbmcsIGFuZFxuICogZmluYWxseSB0byB0aGUgT3BlbkZpbiBydW50aW1lIGl0c2VsZiBhdCB0aGUgXCJzeXN0ZW1cIiBsZXZlbC4gIFJlLXByb3BhZ2F0ZWQgZXZlbnRzIGFyZSBwcmVmaXhlZCB3aXRoIHRoZSBuYW1lIG9mIHRoZSBzY29wZSBpbiB3aGljaFxuICogdGhleSBvcmlnaW5hdGVkIC0gZm9yIGV4YW1wbGUsIGEgXCJzaG93blwiIGV2ZW50IGVtaXR0ZWQgb24gYSB2aWV3IHdpbGwgYmUgcmUtcHJvcGFnYXRlZCBhdCB0aGUgd2luZG93IGxldmVsIGFzIFwidmlldy1zaG93blwiLCBhbmRcbiAqIHRoZW4gdG8gdGhlIGFwcGxpY2F0aW9uIGFzIFwid2luZG93LXZpZXctc2hvd25cIiwgYW5kIGZpbmFsbHkgYXQgdGhlIHN5c3RlbSBsZXZlbCBhcyBcImFwcGxpY2F0aW9uLXdpbmRvdy12aWV3LXNob3duXCIuXG4gKlxuICogQWxsIGV2ZW50IHByb3BhZ2F0aW9ucyBhcmUgdmlzaWJsZSBhdCB0aGUgU3lzdGVtIGxldmVsLCByZWdhcmRsZXNzIG9mIHNvdXJjZSwgc28gdHJhbnNpdGl2ZSByZS1wcm9wYWdhdGlvbnMgKGUuZy4gZnJvbSB2aWV3IHRvIHdpbmRvd1xuICogdG8gYXBwbGljYXRpb24pIGFyZSB2aXNpYmxlIGluIHRoZWlyIGVudGlyZXR5IGF0IHRoZSBzeXN0ZW0gbGV2ZWwuICBTbywgd2UgY2FuIGxpc3RlbiB0byB0aGUgYWJvdmUgZXZlbnQgYXMgXCJzaG93blwiLCBcInZpZXctc2hvd25cIixcbiAqIFwid2luZG93LXZpZXctc2hvd25cIiwgb3IgXCJhcHBsaWNhdGlvbi13aW5kb3ctdmlldy1zaG93bi5cIlxuICovXG5jbGFzcyBFbWl0dGVyQmFzZSBleHRlbmRzIEJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIHRvcGljLCAuLi5hZGRpdGlvbmFsQWNjZXNzb3JzKSB7XG4gICAgICAgIHN1cGVyKHdpcmUpO1xuICAgICAgICB0aGlzLnRvcGljID0gdG9waWM7XG4gICAgICAgIF9FbWl0dGVyQmFzZV9lbWl0dGVyQWNjZXNzb3Iuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIHRoaXMuZXZlbnROYW1lcyA9ICgpID0+ICh0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkuZXZlbnROYW1lcygpIDogW10pO1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVtaXQgPSAoZXZlbnRUeXBlLCBwYXlsb2FkLCAuLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYXNFbWl0dGVyKCkgPyB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpLmVtaXQoZXZlbnRUeXBlLCBwYXlsb2FkLCAuLi5hcmdzKSA6IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhc0VtaXR0ZXIgPSAoKSA9PiB0aGlzLndpcmUuZXZlbnRBZ2dyZWdhdG9yLmhhcyhfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGUodGhpcywgX0VtaXR0ZXJCYXNlX2VtaXR0ZXJBY2Nlc3NvciwgXCJmXCIpKTtcbiAgICAgICAgdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIgPSAoKSA9PiB0aGlzLndpcmUuZXZlbnRBZ2dyZWdhdG9yLmdldE9yQ3JlYXRlKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZSh0aGlzLCBfRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yLCBcImZcIikpO1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9ICh0eXBlKSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJzKHR5cGUpIDogW107XG4gICAgICAgIHRoaXMubGlzdGVuZXJDb3VudCA9ICh0eXBlKSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJDb3VudCh0eXBlKSA6IDA7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyID0gYXN5bmMgKGV2ZW50VHlwZSwgb3B0aW9ucyA9IHt9LCBhcHBseVN1YnNjcmlwdGlvbiwgdW5kb1N1YnNjcmlwdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgcnVudGltZUV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBvcHRpb25zLnRpbWVzdGFtcCB8fCBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIHRvcGljOiB0aGlzLnRvcGljLFxuICAgICAgICAgICAgICAgIHR5cGU6IGV2ZW50VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpO1xuICAgICAgICAgICAgLy8gV2UgYXBwbHkgdGhlIHN1YnNjcmlwdGlvbiBhbmQgdGhlbiB1bmRvIGlmIHRoZSBhc3luYyBjYWxsIGZhaWxzIHRvIGF2b2lkXG4gICAgICAgICAgICAvLyBpbmRldGVybWluYWN5IGluIHN1YnNjcmlwdGlvbiBhcHBsaWNhdGlvbiBvcmRlciwgd2hpY2ggY2FuIGJyZWFrIHRoaW5ncyBlbHNld2hlcmVcbiAgICAgICAgICAgIGFwcGx5U3Vic2NyaXB0aW9uKGVtaXR0ZXIpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3Vic2NyaWJlLXRvLWRlc2t0b3AtZXZlbnQnLCBydW50aW1lRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB1bmRvU3Vic2NyaXB0aW9uKGVtaXR0ZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlRW1pdHRlcklmTm90aGluZ1JlZ2lzdGVyZWQoZW1pdHRlcik7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kZXJlZ2lzdGVyRXZlbnRMaXN0ZW5lciA9IGFzeW5jIChldmVudFR5cGUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcnVudGltZUV2ZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IG9wdGlvbnMudGltZXN0YW1wIHx8IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIHRvcGljOiB0aGlzLnRvcGljLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBldmVudFR5cGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCd1bnN1YnNjcmliZS10by1kZXNrdG9wLWV2ZW50JywgcnVudGltZUV2ZW50KS5jYXRjaCgoKSA9PiBudWxsKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZW1pdHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBvbmx5IGJlIHJlYWNoZWQgaWYgdW5zdWJzY3JpYmUgZnJvbSBldmVudCB0aGF0IGRvZXMgbm90IGV4aXN0IGJ1dCBkbyBub3Qgd2FudCB0byBlcnJvciBoZXJlXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYyh0aGlzLCBfRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yLCBbdG9waWMsIC4uLmFkZGl0aW9uYWxBY2Nlc3NvcnNdLCBcImZcIik7XG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gKGV2ZW50KSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJzKGV2ZW50KSA6IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRXZlbnQgcGF5bG9hZHMgYXJlIGRvY3VtZW50ZWQgaW4gdGhlIHtAbGluayBPcGVuRmluLkV2ZW50c30gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIGFzeW5jIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zLCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5vbihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSwgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RlbmVycyBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKi9cbiAgICBhc3luYyBhZGRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudC4gVGhlIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGUgZmlyc3QgdGltZSB0aGUgZXZlbnQgaXMgZmlyZWQsIGFmdGVyIHdoaWNoIGl0IGlzIHJlbW92ZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBpbiB0aGUge0BsaW5rIE9wZW5GaW4uRXZlbnRzfSBuYW1lc3BhY2UuXG4gICAgICovXG4gICAgYXN5bmMgb25jZShldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRlcmVnaXN0ZXIgPSAoKSA9PiB0aGlzLmRlcmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgb3B0aW9ucywgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIub25jZShldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5vbmNlKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9LCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRXZlbnQgcGF5bG9hZHMgYXJlIGRvY3VtZW50ZWQgaW4gdGhlIHtAbGluayBPcGVuRmluLkV2ZW50c30gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIGFzeW5jIHByZXBlbmRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgb3B0aW9ucywgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9LCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudC4gVGhlIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGUgZmlyc3QgdGltZSB0aGUgZXZlbnQgaXMgZmlyZWQsXG4gICAgICogYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC4gVGhlIGxpc3RlbmVyIGlzIGFkZGVkIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3RlbmVycyBhcnJheS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGluIHRoZSB7QGxpbmsgT3BlbkZpbi5FdmVudHN9IG5hbWVzcGFjZS5cbiAgICAgKi9cbiAgICBhc3luYyBwcmVwZW5kT25jZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZGVyZWdpc3RlciA9ICgpID0+IHRoaXMuZGVyZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zLCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5wcmVwZW5kT25jZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5vbmNlKGV2ZW50VHlwZSwgZGVyZWdpc3Rlcik7XG4gICAgICAgIH0sIChlbWl0dGVyKSA9PiB7XG4gICAgICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGxpc3RlbmVyIGZyb20gdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2F1dGlvbjogQ2FsbGluZyB0aGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSBhcnJheSBpbmRpY2VzIGluIHRoZSBsaXN0ZW5lciBhcnJheSBiZWhpbmQgdGhlIGxpc3RlbmVyLlxuICAgICAqL1xuICAgIGFzeW5jIHJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IGF3YWl0IHRoaXMuZGVyZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGVtaXR0ZXIpIHtcbiAgICAgICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLmRlbGV0ZUVtaXR0ZXJJZk5vdGhpbmdSZWdpc3RlcmVkKGVtaXR0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBhc3luYyBkZXJlZ2lzdGVyQWxsTGlzdGVuZXJzKGV2ZW50VHlwZSkge1xuICAgICAgICBjb25zdCBydW50aW1lRXZlbnQgPSB7IC4uLnRoaXMuaWRlbnRpdHksIHR5cGU6IGV2ZW50VHlwZSwgdG9waWM6IHRoaXMudG9waWMgfTtcbiAgICAgICAgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlZkNvdW50ID0gZW1pdHRlci5saXN0ZW5lckNvdW50KHJ1bnRpbWVFdmVudC50eXBlKTtcbiAgICAgICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlUHJvbWlzZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVmQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvbWlzZXMucHVzaCh0aGlzLndpcmUuc2VuZEFjdGlvbigndW5zdWJzY3JpYmUtdG8tZGVza3RvcC1ldmVudCcsIHJ1bnRpbWVFdmVudCkuY2F0Y2goKCkgPT4gbnVsbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodW5zdWJzY3JpYmVQcm9taXNlcyk7XG4gICAgICAgICAgICByZXR1cm4gZW1pdHRlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICpcbiAgICAgKi9cbiAgICBhc3luYyByZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnRUeXBlKSB7XG4gICAgICAgIGNvbnN0IHJlbW92ZUJ5RXZlbnQgPSBhc3luYyAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSBhd2FpdCB0aGlzLmRlcmVnaXN0ZXJBbGxMaXN0ZW5lcnMoZXZlbnQpO1xuICAgICAgICAgICAgaWYgKGVtaXR0ZXIpIHtcbiAgICAgICAgICAgICAgICBlbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycyhldmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVFbWl0dGVySWZOb3RoaW5nUmVnaXN0ZXJlZChlbWl0dGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgYXdhaXQgcmVtb3ZlQnlFdmVudChldmVudFR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpLmV2ZW50TmFtZXMoKTtcbiAgICAgICAgICAgIGF3YWl0ICgwLCBwcm9taXNlc18xLnByb21pc2VNYXApKGV2ZW50cywgcmVtb3ZlQnlFdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRlbGV0ZUVtaXR0ZXJJZk5vdGhpbmdSZWdpc3RlcmVkKGVtaXR0ZXIpIHtcbiAgICAgICAgaWYgKGVtaXR0ZXIuZXZlbnROYW1lcygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy53aXJlLmV2ZW50QWdncmVnYXRvci5kZWxldGUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCRlKHRoaXMsIF9FbWl0dGVyQmFzZV9lbWl0dGVyQWNjZXNzb3IsIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5iYXNlLkVtaXR0ZXJCYXNlID0gRW1pdHRlckJhc2U7XG5fRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yID0gbmV3IFdlYWtNYXAoKTtcbmNsYXNzIFJlcGx5IHtcbn1cbmJhc2UuUmVwbHkgPSBSZXBseTtcblxudmFyIHRyYW5zcG9ydEVycm9ycyA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodHJhbnNwb3J0RXJyb3JzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnRyYW5zcG9ydEVycm9ycy5SdW50aW1lRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuTm90U3VwcG9ydGVkRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuTm90SW1wbGVtZW50ZWRFcnJvciA9IHRyYW5zcG9ydEVycm9ycy5Ob0Fja0Vycm9yID0gdHJhbnNwb3J0RXJyb3JzLkR1cGxpY2F0ZUNvcnJlbGF0aW9uRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuVW5leHBlY3RlZEFjdGlvbkVycm9yID0gdHJhbnNwb3J0RXJyb3JzLkRpc2Nvbm5lY3RlZEVycm9yID0gdm9pZCAwO1xuY2xhc3MgRGlzY29ubmVjdGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocmVhZHlTdGF0ZSkge1xuICAgICAgICBzdXBlcihgRXhwZWN0ZWQgd2Vic29ja2V0IHN0YXRlIE9QRU4gYnV0IGZvdW5kICR7cmVhZHlTdGF0ZX1gKTtcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gcmVhZHlTdGF0ZTtcbiAgICB9XG59XG50cmFuc3BvcnRFcnJvcnMuRGlzY29ubmVjdGVkRXJyb3IgPSBEaXNjb25uZWN0ZWRFcnJvcjtcbmNsYXNzIFVuZXhwZWN0ZWRBY3Rpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5VbmV4cGVjdGVkQWN0aW9uRXJyb3IgPSBVbmV4cGVjdGVkQWN0aW9uRXJyb3I7XG5jbGFzcyBEdXBsaWNhdGVDb3JyZWxhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxudHJhbnNwb3J0RXJyb3JzLkR1cGxpY2F0ZUNvcnJlbGF0aW9uRXJyb3IgPSBEdXBsaWNhdGVDb3JyZWxhdGlvbkVycm9yO1xuY2xhc3MgTm9BY2tFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5Ob0Fja0Vycm9yID0gTm9BY2tFcnJvcjtcbmNsYXNzIE5vdEltcGxlbWVudGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG50cmFuc3BvcnRFcnJvcnMuTm90SW1wbGVtZW50ZWRFcnJvciA9IE5vdEltcGxlbWVudGVkRXJyb3I7XG5jbGFzcyBOb3RTdXBwb3J0ZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5Ob3RTdXBwb3J0ZWRFcnJvciA9IE5vdFN1cHBvcnRlZEVycm9yO1xuY2xhc3MgSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihlcnIpIHtcbiAgICAgICAgY29uc3QgeyBtZXNzYWdlLCBuYW1lLCBzdGFjaywgLi4ucmVzdCB9ID0gZXJyO1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZSB8fCAnRXJyb3InO1xuICAgICAgICB0aGlzLnN0YWNrID0gc3RhY2sgPz8gdGhpcy50b1N0cmluZygpO1xuICAgICAgICBPYmplY3Qua2V5cyhyZXN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSByZXN0W2tleV07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vIEZvciBkb2N1bWVudGF0aW9uIG9mIHRoZSBlcnJvciBtZXRob2RzIGJlaW5nIHVzZWQgc2VlIGhlcmU6IGh0dHBzOi8vdjguZGV2L2RvY3Mvc3RhY2stdHJhY2UtYXBpXG5jbGFzcyBSdW50aW1lRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgc3RhdGljIGdldENhbGxTaXRlKGNhbGxzVG9SZW1vdmUgPSAwKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IEVycm9yLnN0YWNrVHJhY2VMaW1pdDtcbiAgICAgICAgY29uc3QgcmVhbENhbGxzVG9SZW1vdmUgPSBjYWxsc1RvUmVtb3ZlICsgMTsgLy8gcmVtb3ZlIHRoaXMgY2FsbDtcbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gbGVuZ3RoICsgcmVhbENhbGxzVG9SZW1vdmU7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgICAgICBjb25zdCBfcHJlcGFyZVN0YWNrVHJhY2UgPSBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZTtcbiAgICAgICAgLy8gVGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIHdlIGFjY2VzcyB0aGUgYHN0YWNrYCBwcm9wZXJ0eVxuICAgICAgICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IChfLCBzdGFjaykgPT4gc3RhY2s7XG4gICAgICAgIC8vIHN0YWNrIGlzIG9wdGlvbmFsIGluIG5vbiBjaHJvbWl1bSBjb250ZXh0c1xuICAgICAgICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrPy5zbGljZShyZWFsQ2FsbHNUb1JlbW92ZSkgPz8gW107XG4gICAgICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gX3ByZXBhcmVTdGFja1RyYWNlO1xuICAgICAgICBFcnJvci5zdGFja1RyYWNlTGltaXQgPSBsZW5ndGg7XG4gICAgICAgIHJldHVybiBzdGFjaztcbiAgICB9XG4gICAgc3RhdGljIHByZXBhcmVTdGFja1RyYWNlKGVyciwgY2FsbFNpdGVzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZShlcnIsIGNhbGxTaXRlcyk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0cmluZyA9IFwiXCI7XG4gICAgICAgIHN0cmluZyArPSBlcnIubmFtZSB8fCBcIkVycm9yXCI7XG4gICAgICAgIHN0cmluZyArPSBgOiAke2Vyci5tZXNzYWdlIHx8IFwiXCJ9YDtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsU2l0ZSBvZiBjYWxsU2l0ZXMpIHtcbiAgICAgICAgICAgIHN0cmluZyArPSBgXFxuICAgIGF0ICR7Y2FsbFNpdGUudG9TdHJpbmcoKX1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgfVxuICAgIDtcbiAgICBjb25zdHJ1Y3RvcihwYXlsb2FkLCBjYWxsU2l0ZXMpIHtcbiAgICAgICAgY29uc3QgeyByZWFzb24sIGVycm9yIH0gPSBwYXlsb2FkO1xuICAgICAgICBzdXBlcihyZWFzb24pO1xuICAgICAgICB0aGlzLm5hbWUgPSAnUnVudGltZUVycm9yJztcbiAgICAgICAgaWYgKGVycm9yPy5zdGFjaykge1xuICAgICAgICAgICAgdGhpcy5jYXVzZSA9IG5ldyBJbnRlcm5hbEVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsbFNpdGVzKSB7XG4gICAgICAgICAgICB0aGlzLnN0YWNrID0gUnVudGltZUVycm9yLnByZXBhcmVTdGFja1RyYWNlKHRoaXMsIGNhbGxTaXRlcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG50cmFuc3BvcnRFcnJvcnMuUnVudGltZUVycm9yID0gUnVudGltZUVycm9yO1xuXG52YXIgd2luZG93JDEgPSB7fTtcblxudmFyIEZhY3RvcnkkOCA9IHt9O1xuXG52YXIgdmFsaWRhdGUgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkYXRlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhbGlkYXRlLnZhbGlkYXRlSWRlbnRpdHkgPSB2b2lkIDA7XG5mdW5jdGlvbiB2YWxpZGF0ZUlkZW50aXR5KGlkZW50aXR5KSB7XG4gICAgbGV0IGVycm9yTXNnO1xuICAgIGlmICh0eXBlb2YgaWRlbnRpdHkgIT09ICdvYmplY3QnIHx8IHR5cGVvZiBpZGVudGl0eS51dWlkICE9PSAnc3RyaW5nJykge1xuICAgICAgICBlcnJvck1zZyA9ICdOb3QgYSB2YWxpZCBpZGVudGl0eSBvYmplY3QnO1xuICAgIH1cbiAgICByZXR1cm4gZXJyb3JNc2c7XG59XG52YWxpZGF0ZS52YWxpZGF0ZUlkZW50aXR5ID0gdmFsaWRhdGVJZGVudGl0eTtcblxudmFyIEluc3RhbmNlJDcgPSB7fTtcblxudmFyIGFwcGxpY2F0aW9uID0ge307XG5cbnZhciBGYWN0b3J5JDcgPSB7fTtcblxudmFyIEluc3RhbmNlJDYgPSB7fTtcblxudmFyIHZpZXcgPSB7fTtcblxudmFyIEZhY3RvcnkkNiA9IHt9O1xuXG52YXIgd2FybmluZ3MgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHdhcm5pbmdzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbndhcm5pbmdzLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IHZvaWQgMDtcbmNvbnN0IGhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IChvcHRpb25zKSA9PiB7XG4gICAgaWYgKG9wdGlvbnMuY29udGVudE5hdmlnYXRpb24/LndoaXRlbGlzdCB8fFxuICAgICAgICBvcHRpb25zLmNvbnRlbnROYXZpZ2F0aW9uPy5ibGFja2xpc3QgfHxcbiAgICAgICAgb3B0aW9ucy5jb250ZW50UmVkaXJlY3Q/LndoaXRlbGlzdCB8fFxuICAgICAgICBvcHRpb25zLmNvbnRlbnRSZWRpcmVjdD8uYmxhY2tsaXN0KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgVGhlIHByb3BlcnRpZXMgJ3doaXRlbGlzdCcgYW5kICdibGFja2xpc3QnIGhhdmUgYmVlbiBtYXJrZWQgYXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uIFBsZWFzZSB1c2UgJ2FsbG93bGlzdCcgYW5kICdkZW55bGlzdCcuYCk7XG4gICAgfVxufTtcbndhcm5pbmdzLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IGhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncztcblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeSQzO1xuXG5mdW5jdGlvbiByZXF1aXJlRmFjdG9yeSQzICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkRmFjdG9yeSQzKSByZXR1cm4gRmFjdG9yeSQ2O1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkkMyA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDYsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDYuVmlld01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgYmFzZV8xID0gYmFzZTtcblx0Y29uc3QgdmFsaWRhdGVfMSA9IHZhbGlkYXRlO1xuXHRjb25zdCBpbmRleF8xID0gcmVxdWlyZVZpZXcoKTtcblx0Y29uc3Qgd2FybmluZ3NfMSA9IHdhcm5pbmdzO1xuXHQvKipcblx0ICogU3RhdGljIG5hbWVzcGFjZSBmb3IgT3BlbkZpbiBBUEkgbWV0aG9kcyB0aGF0IGludGVyYWN0IHdpdGggdGhlIHtAbGluayBWaWV3fSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uVmlld2AuXG5cdCAqL1xuXHRjbGFzcyBWaWV3TW9kdWxlIGV4dGVuZHMgYmFzZV8xLkJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBDcmVhdGVzIGEgbmV3IFZpZXcuXG5cdCAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIFZpZXcgY3JlYXRpb24gb3B0aW9uc1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogbGV0IHZpZXc7XG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICogICAgIGNvbnN0IG1lID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUNyZWF0ZScsXG5cdCAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjcmVhdGVWaWV3KClcblx0ICAgICAqICAgICAudGhlbigoY3JlYXRlZFZpZXcpID0+IHtcblx0ICAgICAqICAgICAgICAgdmlldyA9IGNyZWF0ZWRWaWV3O1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZygnVmlldyBjcmVhdGVkLicsIHZpZXcpO1xuXHQgICAgICogICAgICAgICB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIE5vdGUgdGhhdCBjcmVhdGVkIHZpZXdzIG5lZWRzIHRvIG5hdmlnYXRlIHNvbWV3aGVyZSBmb3IgdGhlbSB0byBhY3R1YWxseSByZW5kZXIgYSB3ZWJzaXRlLlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjcmVhdGUob3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IHsgdXVpZCB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIGlmICghb3B0aW9ucy5uYW1lIHx8IHR5cGVvZiBvcHRpb25zLm5hbWUgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgYSBuYW1lIHByb3BlcnR5IGFzIGEgc3RyaW5nIGluIG9yZGVyIHRvIGNyZWF0ZSBhIFZpZXcuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgICgwLCB3YXJuaW5nc18xLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncykob3B0aW9ucyk7XG5cdCAgICAgICAgaWYgKHRoaXMud2lyZS5lbnZpcm9ubWVudC5jaGlsZFZpZXdzKSB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5jcmVhdGVDaGlsZENvbnRlbnQoe1xuXHQgICAgICAgICAgICAgICAgZW50aXR5VHlwZTogJ3ZpZXcnLFxuXHQgICAgICAgICAgICAgICAgb3B0aW9uczogeyAuLi5vcHRpb25zLCB1dWlkIH1cblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLXZpZXcnLCB7IC4uLm9wdGlvbnMsIHV1aWQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLndyYXBTeW5jKHsgdXVpZCwgbmFtZTogb3B0aW9ucy5uYW1lIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBWaWV3IGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGEgVmlldyBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuXHQgICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuXHQgICAgICogZm9yIGEgVmlldyB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlZpZXcud3JhcCh7IHV1aWQ6ICd0ZXN0Vmlld1V1aWQnLCBuYW1lOiAndGVzdFZpZXdOYW1lJyB9KSlcblx0ICAgICAqICAgICAudGhlbih2aWV3ID0+IGNvbnNvbGUubG9nKCd3cmFwcGVkIHZpZXcnLCB2aWV3KSlcblx0ICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHdyYXAoaWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigndmlldy13cmFwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMS52YWxpZGF0ZUlkZW50aXR5KShpZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGVycm9yTXNnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgaW5kZXhfMS5WaWV3KHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIFZpZXcgaWRlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBWaWV3IGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYSBWaWV3IHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcud3JhcFN5bmMoeyB1dWlkOiAndGVzdFZpZXcnLCBuYW1lOiAndGVzdFZpZXdOYW1lJyB9KTtcblx0ICAgICAqIGF3YWl0IHZpZXcuaGlkZSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMS52YWxpZGF0ZUlkZW50aXR5KShpZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGVycm9yTXNnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgaW5kZXhfMS5WaWV3KHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgVmlldyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5WaWV3LmdldEN1cnJlbnQoKVxuXHQgICAgICogICAgIC50aGVuKHZpZXcgPT4gY29uc29sZS5sb2coJ2N1cnJlbnQgdmlldycsIHZpZXcpKVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnQoKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctZ2V0LWN1cnJlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoIXRoaXMud2lyZS5tZS5pc1ZpZXcpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFZpZXcgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwKHsgdXVpZCwgbmFtZSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgVmlldyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogY29uc29sZS5sb2codmlldyk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd2aWV3LWdldC1jdXJyZW50LXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoIXRoaXMud2lyZS5tZS5pc1ZpZXcpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFZpZXcgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQ2LlZpZXdNb2R1bGUgPSBWaWV3TW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQ2O1xufVxuXG52YXIgSW5zdGFuY2UkNSA9IHt9O1xuXG52YXIgbGF6eSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5sYXp5LkFzeW5jUmV0cnlhYmxlTGF6eSA9IGxhenkuTGF6eSA9IHZvaWQgMDtcbi8qKlxuICogSGFuZHkgY2xhc3MgZm9yIG1hbmFnaW5nIGFzeW5jaHJvbm91cyBkZXBlbmRlbmNpZXMgb2YgY2xhc3Nlcy5cbiAqXG4gKiBXaWxsIGNhbGwgdGhlIHByb2R1Y2VyIGZ1bmN0aW9uIG9uY2UgYW5kIG9ubHkgb25jZSB3aGVuIGdldFZhbHVlIGlzIGNhbGxlZCxcbiAqIHJldHVybmluZyB0aGUgcmVzdWx0YW50IHZhbHVlIGZvciBldmVyeSBzdWJzZXF1ZW50IGNhbGwuXG4gKi9cbmNsYXNzIExhenkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHByb2R1Y2VyRm4pIHtcbiAgICAgICAgdGhpcy5wcm9kdWNlckZuID0gcHJvZHVjZXJGbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF6aWx5IGdldCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIHByb2R1Y2VyLlxuICAgICAqIEByZXR1cm5zIFRoZSB2YWx1ZSByZXR1cm5lZCBmcm9tIHRoZSBwcm9kdWNlciBmdW5jdGlvblxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBpZiAoIXRoaXMudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnByb2R1Y2VyRm4oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5sYXp5LkxhenkgPSBMYXp5O1xuLyoqXG4gKiBIYW5keSBjbGFzcyBmb3IgbWFuYWdpbmcgYXN5bmNocm9ub3VzIGRlcGVuZGVuY2llcyBvZiBjbGFzc2VzLlxuICpcbiAqIFdpbGwgY2FsbCBhc3luY2hyb25vdXMgcHJvZHVjZXIgb25seSBhZnRlciBgZ2V0VmFsdWVgIGlzIGNhbGxlZC4gIElmIHRoZVxuICogZGVmZXJyZWQgY29kZSBlcnJvcnMsIHdlIGNhbiB0cnkgaXQgYWdhaW4gYnkgcmUtY2FsbGluZyBgZ2V0VmFsdWVgIGFmdGVyXG4gKiB0aGUgcHJvbWlzZSByZWplY3RzLlxuICovXG5jbGFzcyBBc3luY1JldHJ5YWJsZUxhenkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHByb2R1Y2VyRm4pIHtcbiAgICAgICAgdGhpcy5wcm9kdWNlckZuID0gcHJvZHVjZXJGbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF6aWx5IGdldCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGFzeW5jIHByb2R1Y2VyLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIHZhbHVlIHJldHVybmVkIGZyb20gdGhlIHByb2R1Y2VyIGZ1bmN0aW9uXG4gICAgICovXG4gICAgYXN5bmMgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9taXNlKSB7XG4gICAgICAgICAgICB0aGlzLnByb21pc2UgPSB0aGlzLnByb2R1Y2VyRm4oKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnByb21pc2U7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XG4gICAgfVxufVxubGF6eS5Bc3luY1JldHJ5YWJsZUxhenkgPSBBc3luY1JldHJ5YWJsZUxhenk7XG5cbnZhciBsYXlvdXRFbnRpdGllcyA9IHt9O1xuXG52YXIgYXBpRXhwb3NlciQxID0ge307XG5cbnZhciBhcGlDb25zdW1lciA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoYXBpQ29uc3VtZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuYXBpQ29uc3VtZXIuQXBpQ29uc3VtZXIgPSB2b2lkIDA7XG4vKipcbiAqIENvbnN1bWVyIGZvciBhcGlzIGV4cG9zZWQgd2l0aCB7QHNlZSBBcGlFeHBvc2VyfS5cbiAqXG4gKiBBIHN0cmF0ZWd5IHRoYXQgbWF0Y2hlcyB0aGUgc3RyYXRlZ3kgdXNlZCB0byBleHBvc2UgYSB0YXJnZXQgQVBJIG11c3QgYmUgcHJvdmlkZWQuXG4gKi9cbmNsYXNzIEFwaUNvbnN1bWVyIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBjb25zdHJ1Y3RvcihzdHJhdGVneSkge1xuICAgICAgICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdW1lcyBhbiBhcGkgZXhwb3NlZCB1c2luZyBhIGdpdmVuIHRyYW5zcG9ydCBzdHJhdGVneSwgYW5kIGdlbmVyYXRlcyBhIGNsaWVudFxuICAgICAgICAgKiBmb3IgZWFzeSwgdHlwZSBzYWZlIGNvbnN1bXB0aW9uIG9mIHRoYXQgY2xpZW50LlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBTdHJhdGVneSBzcGVjaWZpYyBjb25zdW1wdGlvbiBvcHRpb25zLlxuICAgICAgICAgKiBAcmV0dXJucyBBbiBhcGkgY2xpZW50IG1hdGNoaW5nIHRoZSBnaXZlbiB0eXBlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb25zdW1lID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV4cG9zZWRQcm9wZXJ0aWVzID0gYXdhaXQgdGhpcy5zdHJhdGVneS5nZXRFeHBvc2VkRnVuY3Rpb25zKG9wdGlvbnMpO1xuICAgICAgICAgICAgcmV0dXJuIGV4cG9zZWRQcm9wZXJ0aWVzLnJlZHVjZSgoY2xpZW50LCBwcm9wKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLmNsaWVudCxcbiAgICAgICAgICAgICAgICBbcHJvcC5rZXldOiB0aGlzLnN0cmF0ZWd5LmNyZWF0ZUZ1bmN0aW9uKHByb3AsIG9wdGlvbnMpXG4gICAgICAgICAgICB9KSwge30pO1xuICAgICAgICB9O1xuICAgIH1cbn1cbmFwaUNvbnN1bWVyLkFwaUNvbnN1bWVyID0gQXBpQ29uc3VtZXI7XG5cbnZhciBhcGlFeHBvc2VyID0ge307XG5cbnZhciBkZWNvcmF0b3JzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWNvcmF0b3JzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmRlY29yYXRvcnMuZXhwb3NlID0gZGVjb3JhdG9ycy5nZXRFeHBvc2VkUHJvcGVydGllcyA9IHZvaWQgMDtcbmNvbnN0IGV4cG9zZWRQcm9wZXJ0aWVzID0gU3ltYm9sKCdleHBvc2VkUHJvcGVydGllcycpO1xuY29uc3QgZ2V0RXhwb3NlZFByb3BlcnRpZXMgPSAodGFyZ2V0KSA9PiB7XG4gICAgcmV0dXJuIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10gfHwgdGFyZ2V0LnByb3RvdHlwZVtleHBvc2VkUHJvcGVydGllc10gfHwgW107XG59O1xuZGVjb3JhdG9ycy5nZXRFeHBvc2VkUHJvcGVydGllcyA9IGdldEV4cG9zZWRQcm9wZXJ0aWVzO1xuLyoqXG4gKiBJbmRpY2F0ZXMgdGhhdCBhIGNsYXNzIG1lbWJlciBmdW5jdGlvbiBjYW4gYmUgZXhwb3NlZCB1c2luZyB7QGxpbmsgQXBpRXhwb3Nlcn0uXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIHNwZWNpZmljIHRvIHRoZSBzdHJhdGVneSB1c2VkIGluIHtAbGluayBBcGlFeHBvc2VyfVxuICovXG4vLyBSZXR1cm5zIGFueSBhcyBkZWNvcmF0b3IgdHlwaW5nIGlzIHdlaXJkLlxuY29uc3QgZXhwb3NlID0gKG9wdGlvbnMpID0+ICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikgPT4ge1xuICAgIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10gPSB0YXJnZXRbZXhwb3NlZFByb3BlcnRpZXNdIHx8IFtdO1xuICAgIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10ucHVzaCh7IGtleSwgZGVzY3JpcHRvciwgb3B0aW9ucyB9KTtcbn07XG5kZWNvcmF0b3JzLmV4cG9zZSA9IGV4cG9zZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwaUV4cG9zZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuYXBpRXhwb3Nlci5BcGlFeHBvc2VyID0gdm9pZCAwO1xuY29uc3QgZGVjb3JhdG9yc18xID0gZGVjb3JhdG9ycztcbi8qKlxuICogRXhwb3NlcyBhcGkgc2VydmljZXMgb24gdGhlIHRyYW5zcG9ydCBvZiBjaG9pY2UuXG4gKi9cbmNsYXNzIEFwaUV4cG9zZXIge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBzdHJhdGVneSBUaGUgZXhwb3NlIHN0cmF0ZWd5IHRvIHVzZSB0byBleHBvc2UgaW5zdGFuY2VzLlxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHN0cmF0ZWd5KSB7XG4gICAgICAgIHRoaXMuc3RyYXRlZ3kgPSBzdHJhdGVneTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV4cG9zZXMgYW4gaW5zdGFuY2Ugb2YgYSBnaXZlbiBhcGkgb25cbiAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIEluc3RhbmNlIG9mIGEgY2xhc3Mgd2hpY2ggaGFzIGJlZW4gZGVjb3JhdGVkIHRvIGluZGljYXRlIHdoaWNoIGZ1bmN0aW9ucyBjYW4gYmUgZXhwb3NlZC5cbiAgICAgICAgICogQHBhcmFtIGluc3RhbmNlT3B0aW9ucyBUcmFuc3BvcnQgc3RyYXRlZ3kgc3BlY2lmaWMgb3B0aW9ucyB0byB1c2Ugd2hlbiBleHBvc2luZy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXhwb3NlSW5zdGFuY2UgPSBhc3luYyAoaW5zdGFuY2UsIGluc3RhbmNlT3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhwb3NhYmxlUHJvcHMgPSAoMCwgZGVjb3JhdG9yc18xLmdldEV4cG9zZWRQcm9wZXJ0aWVzKShpbnN0YW5jZSk7XG4gICAgICAgICAgICBjb25zdCBleHBvc2VkUHJvcHMgPSBhd2FpdCBQcm9taXNlLmFsbChleHBvc2FibGVQcm9wcy5tYXAoYXN5bmMgKHsga2V5LCBvcHRpb25zIH0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXN0b21Db25zdW1wdGlvbk9wdGlvbnMgPSBhd2FpdCB0aGlzLnN0cmF0ZWd5LmV4cG9zZUZ1bmN0aW9uKGluc3RhbmNlW2tleV0uYmluZChpbnN0YW5jZSksIHtcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBtZXRhOiBpbnN0YW5jZU9wdGlvbnNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IGN1c3RvbUNvbnN1bXB0aW9uT3B0aW9uc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnN0cmF0ZWd5LmV4cG9zZU1ldGEoaW5zdGFuY2VPcHRpb25zLCBleHBvc2VkUHJvcHMpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICA7XG59XG5hcGlFeHBvc2VyLkFwaUV4cG9zZXIgPSBBcGlFeHBvc2VyO1xuXG52YXIgc3RyYXRlZ2llcyA9IHt9O1xuXG52YXIgb3BlbmZpbkNoYW5uZWxzID0ge307XG5cbnZhciBjaGFubmVsc0NvbnN1bWVyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsc0NvbnN1bWVyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWxzQ29uc3VtZXIuQ2hhbm5lbHNDb25zdW1lciA9IHZvaWQgMDtcbmNsYXNzIENoYW5uZWxzQ29uc3VtZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKGNoYW5uZWwpIHtcbiAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcbiAgICAgICAgdGhpcy5nZXRFeHBvc2VkRnVuY3Rpb25zID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgaWQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHByb3BzIH0gPSBhd2FpdCB0aGlzLmNoYW5uZWwuZGlzcGF0Y2goYGFwaS1tZXRhOiR7aWR9YCk7XG4gICAgICAgICAgICByZXR1cm4gcHJvcHM7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY3JlYXRlRnVuY3Rpb24gPSAocHJvcCkgPT4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgYWN0aW9uIH0gPSBwcm9wLm9wdGlvbnM7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGFubmVsLmRpc3BhdGNoKGFjdGlvbiwgeyBhcmdzIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICA7XG59XG5jaGFubmVsc0NvbnN1bWVyLkNoYW5uZWxzQ29uc3VtZXIgPSBDaGFubmVsc0NvbnN1bWVyO1xuXG52YXIgY2hhbm5lbHNFeHBvc2VyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsc0V4cG9zZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY2hhbm5lbHNFeHBvc2VyLkNoYW5uZWxzRXhwb3NlciA9IHZvaWQgMDtcbmNsYXNzIENoYW5uZWxzRXhwb3NlciB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgY29uc3RydWN0b3IoY2hhbm5lbFByb3ZpZGVyT3JDbGllbnQpIHtcbiAgICAgICAgdGhpcy5jaGFubmVsUHJvdmlkZXJPckNsaWVudCA9IGNoYW5uZWxQcm92aWRlck9yQ2xpZW50O1xuICAgICAgICB0aGlzLmV4cG9zZUZ1bmN0aW9uID0gYXN5bmMgKHRhcmdldCwgY29uZmlnKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGtleSwgb3B0aW9ucywgbWV0YSB9ID0gY29uZmlnO1xuICAgICAgICAgICAgY29uc3QgeyBpZCB9ID0gbWV0YTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGAke2lkfS4ke29wdGlvbnM/LmFjdGlvbiB8fCBrZXl9YDtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2hhbm5lbFByb3ZpZGVyT3JDbGllbnQucmVnaXN0ZXIoYWN0aW9uLCBhc3luYyAoeyBhcmdzIH0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0KC4uLmFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4geyBhY3Rpb24gfTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5leHBvc2VNZXRhID0gYXN5bmMgKHsgaWQgfSwgcHJvcHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGBhcGktbWV0YToke2lkfWA7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNoYW5uZWxQcm92aWRlck9yQ2xpZW50LnJlZ2lzdGVyKGFjdGlvbiwgKCkgPT4gKHsgcHJvcHMgfSkpO1xuICAgICAgICB9O1xuICAgIH1cbn1cbmNoYW5uZWxzRXhwb3Nlci5DaGFubmVsc0V4cG9zZXIgPSBDaGFubmVsc0V4cG9zZXI7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRfX2V4cG9ydFN0YXIoY2hhbm5lbHNDb25zdW1lciwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihjaGFubmVsc0V4cG9zZXIsIGV4cG9ydHMpOyBcbn0gKG9wZW5maW5DaGFubmVscykpO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKG9wZW5maW5DaGFubmVscywgZXhwb3J0cyk7IFxufSAoc3RyYXRlZ2llcykpO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKGFwaUNvbnN1bWVyLCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKGFwaUV4cG9zZXIsIGV4cG9ydHMpO1xuXHRfX2V4cG9ydFN0YXIoc3RyYXRlZ2llcywgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihkZWNvcmF0b3JzLCBleHBvcnRzKTsgXG59IChhcGlFeHBvc2VyJDEpKTtcblxudmFyIGNoYW5uZWxBcGlSZWxheSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbEFwaVJlbGF5LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWxBcGlSZWxheS5jcmVhdGVSZWxheWVkRGlzcGF0Y2ggPSBjaGFubmVsQXBpUmVsYXkucmVsYXlDaGFubmVsQ2xpZW50QXBpID0gdm9pZCAwO1xuY29uc3QgRVhQRUNURURfRVJST1JTID0gW1xuICAgICdubyBsb25nZXIgY29ubmVjdGVkJyxcbiAgICAnUlRDRGF0YUNoYW5uZWwgY2xvc2VkIHVuZXhwZWN0ZWRseScsXG4gICAgJ1RoZSBjbGllbnQgeW91IGFyZSB0cnlpbmcgdG8gZGlzcGF0Y2ggZnJvbSBpcyBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgdGFyZ2V0IHByb3ZpZGVyJyxcbl07XG4vLyBDaGVja3MgcG9zc2libGUgZXJyb3IgbWVzc2FnZXMgdGhhdCB3ZSB3YW50IHRvIHRyYXAsIGNsaWVudCBlcnJvciBtZXNzYWdlIGNhbiBvcmlnaW5hdGVcbi8vIGZyb20gQ2hhbm5lbFByb3ZpZGVyOjpkaXNwYXRjaCBPUiBDbGFzc2ljU3RyYXRlZ3k6OmNsb3NlRW5kcG9pbnQgT1IgUlRDRW5kUG9pbnQ6OmRhdGFDaGFubmVsOjpvbmNsb3NlXG5jb25zdCBpc0Rpc2Nvbm5lY3RlZEVycm9yID0gKGVycm9yTXNnKSA9PiB7XG4gICAgcmV0dXJuIEVYUEVDVEVEX0VSUk9SUy5zb21lKGUgPT4gZXJyb3JNc2cuaW5jbHVkZXMoZSkpO1xufTtcbi8qKlxuICogQGludGVybmFsXG4gKiBDcmVhdGUgYSBjaGFubmVsIHJlbGF5IGZvciBhIGdpdmVuIGNoYW5uZWwgZXhwb3NpdGlvbiwgYWxsb3dpbmcgYSBzaW5nbGUgcHJvdmlkZXIgdG8gcm91dGVcbiAqIGFjdGlvbnMgdG8gdGhlIGRlc2lnbmF0ZWQgY2xpZW50cy5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggQGV4cG9zZVxuICpcbiAqIEBwYXJhbSBjaGFubmVsUHJvdmlkZXIgVGhlIGNoYW5uZWwgcHJvdmlkZXIgdG8gcmVsYXkgdGhlIGFjdGlvbnMgb24uXG4gKiBAcGFyYW0gY29uZmlnIERldGVybWluZXMgd2hpY2ggYWN0aW9ucyB0byByZWxheS4gUGxlYXNlIGVuc3VyZSBhY3Rpb24gcHJlZml4IG1hdGNoZXMgdGhlIGV4cG9zZWQgYXBpLlxuICovXG5jb25zdCByZWxheUNoYW5uZWxDbGllbnRBcGkgPSBhc3luYyAoY2hhbm5lbFByb3ZpZGVyLCByZWxheUlkKSA9PiB7XG4gICAgY2hhbm5lbFByb3ZpZGVyLnJlZ2lzdGVyKGByZWxheToke3JlbGF5SWR9YCwgKHsgYWN0aW9uLCB0YXJnZXQsIHBheWxvYWQgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY2hhbm5lbFByb3ZpZGVyLmRpc3BhdGNoKHRhcmdldCwgYWN0aW9uLCBwYXlsb2FkKTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5jaGFubmVsQXBpUmVsYXkucmVsYXlDaGFubmVsQ2xpZW50QXBpID0gcmVsYXlDaGFubmVsQ2xpZW50QXBpO1xuY29uc3QgY3JlYXRlUmVsYXllZERpc3BhdGNoID0gKGNsaWVudCwgdGFyZ2V0LCByZWxheUlkLCByZWxheUVycm9yTXNnKSA9PiBhc3luYyAoYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kaXNwYXRjaChgcmVsYXk6JHtyZWxheUlkfWAsIHtcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICB0YXJnZXRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc0Rpc2Nvbm5lY3RlZEVycm9yKGUubWVzc2FnZSkgJiYgcmVsYXlFcnJvck1zZykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlbGF5RXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgfVxufTtcbmNoYW5uZWxBcGlSZWxheS5jcmVhdGVSZWxheWVkRGlzcGF0Y2ggPSBjcmVhdGVSZWxheWVkRGlzcGF0Y2g7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JGIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9MYXlvdXROb2RlX2NsaWVudCwgX1RhYlN0YWNrX2NsaWVudCwgX0NvbHVtbk9yUm93X2NsaWVudDtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShsYXlvdXRFbnRpdGllcywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5sYXlvdXRFbnRpdGllcy5Db2x1bW5PclJvdyA9IGxheW91dEVudGl0aWVzLlRhYlN0YWNrID0gbGF5b3V0RW50aXRpZXMuTGF5b3V0Tm9kZSA9IHZvaWQgMDtcbmNvbnN0IGFwaV9leHBvc2VyXzEgPSBhcGlFeHBvc2VyJDE7XG5jb25zdCBjaGFubmVsX2FwaV9yZWxheV8xID0gY2hhbm5lbEFwaVJlbGF5O1xuLypcbiAgICBUaGlzIGZpbGUgaW5jbHVkZXMgTGF5b3V0Tm9kZSwgQ29sdW1uT3JSb3cgYW5kIFRhYlN0YWNrIGNsYXNzZXMsIHdoaWNoIGFyZSBhbGwgY2xvc2VseVxuICAgIGludGVydHdpbmVkLCBhbmQgc2hhcmUgbWVtYmVycyB2aWEgcGFyZW50IGFic3RyYWN0IGNsYXNzIExheW91dE5vZGUuIFRvIHByZXZlbnQgY2lyY3VsYXJcbiAgICByZWZzLCB3ZSBkZWZpbmUgYW5kIGV4cG9ydCBhbGwgdGhlIGNsYXNzZXMgaGVyZS5cbiovXG4vKipcbiAqIEBpZ25vcmVcbiAqIEBpbnRlcm5hbFxuICogU3VwcGxpZXMgYW4gQXBpQ2xpZW50IGZvciB7QGxpbmsgTGF5b3V0RW50aXRpZXNDb250cm9sbGVyfSBhbmQgaGVscGVyIG1ldGhvZHNcbiAqIGZvciB0aGUgZW50aXRpZXMge0BsaW5rIFRhYlN0YWNrfSBBTkQge0BsaW5rIENvbHVtbk9yUm93fSB0byB1c2UuXG4gKi9cbmNsYXNzIExheW91dE5vZGUge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjbGllbnQsIGVudGl0eUlkKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAaWdub3JlXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBBcGlDbGllbnQgZm9yIHtAbGluayBMYXlvdXRFbnRpdGllc0NvbnRyb2xsZXJ9XG4gICAgICAgICAqL1xuICAgICAgICBfTGF5b3V0Tm9kZV9jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgdGhlIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93IGlzIHRoZSByb290IGNvbnRlbnQgaXRlbVxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBpc1Jvb3QgPSBhd2FpdCBzdGFjay5pc1Jvb3QoKTtcbiAgICAgICAgICogLy8gVGhlIFRhYlN0YWNrIGlzIHJvb3Q6IGZhbHNlXG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgVGFiU3RhY2sgaXMgcm9vdDogJHtpc1Jvb3R9YCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIFJldHJpZXZlcyB0aGUgcGFyZW50IENvbHVtbk9yUm93XG4gICAgICAgICAqIGNvbnN0IHBhcmVudCA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBjb25zdCBwYXJlbnRJc1Jvb3QgPSBhd2FpdCBwYXJlbnQuaXNSb290KCk7XG4gICAgICAgICAqIC8vIFRoZSBwYXJlbnQgQ29sdW1uT3JSb3cgaXMgcm9vdDogdHJ1ZVxuICAgICAgICAgKiBjb25zb2xlLmxvZyhgVGhlIHBhcmVudCBDb2x1bW5PclJvdyBpcyByb290OiAke3BhcmVudElzUm9vdH1gKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzUm9vdCA9ICgpID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5pc1Jvb3QodGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgdGhlIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93IGV4aXN0c1xuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiAvLyBSZXRyaWV2ZXMgdGhlIHBhcmVudCBDb2x1bW5PclJvd1xuICAgICAgICAgKiBjb25zdCBjb2x1bW5PclJvdyA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBsZXQgZXhpc3RzID0gYXdhaXQgc3RhY2suZXhpc3RzKCk7XG4gICAgICAgICAqIC8vIG9yXG4gICAgICAgICAqIGxldCBleGlzdHMgPSBhd2FpdCBjb2x1bW5PclJvdy5leGlzdHMoKTtcbiAgICAgICAgICogLy8gVGhlIGVudGl0eSBleGlzdHM6IHRydWVcbiAgICAgICAgICogY29uc29sZS5sb2coYFRoZSBlbnRpdHkgZXhpc3RzOiAke2V4aXN0c31gKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmV4aXN0cyA9ICgpID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5leGlzdHModGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIHBhcmVudCBvZiB0aGUgVGFiU3RhY2sgb3IgQ29sdW1uT3JSb3dcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogaWYgKCFmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluIGEgcGxhdGZvcm0gVmlldy4nKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKlxuICAgICAgICAgKiBjb25zdCBzdGFjayA9IGF3YWl0IGZpbi5tZS5nZXRDdXJyZW50U3RhY2soKTtcbiAgICAgICAgICogLy8gUmV0cmlldmVzIHRoZSBwYXJlbnQgQ29sdW1uT3JSb3dcbiAgICAgICAgICogY29uc3QgY29sdW1uT3JSb3cgPSBhd2FpdCBzdGFjay5nZXRQYXJlbnQoKTtcbiAgICAgICAgICpcbiAgICAgICAgICogLy8gdW5kZWZpbmVkIGlmIGVudGl0eSBpcyB0aGUgcm9vdCBpdGVtXG4gICAgICAgICAqIGxldCBwYXJlbnQgPSBhd2FpdCBjb2x1bW5PclJvdy5nZXRQYXJlbnQoKTtcbiAgICAgICAgICogLy8gb3JcbiAgICAgICAgICogbGV0IHBhcmVudCA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0UGFyZW50ID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRkKHRoaXMsIF9MYXlvdXROb2RlX2NsaWVudCwgXCJmXCIpLmdldFBhcmVudCh0aGlzLmVudGl0eUlkKTtcbiAgICAgICAgICAgIGlmICghcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBMYXlvdXROb2RlLmdldEVudGl0eShwYXJlbnQsIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFRhYlN0YWNrIGFkamFjZW50IHRvIHRoZSBnaXZlbiBUYWJTdGFjayBvciBDb2x1bW5PclJvdy4gSW5wdXRzIGNhbiBiZSBuZXcgdmlld3MgdG8gY3JlYXRlLCBvciBleGlzdGluZyB2aWV3cy5cbiAgICAgICAgICpcbiAgICAgICAgICogS25vd24gSXNzdWU6IElmIHRoZSBudW1iZXIgb2Ygdmlld3MgdG8gYWRkIG92ZXJmbG93cyB0aGUgdGFiLWNvbnRhaW5lciwgdGhlIGFkZGVkIHZpZXdzIHdpbGwgYmUgc2V0IGFzIGFjdGl2ZVxuICAgICAgICAgKiBkdXJpbmcgZWFjaCByZW5kZXIsIGFuZCB0aGVuIHBsYWNlZCBhdCB0aGUgZnJvbnQgb2YgdGhlIHRhYi1zdGFjaywgd2hpbGUgdGhlIHVuZGVybHlpbmcgb3JkZXIgb2YgdGFicyB3aWxsIHJlbWFpbiB1bmNoYW5nZWQuXG4gICAgICAgICAqIFRoaXMgbWVhbnMgdGhlIHZpZXdzIHlvdSBwYXNzIHRvIGNyZWF0ZUFkamFjZW50U3RhY2soKSBtYXkgbm90IHJlbmRlciBpbiB0aGUgb3JkZXIgZ2l2ZW4gYnkgdGhlIGFycmF5LlxuICAgICAgICAgKiBVbnRpbCBmaXhlZCwgdGhpcyBwcm9ibGVtIGNhbiBiZSBhdm9pZGVkIG9ubHkgaWYgeW91ciB3aW5kb3cgaXMgd2lkZSBlbm91Z2ggdG8gZml0IGNyZWF0aW5nIGFsbCB0aGUgdmlld3MgaW4gdGhlIHRhYnN0YWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gdmlld3MgVGhlIHZpZXdzIHRoYXQgd2lsbCBwb3B1bGF0ZSB0aGUgbmV3IFRhYlN0YWNrLlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBjb250cm9sIG5ldyBUYWJTdGFjayBjcmVhdGlvbi5cbiAgICAgICAgICogQHJldHVybnMgVGhlIG5ld2x5LWNyZWF0ZWQgVGFiU3RhY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIGNvbnN0IGNvbHVtbk9yUm93ID0gYXdhaXQgc3RhY2suZ2V0UGFyZW50KCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIENyZWF0ZSB2aWV3IHJlZmVyZW5jZXMgYnkgc3VwcGx5aW5nIGEgJ25hbWUnIGFuZCAndXJsJ1xuICAgICAgICAgKiBjb25zdCB2aWV3cyA9IFtcbiAgICAgICAgICogICAgIC8vIGlmICduYW1lJyBpcyB1bmRlZmluZWQsIG9uZSB3aWxsIGJlIGdlbmVyYXRlZFxuICAgICAgICAgKiAgICAgLy8gaWYgJ3VybCcgaXMgdW5kZWZpbmVkLCBpdCB3aWxsIGRlZmF1bHQgdGhlIHZpZXcgVVJMIHRvICdhYm91dDpibGFuaydcbiAgICAgICAgICogICAgIHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJ30sXG4gICAgICAgICAqICAgICB7IG5hbWU6ICdvZi1kZXZlbG9wZXJzLXZpZXcnLCB1cmw6ICdodHRwOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvLyd9LFxuICAgICAgICAgKiBdO1xuICAgICAgICAgKlxuICAgICAgICAgKiAvLyBDcmVhdGUgYSB2aWV3IGJlZm9yZWhhbmQgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIG5ldyB0YWIgc3RhY2tcbiAgICAgICAgICogY29uc3Qgb3V0c2lkZVZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuICAgICAgICAgKiAgICAgbmFtZTogJ291dHNpZGUtYmxvb21iZXJnLXZpZXcnLFxuICAgICAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly9ibG9vbWJlcmcuY29tLycsXG4gICAgICAgICAqICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgICAgICogfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIFZpZXdzIHRvIGFkZCBjYW4gYmUgaWRlbnRpdGllcywgb3IgdGhlIHJlZmVyZW5jZSB2aWV3cyBtZW50aW9uZWQgYWJvdmVcbiAgICAgICAgICogY29uc3Qgdmlld3NUb0FkZCA9IFtvdXRzaWRlVmlldy5pZGVudGl0eSwgLi4udmlld3NdO1xuICAgICAgICAgKlxuICAgICAgICAgKiAvLyBQb3NzaWJsZSBwb3NpdGlvbiBpbnB1dHM6ICdyaWdodCcgfCAnbGVmdCcgfCAndG9wJyB8ICdib3R0b20nXG4gICAgICAgICAqIGxldCBzdGFja0Zyb20gPSBhd2FpdCBjb2x1bW5PclJvdy5jcmVhdGVBZGphY2VudFN0YWNrKHZpZXdzVG9BZGQsIHsgcG9zaXRpb246ICdyaWdodCcgfSk7XG4gICAgICAgICAqIC8vIE9yXG4gICAgICAgICAqIGxldCBuZXdTdGFjayA9IGF3YWl0IHN0YWNrLmNyZWF0ZUFkamFjZW50U3RhY2sodmlld3NUb0FkZCwgeyBwb3NpdGlvbjogJ3JpZ2h0JyB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coYEEgbmV3IFRhYlN0YWNrIGNyZWF0ZWQgdG8gdGhlIHJpZ2h0IGhhcyAke25ld1N0YWNrLmxlbmd0aH0gdmlld3MgaW4gaXRgKTtcbiAgICAgICAgICpcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY3JlYXRlQWRqYWNlbnRTdGFjayA9IGFzeW5jICh2aWV3cywgb3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5SWQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikuY3JlYXRlQWRqYWNlbnRTdGFjayh0aGlzLmVudGl0eUlkLCB2aWV3cywgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoeyBlbnRpdHlJZCwgdHlwZTogJ3N0YWNrJyB9LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogUmV0cmlldmVzIHRoZSBhZGphY2VudCBUYWJTdGFja3Mgb2YgdGhlIGdpdmVuIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZWRnZSBFZGdlIHdob3NlIGFkamFjZW50IFRhYlN0YWNrcyB3aWxsIGJlIHJldHVybmVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBjb2x1bW5PclJvdyA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiAvLyBQb3NzaWJsZSBwb3NpdGlvbiBpbnB1dHM6ICdyaWdodCcgfCAnbGVmdCcgfCAndG9wJyB8ICdib3R0b20nXG4gICAgICAgICAqIGxldCByaWdodFN0YWNrcyA9IGF3YWl0IGNvbHVtbk9yUm93LmdldEFkamFjZW50U3RhY2tzKCdyaWdodCcpO1xuICAgICAgICAgKiBsZXQgbGVmdFN0YWNrcyA9IGF3YWl0IGNvbHVtbk9yUm93LmdldEFkamFjZW50U3RhY2tzKCdsZWZ0Jyk7XG4gICAgICAgICAqIC8vIG9yXG4gICAgICAgICAqIGxldCByaWdodFN0YWNrcyA9IGF3YWl0IHN0YWNrLmdldEFkamFjZW50U3RhY2tzKCdyaWdodCcpO1xuICAgICAgICAgKiBsZXQgbGVmdFN0YWNrcyA9IGF3YWl0IHN0YWNrLmdldEFkamFjZW50U3RhY2tzKCdsZWZ0Jyk7XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgZW50aXR5IGhhcyAke3JpZ2h0U3RhY2tzLmxlbmd0aH0gc3RhY2tzIHRvIHRoZSByaWdodCwgYW5kICR7bGVmdFN0YWNrcy5sZW5ndGh9IHN0YWNrcyB0byB0aGUgbGVmdGApO1xuICAgICAgICAgKlxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5nZXRBZGphY2VudFN0YWNrcyA9IGFzeW5jIChlZGdlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhZGphY2VudFN0YWNrcyA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5nZXRBZGphY2VudFN0YWNrcyh7XG4gICAgICAgICAgICAgICAgdGFyZ2V0SWQ6IHRoaXMuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZWRnZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gYWRqYWNlbnRTdGFja3MubWFwKChzdGFjaykgPT4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IHN0YWNrLmVudGl0eUlkXG4gICAgICAgICAgICB9LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikpKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCRiKHRoaXMsIF9MYXlvdXROb2RlX2NsaWVudCwgY2xpZW50LCBcImZcIik7XG4gICAgICAgIHRoaXMuZW50aXR5SWQgPSBlbnRpdHlJZDtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5MYXlvdXROb2RlID0gTGF5b3V0Tm9kZTtcbl9MYXlvdXROb2RlX2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIEBpbnRlcm5hbFxuICogRW5jYXBzdWxhdGVzIEFwaSBjb25zdW1wdGlvbiBvZiB7QGxpbmsgTGF5b3V0RW50aXRpZXNDbGllbnR9IHdpdGggYSByZWxheWVkIGRpc3BhdGNoXG4gKiBAcGFyYW0gY2xpZW50XG4gKiBAcGFyYW0gY29udHJvbGxlcklkXG4gKiBAcGFyYW0gaWRlbnRpdHlcbiAqIEByZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAbGluayBMYXlvdXRFbnRpdGllc0NsaWVudH0gd2l0aCBib3VuZCB0byB0aGUgY29udHJvbGxlcklkXG4gKi9cbkxheW91dE5vZGUubmV3TGF5b3V0RW50aXRpZXNDbGllbnQgPSBhc3luYyAoY2xpZW50LCBjb250cm9sbGVySWQsIGlkZW50aXR5KSA9PiB7XG4gICAgY29uc3QgZGlzcGF0Y2ggPSAoMCwgY2hhbm5lbF9hcGlfcmVsYXlfMS5jcmVhdGVSZWxheWVkRGlzcGF0Y2gpKGNsaWVudCwgaWRlbnRpdHksICdsYXlvdXQtcmVsYXknLCAnWW91IGFyZSB0cnlpbmcgdG8gaW50ZXJhY3Qgd2l0aCBhIGxheW91dCBjb21wb25lbnQgb24gYSB3aW5kb3cgdGhhdCBkb2VzIG5vdCBleGlzdCBvciBoYXMgYmVlbiBkZXN0cm95ZWQuJyk7XG4gICAgY29uc3QgY29uc3VtZXIgPSBuZXcgYXBpX2V4cG9zZXJfMS5BcGlDb25zdW1lcihuZXcgYXBpX2V4cG9zZXJfMS5DaGFubmVsc0NvbnN1bWVyKHsgZGlzcGF0Y2ggfSkpO1xuICAgIHJldHVybiBjb25zdW1lci5jb25zdW1lKHsgaWQ6IGNvbnRyb2xsZXJJZCB9KTtcbn07XG5MYXlvdXROb2RlLmdldEVudGl0eSA9IChkZWZpbml0aW9uLCBjbGllbnQpID0+IHtcbiAgICBjb25zdCB7IGVudGl0eUlkLCB0eXBlIH0gPSBkZWZpbml0aW9uO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdjb2x1bW4nOlxuICAgICAgICBjYXNlICdyb3cnOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2x1bW5PclJvdyhjbGllbnQsIGVudGl0eUlkLCB0eXBlKTtcbiAgICAgICAgY2FzZSAnc3RhY2snOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBUYWJTdGFjayhjbGllbnQsIGVudGl0eUlkKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pc2VkIExheW91dCBFbnRpdHkgZW5jb3VudGVyZWQgKCcke0pTT04uc3RyaW5naWZ5KGRlZmluaXRpb24pfSlgKTtcbiAgICB9XG59O1xuLyoqXG4gKiBBIFRhYlN0YWNrIGlzIHVzZWQgdG8gbWFuYWdlIHRoZSBzdGF0ZSBvZiBhIHN0YWNrIG9mIHRhYnMgd2l0aGluIGFuIE9wZW5GaW4gTGF5b3V0LlxuICovXG5jbGFzcyBUYWJTdGFjayBleHRlbmRzIExheW91dE5vZGUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBjb25zdHJ1Y3RvcihjbGllbnQsIGVudGl0eUlkKSB7XG4gICAgICAgIHN1cGVyKGNsaWVudCwgZW50aXR5SWQpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEFwaUNsaWVudCBmb3Ige0BsaW5rIExheW91dEVudGl0aWVzQ29udHJvbGxlcn1cbiAgICAgICAgICovXG4gICAgICAgIF9UYWJTdGFja19jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUeXBlIG9mIHRoZSBjb250ZW50IGl0ZW0uIEFsd2F5cyBzdGFjaywgYnV0IHVzZWZ1bCBmb3IgZGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBhIHtAbGluayBUYWJTdGFja30gYW5kIHtAbGluayBDb2x1bW5PclJvd30uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnR5cGUgPSAnc3RhY2snO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmV0cmlldmVzIGEgbGlzdCBvZiBhbGwgdmlld3MgYmVsb25naW5nIHRvIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogS25vd24gSXNzdWU6IElmIGFkZGluZyBhIHZpZXcgb3ZlcmZsb3dzIHRoZSB0YWItY29udGFpbmVyIHdpZHRoLCB0aGUgYWRkZWQgdmlldyB3aWxsIGJlIHNldCBhcyBhY3RpdmVcbiAgICAgICAgICogYW5kIHJlbmRlcmVkIGF0IHRoZSBmcm9udCBvZiB0aGUgdGFiLXN0YWNrLCB3aGlsZSB0aGUgdW5kZXJseWluZyBvcmRlciBvZiB0YWJzIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgICAgICogSWYgdGhhdCBoYXBwZW5zIGFuZCB0aGVuIGdldFZpZXdzKCkgaXMgY2FsbGVkLCBpdCB3aWxsIHJldHVybiB0aGUgaWRlbnRpdGllcyBpbiBhIGRpZmZlcmVudCBvcmRlciB0aGFuXG4gICAgICAgICAqIHRoYW4gdGhlIGN1cnJlbnRseSByZW5kZXJlZCB0YWIgb3JkZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHtAbGluayBUYWJTdGFja30gaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiAvLyBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIHdyYXAgYW55IHZpZXcgYW5kIGdldCB0aGUgc3RhY2sgZnJvbSB0aGVyZVxuICAgICAgICAgKiAvLyBjb25zdCB2aWV3RnJvbVNvbWV3aGVyZSA9IGZpbi5WaWV3LndyYXBTeW5jKHNvbWVWaWV3LmlkZW50aXR5KTtcbiAgICAgICAgICogLy8gY29uc3Qgc3RhY2sgPSBhd2FpdCB2aWV3RnJvbVNvbWV3aGVyZS5nZXRDdXJyZW50U3RhY2soKTtcbiAgICAgICAgICogY29uc3Qgdmlld3MgPSBhd2FpdCBzdGFjay5nZXRWaWV3cygpO1xuICAgICAgICAgKiBjb25zb2xlLmxvZyhgU3RhY2sgY29udGFpbnMgJHt2aWV3cy5sZW5ndGh9IHZpZXcocylgKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0Vmlld3MgPSAoKSA9PiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX1RhYlN0YWNrX2NsaWVudCwgXCJmXCIpLmdldFN0YWNrVmlld3ModGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBZGRzIG9yIGNyZWF0ZXMgYSB2aWV3IGluIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgS25vd24gSXNzdWU6IElmIGFkZGluZyBhIHZpZXcgb3ZlcmZsb3dzIHRoZSB0YWItY29udGFpbmVyLCB0aGUgYWRkZWQgdmlldyB3aWxsIGJlIHNldCBhcyBhY3RpdmVcbiAgICAgICAgICogYW5kIHJlbmRlcmVkIGF0IHRoZSBmcm9udCBvZiB0aGUgdGFiLXN0YWNrLCB3aGlsZSB0aGUgdW5kZXJseWluZyBvcmRlciBvZiB0YWJzIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHZpZXcgVGhlIGlkZW50aXR5IG9mIGFuIGV4aXN0aW5nIHZpZXcgdG8gYWRkLCBvciBvcHRpb25zIHRvIGNyZWF0ZSBhIHZpZXcuXG4gICAgICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIHZpZXcgb3B0aW9uczogaW5kZXggbnVtYmVyIHVzZWQgdG8gaW5zZXJ0IHRoZSB2aWV3IGludG8gdGhlIHN0YWNrIGF0IHRoYXQgaW5kZXguIERlZmF1bHRzIHRvIDAgKGZyb250IG9mIHRoZSBzdGFjaylcbiAgICAgICAgICogQHJldHVybnMgUmVzb2x2ZXMgd2l0aCB0aGUge0BsaW5rIE9wZW5GaW4uSWRlbnRpdHkgaWRlbnRpdHl9IG9mIHRoZSBhZGRlZCB2aWV3LlxuICAgICAgICAgKiBAdGhyb3dzIElmIHRoZSB2aWV3IGRvZXMgbm90IGV4aXN0IG9yIGZhaWxzIHRvIGNyZWF0ZS5cbiAgICAgICAgICogQHRocm93cyBJZiB0aGUge0BsaW5rIFRhYlN0YWNrfSBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIC8vIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gd3JhcCBhbnkgdmlldyBhbmQgZ2V0IHRoZSBzdGFjayBmcm9tIHRoZXJlXG4gICAgICAgICAqIC8vIGNvbnN0IHZpZXdGcm9tU29tZXdoZXJlID0gZmluLlZpZXcud3JhcFN5bmMoc29tZVZpZXcuaWRlbnRpdHkpO1xuICAgICAgICAgKiAvLyBjb25zdCBzdGFjayA9IGF3YWl0IHZpZXdGcm9tU29tZXdoZXJlLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBnb29nbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJyB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coJ0lkZW50aXR5IG9mIHRoZSBnb29nbGUgdmlldyBqdXN0IGFkZGVkJywgeyBnb29nbGVWaWV3SWRlbnRpdHkgfSk7XG4gICAgICAgICAqIC8vIHBhc3MgaW4geyBpbmRleDogbnVtYmVyIH0gdG8gc2V0IHRoZSBpbmRleCBpbiB0aGUgc3RhY2suIEhlcmUgMSBtZWFucywgZW5kIG9mIHRoZSBzdGFjayAoZGVmYXVsdHMgdG8gMClcbiAgICAgICAgICogY29uc3QgYXBwbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2FwcGxlLXZpZXcnLCB1cmw6ICdodHRwOi8vYXBwbGUuY29tLycgfSwgeyBpbmRleDogMSB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coJ0lkZW50aXR5IG9mIHRoZSBhcHBsZSB2aWV3IGp1c3QgYWRkZWQnLCB7IGFwcGxlVmlld0lkZW50aXR5IH0pO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hZGRWaWV3ID0gYXN5bmMgKHZpZXcsIG9wdGlvbnMgPSB7IGluZGV4OiAwIH0pID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfVGFiU3RhY2tfY2xpZW50LCBcImZcIikuYWRkVmlld1RvU3RhY2sodGhpcy5lbnRpdHlJZCwgdmlldywgb3B0aW9ucyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZW1vdmVzIGEgdmlldyBmcm9tIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgdmlldyBpZGVudGl0eSBkb2VzIG5vdCBleGlzdCBvciB3YXMgYWxyZWFkeSBkZXN0cm95ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB2aWV3IC0gSWRlbnRpdHkgb2YgdGhlIHZpZXcgdG8gcmVtb3ZlLlxuICAgICAgICAgKiBAdGhyb3dzIElmIHRoZSB2aWV3IGRvZXMgbm90IGV4aXN0IG9yIGRvZXMgbm90IGJlbG9uZyB0byB0aGUgc3RhY2suXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHtAbGluayBUYWJTdGFja30gaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBnb29nbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJyB9KTtcbiAgICAgICAgICpcbiAgICAgICAgICogYXdhaXQgc3RhY2sucmVtb3ZlVmlldyhnb29nbGVWaWV3SWRlbnRpdHkpO1xuICAgICAgICAgKlxuICAgICAgICAgKiB0cnkge1xuICAgICAgICAgKiAgICAgYXdhaXQgc3RhY2sucmVtb3ZlVmlldyhnb29nbGVWaWV3SWRlbnRpdHkpO1xuICAgICAgICAgKiB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgKiAgICAgLy8gVHJpZWQgdG8gcmVtb3ZlIGEgdmlldyAoJ2dvb2dsZS12aWV3Jykgd2hpY2ggZG9lcyBub3QgYmVsb25nIHRvIHRoZSBzdGFjay5cbiAgICAgICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVtb3ZlVmlldyA9IGFzeW5jICh2aWV3KSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX1RhYlN0YWNrX2NsaWVudCwgXCJmXCIpLnJlbW92ZVZpZXdGcm9tU3RhY2sodGhpcy5lbnRpdHlJZCwgdmlldyk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBhY3RpdmUgdmlldyBvZiB0aGUge0BsaW5rIFRhYlN0YWNrfSB3aXRob3V0IGZvY3VzaW5nIGl0LlxuICAgICAgICAgKiBAcGFyYW0gdmlldyAtIElkZW50aXR5IG9mIHRoZSB2aWV3IHRvIGFjdGl2YXRlLlxuICAgICAgICAgKiBAcmV0dXJucyBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdm9pZCBvbmNlIHRoZSB2aWV3IGhhcyBiZWVuIGFjdGl2YXRlZC5cbiAgICAgICAgICogQHRocm93cyBJZiB0aGUge0BsaW5rIFRhYlN0YWNrfSBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHZpZXcgZG9lcyBub3QgZXhpc3QuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIENoYW5nZSB0aGUgYWN0aXZlIHRhYiBvZiBhIGtub3duIFZpZXcncyBUYWJTdGFjazpcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogY29uc3QgdGFyZ2V0VmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogJ3V1aWQnLCBuYW1lOiAndmlldy1uYW1lJyB9KTtcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCB0YXJnZXRWaWV3LmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBhd2FpdCBzdGFjay5zZXRBY3RpdmVWaWV3KHRhcmdldFZpZXcuaWRlbnRpdHkpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICpcbiAgICAgICAgICogU2V0IHRoZSBjdXJyZW50IFZpZXcgYXMgYWN0aXZlIHdpdGhpbiBpdHMgVGFiU3RhY2s6XG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBhd2FpdCBzdGFjay5zZXRBY3RpdmVWaWV3KGZpbi5tZS5pZGVudGl0eSk7XG4gICAgICAgICAqIGBgYFxuICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnNldEFjdGl2ZVZpZXcgPSBhc3luYyAodmlldykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRkKHRoaXMsIF9UYWJTdGFja19jbGllbnQsIFwiZlwiKS5zZXRTdGFja0FjdGl2ZVZpZXcodGhpcy5lbnRpdHlJZCwgdmlldyk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYih0aGlzLCBfVGFiU3RhY2tfY2xpZW50LCBjbGllbnQsIFwiZlwiKTtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5UYWJTdGFjayA9IFRhYlN0YWNrO1xuX1RhYlN0YWNrX2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEEgQ29sdW1uT3JSb3cgaXMgdXNlZCB0byBtYW5hZ2UgdGhlIHN0YXRlIG9mIENvbHVtbiBhbmQgUm93cyB3aXRoaW4gYW4gT3BlbkZpbiBMYXlvdXQuXG4gKi9cbmNsYXNzIENvbHVtbk9yUm93IGV4dGVuZHMgTGF5b3V0Tm9kZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2xpZW50LCBlbnRpdHlJZCwgdHlwZSkge1xuICAgICAgICBzdXBlcihjbGllbnQsIGVudGl0eUlkKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpZ25vcmVcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEFwaUNsaWVudCBmb3Ige0BsaW5rIExheW91dEVudGl0aWVzQ29udHJvbGxlcn1cbiAgICAgICAgICovXG4gICAgICAgIF9Db2x1bW5PclJvd19jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbnRlbnQgYXJyYXkgb2YgdGhlIENvbHVtbk9yUm93XG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIC8vIFJldHJpZXZlcyB0aGUgcGFyZW50IENvbHVtbk9yUm93XG4gICAgICAgICAqIGNvbnN0IGNvbHVtbk9yUm93ID0gYXdhaXQgc3RhY2suZ2V0UGFyZW50KCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIHJldHVybnMgW1RhYlN0YWNrXVxuICAgICAgICAgKiBjb25zdCBjb250ZW50QXJyYXkgPSBhd2FpdCBjb2x1bW5PclJvdy5nZXRDb250ZW50KCk7XG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgQ29sdW1uT3JSb3cgaGFzICR7Y29udGVudEFycmF5Lmxlbmd0aH0gaXRlbShzKWApO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0Q29udGVudCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRJdGVtRW50aXRpZXMgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0NvbHVtbk9yUm93X2NsaWVudCwgXCJmXCIpLmdldENvbnRlbnQodGhpcy5lbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gY29udGVudEl0ZW1FbnRpdGllcy5tYXAoKGVudGl0eSkgPT4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoZW50aXR5LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0NvbHVtbk9yUm93X2NsaWVudCwgXCJmXCIpKSk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYih0aGlzLCBfQ29sdW1uT3JSb3dfY2xpZW50LCBjbGllbnQsIFwiZlwiKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5Db2x1bW5PclJvdyA9IENvbHVtbk9yUm93O1xuX0NvbHVtbk9yUm93X2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBsYXlvdXRfY29uc3RhbnRzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShsYXlvdXRfY29uc3RhbnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmxheW91dF9jb25zdGFudHMuREVGQVVMVF9MQVlPVVRfS0VZID0gbGF5b3V0X2NvbnN0YW50cy5MQVlPVVRfQ09OVFJPTExFUl9JRCA9IHZvaWQgMDtcbmxheW91dF9jb25zdGFudHMuTEFZT1VUX0NPTlRST0xMRVJfSUQgPSAnbGF5b3V0LWVudGl0aWVzJztcbi8vIFRPRE86IGV2ZW50dWFsbHkgZXhwb3J0IHRoaXMgc29tZWhvd1xubGF5b3V0X2NvbnN0YW50cy5ERUZBVUxUX0xBWU9VVF9LRVkgPSAnX19kZWZhdWx0X18nO1xuXG52YXIgbWFpbiA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobWFpbiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5tYWluLldlYkNvbnRlbnRzID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJGogPSBiYXNlO1xuY2xhc3MgV2ViQ29udGVudHMgZXh0ZW5kcyBiYXNlXzEkai5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBpZGVudGl0eSBvZiB0aGUge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgV2ViQ29udGVudHN9LlxuICAgICAqIEBwYXJhbSBlbnRpdHlUeXBlIFRoZSB0eXBlIG9mIHRoZSB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBXZWJDb250ZW50c30uXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHksIGVudGl0eVR5cGUpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgZW50aXR5VHlwZSwgaWRlbnRpdHkudXVpZCwgaWRlbnRpdHkubmFtZSk7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyBhIGJhc2U2NCBlbmNvZGVkIGltYWdlIG9mIGFsbCBvciBwYXJ0IG9mIHRoZSBXZWJDb250ZW50cy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgY2FwdHVyZVBhZ2UgY2FsbC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiAvLyBQTkcgaW1hZ2Ugb2YgYSBmdWxsIHZpc2libGUgVmlld1xuICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHZpZXcuY2FwdHVyZVBhZ2UoKSk7XG4gICAgICpcbiAgICAgKiAvLyBMb3ctcXVhbGl0eSBKUEVHIGltYWdlIG9mIGEgZGVmaW5lZCB2aXNpYmxlIGFyZWEgb2YgdGhlIHZpZXdcbiAgICAgKiBjb25zdCBvcHRpb25zID0ge1xuICAgICAqICAgICBhcmVhOiB7XG4gICAgICogICAgICAgICBoZWlnaHQ6IDEwMCxcbiAgICAgKiAgICAgICAgIHdpZHRoOiAxMDAsXG4gICAgICogICAgICAgICB4OiAxMCxcbiAgICAgKiAgICAgICAgIHk6IDEwLFxuICAgICAqICAgICB9LFxuICAgICAqICAgICBmb3JtYXQ6ICdqcGcnLFxuICAgICAqICAgICBxdWFsaXR5OiAyMFxuICAgICAqIH1cbiAgICAgKiBjb25zb2xlLmxvZyhhd2FpdCB2aWV3LmNhcHR1cmVQYWdlKG9wdGlvbnMpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHduZCA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogLy8gUE5HIGltYWdlIG9mIGEgZnVsbCB2aXNpYmxlIHdpbmRvd1xuICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHduZC5jYXB0dXJlUGFnZSgpKTtcbiAgICAgKlxuICAgICAqIC8vIExvdy1xdWFsaXR5IEpQRUcgaW1hZ2Ugb2YgYSBkZWZpbmVkIHZpc2libGUgYXJlYSBvZiB0aGUgd2luZG93XG4gICAgICogY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgKiAgICAgYXJlYToge1xuICAgICAqICAgICAgICAgaGVpZ2h0OiAxMDAsXG4gICAgICogICAgICAgICB3aWR0aDogMTAwLFxuICAgICAqICAgICAgICAgeDogMTAsXG4gICAgICogICAgICAgICB5OiAxMCxcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgZm9ybWF0OiAnanBnJyxcbiAgICAgKiAgICAgcXVhbGl0eTogMjBcbiAgICAgKiB9XG4gICAgICogY29uc29sZS5sb2coYXdhaXQgd25kLmNhcHR1cmVQYWdlKG9wdGlvbnMpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBjYXB0dXJlUGFnZShvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignY2FwdHVyZS1wYWdlJywgeyBvcHRpb25zLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBKYXZhc2NyaXB0IG9uIHRoZSBXZWJDb250ZW50cywgcmVzdHJpY3RlZCB0byBjb250ZW50cyB5b3Ugb3duIG9yIGNvbnRlbnRzIG93bmVkIGJ5XG4gICAgICogYXBwbGljYXRpb25zIHlvdSBoYXZlIGNyZWF0ZWQuXG4gICAgICogQHBhcmFtIGNvZGUgSmF2YVNjcmlwdCBjb2RlIHRvIGJlIGV4ZWN1dGVkIG9uIHRoZSB2aWV3LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUphdmFTY3JpcHQoY29kZSkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7dXVpZDogJ3V1aWQnLCBuYW1lOiAndmlldyBuYW1lJ30pO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5leGVjdXRlSmF2YVNjcmlwdChjb2RlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBleGVjdXRlSmF2YVNjcmlwdChgY29uc29sZS5sb2coJ0hlbGxvLCBPcGVuZmluJylgKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdKYXZhc2NyaXB0IGV4Y3V0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUphdmFTY3JpcHQoY29kZSkge1xuICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcbiAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmV4ZWN1dGVKYXZhU2NyaXB0Lmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5leGVjdXRlSmF2YVNjcmlwdChjb2RlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBleGVjdXRlSmF2YVNjcmlwdChgY29uc29sZS5sb2coJ0hlbGxvLCBPcGVuZmluJylgKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdKYXZhc2NyaXB0IGV4Y3V0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBleGVjdXRlSmF2YVNjcmlwdChjb2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdleGVjdXRlLWphdmFzY3JpcHQtaW4td2luZG93JywgeyAuLi50aGlzLmlkZW50aXR5LCBjb2RlIH0pXG4gICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIFdlYkNvbnRlbnRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5nZXRab29tTGV2ZWwoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0Wm9vbUxldmVsLmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRab29tTGV2ZWwoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGdldFpvb21MZXZlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtem9vbS1sZXZlbCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB6b29tIGxldmVsIG9mIHRoZSBXZWJDb250ZW50cy5cbiAgICAgKiBAcGFyYW0gbGV2ZWwgVGhlIHpvb20gbGV2ZWxcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFpvb21MZXZlbChudW1iZXIpIHtcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcuc2V0Wm9vbUxldmVsKG51bWJlcik7XG4gICAgICogfVxuICAgICAqXG4gICAgICogc2V0Wm9vbUxldmVsKDQpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1NldHRpbmcgYSAgem9vbSBsZXZlbCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2V0Wm9vbUxldmVsLmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogYXN5bmMgZnVuY3Rpb24gc2V0Wm9vbUxldmVsKG51bWJlcikge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zZXRab29tTGV2ZWwobnVtYmVyKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBzZXRab29tTGV2ZWwoNCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2V0dGluZyBhICB6b29tIGxldmVsJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgc2V0Wm9vbUxldmVsKGxldmVsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2V0LXpvb20tbGV2ZWwnLCB7IC4uLnRoaXMuaWRlbnRpdHksIGxldmVsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRoZSBXZWJDb250ZW50cyB0byBhIHNwZWNpZmllZCBVUkwuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGUgdXJsIG11c3QgY29udGFpbiB0aGUgcHJvdG9jb2wgcHJlZml4IHN1Y2ggYXMgaHR0cDovLyBvciBodHRwczovLy5cbiAgICAgKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCB0byBuYXZpZ2F0ZSB0aGUgV2ViQ29udGVudHMgdG8uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IG1lLmlkZW50aXR5LFxuICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuICAgICAqICAgICB9KTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBjcmVhdGVWaWV3KClcbiAgICAgKiAgICAgLnRoZW4odmlldyA9PiB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2V4YW1wbGUuY29tJykpXG4gICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCduYXZpZ2F0aW9uIGNvbXBsZXRlJykpXG4gICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBuYXZpZ2F0ZSgpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubmF2aWdhdGUoJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cubmF2aWdhdGUuaHRtbCcpO1xuICAgICAqIH1cbiAgICAgKiBuYXZpZ2F0ZSgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ05hdmlnYXRlIHRvIHR1dG9yaWFsJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIG5hdmlnYXRlKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ25hdmlnYXRlLXdpbmRvdycsIHsgLi4udGhpcy5pZGVudGl0eSwgdXJsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRoZSBXZWJDb250ZW50cyBiYWNrIG9uZSBwYWdlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGVCYWNrKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7IG5hbWU6ICd0ZXN0YXBwLXZpZXcnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHZpZXcubmF2aWdhdGUoJ2h0dHBzOi8vd3d3Lmdvb2dsZS5jb20nKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcubmF2aWdhdGVCYWNrKCk7XG4gICAgICogfVxuICAgICAqIG5hdmlnYXRlQmFjaygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ05hdmlnYXRlZCBiYWNrJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIG5hdmlnYXRlQmFjaygpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy53cmFwKHsgbmFtZTogJ3Rlc3RhcHAnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHdpbi5uYXZpZ2F0ZSgnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbScpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLm5hdmlnYXRlQmFjaygpO1xuICAgICAqIH1cbiAgICAgKiBuYXZpZ2F0ZUJhY2soKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdOYXZpZ2F0ZWQgYmFjaycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIG5hdmlnYXRlQmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCduYXZpZ2F0ZS13aW5kb3ctYmFjaycsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5hdmlnYXRlcyB0aGUgV2ViQ29udGVudHMgZm9yd2FyZCBvbmUgcGFnZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIG5hdmlnYXRlRm9yd2FyZCgpIHtcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbScpO1xuICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlQmFjaygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5uYXZpZ2F0ZUZvcndhcmQoKTtcbiAgICAgKiB9XG4gICAgICogbmF2aWdhdGVGb3J3YXJkKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTmF2aWdhdGVkIGZvcndhcmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGVGb3J3YXJkKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLm5hdmlnYXRlKCdodHRwczovL3d3dy5nb29nbGUuY29tJyk7XG4gICAgICogICAgIGF3YWl0IHdpbi5uYXZpZ2F0ZUJhY2soKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5uYXZpZ2F0ZUZvcndhcmQoKTtcbiAgICAgKiB9XG4gICAgICogbmF2aWdhdGVGb3J3YXJkKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTmF2aWdhdGVkIGZvcndhcmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBhc3luYyBuYXZpZ2F0ZUZvcndhcmQoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCduYXZpZ2F0ZS13aW5kb3ctZm9yd2FyZCcsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcHMgYW55IGN1cnJlbnQgbmF2aWdhdGlvbiB0aGUgV2ViQ29udGVudHMgaXMgcGVyZm9ybWluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BOYXZpZ2F0aW9uKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7IG5hbWU6ICd0ZXN0YXBwLXZpZXcnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHZpZXcubmF2aWdhdGUoJ2h0dHBzOi8vd3d3Lmdvb2dsZS5jb20nKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcuc3RvcE5hdmlnYXRpb24oKTtcbiAgICAgKiB9XG4gICAgICogc3RvcE5hdmlnYXRpb24oKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCd5b3Ugc2hhbGwgbm90IG5hdmlnYXRlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BOYXZpZ2F0aW9uKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LndyYXAoeyBuYW1lOiAndGVzdGFwcCcsIHV1aWQ6ICd0ZXN0YXBwJyB9KTtcbiAgICAgKiAgICAgYXdhaXQgd2luLm5hdmlnYXRlKCdodHRwczovL3d3dy5nb29nbGUuY29tJyk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc3RvcE5hdmlnYXRpb24oKTtcbiAgICAgKiB9XG4gICAgICogc3RvcE5hdmlnYXRpb24oKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCd5b3Ugc2hhbGwgbm90IG5hdmlnYXRlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgc3RvcE5hdmlnYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc3RvcC13aW5kb3ctbmF2aWdhdGlvbicsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbG9hZHMgdGhlIFdlYkNvbnRlbnRzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWxvYWQoKSB7XG4gICAgICogXHRjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5yZWxvYWQoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiByZWxvYWQoKS50aGVuKCgpID0+IHtcbiAgICAgKiBcdFx0Y29uc29sZS5sb2coJ1JlbG9hZGVkIHZpZXcnKVxuICAgICAqIH0pLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlbG9hZFdpbmRvdygpIHtcbiAgICAgKiBcdFx0Y29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcbiAgICAgKiBcdFx0XHRcdG5hbWU6ICdteUFwcCcsXG4gICAgICogXHRcdFx0XHR1dWlkOiAnYXBwLTEnLFxuICAgICAqIFx0XHRcdFx0dXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5yZWxvYWQuaHRtbCcsXG4gICAgICogXHRcdFx0XHRhdXRvU2hvdzogdHJ1ZVxuICAgICAqIFx0XHR9KTtcbiAgICAgKiBcdFx0Y29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnJlbG9hZCgpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHJlbG9hZFdpbmRvdygpLnRoZW4oKCkgPT4ge1xuICAgICAqIFx0XHRjb25zb2xlLmxvZygnUmVsb2FkZWQgd2luZG93JylcbiAgICAgKiB9KS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHJlbG9hZChpZ25vcmVDYWNoZSA9IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdyZWxvYWQtd2luZG93Jywge1xuICAgICAgICAgICAgaWdub3JlQ2FjaGUsXG4gICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG4gICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQcmludHMgdGhlIFdlYkNvbnRlbnRzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIFByaW50ZXIgT3B0aW9uc1xuICAgICAqXG4gICAgICogTm90ZTogV2hlbiBgc2lsZW50YCBpcyBzZXQgdG8gYHRydWVgLCB0aGUgQVBJIHdpbGwgcGljayB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBwcmludGVyIGlmIGRldmljZU5hbWVcbiAgICAgKiBpcyBlbXB0eSBhbmQgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIHByaW50aW5nLlxuICAgICAqXG4gICAgICogVXNlIHRoZSBDU1Mgc3R5bGUgYHBhZ2UtYnJlYWstYmVmb3JlOiBhbHdheXM7YCB0byBmb3JjZSBwcmludCB0byBhIG5ldyBwYWdlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogdmlldy5wcmludCh7IHNpbGVudDogZmFsc2UsIGRldmljZU5hbWU6ICdzeXN0ZW0tcHJpbnRlci1uYW1lJyB9KS50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ3ByaW50IGNhbGwgaGFzIGJlZW4gc2VudCB0byB0aGUgc3lzdGVtJyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHByaW50KG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ByaW50JywgeyAuLi50aGlzLmlkZW50aXR5LCBvcHRpb25zIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZCBhbmQgaGlnaGxpZ2h0IHRleHQgb24gYSBwYWdlLlxuICAgICAqIEBwYXJhbSBzZWFyY2hUZXJtIFRlcm0gdG8gZmluZCBpbiBwYWdlXG4gICAgICogQHBhcmFtIG9wdGlvbnMgU2VhcmNoIG9wdGlvbnNcbiAgICAgKlxuICAgICAqIE5vdGU6IEJ5IGRlZmF1bHQsIGVhY2ggc3Vic2VxdWVudCBjYWxsIHdpbGwgaGlnaGxpZ2h0IHRoZSBuZXh0IHRleHQgdGhhdCBtYXRjaGVzIHRoZSBzZWFyY2ggdGVybS5cbiAgICAgKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdHMgZm9yIHRoZSByZXF1ZXN0LiBCeSBzdWJzY3JpYmluZyB0byB0aGVcbiAgICAgKiBmb3VuZC1pbi1wYWdlIGV2ZW50LCB5b3UgY2FuIGdldCB0aGUgcmVzdWx0cyBvZiB0aGlzIGNhbGwgYXMgd2VsbC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogLy9CeSBzdWJzY3JpYmluZyB0byB0aGUgJ2ZvdW5kIGluIHBhZ2UnIGV2ZW50IHdlIGNhbiBnZXQgdGhlIHJlc3VsdHMgb2YgZWFjaCBmaW5kSW5QYWdlIGNhbGwgbWFkZS5cbiAgICAgKiB2aWV3LmFkZExpc3RlbmVyKCdmb3VuZC1pbi1wYWdlJywgKGV2ZW50KSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGV2ZW50KTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBwcm9taXNlIGFsc28gcmV0dXJucyB0aGUgcmVzdWx0cyBmb3IgdGhlIHJlcXVlc3RcbiAgICAgKiB2aWV3LmZpbmRJblBhZ2UoJ2EnKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocmVzdWx0KVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogLy9CeSBzdWJzY3JpYmluZyB0byB0aGUgJ2ZvdW5kIGluIHBhZ2UnIGV2ZW50IHdlIGNhbiBnZXQgdGhlIHJlc3VsdHMgb2YgZWFjaCBmaW5kSW5QYWdlIGNhbGwgbWFkZS5cbiAgICAgKiB3aW4uYWRkTGlzdGVuZXIoJ2ZvdW5kLWluLXBhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXZlbnQpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gVGhlIHByb21pc2UgYWxzbyByZXR1cm5zIHRoZSByZXN1bHRzIGZvciB0aGUgcmVxdWVzdFxuICAgICAqIHdpbi5maW5kSW5QYWdlKCdhJykudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdClcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgZmluZEluUGFnZShzZWFyY2hUZXJtLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdmaW5kLWluLXBhZ2UnLCB7IC4uLnRoaXMuaWRlbnRpdHksIHNlYXJjaFRlcm0sIG9wdGlvbnMgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhIHtAbGluayBWaWV3I2ZpbmRJblBhZ2UgZmluZEluUGFnZX0gY2FsbCBieSBzcGVjaWZ5aW5nIGFueSBvZiB0aGVzZSBhY3Rpb25zOlxuICAgICAqXG4gICAgICogKiBjbGVhclNlbGVjdGlvbiAtIENsZWFyIHRoZSBzZWxlY3Rpb24uXG4gICAgICogKiBrZWVwU2VsZWN0aW9uIC0gVHJhbnNsYXRlIHRoZSBzZWxlY3Rpb24gaW50byBhIG5vcm1hbCBzZWxlY3Rpb24uXG4gICAgICogKiBhY3RpdmF0ZVNlbGVjdGlvbiAtIEZvY3VzIGFuZCBjbGljayB0aGUgc2VsZWN0aW9uIG5vZGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcuZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKlxuICAgICAqIHZpZXcuYWRkTGlzdGVuZXIoJ2ZvdW5kLWluLXBhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICogICAgICAgICB2aWV3LnN0b3BGaW5kSW5QYWdlKCdjbGVhclNlbGVjdGlvbicpO1xuICAgICAqICAgICB9LCA1MDAwKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHZpZXcuZmluZEluUGFnZSgnYScpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogd2luLmFkZExpc3RlbmVyKCdmb3VuZC1pbi1wYWdlJywgKGV2ZW50KSA9PiB7XG4gICAgICogICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAqICAgICAgICAgd2luLnN0b3BGaW5kSW5QYWdlKCdjbGVhclNlbGVjdGlvbicpO1xuICAgICAqICAgICB9LCA1MDAwKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHdpbi5maW5kSW5QYWdlKCdhJykudGhlbihyZXN1bHRzID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHN0b3BGaW5kSW5QYWdlKGFjdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3N0b3AtZmluZC1pbi1wYWdlJywgeyAuLi50aGlzLmlkZW50aXR5LCBhY3Rpb24gfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggYWxsIHN5c3RlbSBwcmludGVyc1xuICAgICAqIEBkZXByZWNhdGVkIHVzZSBTeXN0ZW0uZ2V0UHJpbnRlcnMgaW5zdGVhZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiB2aWV3LmdldFByaW50ZXJzKClcbiAgICAgKiAgICAgLnRoZW4oKHByaW50ZXJzKSA9PiB7XG4gICAgICogICAgICAgICBwcmludGVycy5mb3JFYWNoKChwcmludGVyKSA9PiB7XG4gICAgICogICAgICAgICAgICAgaWYgKHByaW50ZXIuaXNEZWZhdWx0KSB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHByaW50ZXIpO1xuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9KVxuICAgICAqICAgICAuY2F0Y2goKGVycikgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiB3aW4uZ2V0UHJpbnRlcnMoKVxuICAgICAqICAgICAudGhlbigocHJpbnRlcnMpID0+IHtcbiAgICAgKiAgICAgICAgIHByaW50ZXJzLmZvckVhY2goKHByaW50ZXIpID0+IHtcbiAgICAgKiAgICAgICAgICAgICBpZiAocHJpbnRlci5pc0RlZmF1bHQpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocHJpbnRlcik7XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH0pXG4gICAgICogICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgZ2V0UHJpbnRlcnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByaW50ZXJzJywgeyAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlcyBmb2N1cyB0byB0aGUgV2ViQ29udGVudHMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZm9jdXNXaW5kb3coKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZm9jdXMuaHRtbCcsXG4gICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuICAgICAqICAgICB9KTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmZvY3VzKCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZm9jdXNXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgZm9jdXNlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGZvY3VzKHsgZW1pdFN5bnRoRm9jdXNlZCB9ID0geyBlbWl0U3ludGhGb2N1c2VkOiB0cnVlIH0pIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZvY3VzLXdpbmRvdycsIHsgZW1pdFN5bnRoRm9jdXNlZCwgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29sc1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd0RldmVsb3BlclRvb2xzKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gdmlldy5zaG93RGV2ZWxvcGVyVG9vbHMoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBzaG93RGV2ZWxvcGVydG9vbHMoKVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTaG93aW5nIGRldiB0b29scycpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNob3dEZXZlbG9wZXJUb29scygpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIHJldHVybiB3aW4uc2hvd0RldmVsb3BlclRvb2xzKCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogc2hvd0RldmVsb3BlcnRvb2xzKClcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2hvd2luZyBkZXYgdG9vbHMnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIHNob3dEZXZlbG9wZXJUb29scygpIHtcbiAgICAgICAgLy8gTm90ZSB0aGlzIGhpdHMgdGhlIHN5c3RlbSBhY3Rpb24gbWFwIGluIGNvcmUgc3RhdGUgZm9yIGxlZ2FjeSByZWFzb25zLlxuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy1kZXZlbG9wZXItdG9vbHMnLCB0aGlzLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBwcm9jZXNzIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCBhIFdlYkNvbnRlbnRzLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBpbmNsdWRlcyBhbnkgaWZyYW1lcyBhc3NvY2lhdGVkIHdpdGggdGhlIFdlYkNvbnRlbnRzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgY29uc3QgcHJvY2Vzc0luZm8gPSBhd2FpdCB2aWV3LmdldFByb2Nlc3NJbmZvKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgd2luLmdldFByb2Nlc3NJbmZvKCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGdldFByb2Nlc3NJbmZvKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgZGF0YSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByb2Nlc3MtaW5mbycsIHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIG9uIGFsbCBTaGFyZWQgV29ya2Vycy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9tZG4uZ2l0aHViLmlvL2RvbS1leGFtcGxlcy93ZWItd29ya2Vycy9zaW1wbGUtc2hhcmVkLXdvcmtlci8nKTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBzaGFyZWRXb3JrZXJzID0gYXdhaXQgdmlldy5nZXRTaGFyZWRXb3JrZXJzKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luT3B0aW9uID0ge1xuICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuICAgICAqICAgICAgICAgZGVmYXVsdFdpZHRoOiAzMDAsXG4gICAgICogICAgICAgICBkZWZhdWx0SGVpZ2h0OiAzMDAsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycsXG4gICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcbiAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG4gICAgICogICAgIH07XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG4gICAgICogICAgIGNvbnN0IHNoYXJlZFdvcmtlcnMgPSBhd2FpdCB3aW4uZ2V0U2hhcmVkV29ya2VycygpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBhc3luYyBnZXRTaGFyZWRXb3JrZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1zaGFyZWQtd29ya2VycycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZGV2ZWxvcGVyIHRvb2xzIGZvciB0aGUgc2hhcmVkIHdvcmtlciBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lJyxcbiAgICAgKiAgICAgICAgIHRhcmdldDogZmluLm1lLmlkZW50aXR5LFxuICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHZpZXcuaW5zcGVjdFNoYXJlZFdvcmtlcigpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhhbXBsZTpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB3aW5PcHRpb24gPSB7XG4gICAgICogICAgICAgICBuYW1lOidjaGlsZCcsXG4gICAgICogICAgICAgICBkZWZhdWx0V2lkdGg6IDMwMCxcbiAgICAgKiAgICAgICAgIGRlZmF1bHRIZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vbWRuLmdpdGh1Yi5pby9kb20tZXhhbXBsZXMvd2ViLXdvcmtlcnMvc2ltcGxlLXNoYXJlZC13b3JrZXIvJyxcbiAgICAgKiAgICAgICAgIGZyYW1lOiB0cnVlLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLmluc3BlY3RTaGFyZWRXb3JrZXIoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgYXN5bmMgaW5zcGVjdFNoYXJlZFdvcmtlcigpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2luc3BlY3Qtc2hhcmVkLXdvcmtlcicsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zcGVjdHMgdGhlIHNoYXJlZCB3b3JrZXIgYmFzZWQgb24gaXRzIElELlxuICAgICAqIEBwYXJhbSB3b3JrZXJJZCAtIFRoZSBpZCBvZiB0aGUgc2hhcmVkIHdvcmtlci5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9tZG4uZ2l0aHViLmlvL2RvbS1leGFtcGxlcy93ZWItd29ya2Vycy9zaW1wbGUtc2hhcmVkLXdvcmtlci8nKTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBzaGFyZWRXb3JrZXJzID0gYXdhaXQgdmlldy5nZXRTaGFyZWRXb3JrZXJzKCk7XG4gICAgICogICAgIGF3YWl0IHZpZXcuaW5zcGVjdFNoYXJlZFdvcmtlckJ5SWQoc2hhcmVkV29ya2Vyc1swXS5pZCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luT3B0aW9uID0ge1xuICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuICAgICAqICAgICAgICAgZGVmYXVsdFdpZHRoOiAzMDAsXG4gICAgICogICAgICAgICBkZWZhdWx0SGVpZ2h0OiAzMDAsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycsXG4gICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcbiAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG4gICAgICogICAgIH07XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG4gICAgICogICAgIGNvbnN0IHNoYXJlZFdvcmtlcnMgPSBhd2FpdCB3aW4uZ2V0U2hhcmVkV29ya2VycygpO1xuICAgICAqICAgICBhd2FpdCB3aW4uaW5zcGVjdFNoYXJlZFdvcmtlckJ5SWQoc2hhcmVkV29ya2Vyc1swXS5pZCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGluc3BlY3RTaGFyZWRXb3JrZXJCeUlkKHdvcmtlcklkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnNwZWN0LXNoYXJlZC13b3JrZXItYnktaWQnLCB7IC4uLnRoaXMuaWRlbnRpdHksIHdvcmtlcklkIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZGV2ZWxvcGVyIHRvb2xzIGZvciB0aGUgc2VydmljZSB3b3JrZXIgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cDovL2dvb2dsZWNocm9tZS5naXRodWIuaW8vc2FtcGxlcy9zZXJ2aWNlLXdvcmtlci9iYXNpYy9pbmRleC5odG1sJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5pbnNwZWN0U2VydmljZVdvcmtlcigpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIGNvbnN0IHdpbk9wdGlvbiA9IHtcbiAgICAgKiAgICAgICAgIG5hbWU6J2NoaWxkJyxcbiAgICAgKiAgICAgICAgIGRlZmF1bHRXaWR0aDogMzAwLFxuICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuICAgICAqICAgICAgICAgdXJsOiAnaHR0cDovL2dvb2dsZWNocm9tZS5naXRodWIuaW8vc2FtcGxlcy9zZXJ2aWNlLXdvcmtlci9iYXNpYy9pbmRleC5odG1sJyxcbiAgICAgKiAgICAgICAgIGZyYW1lOiB0cnVlLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLmluc3BlY3RTZXJ2aWNlV29ya2VyKCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGluc3BlY3RTZXJ2aWNlV29ya2VyKCkge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignaW5zcGVjdC1zZXJ2aWNlLXdvcmtlcicsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgYSBwb3B1cCB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBOb3RlOiBJZiB0aGlzIFdlYkNvbnRlbnRzIGlzIGEgdmlldyBhbmQgaXRzIGF0dGFjaGVkIHdpbmRvdyBoYXMgYSBwb3B1cCBvcGVuLCB0aGlzIHdpbGwgY2xvc2UgaXQuXG4gICAgICpcbiAgICAgKiBTaG93cyBhIHBvcHVwIHdpbmRvdy4gSW5jbHVkaW5nIGEgYG5hbWVgIGluIGBvcHRpb25zYCB3aWxsIGF0dGVtcHQgdG8gc2hvdyBhbiBleGlzdGluZyB3aW5kb3cgYXMgYSBwb3B1cCwgaWZcbiAgICAgKiB0aGF0IHdpbmRvdyBkb2Vzbid0IGV4aXN0IG9yIG5vIGBuYW1lYCBpcyBpbmNsdWRlZCBhIHdpbmRvdyB3aWxsIGJlIGNyZWF0ZWQuIElmIHRoZSBjYWxsZXIgdmlldyBvciB0aGUgY2FsbGVyXG4gICAgICogdmlldydzIHBhcmVudCB3aW5kb3cgY3VycmVudGx5IGhhcyBhIHBvcHVwIHdpbmRvdyBvcGVuLCBjYWxsaW5nIGBzaG93UG9wdXBXaW5kb3dgIGFnYWluIHdpbGwgZGlzbWlzcyB0aGUgY3VycmVudGx5XG4gICAgICogb3BlbiBwb3B1cCB3aW5kb3cgYmVmb3JlIHNob3dpbmcgdGhlIG5ldyBwb3B1cCB3aW5kb3cuIEFsc28sIGlmIHRoZSBjYWxsZXIgdmlldyBpcyBkZXN0cm95ZWQgb3IgZGV0YWNoZWQsIHRoZSBwb3B1cFxuICAgICAqIHdpbGwgYmUgZGlzbWlzc2VkLlxuICAgICAqXG4gICAgICogTm90ZTogaW4gdGhlIGNhc2Ugd2hlcmUgdGhlIHdpbmRvdyBiZWluZyBzaG93biBhcyBhIHBvcHVwIG5lZWRzIHRvIGJlIGNyZWF0ZWQsIGl0IGlzIGEgY2hpbGQgb2YgdGhlIGNhbGxlciB2aWV3J3MgcGFyZW50IHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYW5kIHNob3cgYSBzaW5nbGUtdXNlIHBvcHVwIHdpbmRvdyB0aGF0IHJldHVybnMgYSBzaW5nbGUgcmVzdWx0IHRvIHRoZSBjYWxsZXIuIGBpbml0aWFsT3B0aW9uc2AgYWxsb3dzXG4gICAgICogdXMgdG8gcGFzcyB3aW5kb3cgb3B0aW9ucyB0byB0aGUgcG9wdXAgd2luZG93IHRoYXQgd2lsbCBiZSBjcmVhdGVkLiBgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJ2AgZW5zdXJlc1xuICAgICAqIHRoYXQgb25jZSB0aGUgcG9wdXAgd2luZG93IGNhbGxzIGBkaXNwYXRjaFBvcHVwUmVzdWx0YCBpdCBpcyBjbG9zZWQuIGBibHVyQmVoYXZpb3I6ICdjbG9zZSdgIHdpbGwgeWllbGQgYSBkaXNtaXNzZWRcbiAgICAgKiByZXN1bHQgc2hvdWxkIHRoZSBwb3B1cCB3aW5kb3cgbG9zZSBmb2N1cy5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIGluaXRpYWxPcHRpb25zOiB7XG4gICAgICogICAgICAgICBmcmFtZTogZmFsc2VcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdjbG9zZScsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogU2FtZSBhcyBhYm92ZSBidXQgdXNpbmcgYW4gZXhpc3Rpbmcgd2luZG93IGFzIGEgcG9wdXAgYnkgcmVmZXJlbmNpbmcgaXRzIGBuYW1lYDpcbiAgICAgKlxuICAgICAqIE5vdGU6IGlmIGEgd2luZG93IHdpdGggdGhlIGBuYW1lYCBwcm92aWRlZCBkb2Vzbid0IGV4aXN0LCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBpbml0aWFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgZnJhbWU6IHRydWVcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbmFtZTogJ215LXBvcHVwJywgLy8gc2hvd3MgdGhlICdteS1wb3B1cCcgd2luZG93IGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGNyZWF0ZXMgaXRcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLCAvLyBuYXZpZ2F0ZXMgdG8gdGhpcyB1cmwgaWYgaXQgZG9lc24ndCBtYXRjaCB0aGUgbG9jYXRpb24uaHJlZiBvZiB0aGUgJ215LXBvcHVwJyB3aW5kb3dcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIHBlcnNpc3Qgd2luZG93IG9uICdkaXNtaXNzZWQnIHJlc3VsdCwgYWx0ZXJuYXRpdmVseSBjaGFuZ2Ugb25SZXN1bHREaXNwYXRjaCBhbmQgYmx1ckJlaGF2aW9yIHRvICdoaWRlJ1xuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIGFuZCBzaG93IGEgcG9wdXAgd2luZG93IHRoYXQgaXMgYWJsZSB0byByZXR1cm4gbXVsdGlwbGUgcmVzdWx0cyB0byB0aGUgY2FsbGVyIHZpYSBhbiBgb25Qb3B1cFJlc3VsdGAgY2FsbGJhY2suIEVhY2hcbiAgICAgKiB0aW1lIHRoZSBwb3B1cCB3aW5kb3cgY2FsbHMgYGRpc3BhdGNoUG9wdXBSZXN1bHRgLCB0aGUgY2FsbGJhY2sgd2lsbCBiZSBleGVjdXRlZCBvbiB0aGUgcmVzdWx0LiBPbmNlIHRoZSBwb3B1cCB3aW5kb3cgaXNcbiAgICAgKiBjbG9zZWQgb3IgaGlkZGVuLCB0aGUgYHNob3dQb3B1cFdpbmRvd2AgcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhIGBkaXNtaXNzZWRgIHJlc3VsdCB0aGF0IHdpbGwgaW5jbHVkZSB0aGUgbW9zdCByZWNlbnRseVxuICAgICAqIGRpc3BhdGNoZWQgcmVzdWx0IGFzIGBsYXN0RGlzcGF0Y2hSZXN1bHRgOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFJlc3VsdENhbGxiYWNrID0gKHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgaWYgKHBheWxvYWQucmVzdWx0ID09PSAnY2xpY2tlZCcpIHtcbiAgICAgKiAgICAgICAgICAgIGlmIChwYXlsb2FkLmRhdGEudG9waWMgPT09ICdjb2xvci1jaGFuZ2VkJykge1xuICAgICAqICAgICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBsaWtlXG4gICAgICogICAgICAgICAgICAgICAgLy8gc2V0Q29sb3IocGF5bG9hZC5kYXRhLnZhbHVlKTtcbiAgICAgKiAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4ubWUuc2hvd1BvcHVwV2luZG93KHtcbiAgICAgKiAgICAgaW5pdGlhbE9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGZyYW1lOiBmYWxzZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICB1cmw6ICc8bXlfcG9wdXBfdXJsPicsXG4gICAgICogICAgIHJlc3VsdERpc3BhdGNoQmVoYXZpb3I6ICdub25lJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDAsXG4gICAgICogICAgIG9uUG9wdXBSZXN1bHQ6IHBvcHVwUmVzdWx0Q2FsbGJhY2tcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFNhbWUgYXMgYWJvdmUgYnV0IHVzaW5nIGFuIGV4aXN0aW5nIHdpbmRvdyBhcyBhIHBvcHVwOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFJlc3VsdENhbGxiYWNrID0gKHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgaWYgKHBheWxvYWQucmVzdWx0ID09PSAnY2xpY2tlZCcpIHtcbiAgICAgKiAgICAgICAgICAgIGlmIChwYXlsb2FkLmRhdGEudG9waWMgPT09ICdjb2xvci1jaGFuZ2VkJykge1xuICAgICAqICAgICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBsaWtlXG4gICAgICogICAgICAgICAgICAgICAgLy8gc2V0Q29sb3IocGF5bG9hZC5kYXRhLnZhbHVlKTtcbiAgICAgKiAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4ubWUuc2hvd1BvcHVwV2luZG93KHtcbiAgICAgKiAgICAgaW5pdGlhbE9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGZyYW1lOiBmYWxzZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICBuYW1lOiAnbXktcG9wdXAnLCAvLyBzaG93cyB0aGUgJ215LXBvcHVwJyB3aW5kb3cgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgY3JlYXRlcyBpdFxuICAgICAqICAgICB1cmw6ICc8bXlfcG9wdXBfdXJsPicsIC8vIG5hdmlnYXRlcyB0byB0aGlzIHVybCBpZiBpdCBkb2Vzbid0IG1hdGNoIHRoZSBsb2NhdGlvbi5ocmVmIG9mIHRoZSAnbXktcG9wdXAnIHdpbmRvd1xuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnbm9uZScsXG4gICAgICogICAgIGJsdXJCZWhhdmlvcjogJ2hpZGUnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIHdlIGNhbiBqdXN0IHVzZSB0aGlzIG9yIHdlIGNhbiBjaGFuZ2UgYmx1ckJlaGF2aW9yIHRvICdoaWRlJ1xuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMCxcbiAgICAgKiAgICAgb25Qb3B1cFJlc3VsdDogcG9wdXBSZXN1bHRDYWxsYmFja1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIG9yIHNob3cgYSBwb3B1cCB3aW5kb3cgdGhhdCBkaXNhYmxlcyB1c2VyIG1vdmVtZW50IChwb3NpdGlvbmluZyBhbmQgcmVzaXppbmcpIGluIHRoZSBjYWxsZXJcbiAgICAgKiB2aWV3J3MgcGFyZW50IHdpbmRvdyBieSB1c2luZyBgYmx1ckJlaGF2aW9yOiAnbW9kYWwnYDpcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIGluaXRpYWxPcHRpb25zOiB7XG4gICAgICogICAgICAgICBmcmFtZTogZmFsc2VcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdtb2RhbCcsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIGEgcG9wdXAgd2luZG93IGFzIGEgbW9kYWw6XG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGUgb25seSB3YXkgdG8gZW5zdXJlIHRydWUgbW9kYWwgYmVoYXZpb3IgaXMgdG8gY3JlYXRlIHRoZSB3aW5kb3cgYmVpbmcgc2hvd24gYXMgYSBwb3B1cCB3aXRoIGFcbiAgICAgKiBgbW9kYWxQYXJlbnRJZGVudGl0eWAgdGhhdCB1c2VzIHRoZSBjYWxsZXIgdmlldydzIHBhcmVudCB3aW5kb3cgaWRlbnRpdHkuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBpbml0aWFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgZnJhbWU6IGZhbHNlLFxuICAgICAqICAgICAgICAgbW9kYWxQYXJlbnRJZGVudGl0eTogZmluLm1lLmlkZW50aXR5XG4gICAgICogICAgIH0sXG4gICAgICogICAgIHVybDogJzxteV9wb3B1cF91cmw+JyxcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnbW9kYWwnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDBcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFBhc3MgZGF0YSB0byBhIHBvcHVwIHdpbmRvdyB0aGF0IGlzIGF2YWlsYWJsZSB3aGVuIHRoZSBwb3B1cCBpcyBzaG93bi5cbiAgICAgKlxuICAgICAqIE5vdGU6IHRoaXMgaXMganVzdCBvbmUgZXhhbXBsZSBmb3IgYSB1c2Ugb2YgYGFkZGl0aW9uYWxPcHRpb25zYCwgaXQgY2FuIGJlIHVzZWQgdG8gdXBkYXRlIGFueSB1cGRhdGFibGVcbiAgICAgKiB3aW5kb3cgb3B0aW9ucyB3aGVuIGNyZWF0aW5nIG9yIHNob3dpbmcgYW4gZXhpc3Rpbmcgd2luZG93IGFzIGEgcG9wdXAuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBhZGRpdGlvbmFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgY3VzdG9tRGF0YToge1xuICAgICAqICAgICAgICAgICAgIGZvbzogJ2JhcidcbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdjbG9zZScsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gQWNjZXNzIGZyb20gdGhlIHBvcHVwIHdpbmRvdyBjb250ZXh0IGxpa2Ugc286XG4gICAgICogY29uc3QgeyBjdXN0b21EYXRhIH0gPSBhd2FpdCBmaW4ubWUuZ2V0T3B0aW9ucygpO1xuICAgICAqIGNvbnN0IHsgZm9vIH0gPSBjdXN0b21EYXRhO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhlY3V0ZSBhIGNhbGxiYWNrIG9uIHRoZSBwb3B1cCdzIE9wZW5GaW4gd2luZG93IHdoZW4gdGhlIHBvcHVwIGlzIHNob3duOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFdpbmRvd0NhbGxiYWNrID0gYXN5bmMgKHdpbikgPT4ge1xuICAgICAqICAgICBhd2FpdCB3aW4uZmxhc2goKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIHVybDogJzxteV9wb3B1cF91cmw+JyxcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDAsXG4gICAgICogICAgIG9uUG9wdXBSZWFkeTogcG9wdXBXaW5kb3dDYWxsYmFjaztcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgYXN5bmMgc2hvd1BvcHVwV2luZG93KG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oYCR7dGhpcy5lbnRpdHlUeXBlfS1zaG93LXBvcHVwLXdpbmRvd2AsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9wdGlvbnM/Lm9uUG9wdXBSZWFkeSkge1xuICAgICAgICAgICAgY29uc3QgcmVhZHlMaXN0ZW5lciA9IGFzeW5jICh7IHBvcHVwTmFtZSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9wdXBXaW5kb3cgPSB0aGlzLmZpbi5XaW5kb3cud3JhcFN5bmMoeyB1dWlkOiB0aGlzLmZpbi5tZS51dWlkLCBuYW1lOiBwb3B1cE5hbWUgfSk7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG9wdGlvbnMub25Qb3B1cFJlYWR5KHBvcHVwV2luZG93KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU29tZXRoaW5nIHdlbnQgd3JvbmcgZHVyaW5nIG9uUG9wdXBSZWFkeSBleGVjdXRpb246ICR7ZXJyb3J9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGludGVybmFsKVxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbmNlKCdwb3B1cC1yZWFkeScsIHJlYWR5TGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogdHJ5Q3JlYXRlUGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3RyeS1jcmVhdGUtcG9wdXAtd2luZG93Jywge1xuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgLy8gSW50ZXJuYWwgdXNlIG9ubHkuXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIGhhc1Jlc3VsdENhbGxiYWNrOiAhIW9wdGlvbnM/Lm9uUG9wdXBSZXN1bHQsXG4gICAgICAgICAgICAgICAgaGFzUmVhZHlDYWxsYmFjazogISFvcHRpb25zPy5vblBvcHVwUmVhZHlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IGRhdGE6IHsgd2lsbE9wZW4sIG9wdGlvbnM6IHBvcHVwT3B0aW9ucyB9IH0gPSB0cnlDcmVhdGVQYXlsb2FkO1xuICAgICAgICBpZiAod2lsbE9wZW4pIHtcbiAgICAgICAgICAgIC8vIFNvbHZlIHRoZSBpc3N1ZSB3aGVyZSBJbnRlcm9wIGluIGEgcG9wdXAgd2luZG93IHdpdGggbm9uIGNyb3NzLW9yaWdpbiB1cmwgaXMgbm90IHdvcmtpbmcoY29yZS0xMDc2KS5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZmluLldpbmRvdy5jcmVhdGUocG9wdXBPcHRpb25zLmluaXRpYWxPcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBub3JtYWxpemVQb3B1cFJlc3VsdCA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IG5hbWUsIHV1aWQsIHJlc3VsdCwgZGF0YSB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgIGNvbnN0IHBvcHVwUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIGlkZW50aXR5OiB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHV1aWRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcG9wdXBSZXN1bHQuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcG9wdXBSZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICAgIGlmIChvcHRpb25zPy5vblBvcHVwUmVzdWx0KSB7XG4gICAgICAgICAgICBjb25zdCBkaXNwYXRjaFJlc3VsdExpc3RlbmVyID0gYXN5bmMgKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBvcHRpb25zLm9uUG9wdXBSZXN1bHQobm9ybWFsaXplUG9wdXBSZXN1bHQocGF5bG9hZCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHRlYXJkb3duTGlzdGVuZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogZml4IHR5cGluZyAoaW50ZXJuYWwpXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3BvcHVwLXJlc3VsdCcsIGRpc3BhdGNoUmVzdWx0TGlzdGVuZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGludGVybmFsKVxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbigncG9wdXAtcmVzdWx0JywgZGlzcGF0Y2hSZXN1bHRMaXN0ZW5lcik7XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgIC8vIGhpbGFyaW91c2x5IHRoaXMgZG9lcyBub3QgbmVlZCBhIHRzLWV4cGVjdC1lcnJvciAtIHRoaXMgaXMgZ2FwIGluIHR5cGUgc291bmRuZXNzXG4gICAgICAgICAgICAvLyBzaG91bGQgaW52ZXN0aWdhdGUgLSBwcm9iYWJseSBkdWUgdG8gYHRlYXJkb3duTGlzdGVuZXJgIHRha2luZyBhIHZvaWQgYXJndW1lbnRcbiAgICAgICAgICAgIC8vIHdoaWNoIG1pZ2h0IHBsYXkgbmljZWx5IHdpdGggdGhlIGBuZXZlcmAgdHlwZT8gIGh1aC4uLlxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbmNlKCdwb3B1cC10ZWFyZG93bicsIHRlYXJkb3duTGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctcG9wdXAtd2luZG93Jywge1xuICAgICAgICAgICAgb3B0aW9uczogcG9wdXBPcHRpb25zLFxuICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG59XG5tYWluLldlYkNvbnRlbnRzID0gV2ViQ29udGVudHM7XG5cbnZhciBoYXNSZXF1aXJlZEluc3RhbmNlJDI7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSQyICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkSW5zdGFuY2UkMikgcmV0dXJuIEluc3RhbmNlJDU7XG5cdGhhc1JlcXVpcmVkSW5zdGFuY2UkMiA9IDE7XG5cdHZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcblx0ICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcblx0ICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuXHQgICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcblx0fTtcblx0dmFyIF9WaWV3X3Byb3ZpZGVyQ2hhbm5lbENsaWVudDtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDUsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRJbnN0YW5jZSQ1LlZpZXcgPSB2b2lkIDA7XG5cdGNvbnN0IHRyYW5zcG9ydF9lcnJvcnNfMSA9IHRyYW5zcG9ydEVycm9ycztcblx0Y29uc3QgbGF6eV8xID0gbGF6eTtcblx0Y29uc3QgbGF5b3V0X2VudGl0aWVzXzEgPSBsYXlvdXRFbnRpdGllcztcblx0Y29uc3QgbGF5b3V0X2NvbnN0YW50c18xID0gbGF5b3V0X2NvbnN0YW50cztcblx0Y29uc3QgbWFpbl8xID0gbWFpbjtcblx0Y29uc3Qgd2luZG93XzEgPSByZXF1aXJlV2luZG93KCk7XG5cdC8qKlxuXHQgKiBBIFZpZXcgY2FuIGJlIHVzZWQgdG8gZW1iZWQgYWRkaXRpb25hbCB3ZWIgY29udGVudCBpbnRvIGEgV2luZG93LlxuXHQgKiBJdCBpcyBsaWtlIGEgY2hpbGQgd2luZG93LCBleGNlcHQgaXQgaXMgcG9zaXRpb25lZCByZWxhdGl2ZSB0byBpdHMgb3duaW5nIHdpbmRvdy5cblx0ICogSXQgaGFzIHRoZSBhYmlsaXR5IHRvIGxpc3RlbiBmb3Ige0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3LXNwZWNpZmljIGV2ZW50c30uXG5cdCAqXG5cdCAqIEJ5IGRlZmF1bHQsIGEgVmlldyB3aWxsIHRyeSB0byBzaGFyZSB0aGUgc2FtZSByZW5kZXJlciBwcm9jZXNzIGFzIG90aGVyIFZpZXdzIG93bmVkIGJ5IGl0cyBwYXJlbnQgQXBwbGljYXRpb24uXG5cdCAqIFRvIGNoYW5nZSB0aGF0IGJlaGF2aW9yLCBzZWUgdGhlIHByb2Nlc3NBZmZpbml0eSB7QGxpbmsgT3BlbkZpbi5WaWV3T3B0aW9ucyB2aWV3IG9wdGlvbn0uXG5cdCAqXG5cdCAqIEEgVmlldydzIGxpZmVjeWNsZSBpcyB0aWVkIHRvIGl0cyBvd25pbmcgd2luZG93IGFuZCBjYW4gYmUgcmUtYXR0YWNoZWQgdG8gYSBkaWZmZXJlbnQgd2luZG93IGF0IGFueSBwb2ludCBkdXJpbmcgaXRzIGxpZmVjeWNsZS5cblx0ICovXG5cdGNsYXNzIFZpZXcgZXh0ZW5kcyBtYWluXzEuV2ViQ29udGVudHMge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCBpZGVudGl0eSwgJ3ZpZXcnKTtcblx0ICAgICAgICB0aGlzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5cdCAgICAgICAgX1ZpZXdfcHJvdmlkZXJDaGFubmVsQ2xpZW50LnNldCh0aGlzLCBuZXcgbGF6eV8xLkxhenkoKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IHRoaXMuZmluLlBsYXRmb3JtLndyYXBTeW5jKHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgICAgICAgICByZXR1cm4gcGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG5cdCAgICAgICAgfSkpO1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEF0dGFjaGVzIHRoZSBjdXJyZW50IHZpZXcgdG8gdGhlIGdpdmVuIHdpbmRvdyBpZGVudGl0eS5cblx0ICAgICAgICAgKiBJZGVudGl0eSBtdXN0IGJlIHRoZSBpZGVudGl0eSBvZiBhIHdpbmRvdyBpbiB0aGUgc2FtZSBhcHBsaWNhdGlvbi5cblx0ICAgICAgICAgKiBUaGlzIGRldGFjaGVzIHRoZSB2aWV3IGZyb20gaXRzIGN1cnJlbnQgd2luZG93LCBhbmQgc2V0cyB0aGUgdmlldyB0byBiZSBkZXN0cm95ZWQgd2hlbiBpdHMgbmV3IHdpbmRvdyBjbG9zZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVBdHRhY2gnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gYXR0YWNoVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBjb25zdCB3aW5PcHRpb24gPSB7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOid3aW5PcHRpb25OYW1lJyxcblx0ICAgICAgICAgKiAgICAgICAgIGRlZmF1bHRXaWR0aDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5jcmVhdGUuaHRtbCcsXG5cdCAgICAgICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcblx0ICAgICAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgICAgICogICAgIH07XG5cdCAgICAgICAgICogICAgIGNvbnN0IG5ld1dpbmRvdyA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG5cdCAgICAgICAgICogICAgIHZpZXcuYXR0YWNoKG5ld1dpbmRvdy5pZGVudGl0eSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXR0YWNoVmlldygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IGF0dGFjaGVkIHRvIG5ldyB3aW5kb3cuJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuYXR0YWNoID0gYXN5bmMgKHRhcmdldCkgPT4ge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignYXR0YWNoLXZpZXcnLCB7IHRhcmdldCwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlc3Ryb3lzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcud3JhcFN5bmMoeyB1dWlkOiAndmlld1V1aWQnLCBuYW1lOiAndmlld05hbWUnIH0pO1xuXHQgICAgICAgICAqIHZpZXcuZGVzdHJveSgpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmRlc3Ryb3kgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdkZXN0cm95LXZpZXcnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBTaG93cyB0aGUgY3VycmVudCB2aWV3IGlmIGl0IGlzIGN1cnJlbnRseSBoaWRkZW4uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVTaG93Jyxcblx0ICAgICAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgICAgICogICAgICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIGhpZGVBbmRTaG93VmlldygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybCBvcHRpb24uJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5oaWRlKCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKFwiVmlldyBoaWRkZW4uXCIpO1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZpZXcuc2hvdygpO1xuXHQgICAgICAgICAqICAgICBjb25zb2xlLmxvZyhcIlZpZXcgc2hvd24uXCIpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGhpZGVBbmRTaG93VmlldygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IGhpZGRlbiBhbmQgc2hvd24uJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuc2hvdyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctdmlldycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFNldHMgdGhlIGJvdW5kcyAodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgdmlldyByZWxhdGl2ZSB0byBpdHMgd2luZG93IGFuZCBzaG93cyBpdCBpZiBpdCBpcyBoaWRkZW4uXG5cdCAgICAgICAgICogVGhpcyBtZXRob2QgZW5zdXJlcyB0aGUgdmlldyBpcyBib3RoIHBvc2l0aW9uZWQgYW5kIHNob3dpbmcuIEl0IHdpbGwgcmVwb3NpdGlvbiBhIHZpc2libGUgdmlldyBhbmQgYm90aCBzaG93IGFuZCByZXBvc2l0aW9uIGEgaGlkZGVuIHZpZXcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmVtYXJrcyBWaWV3IHBvc2l0aW9uIGlzIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAgICAgKiAoe3RvcDogMCwgbGVmdDogMH0gcmVwcmVzZW50cyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cpXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVTZXRCb3VuZHMnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd1ZpZXdBdCgpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3LnNob3dBdCh7XG5cdCAgICAgICAgICogICAgICAgICB0b3A6IDEwMCxcblx0ICAgICAgICAgKiAgICAgICAgIGxlZnQ6IDEwMCxcblx0ICAgICAgICAgKiAgICAgICAgIHdpZHRoOiAzMDAsXG5cdCAgICAgICAgICogICAgICAgICBoZWlnaHQ6IDMwMFxuXHQgICAgICAgICAqICAgICB9LCB7XG5cdCAgICAgICAgICogICAgICAgYnJpbmdUb0Zyb250IDogdHJ1ZVxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBzaG93Vmlld0F0KClcblx0ICAgICAgICAgKiAgICAgLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1ZpZXcgc2V0IHRvIG5ldyBib3VuZHMgYW5kIHNob3duLicpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnNob3dBdCA9IGFzeW5jIChib3VuZHMsIG9wdGlvbnMgPSB7fSkgPT4ge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy12aWV3LWF0JywgeyBib3VuZHMsIC4uLnRoaXMuaWRlbnRpdHksIG9wdGlvbnMgfSk7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBCcmluZ3MgdGhlIHNwZWNpZmllZCB2aWV3IHRvIHRoZSBmcm9udCBvZiBpdHMgY3VycmVudCB3aW5kb3cuIFRoaXMgZW5zdXJlcyB0aGUgdmlldyB3aWxsIGJlIHZpc2libGUgb24gdG9wIG9mIGFueSBvdGhlciB2aWV3c1xuXHQgICAgICAgICAqIHdoaWNoIGhhdmUgb3ZlcmxhcHBpbmcgYm91bmRzIHdpdGggaXQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBQbGVhc2Ugbm90ZSwgdGhpcyBpcyBub3QgYSBwZXJtYW5lbnQgYWN0aW9uIC0gd2hlbiBhIG5ldyB2aWV3IGlzIGNyZWF0ZWQgb3IgYXR0YWNoZWQgdG8gdGhlIHdpbmRvdywgaXQgd2lsbCBkaXNwbGF5IG9uIHRvcCBvZiBhbGwgb3RoZXIgdmlld3Ncblx0ICAgICAgICAgKiBpbiB0aGUgd2luZG93IHRoYXQgc2hhcmUgYm91bmRzIHdpdGggaXQuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdicmluZy12aWV3LXRvLWZyb250JywgeyAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSGlkZXMgdGhlIGN1cnJlbnQgdmlldyBpZiBpdCBpcyBjdXJyZW50bHkgdmlzaWJsZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUhpZGUnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gaGlkZVZpZXcoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5oaWRlKCk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogaGlkZVZpZXcoKVxuXHQgICAgICAgICAqICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnVmlldyBoaWRkZW4uJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuaGlkZSA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hpZGUtdmlldycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFNldHMgdGhlIGJvdW5kcyAodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgdmlldyByZWxhdGl2ZSB0byBpdHMgd2luZG93LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJlbWFya3MgVmlldyBwb3NpdGlvbiBpcyByZWxhdGl2ZSB0byB0aGUgYm91bmRzIG9mIHRoZSB3aW5kb3cuXG5cdCAgICAgICAgICogKHt0b3A6IDAsIGxlZnQ6IDB9IHJlcHJlc2VudHMgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93KVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBqc1xuXHQgICAgICAgICAqIGxldCB2aWV3O1xuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVZpZXcoKSB7XG5cdCAgICAgICAgICogICAgIGNvbnN0IG1lID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG5cdCAgICAgICAgICogICAgIHJldHVybiBmaW4uVmlldy5jcmVhdGUoe1xuXHQgICAgICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lU2V0Qm91bmRzJyxcblx0ICAgICAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgICAgICogICAgICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFZpZXdCb3VuZHMoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5zZXRCb3VuZHMoe1xuXHQgICAgICAgICAqICAgICAgICAgdG9wOiAxMDAsXG5cdCAgICAgICAgICogICAgICAgICBsZWZ0OiAxMDAsXG5cdCAgICAgICAgICogICAgICAgICB3aWR0aDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgaGVpZ2h0OiAzMDBcblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogc2V0Vmlld0JvdW5kcygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IHNldCB0byBuZXcgYm91bmRzLicpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnNldEJvdW5kcyA9IGFzeW5jIChib3VuZHMpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC12aWV3LWJvdW5kcycsIHsgYm91bmRzLCAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogR2V0cyB0aGUgYm91bmRzICh0b3AsIGxlZnQsIHdpZHRoLCBoZWlnaHQpIG9mIHRoZSB2aWV3IHJlbGF0aXZlIHRvIGl0cyB3aW5kb3cuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmVtYXJrcyBWaWV3IHBvc2l0aW9uIGlzIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAgICAgKiAoe3RvcDogMCwgbGVmdDogMH0gcmVwcmVzZW50cyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cpXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgIG5hbWU6ICd2aWV3TmFtZVNldEJvdW5kcycsXG5cdCAgICAgICAgICogICAgIHRhcmdldDogZmluLm1lLmlkZW50aXR5LFxuXHQgICAgICAgICAqICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogfSk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGF3YWl0IHZpZXcuc2V0Qm91bmRzKHtcblx0ICAgICAgICAgKiAgICAgdG9wOiAxMDAsXG5cdCAgICAgICAgICogICAgIGxlZnQ6IDEwMCxcblx0ICAgICAgICAgKiAgICAgd2lkdGg6IDMwMCxcblx0ICAgICAgICAgKiAgICAgaGVpZ2h0OiAzMDBcblx0ICAgICAgICAgKiB9KTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHZpZXcuZ2V0Qm91bmRzKCkpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldEJvdW5kcyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgYWNrID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC12aWV3LWJvdW5kcycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFjay5wYXlsb2FkLmRhdGE7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBHZXRzIHRoZSBWaWV3J3MgaW5mby5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUdldEluZm8nLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Vmlld0luZm8oKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIHZpZXcuZ2V0SW5mbygpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGdldFZpZXdJbmZvKClcblx0ICAgICAgICAgKiAgICAgLnRoZW4oKGluZm8pID0+IGNvbnNvbGUubG9nKCdWaWV3IGluZm8gZmV0Y2hlZC4nLCBpbmZvKSlcblx0ICAgICAgICAgKiAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAgICAgKiBgYGBcblx0ICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5nZXRJbmZvID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBhY2sgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXZpZXctaW5mbycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFjay5wYXlsb2FkLmRhdGE7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGxheW91dCBmb3IgdGhlIHdpbmRvdyB0aGUgdmlldyBpcyBhdHRhY2hlZCB0by5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiAgICAgLy9nZXQgdGhlIGN1cnJlbnQgVmlld1xuXHQgICAgICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIC8vZ2V0IGEgcmVmZXJlbmNlIHRvIHRoZSBMYXlvdXQgZm9yIHRoZSBXaW5kb3cgdGhlIHZpZXcgaXMgcGFydCBvZlxuXHQgICAgICAgICAqICAgICBjb25zdCBsYXlvdXQgPSBhd2FpdCB2aWV3LmdldFBhcmVudExheW91dCgpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldFBhcmVudExheW91dCA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctZ2V0LXBhcmVudC1sYXlvdXQnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSkuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBjb25zdCBsYXlvdXRXaW5kb3cgPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRXaW5kb3coKTtcblx0ICAgICAgICAgICAgbGV0IGxheW91dFdpbmRvd0lkZW50aXR5ID0gbGF5b3V0V2luZG93LmlkZW50aXR5O1xuXHQgICAgICAgICAgICAvLyBUT0RPOiBDT1JFLTE4NTcgLSB3aGVuIHdlIHRlYXJvdXQgYWN0aXZlIGxheW91dCBvciBkcmFnIGEgdmlldyBvdXQgb2YgYSB3aW5kb3csIHRoZSBhYm92ZSBpZGVudGl0eSBpbmNsdWRlcyB0aGUgd2hvbGUgd2luZG93IGluZm8uXG5cdCAgICAgICAgICAgIGlmIChsYXlvdXRXaW5kb3dJZGVudGl0eS5pZGVudGl0eSkge1xuXHQgICAgICAgICAgICAgICAgbGF5b3V0V2luZG93SWRlbnRpdHkgPSBsYXlvdXRXaW5kb3dJZGVudGl0eS5pZGVudGl0eTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJDaGFubmVsQ2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVmlld19wcm92aWRlckNoYW5uZWxDbGllbnQsIFwiZlwiKS5nZXRWYWx1ZSgpO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgbGF5b3V0X2VudGl0aWVzXzEuTGF5b3V0Tm9kZS5uZXdMYXlvdXRFbnRpdGllc0NsaWVudChwcm92aWRlckNoYW5uZWxDbGllbnQsIGxheW91dF9jb25zdGFudHNfMS5MQVlPVVRfQ09OVFJPTExFUl9JRCwgbGF5b3V0V2luZG93SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0SWRlbnRpdHkgPSBhd2FpdCBjbGllbnQuZ2V0TGF5b3V0SWRlbnRpdHlGb3JWaWV3T3JUaHJvdyh0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcChsYXlvdXRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IGFsbG93ZWRFcnJvcnMgPSBbXG5cdCAgICAgICAgICAgICAgICAgICAgJ05vIGFjdGlvbiByZWdpc3RlcmVkIGF0IHRhcmdldCBmb3InLFxuXHQgICAgICAgICAgICAgICAgICAgICdnZXRMYXlvdXRJZGVudGl0eUZvclZpZXdPclRocm93IGlzIG5vdCBhIGZ1bmN0aW9uJ1xuXHQgICAgICAgICAgICAgICAgXTtcblx0ICAgICAgICAgICAgICAgIGlmICghYWxsb3dlZEVycm9ycy5zb21lKChtKSA9PiBlLm1lc3NhZ2UuaW5jbHVkZXMobSkpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIGxvZ2ljIGZvciBtaXNzaW5nIGVuZHBvaW50XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5maW4uUGxhdGZvcm0uTGF5b3V0LndyYXAobGF5b3V0V2luZG93SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBHZXRzIHRoZSBWaWV3J3Mgb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUdldE9wdGlvbnMnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Vmlld09wdGlvbnMoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogbWUuaWRlbnRpdHkudXVpZCwgbmFtZTogJ3ZpZXdOYW1lR2V0T3B0aW9ucycgfSk7XG5cdCAgICAgICAgICogICAgIHJldHVybiB2aWV3LmdldE9wdGlvbnMoKTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBnZXRWaWV3T3B0aW9ucygpXG5cdCAgICAgICAgICogICAgIC50aGVuKChpbmZvKSA9PiBjb25zb2xlLmxvZygnVmlldyBvcHRpb25zIGZldGNoZWQuJywgaW5mbykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuZ2V0T3B0aW9ucyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtdmlldy1vcHRpb25zJywgeyAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogVXBkYXRlcyB0aGUgdmlldydzIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2dvb2dsZS5jb20nLFxuXHQgICAgICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lVXBkYXRlT3B0aW9ucycsXG5cdCAgICAgICAgICogICAgICAgICB0YXJnZXQ6IG1lLmlkZW50aXR5LFxuXHQgICAgICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiB1cGRhdGVWaWV3T3B0aW9ucygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybCBvcHRpb24uJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHsgYXV0b1Jlc2l6ZToge1xuXHQgICAgICAgICAqICAgICAgICAgd2lkdGg6IHRydWUsXG5cdCAgICAgICAgICogICAgICAgICBob3Jpem9udGFsOiB0cnVlXG5cdCAgICAgICAgICogICAgIH19O1xuXHQgICAgICAgICAqICAgICByZXR1cm4gdmlldy51cGRhdGVPcHRpb25zKG5ld09wdGlvbnMpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIHVwZGF0ZVZpZXdPcHRpb25zKClcblx0ICAgICAgICAgKiAgICAgLnRoZW4ocGF5bG9hZCA9PiBjb25zb2xlLmxvZygnVmlldyBvcHRpb25zIHVwZGF0ZWQ6ICcsIHBheWxvYWQpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnVwZGF0ZU9wdGlvbnMgPSBhc3luYyAob3B0aW9ucykgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3VwZGF0ZS12aWV3LW9wdGlvbnMnLCB7IG9wdGlvbnMsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmV0cmlldmVzIHRoZSB3aW5kb3cgdGhlIHZpZXcgaXMgY3VycmVudGx5IGF0dGFjaGVkIHRvLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBqc1xuXHQgICAgICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy53cmFwU3luYyh7IHV1aWQ6ICd2aWV3VXVpZCcsIG5hbWU6ICd2aWV3TmFtZScgfSk7XG5cdCAgICAgICAgICogdmlldy5nZXRDdXJyZW50V2luZG93KClcblx0ICAgICAgICAgKiAgICAgLnRoZW4od2luID0+IGNvbnNvbGUubG9nKCdjdXJyZW50IHdpbmRvdycsIHdpbikpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7KVxuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldEN1cnJlbnRXaW5kb3cgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtdmlldy13aW5kb3cnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgd2luZG93XzEuX1dpbmRvdyh0aGlzLndpcmUsIGRhdGEpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmV0cmlldmVzIHRoZSBjdXJyZW50IHtAbGluayBPcGVuRmluLlRhYlN0YWNrfSBvZiB0aGUgdmlldyBpZiBpdCBiZWxvbmdzIHRvIG9uZS5cblx0ICAgICAgICAgKiBAcmV0dXJucyB0aGlzIHZpZXcgYmVsb25ncyB0by5cblx0ICAgICAgICAgKiBAdGhyb3dzIGlmIHRoaXMgdmlldyBkb2VzIG5vdCBiZWxvbmcgdG8gYSBUYWJTdGFjayBvciBpZiB0aGUgd2luZG93IGhhcyBiZWVuIGRlc3Ryb3llZC5cblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogaWYgKCFmaW4ubWUuaXNWaWV3KSB7XG5cdCAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuXHQgICAgICAgICAqIC8vIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gd3JhcCBhbnkgdmlldyBhbmQgZ2V0IHRoZSBzdGFjayBmcm9tIHRoZXJlXG5cdCAgICAgICAgICogLy8gY29uc3Qgdmlld0Zyb21Tb21ld2hlcmUgPSBmaW4uVmlldy53cmFwU3luYyhzb21lVmlldy5pZGVudGl0eSk7XG5cdCAgICAgICAgICogLy8gY29uc3Qgc3RhY2sgPSBhd2FpdCB2aWV3RnJvbVNvbWV3aGVyZS5nZXRDdXJyZW50U3RhY2soKTtcblx0ICAgICAgICAgKiBjb25zdCB2aWV3cyA9IGF3YWl0IHN0YWNrLmdldFZpZXdzKCk7XG5cdCAgICAgICAgICogY29uc29sZS5sb2coYFN0YWNrIGNvbnRhaW5zICR7dmlld3MubGVuZ3RofSB2aWV3KHMpYCk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5nZXRDdXJyZW50U3RhY2sgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd2aWV3LWdldC1jdXJyZW50LXN0YWNrJykuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0V2luZG93ID0gYXdhaXQgdGhpcy5nZXRDdXJyZW50V2luZG93KCk7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwcm92aWRlckNoYW5uZWxDbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9WaWV3X3Byb3ZpZGVyQ2hhbm5lbENsaWVudCwgXCJmXCIpLmdldFZhbHVlKCk7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBsYXlvdXRfZW50aXRpZXNfMS5MYXlvdXROb2RlLm5ld0xheW91dEVudGl0aWVzQ2xpZW50KHByb3ZpZGVyQ2hhbm5lbENsaWVudCwgbGF5b3V0X2NvbnN0YW50c18xLkxBWU9VVF9DT05UUk9MTEVSX0lELCBsYXlvdXRXaW5kb3cuaWRlbnRpdHkpO1xuXHQgICAgICAgICAgICAgICAgY29uc3Qgc3RhY2tEZWZpbml0aW9uID0gKGF3YWl0IGNsaWVudC5nZXRTdGFja0J5Vmlldyh0aGlzLmlkZW50aXR5KSk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbGF5b3V0X2VudGl0aWVzXzEuTGF5b3V0Tm9kZS5nZXRFbnRpdHkoc3RhY2tEZWZpbml0aW9uLCBjbGllbnQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5SdW50aW1lRXJyb3IoeyByZWFzb246ICdUaGlzIHZpZXcgZG9lcyBub3QgYmVsb25nIHRvIGEgc3RhY2suJywgZXJyb3IgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFRyaWdnZXJzIHRoZSBiZWZvcmUtdW5sb2FkIGhhbmRsZXIgZm9yIHRoZSBWaWV3LCBpZiBvbmUgaXMgc2V0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJlbWFya3MgUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGhhbmRsZXIgaXMgdHJ5aW5nIHRvIHByZXZlbnQgdGhlIFZpZXcgZnJvbSB1bmxvYWRpbmcsIGFuZCBgZmFsc2VgIGlmIGl0IGlzbid0LlxuXHQgICAgICAgICAqIE9ubHkgZW5hYmxlZCB3aGVuIHNldHRpbmcgZW5hYmxlQmVmb3JlVW5sb2FkOiB0cnVlIGluIHlvdXIgVmlldyBvcHRpb25zLiBJZiB0aGlzIG9wdGlvbiBpcyBub3QgZW5hYmxlZCBpdCB3aWxsXG5cdCAgICAgICAgICogYWx3YXlzIHJldHVybiBmYWxzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgUGxhdGZvcm0gUHJvdmlkZXIgdG8gZGV0ZXJtaW5lIHRoZSBzdGF0dXMgb2YgZWFjaCBiZWZvcmUgdW5sb2FkIGhhbmRsZXIgaW4gVmlld3Mgd2hlbiBjbG9zaW5nIHRoZSBXaW5kb3cuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiAvLyBmcm9tIGluc2lkZSBhIFZpZXcgY29udGV4dFxuXHQgICAgICAgICAqIGNvbnN0IHVubG9hZFByZXZlbnRlZCA9IGF3YWl0IGZpbi5tZS50cmlnZ2VyQmVmb3JlVW5sb2FkKCk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy50cmlnZ2VyQmVmb3JlVW5sb2FkID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3RyaWdnZXItYmVmb3JlLXVubG9hZCcsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UucGF5bG9hZC5kYXRhO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogKipOT1RFKio6IEludGVybmFsIHVzZSBvbmx5LlxuXHQgICAgICAgICAqIEF0dGFjaGVzIHRoaXMgdmlldyB0byBhbiBIVE1MIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgY29udGV4dC4gVGhlIHZpZXcgd2lsbCByZXNpemUgcmVzcG9uc2l2ZWx5IHdoZW4gdGhlIGVsZW1lbnQgYm91bmRzIGNoYW5nZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICoqS25vd24gaXNzdWUqKjogVmlldy5iaW5kVG9FbGVtZW50IGRvZXMgbm90IHRyYWNrIHBvc2l0aW9uIGNoYW5nZXMsIGlmIHRoZSBlbGVtZW50IGhhcyBmaXhlZCBweCB3aWR0aCBhbmQgaGVpZ2h0IHZhbHVlcyBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIHZpZXcgdG8gbm90IHVwZGF0ZSByZXNwb25zaXZlbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAqKktub3duIGlzc3VlKio6IFdoZW4gVmlldy5iaW5kVG9FbGVtZW50IGlzIHVzZWQgb24gYSBlbGVtZW50IHRoYXQgdGFrZXMgdXAgdGhlIGVudGlyZSBwYWdlIGluIGEgcGxhdGZvcm0gd2luZG93LCB0aGUgYm91bmQgdmlldyB3aWxsIG5vdCByZXNwb25kIHJlc3BvbnNpdmVseSB3aGVuIHRoZSB3aW5kb3cgaXMgcmVzaXplZCB0byBiZSBzbWFsbGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgLSBIVE1MIGVsZW1lbnQgdG8gYXR0YWNoIHRoZSB2aWV3IHRvLlxuXHQgICAgICAgICAqIEByZXR1cm5zIC0gQ2xlYW51cCBmdW5jdGlvbiB0aGF0IHdpbGwgZGlzY29ubmVjdCB0aGUgZWxlbWVudCByZXNpemUgb2JzZXJ2ZXIuXG5cdCAgICAgICAgICogQGludGVybmFsXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqIEByZW1hcmtzIFZpZXcgd2lsbCByZXNpemUgYWNjb3JkaW5nbHkgd2hlbiB0aGUgZWxlbWVudCBpcyByZXNpemVkLiBJZiB0aGUgZWxlbWVudCBpcyByZXBvc2l0aW9uZWQgaW4gdGhlIERPTSB0aGUgdmlldyB3aWxsIG5vdCBiZSByZXBvc2l0aW9uZWQsIHRvIGhhbmRsZSB0aGlzIGNhc2UgY2FsbCBgYmluZFRvRWxlbWVudGAgYWdhaW4gb25jZSB0aGUgZWxlbWVudCBjaGFuZ2VzIHBvc2l0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBodG1sXG5cdCAgICAgICAgICogPGRpdiBpZD1cInZpZXctY29udGFpbmVyXCI+PC9kaXY+XG5cdCAgICAgICAgICogPHNjcmlwdD5cblx0ICAgICAgICAgKiAgICAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQW5kQXR0YWNoVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IHVybCA9ICdodHRwczovL2V4YW1wbGUuY29tJztcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IGVsZW1lbnRJZCA9ICd2aWV3LWNvbnRhaW5lcic7XG5cdCAgICAgICAgICogICAgICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuXHQgICAgICAgICAqICAgICAgICAgICAgIG5hbWU6ICdteS12aWV3Jyxcblx0ICAgICAgICAgKiAgICAgICAgICAgICB1cmwsXG5cdCAgICAgICAgICogICAgICAgICAgICAgdGFyZ2V0OiBmaW4ubWUuaWRlbnRpdHlcblx0ICAgICAgICAgKiAgICAgICAgIH0pO1xuXHQgICAgICAgICAqICAgICAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSh1cmwpO1xuXHQgICAgICAgICAqICAgICAgICAgYXdhaXQgdmlldy5iaW5kVG9FbGVtZW50KGVsZW1lbnQpO1xuXHQgICAgICAgICAqICAgICB9XG5cdCAgICAgICAgICogICAgIGNyZWF0ZUFuZEF0dGFjaFZpZXcoKS5jYXRjaChjb25zb2xlLmVycm9yKTtcblx0ICAgICAgICAgKiA8L3NjcmlwdD5cblx0ICAgICAgICAgKiBgYGBcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmJpbmRUb0VsZW1lbnQgPSBhc3luYyAoZWxlbWVudCkgPT4ge1xuXHQgICAgICAgICAgICBpZiAoIWVsZW1lbnQpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxlbWVudCBub3QgZm91bmQuJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3Qgb25DaGFuZ2UgPSBhc3luYyAoYm91bmRzKSA9PiB0aGlzLnNldEJvdW5kcyhib3VuZHMpO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50Lm9ic2VydmVCb3VuZHMoZWxlbWVudCwgb25DaGFuZ2UpO1xuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZvY3VzZXMgdGhlIHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy53cmFwU3luYyh7IHV1aWQ6ICd2aWV3VXVpZCcsIG5hbWU6ICd2aWV3TmFtZScgfSk7XG5cdCAgICAgKiBhd2FpdCB2aWV3LmZvY3VzKCk7XG5cdCAgICAgKiAvLyBkbyB0aGluZ3Mgd2l0aCB0aGUgZm9jdXNlZCB2aWV3XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZm9jdXMoeyBlbWl0U3ludGhGb2N1c2VkIH0gPSB7IGVtaXRTeW50aEZvY3VzZWQ6IHRydWUgfSkge1xuXHQgICAgICAgIGNvbnN0IHdpbiA9IGF3YWl0IHRoaXMuZ2V0Q3VycmVudFdpbmRvdygpO1xuXHQgICAgICAgIGF3YWl0IHdpbi5mb2N1c2VkV2ViVmlld1dhc0NoYW5nZWQoKTtcblx0ICAgICAgICBhd2FpdCBzdXBlci5mb2N1cyh7IGVtaXRTeW50aEZvY3VzZWQgfSk7XG5cdCAgICB9XG5cdH1cblx0SW5zdGFuY2UkNS5WaWV3ID0gVmlldztcblx0X1ZpZXdfcHJvdmlkZXJDaGFubmVsQ2xpZW50ID0gbmV3IFdlYWtNYXAoKTtcblx0cmV0dXJuIEluc3RhbmNlJDU7XG59XG5cbnZhciBoYXNSZXF1aXJlZFZpZXc7XG5cbmZ1bmN0aW9uIHJlcXVpcmVWaWV3ICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkVmlldykgcmV0dXJuIHZpZXc7XG5cdGhhc1JlcXVpcmVkVmlldyA9IDE7XG5cdChmdW5jdGlvbiAoZXhwb3J0cykge1xuXHRcdHZhciBfX2NyZWF0ZUJpbmRpbmcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jcmVhdGVCaW5kaW5nKSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdFx0ICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG5cdFx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0XHQgICAgfVxuXHRcdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xuXHRcdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdFx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdFx0ICAgIG9bazJdID0gbVtrXTtcblx0XHR9KSk7XG5cdFx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0XHQgICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChleHBvcnRzLCBwKSkgX19jcmVhdGVCaW5kaW5nKGV4cG9ydHMsIG0sIHApO1xuXHRcdH07XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRcdC8qKlxuXHRcdCAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIE9wZW5GaW4gYFZpZXdgIEFQSSAoYGZpbi5WaWV3YCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBWaWV3TW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYFZpZXdgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uVmlld2AuXG5cdFx0ICogKiB7QGxpbmsgVmlld30gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gVmlldywgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlZpZXcuZ2V0Q3VycmVudGAuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdFx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQzKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UkMigpLCBleHBvcnRzKTsgXG5cdH0gKHZpZXcpKTtcblx0cmV0dXJuIHZpZXc7XG59XG5cbnZhciBoYXNSZXF1aXJlZEluc3RhbmNlJDE7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSQxICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkSW5zdGFuY2UkMSkgcmV0dXJuIEluc3RhbmNlJDY7XG5cdGhhc1JlcXVpcmVkSW5zdGFuY2UkMSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSQ2LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW5zdGFuY2UkNi5BcHBsaWNhdGlvbiA9IHZvaWQgMDtcblx0LyogZXNsaW50LWRpc2FibGUgaW1wb3J0L3ByZWZlci1kZWZhdWx0LWV4cG9ydCAqL1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCB3aW5kb3dfMSA9IHJlcXVpcmVXaW5kb3coKTtcblx0Y29uc3Qgdmlld18xID0gcmVxdWlyZVZpZXcoKTtcblx0LyoqXG5cdCAqIEFuIG9iamVjdCByZXByZXNlbnRpbmcgYW4gYXBwbGljYXRpb24uIEFsbG93cyB0aGUgZGV2ZWxvcGVyIHRvIGNyZWF0ZSxcblx0ICogZXhlY3V0ZSwgc2hvdy9jbG9zZSBhbiBhcHBsaWNhdGlvbiBhcyB3ZWxsIGFzIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50cyBhcHBsaWNhdGlvbiBldmVudHN9LlxuXHQgKi9cblx0Y2xhc3MgQXBwbGljYXRpb24gZXh0ZW5kcyBiYXNlXzEuRW1pdHRlckJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCAnYXBwbGljYXRpb24nLCBpZGVudGl0eS51dWlkKTtcblx0ICAgICAgICB0aGlzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5cdCAgICAgICAgdGhpcy53aW5kb3cgPSBuZXcgd2luZG93XzEuX1dpbmRvdyh0aGlzLndpcmUsIHtcblx0ICAgICAgICAgICAgdXVpZDogdGhpcy5pZGVudGl0eS51dWlkLFxuXHQgICAgICAgICAgICBuYW1lOiB0aGlzLmlkZW50aXR5LnV1aWRcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIHdpbmRvd0xpc3RGcm9tSWRlbnRpdHlMaXN0KGlkZW50aXR5TGlzdCkge1xuXHQgICAgICAgIGNvbnN0IHdpbmRvd0xpc3QgPSBbXTtcblx0ICAgICAgICBpZGVudGl0eUxpc3QuZm9yRWFjaCgoaWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgd2luZG93TGlzdC5wdXNoKG5ldyB3aW5kb3dfMS5fV2luZG93KHRoaXMud2lyZSwge1xuXHQgICAgICAgICAgICAgICAgdXVpZDogaWRlbnRpdHkudXVpZCxcblx0ICAgICAgICAgICAgICAgIG5hbWU6IGlkZW50aXR5Lm5hbWVcblx0ICAgICAgICAgICAgfSkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB3aW5kb3dMaXN0O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBhcHBsaWNhdGlvbiBpcyBjdXJyZW50bHkgcnVubmluZy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc0FwcFJ1bm5pbmcoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmlzUnVubmluZygpO1xuXHQgICAgICogfVxuXHQgICAgICogaXNBcHBSdW5uaW5nKCkudGhlbihydW5uaW5nID0+IGNvbnNvbGUubG9nKGBDdXJyZW50IGFwcCBpcyBydW5uaW5nOiAke3J1bm5pbmd9YCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBpc1J1bm5pbmcoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpcy1hcHBsaWNhdGlvbi1ydW5uaW5nJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENsb3NlcyB0aGUgYXBwbGljYXRpb24gYW5kIGFueSBjaGlsZCB3aW5kb3dzIGNyZWF0ZWQgYnkgdGhlIGFwcGxpY2F0aW9uLlxuXHQgICAgICogQ2xlYW5zIHRoZSBhcHBsaWNhdGlvbiBmcm9tIHN0YXRlIHNvIGl0IGlzIG5vIGxvbmdlciBmb3VuZCBpbiBnZXRBbGxBcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgQ2xvc2Ugd2lsbCBiZSBwcmV2ZW50ZWQgZnJvbSBjbG9zaW5nIHdoZW4gZm9yY2UgaXMgZmFsc2UgYW5kXG5cdCAgICAgKiAg4oCYY2xvc2UtcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjbG9zZUFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhbGxBcHBzMSA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0QWxsQXBwbGljYXRpb25zKCk7IC8vW3t1dWlkOiAnYXBwMScsIGlzUnVubmluZzogdHJ1ZX0sIHt1dWlkOiAnYXBwMicsIGlzUnVubmluZzogdHJ1ZX1dXG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLndyYXAoe3V1aWQ6ICdhcHAyJ30pO1xuXHQgICAgICogICAgIGF3YWl0IGFwcC5xdWl0KCk7XG5cdCAgICAgKiAgICAgY29uc3QgYWxsQXBwczIgPSBhd2FpdCBmaW4uU3lzdGVtLmdldEFsbEFwcGxpY2F0aW9ucygpOyAvL1t7dXVpZDogJ2FwcDEnLCBpc1J1bm5pbmc6IHRydWV9XVxuXHQgICAgICpcblx0ICAgICAqIH1cblx0ICAgICAqIGNsb3NlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gcXVpdCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcXVpdChmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy5fY2xvc2UoZm9yY2UpO1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZGVzdHJveS1hcHBsaWNhdGlvbicsIHsgZm9yY2UsIC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBhY2NlcHRhYmxlRXJyb3JzID0gWydSZW1vdGUgY29ubmVjdGlvbiBoYXMgY2xvc2VkJywgJ0NvdWxkIG5vdCBsb2NhdGUgdGhlIHJlcXVlc3RlZCBhcHBsaWNhdGlvbiddO1xuXHQgICAgICAgICAgICBpZiAoIWFjY2VwdGFibGVFcnJvcnMuc29tZSgobXNnKSA9PiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKG1zZykpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIF9jbG9zZShmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Nsb3NlLWFwcGxpY2F0aW9uJywgeyBmb3JjZSwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGlmICghZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnUmVtb3RlIGNvbm5lY3Rpb24gaGFzIGNsb3NlZCcpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgdXNlIEFwcGxpY2F0aW9uLnF1aXQgaW5zdGVhZFxuXHQgICAgICogQ2xvc2VzIHRoZSBhcHBsaWNhdGlvbiBhbmQgYW55IGNoaWxkIHdpbmRvd3MgY3JlYXRlZCBieSB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgLSBDbG9zZSB3aWxsIGJlIHByZXZlbnRlZCBmcm9tIGNsb3Npbmcgd2hlbiBmb3JjZSBpcyBmYWxzZSBhbmQg4oCYY2xvc2UtcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvdy5cblx0ICAgICAqIEBwYXJhbSBjYWxsYmFjayAtIGNhbGxlZCBpZiB0aGUgbWV0aG9kIHN1Y2NlZWRzLlxuXHQgICAgICogQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBjYWxsZWQgaWYgdGhlIG1ldGhvZCBmYWlscy4gVGhlIHJlYXNvbiBmb3IgZmFpbHVyZSBpcyBwYXNzZWQgYXMgYW4gYXJndW1lbnQuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY2xvc2VBcHAoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmNsb3NlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKiBjbG9zZUFwcCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIGNsb3NlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY2xvc2UoZm9yY2UgPSBmYWxzZSkge1xuXHQgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gV2FybmluZzogQXBwbGljYXRpb24uY2xvc2UgaXMgZGVwcmVjYXRlZCBQbGVhc2UgdXNlIEFwcGxpY2F0aW9uLnF1aXQnKTtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tY2xvc2UnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2UoZm9yY2UpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2Ygd3JhcHBlZCBmaW4uV2luZG93cyBmb3IgZWFjaCBvZiB0aGUgYXBwbGljYXRpb27igJlzIGNoaWxkIHdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Q2hpbGRXaW5kb3dzKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRDaGlsZFdpbmRvd3MoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRDaGlsZFdpbmRvd3MoKS50aGVuKGNoaWxkcmVuID0+IGNvbnNvbGUubG9nKGNoaWxkcmVuKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldENoaWxkV2luZG93cygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jaGlsZC13aW5kb3dzJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgaWRlbnRpdHlMaXN0ID0gW107XG5cdCAgICAgICAgICAgIHBheWxvYWQuZGF0YS5mb3JFYWNoKCh3aW5OYW1lKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZGVudGl0eUxpc3QucHVzaCh7IHV1aWQ6IHRoaXMuaWRlbnRpdHkudXVpZCwgbmFtZTogd2luTmFtZSB9KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLndpbmRvd0xpc3RGcm9tSWRlbnRpdHlMaXN0KGlkZW50aXR5TGlzdCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyB0aGUgSlNPTiBtYW5pZmVzdCB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSB0aGUgYXBwbGljYXRpb24uIEludm9rZXMgdGhlIGVycm9yIGNhbGxiYWNrXG5cdCAgICAgKiBpZiB0aGUgYXBwbGljYXRpb24gd2FzIG5vdCBjcmVhdGVkIGZyb20gYSBtYW5pZmVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRNYW5pZmVzdCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0TWFuaWZlc3QoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRNYW5pZmVzdCgpLnRoZW4obWFuaWZlc3QgPT4gY29uc29sZS5sb2cobWFuaWZlc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0TWFuaWZlc3QoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYXBwbGljYXRpb24tbWFuaWZlc3QnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIFVVSUQgb2YgdGhlIGFwcGxpY2F0aW9uIHRoYXQgbGF1bmNoZXMgdGhpcyBhcHBsaWNhdGlvbi4gSW52b2tlcyB0aGUgZXJyb3IgY2FsbGJhY2tcblx0ICAgICAqIGlmIHRoZSBhcHBsaWNhdGlvbiB3YXMgY3JlYXRlZCBmcm9tIGEgbWFuaWZlc3QuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50VXVpZCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtQXBwbGljYXRpb24uZ2V0UGFyZW50VXVpZC5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFBhcmVudFV1aWQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRQYXJlbnRVdWlkKCkudGhlbihwYXJlbnRVdWlkID0+IGNvbnNvbGUubG9nKHBhcmVudFV1aWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0UGFyZW50VXVpZCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1wYXJlbnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGN1cnJlbnQgYXBwbGljYXRpb24ncyBzaG9ydGN1dCBjb25maWd1cmF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFNob3J0Y3V0cygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24ud3JhcCh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFNob3J0Y3V0cygpO1xuXHQgICAgICogfVxuXHQgICAgICogZ2V0U2hvcnRjdXRzKCkudGhlbihjb25maWcgPT4gY29uc29sZS5sb2coY29uZmlnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldFNob3J0Y3V0cygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1zaG9ydGN1dHMnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGN1cnJlbnQgYXBwbGljYXRpb24ncyB2aWV3cy5cblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRWaWV3cygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0Vmlld3MoKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGdldFZpZXdzKCkudGhlbih2aWV3cyA9PiBjb25zb2xlLmxvZyh2aWV3cykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRWaWV3cygpIHtcblx0ICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdhcHBsaWNhdGlvbi1nZXQtdmlld3MnLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhLm1hcCgoaWQpID0+IG5ldyB2aWV3XzEuVmlldyh0aGlzLndpcmUsIGlkKSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgem9vbSBsZXZlbCBvZiB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRab29tTGV2ZWwoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0Wm9vbUxldmVsKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWFwcGxpY2F0aW9uLXpvb20tbGV2ZWwnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB0aGUgbWFpbiBXaW5kb3cgb2YgdGhlIGFwcGxpY2F0aW9uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0V2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1BcHBsaWNhdGlvbi5nZXRXaW5kb3cuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3coKS50aGVuKHdpbiA9PiB7XG5cdCAgICAgKiAgICAgd2luLnNob3dBdCgwLCA0MDApO1xuXHQgICAgICogICAgIHdpbi5mbGFzaCgpO1xuXHQgICAgICogfSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldFdpbmRvdygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tZ2V0LXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy53aW5kb3cpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBNYW51YWxseSByZWdpc3RlcnMgYSB1c2VyIHdpdGggdGhlIGxpY2Vuc2luZyBzZXJ2aWNlLiBUaGUgb25seSBkYXRhIHNlbnQgYnkgdGhpcyBjYWxsIGlzIHVzZXJOYW1lIGFuZCBhcHBOYW1lLlxuXHQgICAgICogQHBhcmFtIHVzZXJOYW1lIC0gdXNlcm5hbWUgdG8gYmUgcGFzc2VkIHRvIHRoZSBSVk0uXG5cdCAgICAgKiBAcGFyYW0gYXBwTmFtZSAtIGFwcCBuYW1lIHRvIGJlIHBhc3NlZCB0byB0aGUgUlZNLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlZ2lzdGVyVXNlcigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAucmVnaXN0ZXJVc2VyKCd1c2VyJywgJ215QXBwJyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogcmVnaXN0ZXJVc2VyKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQgdGhlIHVzZXInKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHJlZ2lzdGVyVXNlcih1c2VyTmFtZSwgYXBwTmFtZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVnaXN0ZXItdXNlcicsIHsgdXNlck5hbWUsIGFwcE5hbWUsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZW1vdmVzIHRoZSBhcHBsaWNhdGlvbuKAmXMgaWNvbiBmcm9tIHRoZSB0cmF5LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlbW92ZVRyYXlJY29uKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5yZW1vdmVUcmF5SWNvbigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlbW92ZVRyYXlJY29uKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnUmVtb3ZlZCB0aGUgdHJheSBpY29uLicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVtb3ZlVHJheUljb24oKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdyZW1vdmUtdHJheS1pY29uJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXN0YXJ0cyB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcmVzdGFydEFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAucmVzdGFydCgpO1xuXHQgICAgICogfVxuXHQgICAgICogcmVzdGFydEFwcCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIHJlc3RhcnRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVzdGFydCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Jlc3RhcnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIERFUFJFQ0FURUQgbWV0aG9kIHRvIHJ1biB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKiBOZWVkZWQgd2hlbiBzdGFydGluZyBhcHBsaWNhdGlvbiB2aWEge0BsaW5rIEFwcGxpY2F0aW9uLmNyZWF0ZX0sIGJ1dCBOT1QgbmVlZGVkIHdoZW4gc3RhcnRpbmcgdmlhIHtAbGluayBBcHBsaWNhdGlvbi5zdGFydH0uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcnVuKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5jcmVhdGUoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtQXBwbGljYXRpb24ucnVuLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGF3YWl0IGFwcC5ydW4oKTtcblx0ICAgICAqIH1cblx0ICAgICAqIHJ1bigpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIGlzIHJ1bm5pbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICBydW4oKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiBXYXJuaW5nOiBBcHBsaWNhdGlvbi5ydW4gaXMgZGVwcmVjYXRlZCBQbGVhc2UgdXNlIGZpbi5BcHBsaWNhdGlvbi5zdGFydCcpO1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdhcHBsaWNhdGlvbi1ydW4nLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fcnVuKCk7XG5cdCAgICB9XG5cdCAgICBfcnVuKG9wdHMgPSB7fSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3J1bi1hcHBsaWNhdGlvbicsIHtcblx0ICAgICAgICAgICAgbWFuaWZlc3RVcmw6IHRoaXMuX21hbmlmZXN0VXJsLFxuXHQgICAgICAgICAgICBvcHRzLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSW5zdHJ1Y3RzIHRoZSBSVk0gdG8gc2NoZWR1bGUgb25lIHJlc3RhcnQgb2YgdGhlIGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNjaGVkdWxlUmVzdGFydCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2NoZWR1bGVSZXN0YXJ0KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2NoZWR1bGVSZXN0YXJ0KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gaXMgc2NoZWR1bGVkIHRvIHJlc3RhcnQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNjaGVkdWxlUmVzdGFydCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlbGF1bmNoLW9uLWNsb3NlJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIFJWTSB0byB1cGxvYWQgdGhlIGFwcGxpY2F0aW9uJ3MgbG9ncy4gT24gc3VjY2Vzcyxcblx0ICAgICAqIGFuIG9iamVjdCBjb250YWluaW5nIGxvZ0lkIGlzIHJldHVybmVkLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNlbmRMb2coKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnNlbmRBcHBsaWNhdGlvbkxvZygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHNlbmRMb2coKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mby5sb2dJZCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZW5kQXBwbGljYXRpb25Mb2coKSB7XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2VuZC1hcHBsaWNhdGlvbi1sb2cnLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIG9yIHJlbW92ZXMgYSBjdXN0b20gSnVtcExpc3QgZm9yIHRoZSBhcHBsaWNhdGlvbi4gT25seSBhcHBsaWNhYmxlIGluIFdpbmRvd3MgT1MuXG5cdCAgICAgKiBJZiBjYXRlZ29yaWVzIGlzIG51bGwgdGhlIHByZXZpb3VzbHkgc2V0IGN1c3RvbSBKdW1wTGlzdCAoaWYgYW55KSB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBzdGFuZGFyZCBKdW1wTGlzdCBmb3IgdGhlIGFwcCAobWFuYWdlZCBieSBXaW5kb3dzKS5cblx0ICAgICAqXG5cdCAgICAgKiBOb3RlOiBJZiB0aGUgXCJuYW1lXCIgcHJvcGVydHkgaXMgb21pdHRlZCBpdCBkZWZhdWx0cyB0byBcInRhc2tzXCIuXG5cdCAgICAgKiBAcGFyYW0ganVtcExpc3RDYXRlZ29yaWVzIEFuIGFycmF5IG9mIEp1bXBMaXN0IENhdGVnb3JpZXMgdG8gcG9wdWxhdGUuIElmIG51bGwsIHJlbW92ZSBhbnkgZXhpc3RpbmcgSnVtcExpc3QgY29uZmlndXJhdGlvbiBhbmQgc2V0IHRvIFdpbmRvd3MgZGVmYXVsdC5cblx0ICAgICAqXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSWYgY2F0ZWdvcmllcyBpcyBudWxsIHRoZSBwcmV2aW91c2x5IHNldCBjdXN0b20gSnVtcExpc3QgKGlmIGFueSkgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgc3RhbmRhcmQgSnVtcExpc3QgZm9yIHRoZSBhcHAgKG1hbmFnZWQgYnkgV2luZG93cykuXG5cdCAgICAgKlxuXHQgICAgICogVGhlIGJvdHRvbW1vc3QgaXRlbSBpbiB0aGUganVtcGxpc3Qgd2lsbCBhbHdheXMgYmUgYW4gaXRlbSBwb2ludGluZyB0byB0aGUgY3VycmVudCBhcHAuIEl0cyBuYW1lIGlzIHRha2VuIGZyb20gdGhlIG1hbmlmZXN0J3Ncblx0ICAgICAqICoqYCBzaG9ydGN1dC5uYW1lIGAqKiBhbmQgdXNlcyAqKmAgc2hvcnRjdXQuY29tcGFueSBgKiogYXMgYSBmYWxsYmFjay4gQ2xpY2tpbmcgdGhhdCBpdGVtIHdpbGwgbGF1bmNoIHRoZSBhcHAgZnJvbSBpdHMgY3VycmVudCBtYW5pZmVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBOb3RlOiBJZiB0aGUgXCJuYW1lXCIgcHJvcGVydHkgaXMgb21pdHRlZCBpdCBkZWZhdWx0cyB0byBcInRhc2tzXCIuXG5cdCAgICAgKlxuXHQgICAgICogTm90ZTogV2luZG93IE9TIGNhY2hlcyBqdW1wbGlzdHMgaWNvbnMsIHRoZXJlZm9yZSBhbiBpY29uIGNoYW5nZSBtaWdodCBvbmx5IGJlIHZpc2libGUgYWZ0ZXIgdGhlIGNhY2hlIGlzIHJlbW92ZWQgb3IgdGhlXG5cdCAgICAgKiB1dWlkIG9yIHNob3J0Y3V0Lm5hbWUgaXMgY2hhbmdlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwTmFtZSA9ICdNeSBBcHAnO1xuXHQgICAgICogICAgIGNvbnN0IGp1bXBMaXN0Q29uZmlnID0gWyAvLyBhcnJheSBvZiBKdW1wTGlzdCBjYXRlZ29yaWVzXG5cdCAgICAgKiAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgIC8vIGhhcyBubyBuYW1lIGFuZCBubyB0eXBlIHNvIGB0eXBlYCBpcyBhc3N1bWVkIHRvIGJlIFwidGFza3NcIlxuXHQgICAgICogICAgICAgICAgICAgaXRlbXM6IFsgLy8gYXJyYXkgb2YgSnVtcExpc3QgaXRlbXNcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6IGBMYXVuY2ggJHthcHBOYW1lfWAsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBSdW5zICR7YXBwTmFtZX0gd2l0aCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uYCxcblx0ICAgICAqICAgICAgICAgICAgICAgICBkZWVwTGluazogJ2ZpbnM6Ly9wYXRoLnRvL2FwcC9tYW5pZmVzdC5qc29uJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICBpY29uUGF0aDogJ2h0dHBzOi8vcGF0aC50by9hcHAvaWNvbi5pY28nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25JbmRleDogMFxuXHQgICAgICogICAgICAgICAgICAgfSxcblx0ICAgICAqICAgICAgICAgICAgIHsgdHlwZTogJ3NlcGFyYXRvcicgfSxcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6IGBSZXN0b3JlICR7YXBwTmFtZX1gLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVzdG9yZSB0byBsYXN0IGNvbmZpZ3VyYXRpb24nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlZXBMaW5rOiAnZmluczovL3BhdGgudG8vYXBwL21hbmlmZXN0Lmpzb24/JCR1c2UtbGFzdC1jb25maWd1cmF0aW9uPXRydWUnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25QYXRoOiAnaHR0cHM6Ly9wYXRoLnRvL2FwcC9pY29uLmljbycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvbkluZGV4OiAwXG5cdCAgICAgKiAgICAgICAgICAgICB9LFxuXHQgICAgICogICAgICAgICAgICAgXVxuXHQgICAgICogICAgICAgICB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBuYW1lOiAnVG9vbHMnLFxuXHQgICAgICogICAgICAgICAgICAgaXRlbXM6IFsgLy8gYXJyYXkgb2YgSnVtcExpc3QgaXRlbXNcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6ICdUb29sIEEnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUnVucyBUb29sIEEnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlZXBMaW5rOiAnZmluczovL3BhdGgudG8vdG9vbC1hL21hbmlmZXN0Lmpzb24nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25QYXRoOiAnaHR0cHM6Ly9wYXRoLnRvL3Rvb2wtYS9pY29uLmljbycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvbkluZGV4OiAwXG5cdCAgICAgKiAgICAgICAgICAgICB9LFxuXHQgICAgICogICAgICAgICAgICAge1xuXHQgICAgICogICAgICAgICAgICAgICAgIHR5cGU6ICd0YXNrJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICB0aXRsZTogJ1Rvb2wgQicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSdW5zIFRvb2wgQicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVlcExpbms6ICdmaW5zOi8vcGF0aC50by90b29sLWIvbWFuaWZlc3QuanNvbicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvblBhdGg6ICdodHRwczovL3BhdGgudG8vdG9vbC1iL2ljb24uaWNvJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICBpY29uSW5kZXg6IDBcblx0ICAgICAqICAgICAgICAgICAgIH1dXG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICBdO1xuXHQgICAgICpcblx0ICAgICAqICAgICBhcHAuc2V0SnVtcExpc3QoanVtcExpc3RDb25maWcpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0p1bXBMaXN0IGFwcGxpZWQnKSkuY2F0Y2goZSA9PiBjb25zb2xlLmxvZyhgSnVtcExpc3QgZmFpbGVkIHRvIGFwcGx5OiAke2UudG9TdHJpbmcoKX1gKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBUbyBoYW5kbGUgZGVlcGxpbmsgYXJnczpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgZnVuY3Rpb24gaGFuZGxlVXNlTGFzdENvbmZpZ3VyYXRpb24oKSB7XG5cdCAgICAgKiAgICAgICAgIC8vIHRoaXMgaGFuZGxlciBpcyBjYWxsZWQgd2hlbiB0aGUgYXBwIGlzIGJlaW5nIGxhdW5jaGVkXG5cdCAgICAgKiAgICAgICAgIGFwcC5vbigncnVuLXJlcXVlc3RlZCcsIGV2ZW50ID0+IHtcblx0ICAgICAqICAgICAgICAgICAgIGlmKGV2ZW50LnVzZXJBcHBDb25maWdBcmdzWyd1c2UtbGFzdC1jb25maWd1cmF0aW9uJ10pIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAvLyB5b3VyIGxvZ2ljIGhlcmVcblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgIC8vIHRoaXMgaGFuZGxlciBpcyBjYWxsZWQgd2hlbiB0aGUgYXBwIHdhcyBhbHJlYWR5IHJ1bm5pbmcgd2hlbiB0aGUgbGF1bmNoIHdhcyByZXF1ZXN0ZWRcblx0ICAgICAqICAgICAgICAgZmluLmRlc2t0b3AubWFpbihmdW5jdGlvbihhcmdzKSB7XG5cdCAgICAgKiAgICAgICAgICAgICBpZihhcmdzICYmIGFyZ3NbJ3VzZS1sYXN0LWNvbmZpZ3VyYXRpb24nXSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIHlvdXIgbG9naWMgaGVyZVxuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9KTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc2V0SnVtcExpc3QoanVtcExpc3RDYXRlZ29yaWVzKSB7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1qdW1wLWxpc3QnLCB7IGNvbmZpZzoganVtcExpc3RDYXRlZ29yaWVzLCAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBZGRzIGEgY3VzdG9taXphYmxlIGljb24gaW4gdGhlIHN5c3RlbSB0cmF5LiAgVG8gbGlzdGVuIGZvciBhIGNsaWNrIG9uIHRoZSBpY29uIHVzZSB0aGUgYHRyYXktaWNvbi1jbGlja2VkYCBldmVudC5cblx0ICAgICAqIEBwYXJhbSBpY29uIEltYWdlIFVSTCBvciBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYmUgdXNlZCBhcyB0aGUgaWNvblxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGltYWdlVXJsID0gXCJodHRwOi8vY2RuLm9wZW5maW4uY28vYXNzZXRzL3Rlc3RpbmcvaWNvbnMvY2lyY2xlZC1kaWdpdC1vbmUucG5nXCI7XG5cdCAgICAgKiBjb25zdCBiYXNlNjRFbmNvZGVkSW1hZ2UgPSBcImlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBZ0FBQUFJQVFNQUFBRCt3U3pJQUFBQUJsQk1WRVhcXFxuXHQgICAgICogLy8vKy92NytqUTNZNUFBQUFEa2xFUVZRSTEyUDRBSVg4RUFnQUxnQUQvYU5wYnRFQUFBQUFTVVZPUks1Q1lJSVwiO1xuXHQgICAgICogY29uc3QgZGF0YVVSTCA9IFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBVUFBQUFGQ0FZQUFBQ05ieWJsQUFBQUhFbEVRVlFJMTJQNC8vOC93MzhHSUFYRElCS0UwREhcXFxuXHQgICAgICogeGdsak5CQUFPOVRYTDBZNE9Id0FBQUFCSlJVNUVya0pnZ2c9PVwiO1xuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFRyYXlJY29uKGljb24pIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2V0VHJheUljb24oaWNvbik7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogLy8gdXNlIGltYWdlIHVybCB0byBzZXQgdHJheSBpY29uXG5cdCAgICAgKiBzZXRUcmF5SWNvbihpbWFnZVVybCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2V0dGluZyB0cmF5IGljb24nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICpcblx0ICAgICAqIC8vIHVzZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gc2V0IHRyYXkgaWNvblxuXHQgICAgICogc2V0VHJheUljb24oYmFzZTY0RW5jb2RlZEltYWdlKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIHRyYXkgaWNvbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKlxuXHQgICAgICogLy8gdXNlIGEgZGF0YVVSTCB0byBzZXQgdHJheSBpY29uXG5cdCAgICAgKiBzZXRUcmF5SWNvbihkYXRhVVJMKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIHRyYXkgaWNvbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgc2V0VHJheUljb24oaWNvbikge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3NldC10cmF5LWljb24nLCB7XG5cdCAgICAgICAgICAgIGVuYWJsZWRJY29uOiBpY29uLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBuZXcgYXBwbGljYXRpb24ncyBzaG9ydGN1dCBjb25maWd1cmF0aW9uLiBXaW5kb3dzIG9ubHkuXG5cdCAgICAgKiBAcGFyYW0gY29uZmlnIE5ldyBhcHBsaWNhdGlvbidzIHNob3J0Y3V0IGNvbmZpZ3VyYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgQXBwbGljYXRpb24gaGFzIHRvIGJlIGxhdW5jaGVkIHdpdGggYSBtYW5pZmVzdCBhbmQgaGFzIHRvIGhhdmUgc2hvcnRjdXQgY29uZmlndXJhdGlvbiAoaWNvbiB1cmwsIG5hbWUsIGV0Yy4pIGluIGl0cyBtYW5pZmVzdFxuXHQgICAgICogdG8gYmUgYWJsZSB0byBjaGFuZ2Ugc2hvcnRjdXQgc3RhdGVzLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFNob3J0Y3V0cyhjb25maWcpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuc2V0U2hvcnRjdXRzKGNvbmZpZyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0U2hvcnRjdXRzKHtcblx0ICAgICAqICAgICBkZXNrdG9wOiB0cnVlLFxuXHQgICAgICogICAgIHN0YXJ0TWVudTogZmFsc2UsXG5cdCAgICAgKiAgICAgc3lzdGVtU3RhcnR1cDogdHJ1ZVxuXHQgICAgICogfSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2hvcnRjdXRzIGFyZSBzZXQuJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBzZXRTaG9ydGN1dHMoY29uZmlnKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtc2hvcnRjdXRzJywgeyBkYXRhOiBjb25maWcsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIHRoZSBxdWVyeSBzdHJpbmcgaW4gYWxsIHNob3J0Y3V0cyBmb3IgdGhpcyBhcHAuIFJlcXVpcmVzIFJWTSA1LjUrLlxuXHQgICAgICogQHBhcmFtIHF1ZXJ5U3RyaW5nIFRoZSBuZXcgcXVlcnkgc3RyaW5nIGZvciB0aGlzIGFwcCdzIHNob3J0Y3V0cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBuZXdRdWVyeUFyZ3MgPSAnYXJnPXRydWUmYXJnMj1mYWxzZSc7XG5cdCAgICAgKiBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogdHJ5IHtcblx0ICAgICAqICAgICBhd2FpdCBhcHAuc2V0U2hvcnRjdXRRdWVyeVBhcmFtcyhuZXdRdWVyeUFyZ3MpO1xuXHQgICAgICogfSBjYXRjaChlcnIpIHtcblx0ICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRTaG9ydGN1dFF1ZXJ5UGFyYW1zKHF1ZXJ5U3RyaW5nKSB7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1zaG9ydGN1dC1xdWVyeS1hcmdzJywgeyBkYXRhOiBxdWVyeVN0cmluZywgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyB0aGUgem9vbSBsZXZlbCBvZiB0aGUgYXBwbGljYXRpb24uIFRoZSBvcmlnaW5hbCBzaXplIGlzIDAgYW5kIGVhY2ggaW5jcmVtZW50IGFib3ZlIG9yIGJlbG93IHJlcHJlc2VudHMgem9vbWluZyAyMCVcblx0ICAgICAqIGxhcmdlciBvciBzbWFsbGVyIHRvIGRlZmF1bHQgbGltaXRzIG9mIDMwMCUgYW5kIDUwJSBvZiBvcmlnaW5hbCBzaXplLCByZXNwZWN0aXZlbHkuXG5cdCAgICAgKiBAcGFyYW0gbGV2ZWwgVGhlIHpvb20gbGV2ZWxcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzZXRab29tTGV2ZWwobnVtYmVyKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnNldFpvb21MZXZlbChudW1iZXIpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHNldFpvb21MZXZlbCg1KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIGEgIHpvb20gbGV2ZWwnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNldFpvb21MZXZlbChsZXZlbCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2V0LWFwcGxpY2F0aW9uLXpvb20tbGV2ZWwnLCB7IGxldmVsLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBhIHVzZXJuYW1lIHRvIGNvcnJlbGF0ZSB3aXRoIEFwcCBMb2cgTWFuYWdlbWVudC5cblx0ICAgICAqIEBwYXJhbSB1c2VybmFtZSBVc2VybmFtZSB0byBjb3JyZWxhdGUgd2l0aCBBcHAncyBMb2cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gc2V0QXBwTG9nVXNlcigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2V0QXBwTG9nVXNlcm5hbWUoJ3VzZXJuYW1lJyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0QXBwTG9nVXNlcigpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1N1Y2Nlc3MnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICpcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRBcHBMb2dVc2VybmFtZSh1c2VybmFtZSkge1xuXHQgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtYXBwLWxvZy11c2VybmFtZScsIHsgZGF0YTogdXNlcm5hbWUsIC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3lzdGVtIHRyYXkuIElmIHRoZSBzeXN0ZW0gdHJheSBpcyBub3Qgc2V0LCBpdCB3aWxsIHRocm93IGFuIGVycm9yIG1lc3NhZ2UuXG5cdCAgICAgKiBAcmVtYXJrcyBUaGUgb25seSBpbmZvcm1hdGlvbiBjdXJyZW50bHkgcmV0dXJuZWQgaXMgdGhlIHBvc2l0aW9uIGFuZCBkaW1lbnNpb25zLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFRyYXlJY29uSW5mbygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24ud3JhcCh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFRyYXlJY29uSW5mbygpO1xuXHQgICAgICogfVxuXHQgICAgICogZ2V0VHJheUljb25JbmZvKCkudGhlbihpbmZvID0+IGNvbnNvbGUubG9nKGluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0VHJheUljb25JbmZvKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXRyYXktaWNvbi1pbmZvJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENoZWNrcyBpZiB0aGUgYXBwbGljYXRpb24gaGFzIGFuIGFzc29jaWF0ZWQgdHJheSBpY29uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi53cmFwKHsgdXVpZDogJ3Rlc3RhcHAnIH0pO1xuXHQgICAgICogY29uc3QgaGFzVHJheUljb24gPSBhd2FpdCBhcHAuaGFzVHJheUljb24oKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKGhhc1RyYXlJY29uKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBoYXNUcmF5SWNvbigpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hhcy10cmF5LWljb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2xvc2VzIHRoZSBhcHBsaWNhdGlvbiBieSB0ZXJtaW5hdGluZyBpdHMgcHJvY2Vzcy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiB0ZXJtaW5hdGVBcHAoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnRlcm1pbmF0ZSgpO1xuXHQgICAgICogfVxuXHQgICAgICogdGVybWluYXRlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gdGVybWluYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgdGVybWluYXRlKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndGVybWluYXRlLWFwcGxpY2F0aW9uJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBXYWl0cyBmb3IgYSBoYW5naW5nIGFwcGxpY2F0aW9uLiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGluIHJlc3BvbnNlIHRvIGFuIGFwcGxpY2F0aW9uXG5cdCAgICAgKiBcIm5vdC1yZXNwb25kaW5nXCIgdG8gYWxsb3cgdGhlIGFwcGxpY2F0aW9uIHRvIGNvbnRpbnVlIGFuZCB0byBnZW5lcmF0ZSBhbm90aGVyIFwibm90LXJlc3BvbmRpbmdcIlxuXHQgICAgICogbWVzc2FnZSBhZnRlciBhIGNlcnRhaW4gcGVyaW9kIG9mIHRpbWUuXG5cdCAgICAgKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICB3YWl0KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignd2FpdC1mb3ItaHVuZy1hcHBsaWNhdGlvbicsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBhcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBJZiB0aGUgYXBwbGljYXRpb24gd2FzIG5vdCBsYXVuY2hlZCBmcm9tIGEgbWFuaWZlc3QsIHRoZSBjYWxsIHdpbGwgcmV0dXJuIHRoZSBjbG9zZXN0IHBhcmVudCBhcHBsaWNhdGlvbiBgbWFuaWZlc3RgXG5cdCAgICAgKiBhbmQgYG1hbmlmZXN0VXJsYC4gIGBpbml0aWFsT3B0aW9uc2Agc2hvd3MgdGhlIHBhcmFtZXRlcnMgdXNlZCB3aGVuIGxhdW5jaGVkIHByb2dyYW1tYXRpY2FsbHksIG9yIHRoZSBgc3RhcnR1cF9hcHBgIG9wdGlvbnNcblx0ICAgICAqIGlmIGxhdW5jaGVkIGZyb20gbWFuaWZlc3QuIFRoZSBgcGFyZW50VXVpZGAgd2lsbCBiZSB0aGUgdXVpZCBvZiB0aGUgaW1tZWRpYXRlIHBhcmVudCAoaWYgYXBwbGljYWJsZSkuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0SW5mbygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0SW5mbygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldEluZm8oKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRJbmZvKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWluZm8nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGFsbCBwcm9jZXNzIGluZm9ybWF0aW9uIGZvciBlbnRpdGllcyAod2luZG93cyBhbmQgdmlld3MpIGFzc29jaWF0ZWQgd2l0aCBhbiBhcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgYXBwLmdldFByb2Nlc3NJbmZvKCk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0UHJvY2Vzc0luZm8oKSB7XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGEgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLWdldC1wcm9jZXNzLWluZm8nLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBmaWxlIGF1dG8gZG93bmxvYWQgbG9jYXRpb24uIEl0J3Mgb25seSBhbGxvd2VkIGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuXHQgICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cblx0ICAgICAqIEBwYXJhbSBkb3dubG9hZExvY2F0aW9uIGZpbGUgYXV0byBkb3dubG9hZCBsb2NhdGlvblxuXHQgICAgICpcblx0ICAgICAqIEB0aHJvd3MgaWYgc2V0dGluZyBmaWxlIGF1dG8gZG93bmxvYWQgbG9jYXRpb24gb24gZGlmZmVyZW50IGFwcGxpY2F0aW9ucy5cblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGRvd25sb2FkTG9jYXRpb24gPSAnQzpcXFxcZGV2XFxcXHRlbXAnO1xuXHQgICAgICogY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqIHRyeSB7XG5cdCAgICAgKiAgICAgYXdhaXQgYXBwLnNldEZpbGVEb3dubG9hZExvY2F0aW9uKGRvd25sb2FkTG9jYXRpb24pO1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKCdGaWxlIGRvd25sb2FkIGxvY2F0aW9uIGlzIHNldCcpO1xuXHQgICAgICogfSBjYXRjaChlcnIpIHtcblx0ICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRGaWxlRG93bmxvYWRMb2NhdGlvbihkb3dubG9hZExvY2F0aW9uKSB7XG5cdCAgICAgICAgY29uc3QgeyBuYW1lIH0gPSB0aGlzLndpcmUubWU7XG5cdCAgICAgICAgY29uc3QgZW50aXR5SWRlbnRpdHkgPSB7IHV1aWQ6IHRoaXMuaWRlbnRpdHkudXVpZCwgbmFtZSB9O1xuXHQgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtZmlsZS1kb3dubG9hZC1sb2NhdGlvbicsIHsgLi4uZW50aXR5SWRlbnRpdHksIGRvd25sb2FkTG9jYXRpb24gfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdldHMgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uLiBJdCdzIG9ubHkgYWxsb3dlZCBpbiB0aGUgc2FtZSBhcHBsaWNhdGlvbi4gSWYgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uIGlzIG5vdCBzZXQsIGl0IHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IGxvY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuXHQgICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cblx0ICAgICAqXG5cdCAgICAgKiBAdGhyb3dzIGlmIGdldHRpbmcgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uIG9uIGRpZmZlcmVudCBhcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogY29uc3QgZmlsZURvd25sb2FkRGlyID0gIGF3YWl0IGFwcC5nZXRGaWxlRG93bmxvYWRMb2NhdGlvbigpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEZpbGVEb3dubG9hZExvY2F0aW9uKCkge1xuXHQgICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZmlsZS1kb3dubG9hZC1sb2NhdGlvbicsIHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgICAgIHJldHVybiBkYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG93cyBhIG1lbnUgb24gdGhlIHRyYXkgaWNvbi4gVXNlIHdpdGggdHJheS1pY29uLWNsaWNrZWQgZXZlbnQuXG5cdCAgICAgKiBAcGFyYW0gb3B0aW9uc1xuXHQgICAgICogQHR5cGVQYXJhbSBEYXRhIFVzZXItZGVmaW5lZCBzaGFwZSBmb3IgZGF0YSByZXR1cm5lZCB1cG9uIG1lbnUgaXRlbSBjbGljay4gU2hvdWxkIGJlIGFcblx0ICAgICAqIFt1bmlvbl0oaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9ldmVyeWRheS10eXBlcy5odG1sI3VuaW9uLXR5cGVzKVxuXHQgICAgICogb2YgYWxsIHBvc3NpYmxlIGRhdGEgc2hhcGVzIGZvciB0aGUgZW50aXJlIG1lbnUsIGFuZCB0aGUgY2xpY2sgaGFuZGxlciBzaG91bGQgcHJvY2Vzc1xuXHQgICAgICogdGhlc2Ugd2l0aCBhIFwicmVkdWNlclwiIHBhdHRlcm4uXG5cdCAgICAgKiBAdGhyb3dzIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gdHJheSBpY29uIHNldFxuXHQgICAgICogQHRocm93cyBpZiB0aGUgc3lzdGVtIHRyYXkgaXMgY3VycmVudGx5IGhpZGRlblxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgaWNvblVybCA9ICdodHRwOi8vY2RuLm9wZW5maW4uY28vYXNzZXRzL3Rlc3RpbmcvaWNvbnMvY2lyY2xlZC1kaWdpdC1vbmUucG5nJztcblx0ICAgICAqIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICpcblx0ICAgICAqIGF3YWl0IGFwcC5zZXRUcmF5SWNvbihpY29uVXJsKTtcblx0ICAgICAqXG5cdCAgICAgKiBjb25zdCB0ZW1wbGF0ZSA9IFtcblx0ICAgICAqICB7XG5cdCAgICAgKiAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgIGRhdGE6ICdoZWxsbyBmcm9tIGl0ZW0gMSdcblx0ICAgICAqICB9LFxuXHQgICAgICogIHsgdHlwZTogJ3NlcGFyYXRvcicgfSxcblx0ICAgICAqICB7XG5cdCAgICAgKiAgICBsYWJlbDogJ01lbnUgSXRlbSAyJyxcblx0ICAgICAqICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICBjaGVja2VkOiB0cnVlLFxuXHQgICAgICogICAgZGF0YTogJ1RoZSB1c2VyIGNsaWNrZWQgdGhlIGNoZWNrYm94J1xuXHQgICAgICogIH0sXG5cdCAgICAgKiAge1xuXHQgICAgICogICAgbGFiZWw6ICdzZWUgbW9yZScsXG5cdCAgICAgKiAgICBlbmFibGVkOiBmYWxzZSxcblx0ICAgICAqICAgIHN1Ym1lbnU6IFtcblx0ICAgICAqICAgICAgeyBsYWJlbDogJ3N1Ym1lbnUgMScsIGRhdGE6ICdoZWxsbyBmcm9tIHN1Ym1lbnUnIH1cblx0ICAgICAqICAgIF1cblx0ICAgICAqICB9XG5cdCAgICAgKiBdO1xuXHQgICAgICpcblx0ICAgICAqIGFwcC5hZGRMaXN0ZW5lcigndHJheS1pY29uLWNsaWNrZWQnLCAoZXZlbnQpID0+IHtcblx0ICAgICAqICAgLy8gcmlnaHQtY2xpY2tcblx0ICAgICAqICAgaWYgKGV2ZW50LmJ1dHRvbiA9PT0gMikge1xuXHQgICAgICogICAgIGFwcC5zaG93VHJheUljb25Qb3B1cE1lbnUoeyB0ZW1wbGF0ZSB9KS50aGVuKHIgPT4ge1xuXHQgICAgICogICAgICAgaWYgKHIucmVzdWx0ID09PSAnY2xvc2VkJykge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZygnbm90aGluZyBoYXBwZW5lZCcpO1xuXHQgICAgICogICAgICAgfSBlbHNlIHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coci5kYXRhKTtcblx0ICAgICAqICAgICAgIH1cblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgfVxuXHQgICAgICogfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc2hvd1RyYXlJY29uUG9wdXBNZW51KG9wdGlvbnMpIHtcblx0ICAgICAgICBjb25zdCB7IG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICBjb25zdCBlbnRpdHlJZGVudGl0eSA9IHsgdXVpZDogdGhpcy5pZGVudGl0eS51dWlkLCBuYW1lIH07XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy10cmF5LWljb24tcG9wdXAtbWVudScsIHsgLi4uZW50aXR5SWRlbnRpdHksIG9wdGlvbnMgfSk7XG5cdCAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2xvc2VzIHRoZSB0cmF5IGljb24gbWVudS5cblx0ICAgICAqXG5cdCAgICAgKiBAdGhyb3dzIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gdHJheSBpY29uIHNldFxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgYXBwID0gZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKlxuXHQgICAgICogYXdhaXQgYXBwLmNsb3NlVHJheUljb25Qb3B1cE1lbnUoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjbG9zZVRyYXlJY29uUG9wdXBNZW51KCkge1xuXHQgICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIGNvbnN0IGVudGl0eUlkZW50aXR5ID0geyB1dWlkOiB0aGlzLmlkZW50aXR5LnV1aWQsIG5hbWUgfTtcblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xvc2UtdHJheS1pY29uLXBvcHVwLW1lbnUnLCB7IC4uLmVudGl0eUlkZW50aXR5IH0pO1xuXHQgICAgfVxuXHR9XG5cdEluc3RhbmNlJDYuQXBwbGljYXRpb24gPSBBcHBsaWNhdGlvbjtcblx0cmV0dXJuIEluc3RhbmNlJDY7XG59XG5cbnZhciBoYXNSZXF1aXJlZEZhY3RvcnkkMjtcblxuZnVuY3Rpb24gcmVxdWlyZUZhY3RvcnkkMiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZhY3RvcnkkMikgcmV0dXJuIEZhY3RvcnkkNztcblx0aGFzUmVxdWlyZWRGYWN0b3J5JDIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoRmFjdG9yeSQ3LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0RmFjdG9yeSQ3LkFwcGxpY2F0aW9uTW9kdWxlID0gdm9pZCAwO1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCB2YWxpZGF0ZV8xID0gdmFsaWRhdGU7XG5cdGNvbnN0IEluc3RhbmNlXzEgPSByZXF1aXJlSW5zdGFuY2UkMSgpO1xuXHQvKipcblx0ICogU3RhdGljIG5hbWVzcGFjZSBmb3IgT3BlbkZpbiBBUEkgbWV0aG9kcyB0aGF0IGludGVyYWN0IHdpdGggdGhlIHtAbGluayBBcHBsaWNhdGlvbn0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkFwcGxpY2F0aW9uYC5cblx0ICovXG5cdGNsYXNzIEFwcGxpY2F0aW9uTW9kdWxlIGV4dGVuZHMgYmFzZV8xLkJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBBcHBsaWNhdGlvbiBpZGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBXcmFwcGluZyBhbiBBcHBsaWNhdGlvbiBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuXHQgICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuXHQgICAgICogZm9yIGFuIEFwcGxpY2F0aW9uIHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLndyYXAoeyB1dWlkOiAndGVzdGFwcCcgfSlcblx0ICAgICAqIC50aGVuKGFwcCA9PiBhcHAuaXNSdW5uaW5nKCkpXG5cdCAgICAgKiAudGhlbihydW5uaW5nID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiBpcyBydW5uaW5nOiAnICsgcnVubmluZykpXG5cdCAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBhc3luYyB3cmFwKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dyYXAtYXBwbGljYXRpb24nKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIEFwcGxpY2F0aW9uIGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGFuIEFwcGxpY2F0aW9uIGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYW4gQXBsaWNhdGlvbiB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi53cmFwU3luYyh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqIGF3YWl0IGFwcC5jbG9zZSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3cmFwLWFwcGxpY2F0aW9uLXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgX2NyZWF0ZShhcHBPcHRpb25zKSB7XG5cdCAgICAgICAgLy8gc2V0IGRlZmF1bHRzOlxuXHQgICAgICAgIGlmIChhcHBPcHRpb25zLndhaXRGb3JQYWdlTG9hZCA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIGFwcE9wdGlvbnMud2FpdEZvclBhZ2VMb2FkID0gZmFsc2U7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhcHBPcHRpb25zLmF1dG9TaG93ID09PSB1bmRlZmluZWQgJiYgYXBwT3B0aW9ucy5pc1BsYXRmb3JtQ29udHJvbGxlciA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIGFwcE9wdGlvbnMuYXV0b1Nob3cgPSB0cnVlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLWFwcGxpY2F0aW9uJywgYXBwT3B0aW9ucyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQ6IGFwcE9wdGlvbnMudXVpZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogREVQUkVDQVRFRCBtZXRob2QgdG8gY3JlYXRlIGEgbmV3IEFwcGxpY2F0aW9uLiBVc2Uge0BsaW5rIEFwcGxpY2F0aW9uLkFwcGxpY2F0aW9uTW9kdWxlLnN0YXJ0IEFwcGxpY2F0aW9uLnN0YXJ0fSBpbnN0ZWFkLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uY3JlYXRlKHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0zJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLUFwcGxpY2F0aW9uLmNyZWF0ZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBhd2FpdCBhcHAucnVuKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogY3JlYXRlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gaXMgY3JlYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblx0ICAgIGNyZWF0ZShhcHBPcHRpb25zKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiBXYXJuaW5nOiBmaW4uQXBwbGljYXRpb24uY3JlYXRlIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgZmluLkFwcGxpY2F0aW9uLnN0YXJ0Jyk7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLWNyZWF0ZScpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9jcmVhdGUoYXBwT3B0aW9ucyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYW5kIHN0YXJ0cyBhIG5ldyBBcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzdGFydCgpIHtcblx0ICAgICAqICAgICByZXR1cm4gZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLUFwcGxpY2F0aW9uLnN0YXJ0Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogfVxuXHQgICAgICogc3RhcnQoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiBpcyBydW5uaW5nJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc3RhcnQoYXBwT3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzdGFydC1hcHBsaWNhdGlvbicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGFwcCA9IGF3YWl0IHRoaXMuX2NyZWF0ZShhcHBPcHRpb25zKTtcblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncnVuLWFwcGxpY2F0aW9uJywgeyB1dWlkOiBhcHBPcHRpb25zLnV1aWQgfSk7XG5cdCAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQXN5bmNocm9ub3VzbHkgc3RhcnRzIGEgYmF0Y2ggb2YgYXBwbGljYXRpb25zIGdpdmVuIGFuIGFycmF5IG9mIGFwcGxpY2F0aW9uIGlkZW50aWZpZXJzIGFuZCBtYW5pZmVzdFVybHMuXG5cdCAgICAgKiBSZXR1cm5zIG9uY2UgdGhlIFJWTSBpcyBmaW5pc2hlZCBhdHRlbXB0aW5nIHRvIGxhdW5jaCB0aGUgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIG9wdHMgLSBQYXJhbWV0ZXJzIHRoYXQgdGhlIFJWTSB3aWxsIHVzZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKlxuXHQgICAgICogY29uc3QgYXBwbGljYXRpb25JbmZvQXJyYXkgPSBbXG5cdCAgICAgKiAgICAge1xuXHQgICAgICogICAgICAgICBcInV1aWRcIjogJ0FwcC0xJyxcblx0ICAgICAqICAgICAgICAgXCJtYW5pZmVzdFVybFwiOiAnaHR0cDovL2xvY2FsaG9zdDo1NTU1L2FwcDEuanNvbicsXG5cdCAgICAgKiAgICAgfSxcblx0ICAgICAqICAgICB7XG5cdCAgICAgKiAgICAgICAgIFwidXVpZFwiOiAnQXBwLTInLFxuXHQgICAgICogICAgICAgICBcIm1hbmlmZXN0VXJsXCI6ICdodHRwOi8vbG9jYWxob3N0OjU1NTUvYXBwMi5qc29uJyxcblx0ICAgICAqICAgICB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgXCJ1dWlkXCI6ICdBcHAtMycsXG5cdCAgICAgKiAgICAgICAgIFwibWFuaWZlc3RVcmxcIjogJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAzLmpzb24nLFxuXHQgICAgICogICAgIH1cblx0ICAgICAqIF1cblx0ICAgICAqXG5cdCAgICAgKiBmaW4uQXBwbGljYXRpb24uc3RhcnRNYW55TWFuaWZlc3RzKGFwcGxpY2F0aW9uSW5mb0FycmF5KVxuXHQgICAgICogICAgIC50aGVuKCgpID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1JWTSBoYXMgZmluaXNoZWQgbGF1bmNoaW5nIHRoZSBhcHBsaWNhdGlvbiBsaXN0LicpO1xuXHQgICAgICogICAgIH0pXG5cdCAgICAgKiAgICAgLmNhdGNoKChlcnIpID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzdGFydE1hbnlNYW5pZmVzdHMoYXBwbGljYXRpb25zLCBvcHRzKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdydW4tYXBwbGljYXRpb25zJywgeyBhcHBsaWNhdGlvbnMsIG9wdHMgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFwcGxpY2F0aW9uIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgYXBwbGljYXRpb25cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc0N1cnJlbnRBcHBSdW5uaW5nICgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuaXNSdW5uaW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNDdXJyZW50QXBwUnVubmluZygpLnRoZW4ocnVubmluZyA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coYEN1cnJlbnQgYXBwIGlzIHJ1bm5pbmc6ICR7cnVubmluZ31gKTtcblx0ICAgICAqIH0pLmNhdGNoKGVyciA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuXHQgICAgICogfSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnQoKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jdXJyZW50LWFwcGxpY2F0aW9uJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQ6IHRoaXMud2lyZS5tZS51dWlkIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQXBwbGljYXRpb24gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBhcHBsaWNhdGlvblxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGlzQ3VycmVudEFwcFJ1bm5pbmcgKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuaXNSdW5uaW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNDdXJyZW50QXBwUnVubmluZygpLnRoZW4ocnVubmluZyA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coYEN1cnJlbnQgYXBwIGlzIHJ1bm5pbmc6ICR7cnVubmluZ31gKTtcblx0ICAgICAqIH0pLmNhdGNoKGVyciA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuXHQgICAgICogfSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY3VycmVudC1hcHBsaWNhdGlvbi1zeW5jJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcFN5bmMoeyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3QgYW5kIHJldHVybnMgYSBydW5uaW5nIGluc3RhbmNlIG9mIHRoZSBhcHBsaWNhdGlvbi5cblx0ICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgYXBwJ3MgbWFuaWZlc3QuXG5cdCAgICAgKiBAcGFyYW0gb3B0cyAtIFBhcmFtZXRlcnMgdGhhdCB0aGUgUlZNIHdpbGwgdXNlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5BcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdCgnaHR0cDovL2xvY2FsaG9zdDo1NTU1L2FwcC5qc29uJykudGhlbihhcHAgPT4gY29uc29sZS5sb2coJ0FwcCBpcyBydW5uaW5nJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBGb3IgYSBsb2NhbCBtYW5pZmVzdCBmaWxlOlxuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLnN0YXJ0RnJvbU1hbmlmZXN0KCdmaWxlOi8vL0M6L3NvbWVmb2xkZXIvYXBwLmpzb24nKS50aGVuKGFwcCA9PiBjb25zb2xlLmxvZygnQXBwIGlzIHJ1bm5pbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHN0YXJ0RnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsLCBvcHRzKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLXN0YXJ0LWZyb20tbWFuaWZlc3QnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLl9jcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpO1xuXHQgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSBtZXRob2Qgd2l0aG91dCB3YXJuaW5nLlxuXHQgICAgICAgIGF3YWl0IGFwcC5fcnVuKG9wdHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBBcHBsaWNhdGlvbi5BcHBsaWNhdGlvbk1vZHVsZS5zdGFydEZyb21NYW5pZmVzdCBBcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdH0gaW5zdGVhZC5cblx0ICAgICAqIFJldHJpZXZlcyBhcHBsaWNhdGlvbidzIG1hbmlmZXN0IGFuZCByZXR1cm5zIGEgd3JhcHBlZCBhcHBsaWNhdGlvbi5cblx0ICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgYXBwJ3MgbWFuaWZlc3QuXG5cdCAgICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBjYWxsZWQgaWYgdGhlIG1ldGhvZCBzdWNjZWVkcy5cblx0ICAgICAqIEBwYXJhbSBlcnJvckNhbGxiYWNrIC0gY2FsbGVkIGlmIHRoZSBtZXRob2QgZmFpbHMuIFRoZSByZWFzb24gZm9yIGZhaWx1cmUgaXMgcGFzc2VkIGFzIGFuIGFyZ3VtZW50LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5BcHBsaWNhdGlvbi5jcmVhdGVGcm9tTWFuaWZlc3QoJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAuanNvbicpLnRoZW4oYXBwID0+IGNvbnNvbGUubG9nKGFwcCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICBjcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ0RlcHJlY2F0aW9uIFdhcm5pbmc6IGZpbi5BcHBsaWNhdGlvbi5jcmVhdGVGcm9tTWFuaWZlc3QgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBmaW4uQXBwbGljYXRpb24uc3RhcnRGcm9tTWFuaWZlc3QnKTtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tY3JlYXRlLWZyb20tbWFuaWZlc3QnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlRnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsKTtcblx0ICAgIH1cblx0ICAgIF9jcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdnZXQtYXBwbGljYXRpb24tbWFuaWZlc3QnLCB7IG1hbmlmZXN0VXJsIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB1dWlkID0gcGF5bG9hZC5kYXRhLnBsYXRmb3JtID8gcGF5bG9hZC5kYXRhLnBsYXRmb3JtLnV1aWQgOiBwYXlsb2FkLmRhdGEuc3RhcnR1cF9hcHAudXVpZDtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQgfSk7XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKGFwcCkgPT4ge1xuXHQgICAgICAgICAgICBhcHAuX21hbmlmZXN0VXJsID0gbWFuaWZlc3RVcmw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZXJzY29yZS1kYW5nbGVcblx0ICAgICAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0fVxuXHRGYWN0b3J5JDcuQXBwbGljYXRpb25Nb2R1bGUgPSBBcHBsaWNhdGlvbk1vZHVsZTtcblx0cmV0dXJuIEZhY3RvcnkkNztcbn1cblxudmFyIGhhc1JlcXVpcmVkQXBwbGljYXRpb247XG5cbmZ1bmN0aW9uIHJlcXVpcmVBcHBsaWNhdGlvbiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEFwcGxpY2F0aW9uKSByZXR1cm4gYXBwbGljYXRpb247XG5cdGhhc1JlcXVpcmVkQXBwbGljYXRpb24gPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHRcdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHRcdCAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG5cdFx0ICAgIH1cblx0XHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0XHR9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICBvW2syXSA9IG1ba107XG5cdFx0fSkpO1xuXHRcdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdFx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0XHR9O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludHMgZm9yIHRoZSBPcGVuRmluIGBBcHBsaWNhdGlvbmAgQVBJIChgZmluLkFwcGxpY2F0aW9uYCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBBcHBsaWNhdGlvbk1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBBcHBsaWNhdGlvbmAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5BcHBsaWNhdGlvbmAuXG5cdFx0ICogKiB7QGxpbmsgQXBwbGljYXRpb259IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIEFwcGxpY2F0aW9uLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudGAuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdFx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQyKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UkMSgpLCBleHBvcnRzKTsgXG5cdH0gKGFwcGxpY2F0aW9uKSk7XG5cdHJldHVybiBhcHBsaWNhdGlvbjtcbn1cblxudmFyIHByb21pc2lmeVN1YnNjcmlwdGlvbiQxID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9taXNpZnlTdWJzY3JpcHRpb24kMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5wcm9taXNpZnlTdWJzY3JpcHRpb24kMS5wcm9taXNpZnlTdWJzY3JpcHRpb24gPSB2b2lkIDA7XG5jb25zdCBwcm9taXNpZnlTdWJzY3JpcHRpb24gPSBhc3luYyAoZW1pdHRlciwgZXZlbnROYW1lLCBwcmVkaWNhdGUgPSAoKSA9PiB0cnVlLCB0aW1lb3V0KSA9PiB7XG4gICAgbGV0IHJlc29sdmU7XG4gICAgbGV0IHJlamVjdDtcbiAgICBsZXQgdGltZXI7XG4gICAgY29uc3QgdmFsdWVQcm9taXNlID0gbmV3IFByb21pc2UoKHksIG4pID0+IHtcbiAgICAgICAgcmVzb2x2ZSA9IHk7XG4gICAgICAgIHJlamVjdCA9IG47XG4gICAgfSk7XG4gICAgY29uc3QgbGlzdGVuZXIgPSAoZSkgPT4ge1xuICAgICAgICBpZiAocHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZShlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgYXdhaXQgZW1pdHRlci5vbihldmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignZXZlbnQgdGltZWQgb3V0JykpLCB0aW1lb3V0KTtcbiAgICB9XG4gICAgdmFsdWVQcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpLmNhdGNoKCgpID0+IG51bGwpO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldFZhbHVlOiAoKSA9PiB2YWx1ZVByb21pc2VcbiAgICB9O1xufTtcbnByb21pc2lmeVN1YnNjcmlwdGlvbiQxLnByb21pc2lmeVN1YnNjcmlwdGlvbiA9IHByb21pc2lmeVN1YnNjcmlwdGlvbjtcblxudmFyIGhhc1JlcXVpcmVkSW5zdGFuY2U7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEluc3RhbmNlKSByZXR1cm4gSW5zdGFuY2UkNztcblx0aGFzUmVxdWlyZWRJbnN0YW5jZSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSQ3LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW5zdGFuY2UkNy5fV2luZG93ID0gdm9pZCAwO1xuXHQvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5cdC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuXHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5cdC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblx0Y29uc3QgYXBwbGljYXRpb25fMSA9IHJlcXVpcmVBcHBsaWNhdGlvbigpO1xuXHRjb25zdCBtYWluXzEgPSBtYWluO1xuXHRjb25zdCB2aWV3XzEgPSByZXF1aXJlVmlldygpO1xuXHRjb25zdCB3YXJuaW5nc18xID0gd2FybmluZ3M7XG5cdGNvbnN0IHByb21pc2lmeVN1YnNjcmlwdGlvbl8xID0gcHJvbWlzaWZ5U3Vic2NyaXB0aW9uJDE7XG5cdC8qKlxuXHQgKiBBIGJhc2ljIHdpbmRvdyB0aGF0IHdyYXBzIGEgbmF0aXZlIEhUTUwgd2luZG93LiBQcm92aWRlcyBtb3JlIGZpbmUtZ3JhaW5lZFxuXHQgKiBjb250cm9sIG92ZXIgdGhlIHdpbmRvdyBzdGF0ZSBzdWNoIGFzIHRoZSBhYmlsaXR5IHRvIG1pbmltaXplLCBtYXhpbWl6ZSwgcmVzdG9yZSwgZXRjLlxuXHQgKiBCeSBkZWZhdWx0IGEgd2luZG93IGRvZXMgbm90IHNob3cgdXBvbiBpbnN0YW50aWF0aW9uOyBpbnN0ZWFkIHRoZSB3aW5kb3cncyBzaG93KCkgbWV0aG9kXG5cdCAqIG11c3QgYmUgaW52b2tlZCBtYW51YWxseS4gVGhlIG5ldyB3aW5kb3cgYXBwZWFycyBpbiB0aGUgc2FtZSBwcm9jZXNzIGFzIHRoZSBwYXJlbnQgd2luZG93LlxuXHQgKiBJdCBoYXMgdGhlIGFiaWxpdHkgdG8gbGlzdGVuIGZvciB7QGxpbmsgT3BlbkZpbi5XaW5kb3dFdmVudHMgd2luZG93IHNwZWNpZmljIGV2ZW50c30uXG5cdCAqL1xuXHQvLyBUaGUgd2luZG93LldpbmRvdyBuYW1lIGlzIHRha2VuXG5cdGNsYXNzIF9XaW5kb3cgZXh0ZW5kcyBtYWluXzEuV2ViQ29udGVudHMge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCBpZGVudGl0eSwgJ3dpbmRvdycpO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgY3JlYXRlV2luZG93KG9wdGlvbnMpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWNyZWF0ZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBDT05TVFJVQ1RPUl9DQl9UT1BJQyA9ICdmaXJlLWNvbnN0cnVjdG9yLWNhbGxiYWNrJztcblx0ICAgICAgICBjb25zdCByZXNwb25zZVN1YnNjcmlwdGlvbiA9IGF3YWl0ICgwLCBwcm9taXNpZnlTdWJzY3JpcHRpb25fMS5wcm9taXNpZnlTdWJzY3JpcHRpb24pKHRoaXMsIENPTlNUUlVDVE9SX0NCX1RPUElDKTtcblx0ICAgICAgICAvLyBzZXQgZGVmYXVsdHM6XG5cdCAgICAgICAgaWYgKG9wdGlvbnMud2FpdEZvclBhZ2VMb2FkID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgb3B0aW9ucy53YWl0Rm9yUGFnZUxvYWQgPSBmYWxzZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKG9wdGlvbnMuYXV0b1Nob3cgPT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICBvcHRpb25zLmF1dG9TaG93ID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgKDAsIHdhcm5pbmdzXzEuaGFuZGxlRGVwcmVjYXRlZFdhcm5pbmdzKShvcHRpb25zKTtcblx0ICAgICAgICBjb25zdCB3aW5kb3dDcmVhdGlvbiA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5jcmVhdGVDaGlsZENvbnRlbnQoeyBlbnRpdHlUeXBlOiAnd2luZG93Jywgb3B0aW9ucyB9KTtcblx0ICAgICAgICBjb25zdCBbcmVzcG9uc2VdID0gYXdhaXQgUHJvbWlzZS5hbGwoW3Jlc3BvbnNlU3Vic2NyaXB0aW9uLmdldFZhbHVlKCksIHdpbmRvd0NyZWF0aW9uXSk7XG5cdCAgICAgICAgbGV0IGNiUGF5bG9hZDtcblx0ICAgICAgICBjb25zdCB7IHN1Y2Nlc3MgfSA9IHJlc3BvbnNlO1xuXHQgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHJlc3BvbnNlLmRhdGE7XG5cdCAgICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSByZXNwb25zZURhdGE7XG5cdCAgICAgICAgaWYgKHN1Y2Nlc3MpIHtcblx0ICAgICAgICAgICAgY2JQYXlsb2FkID0ge1xuXHQgICAgICAgICAgICAgICAgaHR0cFJlc3BvbnNlQ29kZTogcmVzcG9uc2VEYXRhLmh0dHBSZXNwb25zZUNvZGUsXG5cdCAgICAgICAgICAgICAgICBhcGlJbmplY3RlZDogcmVzcG9uc2VEYXRhLmFwaUluamVjdGVkXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICBjYlBheWxvYWQgPSB7XG5cdCAgICAgICAgICAgICAgICBtZXNzYWdlOiByZXNwb25zZURhdGEubWVzc2FnZSxcblx0ICAgICAgICAgICAgICAgIG5ldHdvcmtFcnJvckNvZGU6IHJlc3BvbnNlRGF0YS5uZXR3b3JrRXJyb3JDb2RlLFxuXHQgICAgICAgICAgICAgICAgc3RhY2s6IHJlc3BvbnNlRGF0YS5zdGFja1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCBwYWdlUmVzb2x2ZSA9IHtcblx0ICAgICAgICAgICAgbWVzc2FnZSxcblx0ICAgICAgICAgICAgY2JQYXlsb2FkLFxuXHQgICAgICAgICAgICBzdWNjZXNzXG5cdCAgICAgICAgfTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIGVuZm9yY2UgYSA1LjAgY29udHJhY3QgdGhhdCB0aGUgY2hpbGQncyBtYWluIGZ1bmN0aW9uXG5cdCAgICAgICAgICAgIC8vIHdpbGwgbm90IGZpcmUgYmVmb3JlIHRoZSBwYXJlbnQncyBzdWNjZXNzIGNhbGxiYWNrIG9uIGNyZWF0aW9uLlxuXHQgICAgICAgICAgICAvLyBpZiB0aGUgY2hpbGQgd2luZG93IGlzIG5vdCBhY2Nlc3NpYmxlIChDT1JTKSB0aGlzIGNvbnRyYWN0IGRvZXNcblx0ICAgICAgICAgICAgLy8gbm90IGhvbGQuXG5cdCAgICAgICAgICAgIGNvbnN0IHdlYldpbmRvdyA9IHRoaXMuZ2V0V2ViV2luZG93KCk7XG5cdCAgICAgICAgICAgIHdlYldpbmRvdy5maW4uX19pbnRlcm5hbF8ub3BlbmVyU3VjY2Vzc0NCQ2FsbGVkKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgIC8vIGNvbW1vbiBmb3IgbWFpbiB3aW5kb3dzLCB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvci4gaGVyZSBqdXN0IHRvIGhhdmUgYSBkZWJ1ZyB0YXJnZXQuXG5cdCAgICAgICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChwYWdlUmVzb2x2ZS5zdWNjZXNzKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QocGFnZVJlc29sdmUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2YgZnJhbWUgaW5mbyBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgbWFpbiBmcmFtZSBhbmQgYW55XG5cdCAgICAgKiBpZnJhbWVzIHRoYXQgYXJlIGN1cnJlbnRseSBvbiB0aGUgcGFnZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldEFsbEZyYW1lcygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmdldEFsbEZyYW1lcy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRBbGxGcmFtZXMoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRBbGxGcmFtZXMoKS50aGVuKGZyYW1lc0luZm8gPT4gY29uc29sZS5sb2coZnJhbWVzSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRBbGxGcmFtZXMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWZyYW1lcycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGJvdW5kcyAodG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Qm91bmRzKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMycsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0Qm91bmRzLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldEJvdW5kcygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldEJvdW5kcygpLnRoZW4oYm91bmRzID0+IGNvbnNvbGUubG9nKGJvdW5kcykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRCb3VuZHMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignZ2V0LXdpbmRvdy1ib3VuZHMnLCB0aGlzLmlkZW50aXR5KVxuXHQgICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENlbnRlcnMgdGhlIHdpbmRvdyBvbiBpdHMgY3VycmVudCBzY3JlZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgRG9lcyBub3QgaGF2ZSBhbiBlZmZlY3Qgb24gbWluaW1pemVkIG9yIG1heGltaXplZCB3aW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY2VudGVyV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuY2VudGVyLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmNlbnRlcigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGNlbnRlcldpbmRvdygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBjZW50ZXJlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIGNlbnRlcigpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NlbnRlci13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlbW92ZXMgZm9jdXMgZnJvbSB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gYmx1cldpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmJsdXIuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uYmx1cigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGJsdXJXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdCbHVyZWQgV2luZG93JykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBibHVyKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignYmx1ci13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEJyaW5ncyB0aGUgd2luZG93IHRvIHRoZSBmcm9udCBvZiB0aGUgd2luZG93IHN0YWNrLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gQnJpbmdXaW5kb3dUb0Zyb250KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuYnJpbmdUb0Zyb250Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmJyaW5nVG9Gcm9udCgpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIEJyaW5nV2luZG93VG9Gcm9udCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBpcyBpbiB0aGUgZnJvbnQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGJyaW5nVG9Gcm9udCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2JyaW5nLXdpbmRvdy10by1mcm9udCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUGVyZm9ybXMgdGhlIHNwZWNpZmllZCB3aW5kb3cgdHJhbnNpdGlvbnMuXG5cdCAgICAgKiBAcGFyYW0gdHJhbnNpdGlvbnMgLSBEZXNjcmliZXMgdGhlIGFuaW1hdGlvbnMgdG8gcGVyZm9ybS4gU2VlIHRoZSB0dXRvcmlhbC5cblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIGFuaW1hdGlvbi4gU2VlIHRoZSB0dXRvcmlhbC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBgXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBhbmltYXRlV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHRyYW5zaXRpb25zID0ge1xuXHQgICAgICogICAgICAgICBvcGFjaXR5OiB7XG5cdCAgICAgKiAgICAgICAgICAgICBvcGFjaXR5OiAwLjcsXG5cdCAgICAgKiAgICAgICAgICAgICBkdXJhdGlvbjogNTAwXG5cdCAgICAgKiAgICAgICAgIH0sXG5cdCAgICAgKiAgICAgICAgIHBvc2l0aW9uOiB7XG5cdCAgICAgKiAgICAgICAgICAgICB0b3A6IDEwMCxcblx0ICAgICAqICAgICAgICAgICAgIGxlZnQ6IDEwMCxcblx0ICAgICAqICAgICAgICAgICAgIGR1cmF0aW9uOiA1MDAsXG5cdCAgICAgKiAgICAgICAgICAgICByZWxhdGl2ZTogdHJ1ZVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqICAgICBjb25zdCBvcHRpb25zID0ge1xuXHQgICAgICogICAgICAgICBpbnRlcnJ1cHQ6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIHR3ZWVuOiAnZWFzZS1pbidcblx0ICAgICAqICAgICB9O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gd2luLmFuaW1hdGUodHJhbnNpdGlvbnMsIG9wdGlvbnMpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFuaW1hdGVXaW5kb3coKVxuXHQgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBbmltYXRpb24gZG9uZScpKVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhbmltYXRlKHRyYW5zaXRpb25zLCBvcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignYW5pbWF0ZS13aW5kb3cnLCB7XG5cdCAgICAgICAgICAgIHRyYW5zaXRpb25zLFxuXHQgICAgICAgICAgICBvcHRpb25zLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSGlkZXMgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGhpZGVXaW5kb3coKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5oaWRlLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmhpZGUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBoaWRlV2luZG93KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnV2luZG93IGlzIGhpZGRlbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgaGlkZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hpZGUtd2luZG93JywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBjbG9zZXMgdGhlIHdpbmRvdyBhcHBsaWNhdGlvblxuXHQgICAgICogQHBhcmFtIGZvcmNlIENsb3NlIHdpbGwgYmUgcHJldmVudGVkIGZyb20gY2xvc2luZyB3aGVuIGZvcmNlIGlzIGZhbHNlIGFuZFxuXHQgICAgICogIOKAmGNsb3NlLXJlcXVlc3RlZOKAmSBoYXMgYmVlbiBzdWJzY3JpYmVkIHRvIGZvciBhcHBsaWNhdGlvbuKAmXMgbWFpbiB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjbG9zZVdpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTMnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmNsb3NlLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmNsb3NlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogY2xvc2VXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgY2xvc2VkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBjbG9zZShmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbG9zZS13aW5kb3cnLCB7IGZvcmNlLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4ge1xuXHQgICAgICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbnVsbCk7XG5cdCAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBmb2N1c2VkV2ViVmlld1dhc0NoYW5nZWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmb2N1c2VkLXdlYnZpZXctY2hhbmdlZCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyB0aGUgbmF0aXZlIE9TIGxldmVsIElkLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIEluIFdpbmRvd3MsIGl0IHdpbGwgcmV0dXJuIHRoZSBXaW5kb3dzIFtoYW5kbGVdKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3dpbmRvd3MvZGVza3RvcC9XaW5Qcm9nL3dpbmRvd3MtZGF0YS10eXBlcyNIV05EKS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFdpbmRvd05hdGl2ZUlkKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMycsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0TmF0aXZlSWQuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZ2V0TmF0aXZlSWQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3dOYXRpdmVJZCgpLnRoZW4obmF0aXZlSWQgPT4gY29uc29sZS5sb2cobmF0aXZlSWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0TmF0aXZlSWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LW5hdGl2ZS1pZCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgd2luZG93J3MgYXR0YWNoZWQgdmlld3MuXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKlxuXHQgICAgICogd2luLmdldEN1cnJlbnRWaWV3cygpXG5cdCAgICAgKiAgIC50aGVuKHZpZXdzID0+IGNvbnNvbGUubG9nKHZpZXdzKSlcblx0ICAgICAqICAgLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEN1cnJlbnRWaWV3cygpIHtcblx0ICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZ2V0LXZpZXdzJywgdGhpcy5pZGVudGl0eSk7XG5cdCAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YS5tYXAoKGlkKSA9PiBuZXcgdmlld18xLlZpZXcodGhpcy53aXJlLCBpZCkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFdpbmRvdy5fV2luZG93LmRpc2FibGVVc2VyTW92ZW1lbnR9IGluc3RlYWQuXG5cdCAgICAgKi9cblx0ICAgIGRpc2FibGVGcmFtZSgpIHtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ0Z1bmN0aW9uIGlzIGRlcHJlY2F0ZWQ7IHVzZSBkaXNhYmxlVXNlck1vdmVtZW50IGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdkaXNhYmxlLXdpbmRvdy1mcmFtZScsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJldmVudHMgYSB1c2VyIGZyb20gY2hhbmdpbmcgYSB3aW5kb3cncyBzaXplL3Bvc2l0aW9uIHdoZW4gdXNpbmcgdGhlIHdpbmRvdydzIGZyYW1lLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZGlzYWJsZVVzZXJNb3ZlbWVudCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTMnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmRpc2FibGVGcmFtZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5kaXNhYmxlVXNlck1vdmVtZW50KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZGlzYWJsZVVzZXJNb3ZlbWVudCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBpcyBkaXNhYmxlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZGlzYWJsZVVzZXJNb3ZlbWVudCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rpc2FibGUtd2luZG93LWZyYW1lJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFdpbmRvdy5fV2luZG93LmVuYWJsZVVzZXJNb3ZlbWVudH0gaW5zdGVhZC5cblx0ICAgICAqL1xuXHQgICAgZW5hYmxlRnJhbWUoKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdGdW5jdGlvbiBpcyBkZXByZWNhdGVkOyB1c2UgZW5hYmxlVXNlck1vdmVtZW50IGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdlbmFibGUtd2luZG93LWZyYW1lJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZS1lbmFibGVzIHVzZXIgY2hhbmdlcyB0byBhIHdpbmRvdydzIHNpemUvcG9zaXRpb24gd2hlbiB1c2luZyB0aGUgd2luZG93J3MgZnJhbWUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBlbmFibGVVc2VyTW92ZW1lbnQoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0zJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5lbmFibGVGcmFtZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5lbmFibGVVc2VyTW92ZW1lbnQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBlbmFibGVVc2VyTW92ZW1lbnQoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgaXMgZW5hYmxlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZW5hYmxlVXNlck1vdmVtZW50KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZW5hYmxlLXdpbmRvdy1mcmFtZScsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmxhc2hlcyB0aGUgd2luZG934oCZcyBmcmFtZSBhbmQgdGFza2JhciBpY29uIHVudGlsIHN0b3BGbGFzaGluZyBpcyBjYWxsZWQgb3IgdW50aWwgYSBmb2N1cyBldmVudCBpcyBmaXJlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBPbiBtYWNPUyBmbGFzaCBvbmx5IHdvcmtzIG9uIGluYWN0aXZlIHdpbmRvd3MuXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHdpbmRvd0ZsYXNoKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZmxhc2guaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZmxhc2goKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiB3aW5kb3dGbGFzaCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBmbGFzaGluZycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZmxhc2goKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmbGFzaC13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFN0b3BzIHRoZSB0YXNrYmFyIGljb24gZnJvbSBmbGFzaGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BXaW5kb3dGbGFzaGluZygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnN0b3BGbGFzaGluZy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zdG9wRmxhc2hpbmcoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzdG9wV2luZG93Rmxhc2hpbmcoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiB3aW5kb3cgZmxhc2hpbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHN0b3BGbGFzaGluZygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3N0b3AtZmxhc2gtd2luZG93JywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGFuIGluZm9ybWF0aW9uIG9iamVjdCBmb3IgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldEluZm8oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5nZXRJbmZvLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldEluZm8oKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRJbmZvKCkudGhlbihpbmZvID0+IGNvbnNvbGUubG9nKGluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mbygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC13aW5kb3ctaW5mbycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgdGhlIHdpbmRvdydzIExheW91dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogICAgIC8vZ2V0IHRoZSBjdXJyZW50IHdpbmRvd1xuXHQgICAgICogICAgIGNvbnN0IHdpbmRvdyA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAvL2dldCB0aGUgbGF5b3V0IGZvciB0aGUgd2luZG93XG5cdCAgICAgKiAgICAgY29uc3QgbGF5b3V0ID0gYXdhaXQgd2luZG93LmdldExheW91dCgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldExheW91dChsYXlvdXRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZ2V0LWxheW91dCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IG9wdHMgPSBhd2FpdCB0aGlzLmdldE9wdGlvbnMoKTtcblx0ICAgICAgICBpZiAoIW9wdHMubGF5b3V0ICYmICFvcHRzLmxheW91dFNuYXBzaG90KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2luZG93IGRvZXMgbm90IGhhdmUgYSBMYXlvdXQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuZmluLlBsYXRmb3JtLkxheW91dC53cmFwKGxheW91dElkZW50aXR5ID8/IHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHNldHRpbmdzIG9mIHRoZSB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRXaW5kb3dPcHRpb25zKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0T3B0aW9ucy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRPcHRpb25zKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZ2V0V2luZG93T3B0aW9ucygpLnRoZW4ob3B0cyA9PiBjb25zb2xlLmxvZyhvcHRzKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldE9wdGlvbnMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LW9wdGlvbnMnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgcGFyZW50IGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50QXBwbGljYXRpb24oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5nZXRQYXJlbnRBcHBsaWNhdGlvbi5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRQYXJlbnRBcHBsaWNhdGlvbigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldFBhcmVudEFwcGxpY2F0aW9uKCkudGhlbihwYXJlbnRBcHBsaWNhdGlvbiA9PiBjb25zb2xlLmxvZyhwYXJlbnRBcHBsaWNhdGlvbikpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRQYXJlbnRBcHBsaWNhdGlvbigpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWdldC1wYXJlbnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBhcHBsaWNhdGlvbl8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgdGhpcy5pZGVudGl0eSkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBwYXJlbnQgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50V2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0UGFyZW50V2luZG93Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldFBhcmVudFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldFBhcmVudFdpbmRvdygpLnRoZW4ocGFyZW50V2luZG93ID0+IGNvbnNvbGUubG9nKHBhcmVudFdpbmRvdykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRQYXJlbnRXaW5kb3coKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy1nZXQtcGFyZW50LXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IGFwcGxpY2F0aW9uXzEuQXBwbGljYXRpb24odGhpcy53aXJlLCB0aGlzLmlkZW50aXR5KSkudGhlbigoYXBwKSA9PiBhcHAuZ2V0V2luZG93KCkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiAqKipERVBSRUNBVEVEIC0gcGxlYXNlIHVzZSBXaW5kb3cuY2FwdHVyZVBhZ2UuKioqXG5cdCAgICAgKiBHZXRzIGEgYmFzZTY0IGVuY29kZWQgUE5HIGltYWdlIG9mIHRoZSB3aW5kb3cgb3IganVzdCBwYXJ0IGEgb2YgaXQuXG5cdCAgICAgKiBAcGFyYW0gYXJlYSBUaGUgYXJlYSBvZiB0aGUgd2luZG93IHRvIGJlIGNhcHR1cmVkLlxuXHQgICAgICogT21pdHRpbmcgaXQgd2lsbCBjYXB0dXJlIHRoZSB3aG9sZSB2aXNpYmxlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgV2luZG93LmNhcHR1cmVQYWdlXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldFNuYXBzaG90KGFyZWEpIHtcblx0ICAgICAgICBjb25zdCByZXEgPSB7IGFyZWEsIC4uLnRoaXMuaWRlbnRpdHkgfTtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ1dpbmRvdy5nZXRTbmFwc2hvdCBoYXMgYmVlbiBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIFdpbmRvdy5jYXB0dXJlUGFnZScpO1xuXHQgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LXNuYXBzaG90JywgcmVxKTtcblx0ICAgICAgICByZXR1cm4gcmVzLnBheWxvYWQuZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgY3VycmVudCBzdGF0ZSAoXCJtaW5pbWl6ZWRcIiwgXCJtYXhpbWl6ZWRcIiwgb3IgXCJub3JtYWxcIikgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFdpbmRvd1N0YXRlKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0U3RhdGUuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZ2V0U3RhdGUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3dTdGF0ZSgpLnRoZW4od2luU3RhdGUgPT4gY29uc29sZS5sb2cod2luU3RhdGUpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0U3RhdGUoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LXN0YXRlJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFByZXZpb3VzbHkgY2FsbGVkIGdldE5hdGl2ZVdpbmRvdy5cblx0ICAgICAqIFJldHVybnMgdGhlIFtXaW5kb3cgT2JqZWN0XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93KVxuXHQgICAgICogdGhhdCByZXByZXNlbnRzIHRoZSB3ZWIgY29udGV4dCBvZiB0aGUgdGFyZ2V0IHdpbmRvdy4gVGhpcyBpcyB0aGUgc2FtZSBvYmplY3QgdGhhdFxuXHQgICAgICogeW91IHdvdWxkIGdldCBmcm9tIGNhbGxpbmcgW3dpbmRvdy5vcGVuKCldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvb3BlbikgaW4gYSBzdGFuZGFyZCB3ZWIgY29udGV4dC5cblx0ICAgICAqIFRoZSB0YXJnZXQgd2luZG93IG5lZWRzIHRvIGJlIGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFzIHRoZSByZXF1ZXN0aW5nIHdpbmRvd1xuXHQgICAgICogYXMgd2VsbCBhcyBjb21wbHkgd2l0aCBbc2FtZS1vcmlnaW5dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL1NlY3VyaXR5L1NhbWUtb3JpZ2luX3BvbGljeSkgcG9saWN5IHJlcXVpcmVtZW50cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogSW5qZWN0aW5nIGNvbnRlbnQgaW50byBhbiBlbXB0eSB3aW5kb3c6XG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIChhc3luYyAoKT0+IHtcblx0ICAgICAqICAgICB0cnkge1xuXHQgICAgICogICAgICAgICBjb25zdCB3aW5OYW1lID0gYGNoaWxkLXdpbmRvdy0ke0RhdGUubm93KCl9YDtcblx0ICAgICAqICAgICAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUoe1xuXHQgICAgICogICAgICAgICAgICAgbmFtZTogd2luTmFtZSxcblx0ICAgICAqICAgICAgICAgICAgIHVybDogJ2Fib3V0OmJsYW5rJ1xuXHQgICAgICogICAgICAgICB9KTtcblx0ICAgICAqICAgICAgICAgd2luLmdldFdlYldpbmRvdygpLmRvY3VtZW50LndyaXRlKCc8aDE+SGVsbG8gV29ybGQ8L2gxPicpO1xuXHQgICAgICogICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSkoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIENsb25pbmcgRE9NIGVsZW1lbnRzIGZyb20gdGhlIHBhcmVudCB3aW5kb3cgKGluIHRoaXMgZXhhbXBsZSB3ZSBjbG9uZSBhbiBgaDNgIGVsZW1lbnQgZnJvbSB0aGUgcGFyZW50IHdpbmRvdyk6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogKGFzeW5jICgpPT4ge1xuXHQgICAgICogICAgIHRyeSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IGN1cnJlbnRXaW5kb3cgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICAgICAgY29uc3QgcGFyZW50V2luZG93ID0gYXdhaXQgY3VycmVudFdpbmRvdy5nZXRQYXJlbnRXaW5kb3coKTtcblx0ICAgICAqICAgICAgICAgY29uc3QgY2xvbmVkSDMgPSBwYXJlbnRXaW5kb3cuZ2V0V2ViV2luZG93KCkuZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaDMnKS5jbG9uZU5vZGUodHJ1ZSk7XG5cdCAgICAgKiAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKGNsb25lZEgzKTtcblx0ICAgICAqXG5cdCAgICAgKiAgICAgfSBjYXRjaCAoZXJyKSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogUmVuZGVyaW5nIG9uIGEgY2hpbGQgd2luZG93IHZpYSBhIGxpYnJhcnkgKGluIHRoaXMgZXhhbXBsZSB3ZSBhcmUgdXNpbmcgdGhlIFtsaXQtaHRtbF0oaHR0cHM6Ly9saXQtaHRtbC5wb2x5bWVyLXByb2plY3Qub3JnLylcblx0ICAgICAqIHRlbXBsYXRlIGxpYnJhcnkgdG8gcmVuZGVyIGNvbnRlbnQgb24gYSBibGFuayBjaGlsZCB3aW5kb3cuIFlvdSBhcmUgbm90IGdvaW5nIHRvIGJlIGFibGUgdG8gY29weSBwYXN0ZSB0aGlzIGV4YW1wbGUgd2l0aG91dFxuXHQgICAgICogY29uZmlndXJpbmcgdGhlIHByb2plY3QgY29ycmVjdGx5IGJ1dCB0aGlzIHdvdWxkIGRlbW9uc3RyYXRlIHNvbWUgdGVtcGxhdGluZyBvcHRpb25zIGF2YWlsYWJsZSk6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogKGFzeW5jICgpPT4ge1xuXHQgICAgICogICAgIHRyeSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHtcblx0ICAgICAqICAgICAgICAgICAgIG5hbWU6IGBjaGlsZC13aW5kb3ctJHtEYXRlLm5vdygpfWAsXG5cdCAgICAgKiAgICAgICAgICAgICB1cmw6ICdhYm91dDpibGFuaydcblx0ICAgICAqICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IHRlbXBsYXRlID0gaHRtbGBcblx0ICAgICAqICAgICAgICAgICAgIDxkaXY+XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgPHNwYW4+Q2xpY2sgaGVyZTogPC9zcGFuPlxuXHQgICAgICogICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPSR7KCk9PiBjb25zb2xlLmxvZygnSGVsbG8gV29ybGQhJyl9PmxvZyB0byB0aGUgY29uc29sZTwvYnV0dG9uPlxuXHQgICAgICogICAgICAgICAgICAgPC9kaXY+YDtcblx0ICAgICAqICAgICAgICAgcmVuZGVyKHRlbXBsYXRlLCB3aW4uZ2V0V2ViV2luZG93KCkuZG9jdW1lbnQuYm9keSk7XG5cdCAgICAgKlxuXHQgICAgICogICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSkoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRXZWJXaW5kb3coKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy1nZXQtd2ViLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0V2ViV2luZG93KHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB3aW5kb3cgaXMgYSBtYWluIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHduZCA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqIGNvbnN0IGlzTWFpblduZCA9IHduZC5pc01haW5XaW5kb3coKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKCdJcyB0aGlzIGEgbWFpbiB3aW5kb3c/ICcgKyBpc01haW5XbmQpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGlzTWFpbldpbmRvdygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWlzLW1haW4td2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMubWUudXVpZCA9PT0gdGhpcy5tZS5uYW1lO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IHNob3dpbmcuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc1dpbmRvd1Nob3dpbmcoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5pc1Nob3dpbmcuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uaXNTaG93aW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNXaW5kb3dTaG93aW5nKCkudGhlbihib29sID0+IGNvbnNvbGUubG9nKGJvb2wpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgaXNTaG93aW5nKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignaXMtd2luZG93LXNob3dpbmcnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTWF4aW1pemVzIHRoZSB3aW5kb3dcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIG1heFdpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93Lm1heGltaXplLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLm1heGltaXplKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogbWF4V2luZG93KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTWF4aW1pemVkIHdpbmRvdycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgbWF4aW1pemUoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdtYXhpbWl6ZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIE1pbmltaXplcyB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gbWluV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubWluaW1pemUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtaW5XaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdNaW5pbWl6ZWQgd2luZG93JykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBtaW5pbWl6ZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ21pbmltaXplLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTW92ZXMgdGhlIHdpbmRvdyBieSBhIHNwZWNpZmllZCBhbW91bnQuXG5cdCAgICAgKiBAcGFyYW0gZGVsdGFMZWZ0IFRoZSBjaGFuZ2UgaW4gdGhlIGxlZnQgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGRlbHRhVG9wIFRoZSBjaGFuZ2UgaW4gdGhlIHRvcCBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5tb3ZlQnkuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBtb3ZlQnkobGVmdCwgdG9wKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5tb3ZlQnkobGVmdCwgdG9wKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtb3ZlQnkoNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01vdmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBtb3ZlQnkoZGVsdGFMZWZ0LCBkZWx0YVRvcCwgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignbW92ZS13aW5kb3ctYnknLCB7XG5cdCAgICAgICAgICAgIGRlbHRhTGVmdCxcblx0ICAgICAgICAgICAgZGVsdGFUb3AsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIE1vdmVzIHRoZSB3aW5kb3cgdG8gYSBzcGVjaWZpZWQgbG9jYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gbGVmdCBUaGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG5cdCAgICAgKiBAcGFyYW0gdG9wIFRoZSB0b3AgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cubW92ZVRvLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gbW92ZVRvKGxlZnQsIHRvcCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubW92ZVRvKGxlZnQsIHRvcClcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtb3ZlVG8oNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01vdmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIG1vdmVUbyhsZWZ0LCB0b3AsIHBvc2l0aW9uaW5nT3B0aW9ucykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ21vdmUtd2luZG93Jywge1xuXHQgICAgICAgICAgICBsZWZ0LFxuXHQgICAgICAgICAgICB0b3AsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc2l6ZXMgdGhlIHdpbmRvdyBieSBhIHNwZWNpZmllZCBhbW91bnQuXG5cdCAgICAgKiBAcGFyYW0gZGVsdGFXaWR0aCBUaGUgY2hhbmdlIGluIHRoZSB3aWR0aCBvZiB0aGUgd2luZG93XG5cdCAgICAgKiBAcGFyYW0gZGVsdGFIZWlnaHQgVGhlIGNoYW5nZSBpbiB0aGUgaGVpZ2h0IG9mIHRoZSB3aW5kb3dcblx0ICAgICAqIEBwYXJhbSBhbmNob3IgU3BlY2lmaWVzIGEgY29ybmVyIHRvIHJlbWFpbiBmaXhlZCBkdXJpbmcgdGhlIHJlc2l6ZS5cblx0ICAgICAqIENhbiB0YWtlIHRoZSB2YWx1ZXM6IFwidG9wLWxlZnRcIiwgXCJ0b3AtcmlnaHRcIiwgXCJib3R0b20tbGVmdFwiLCBvciBcImJvdHRvbS1yaWdodFwiLlxuXHQgICAgICogSWYgdW5kZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyBcInRvcC1sZWZ0XCJcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnJlc2l6ZUJ5Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcmVzaXplQnkobGVmdCwgdG9wLCBhbmNob3IpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnJlc2l6ZUJ5KGxlZnQsIHRvcCwgYW5jaG9yKVxuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlc2l6ZUJ5KDU4MCwgMzAwLCAndG9wLXJpZ2h0JykudGhlbigoKSA9PiBjb25zb2xlLmxvZygnUmVzaXplZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVzaXplQnkoZGVsdGFXaWR0aCwgZGVsdGFIZWlnaHQsIGFuY2hvciwgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbigncmVzaXplLXdpbmRvdy1ieScsIHtcblx0ICAgICAgICAgICAgZGVsdGFXaWR0aDogTWF0aC5mbG9vcihkZWx0YVdpZHRoKSxcblx0ICAgICAgICAgICAgZGVsdGFIZWlnaHQ6IE1hdGguZmxvb3IoZGVsdGFIZWlnaHQpLFxuXHQgICAgICAgICAgICBhbmNob3IsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc2l6ZXMgdGhlIHdpbmRvdyB0byB0aGUgc3BlY2lmaWVkIGRpbWVuc2lvbnMuXG5cdCAgICAgKiBAcGFyYW0gd2lkdGggVGhlIGNoYW5nZSBpbiB0aGUgd2lkdGggb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGhlaWdodCBUaGUgY2hhbmdlIGluIHRoZSBoZWlnaHQgb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGFuY2hvciBTcGVjaWZpZXMgYSBjb3JuZXIgdG8gcmVtYWluIGZpeGVkIGR1cmluZyB0aGUgcmVzaXplLlxuXHQgICAgICogQ2FuIHRha2UgdGhlIHZhbHVlczogXCJ0b3AtbGVmdFwiLCBcInRvcC1yaWdodFwiLCBcImJvdHRvbS1sZWZ0XCIsIG9yIFwiYm90dG9tLXJpZ2h0XCIuXG5cdCAgICAgKiBJZiB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IGlzIFwidG9wLWxlZnRcIlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cucmVzaXplVG8uaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiByZXNpemVUbyhsZWZ0LCB0b3AsIGFuY2hvcikge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ucmVzaXplVG8obGVmdCwgdG9wLCBhbmNob3IpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlc2l6ZVRvKDU4MCwgMzAwLCAndG9wLWxlZnQnKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdSZXNpemVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICByZXNpemVUbyh3aWR0aCwgaGVpZ2h0LCBhbmNob3IsIHBvc2l0aW9uaW5nT3B0aW9ucykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3Jlc2l6ZS13aW5kb3cnLCB7XG5cdCAgICAgICAgICAgIHdpZHRoOiBNYXRoLmZsb29yKHdpZHRoKSxcblx0ICAgICAgICAgICAgaGVpZ2h0OiBNYXRoLmZsb29yKGhlaWdodCksXG5cdCAgICAgICAgICAgIGFuY2hvcixcblx0ICAgICAgICAgICAgcG9zaXRpb25pbmdPcHRpb25zLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzdG9yZXMgdGhlIHdpbmRvdyB0byBpdHMgbm9ybWFsIHN0YXRlIChpLmUuLCB1bm1pbmltaXplZCwgdW5tYXhpbWl6ZWQpLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cucmVzdG9yZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlc3RvcmUoKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5yZXN0b3JlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogcmVzdG9yZSgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Jlc3RvcmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICByZXN0b3JlKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVzdG9yZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFdpbGwgYnJpbmcgdGhlIHdpbmRvdyB0byB0aGUgZnJvbnQgb2YgdGhlIGVudGlyZSBzdGFjayBhbmQgZ2l2ZSBpdCBmb2N1cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnNldEFzRm9yZWdyb3VuZC5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldEFzRm9yZWdyb3VuZCgpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnNldEFzRm9yZWdyb3VuZCgpXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0QXNGb3JlZ3JvdW5kKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnSW4gdGhlIGZvcmVncm91bmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNldEFzRm9yZWdyb3VuZCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1mb3JlZ3JvdW5kLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyB0aGUgd2luZG93J3Mgc2l6ZSBhbmQgcG9zaXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5zZXRCb3VuZHMuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzZXRCb3VuZHMoYm91bmRzKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zZXRCb3VuZHMoYm91bmRzKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzZXRCb3VuZHMoe1xuXHQgICAgICogICAgIGhlaWdodDogMTAwLFxuXHQgICAgICogICAgIHdpZHRoOiAyMDAsXG5cdCAgICAgKiAgICAgdG9wOiA0MDAsXG5cdCAgICAgKiAgICAgbGVmdDogNDAwXG5cdCAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdCb3VuZHMgc2V0IHRvIHdpbmRvdycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgc2V0Qm91bmRzKGJvdW5kcywgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignc2V0LXdpbmRvdy1ib3VuZHMnLCB7IC4uLmJvdW5kcywgLi4udGhpcy5pZGVudGl0eSwgcG9zaXRpb25pbmdPcHRpb25zIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNob3dzIHRoZSB3aW5kb3cgaWYgaXQgaXMgaGlkZGVuLlxuXHQgICAgICogQHBhcmFtIGZvcmNlIFNob3cgd2lsbCBiZSBwcmV2ZW50ZWQgZnJvbSBzaG93aW5nIHdoZW4gZm9yY2UgaXMgZmFsc2UgYW5kXG5cdCAgICAgKiAg4oCYc2hvdy1yZXF1ZXN0ZWTigJkgaGFzIGJlZW4gc3Vic2NyaWJlZCB0byBmb3IgYXBwbGljYXRpb27igJlzIG1haW4gd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2hvdy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IGZhbHNlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzaG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc2hvdygpXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2hvdygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Nob3dpbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNob3coZm9yY2UgPSBmYWxzZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy13aW5kb3cnLCB7IGZvcmNlLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgdGhlIHdpbmRvdyBpZiBpdCBpcyBoaWRkZW4gYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gbGVmdCBUaGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgd2luZG93IGluIHBpeGVsc1xuXHQgICAgICogQHBhcmFtIHRvcCBUaGUgdG9wIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cgaW4gcGl4ZWxzXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgU2hvdyB3aWxsIGJlIHByZXZlbnRlZCBmcm9tIGNsb3Npbmcgd2hlbiBmb3JjZSBpcyBmYWxzZSBhbmRcblx0ICAgICAqIOKAmHNob3ctcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvd1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2hvd0F0Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd0F0KGxlZnQsIHRvcCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc2hvd0F0KGxlZnQsIHRvcClcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzaG93QXQoNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Nob3dpbmcgYXQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNob3dBdChsZWZ0LCB0b3AsIGZvcmNlID0gZmFsc2UpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdzaG93LWF0LXdpbmRvdycsIHtcblx0ICAgICAgICAgICAgZm9yY2UsXG5cdCAgICAgICAgICAgIGxlZnQ6IE1hdGguZmxvb3IobGVmdCksXG5cdCAgICAgICAgICAgIHRvcDogTWF0aC5mbG9vcih0b3ApLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29sc1xuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBXaW5kb3cuc2hvd0RldmVsb3BlclRvb2xzXG5cdCAgICAgKi9cblx0ICAgIC8qKlxuXHQgICAgICogVXBkYXRlcyB0aGUgd2luZG93IHVzaW5nIHRoZSBwYXNzZWQgb3B0aW9ucy5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBWYWx1ZXMgdGhhdCBhcmUgb2JqZWN0cyBhcmUgZGVlcC1tZXJnZWQsIG92ZXJ3cml0aW5nIG9ubHkgdGhlIHZhbHVlcyB0aGF0IGFyZSBwcm92aWRlZC5cblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIENoYW5nZXMgYSB3aW5kb3cncyBvcHRpb25zIHRoYXQgd2VyZSBkZWZpbmVkIHVwb24gY3JlYXRpb24uIFNlZSB0dXRvcmlhbFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gdXBkYXRlT3B0aW9ucygpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gd2luLnVwZGF0ZU9wdGlvbnMoe21heFdpZHRoOiAxMDB9KTtcblx0ICAgICAqIH1cblx0ICAgICAqIHVwZGF0ZU9wdGlvbnMoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdvcHRpb25zIGlzIHVwZGF0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgdXBkYXRlT3B0aW9ucyhvcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd1cGRhdGUtd2luZG93LW9wdGlvbnMnLCB7IG9wdGlvbnMsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBQcm92aWRlcyBjcmVkZW50aWFscyB0byBhdXRoZW50aWNhdGlvbiByZXF1ZXN0c1xuXHQgICAgICogQHBhcmFtIHVzZXJOYW1lIHVzZXJOYW1lIHRvIHByb3ZpZGUgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIGNoYWxsZW5nZVxuXHQgICAgICogQHBhcmFtIHBhc3N3b3JkIHBhc3N3b3JkIHRvIHByb3ZpZGUgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIGNoYWxsZW5nZVxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLndyYXAoe3V1aWQ6ICdPcGVuZmluUE9DJ30pLnRoZW4oYXBwID0+IHtcblx0ICAgICAqICAgICBhcHAub24oJ3dpbmRvdy1hdXRoLXJlcXVlc3RlZCcsIGV2dCA9PiB7XG5cdCAgICAgKiAgICAgICAgIGxldCB3aW4gPSBmaW4uV2luZG93LndyYXAoeyB1dWlkOiBldnQudXVpZCwgbmFtZTogZXZ0Lm5hbWV9KTtcblx0ICAgICAqICAgICAgICAgd2luLmF1dGhlbnRpY2F0ZSgndXNlck5hbWUnLCAnUEBhc3N3MHJkJykudGhlbigoKT0+IGNvbnNvbGUubG9nKCdhdXRoZW50aWNhdGVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGF1dGhlbnRpY2F0ZSh1c2VyTmFtZSwgcGFzc3dvcmQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCd3aW5kb3ctYXV0aGVudGljYXRlJywgeyB1c2VyTmFtZSwgcGFzc3dvcmQsIC4uLnRoaXMuaWRlbnRpdHkgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgYSBtZW51IG9uIHRoZSB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSB1c2VyIGhhcyBlaXRoZXIgc2VsZWN0ZWQgYW4gaXRlbSBvciBjbG9zZWQgdGhlIG1lbnUuIChUaGlzIG1heSB0YWtlIGxvbmdlciB0aGFuIG90aGVyIGFwaXMpLlxuXHQgICAgICogUmVzb2x2ZXMgdG8gYW4gb2JqZWN0IHdpdGggYHtyZXN1bHQ6ICdjbGlja2VkJywgZGF0YSB9YCB3aGVyZSBkYXRhIGlzIHRoZSBkYXRhIGZpZWxkIG9uIHRoZSBtZW51IGl0ZW0gY2xpY2tlZCwgb3IgYHtyZXN1bHQgJ2Nsb3NlZCd9YCB3aGVuIHRoZSB1c2VyIGRvZXNuJ3Qgc2VsZWN0IGFueXRoaW5nLlxuXHQgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aWxsIGNsb3NlIHByZXZpb3VzbHkgb3BlbmVkIG1lbnVzLlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICogQHBhcmFtIG9wdGlvbnNcblx0ICAgICAqIEB0eXBlUGFyYW0gRGF0YSBVc2VyLWRlZmluZWQgc2hhcGUgZm9yIGRhdGEgcmV0dXJuZWQgdXBvbiBtZW51IGl0ZW0gY2xpY2suICBTaG91bGQgYmUgYVxuXHQgICAgICogW3VuaW9uXShodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay8yL2V2ZXJ5ZGF5LXR5cGVzLmh0bWwjdW5pb24tdHlwZXMpXG5cdCAgICAgKiBvZiBhbGwgcG9zc2libGUgZGF0YSBzaGFwZXMgZm9yIHRoZSBlbnRpcmUgbWVudSwgYW5kIHRoZSBjbGljayBoYW5kbGVyIHNob3VsZCBwcm9jZXNzXG5cdCAgICAgKiB0aGVzZSB3aXRoIGEgXCJyZWR1Y2VyXCIgcGF0dGVybi5cblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gc2hvdyBhIGRyb3AgZG93biBtZW51IG92ZXIgdmlld3MgaW4gYSBwbGF0Zm9ybSB3aW5kb3c6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgdGVtcGxhdGUgPSBbXG5cdCAgICAgKiAgICAge1xuXHQgICAgICogICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgICAgICAgZGF0YTogJ2hlbGxvIGZyb20gaXRlbSAxJ1xuXHQgICAgICogICAgIH0sXG5cdCAgICAgKiAgICAgeyB0eXBlOiAnc2VwYXJhdG9yJyB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgbGFiZWw6ICdNZW51IEl0ZW0gMicsXG5cdCAgICAgKiAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICAgICAgIGNoZWNrZWQ6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIGRhdGE6ICdUaGUgdXNlciBjbGlja2VkIHRoZSBjaGVja2JveCdcblx0ICAgICAqICAgICB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgbGFiZWw6ICdzZWUgbW9yZScsXG5cdCAgICAgKiAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuXHQgICAgICogICAgICAgICBzdWJtZW51OiBbXG5cdCAgICAgKiAgICAgICAgICAgICB7IGxhYmVsOiAnc3VibWVudSAxJywgZGF0YTogJ2hlbGxvIGZyb20gc3VibWVudScgfVxuXHQgICAgICogICAgICAgICBdXG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogXVxuXHQgICAgICogZmluLm1lLnNob3dQb3B1cE1lbnUoeyB0ZW1wbGF0ZSB9KS50aGVuKHIgPT4ge1xuXHQgICAgICogICAgIGlmIChyLnJlc3VsdCA9PT0gJ2Nsb3NlZCcpIHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ25vdGhpbmcgaGFwcGVuZWQnKTtcblx0ICAgICAqICAgICB9IGVsc2Uge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZyhyLmRhdGEpXG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIE92ZXJyaWRpbmcgdGhlIGJ1aWx0IGluIGNvbnRleHQgbWVudSAobm90ZTogdGhhdCB0aGlzIGNhbiBiZSBkb25lIHBlciBlbGVtZW50IG9yIGRvY3VtZW50IHdpZGUpOlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZSA9PiB7XG5cdCAgICAgKiAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICogICAgIGNvbnN0IHRlbXBsYXRlID0gW1xuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgICAgICAgICAgIGRhdGE6ICdoZWxsbyBmcm9tIGl0ZW0gMSdcblx0ICAgICAqICAgICAgICAgfSxcblx0ICAgICAqICAgICAgICAgeyB0eXBlOiAnc2VwYXJhdG9yJyB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAyJyxcblx0ICAgICAqICAgICAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICAgICAgICAgICBjaGVja2VkOiB0cnVlLFxuXHQgICAgICogICAgICAgICAgICAgZGF0YTogJ1RoZSB1c2VyIGNsaWNrZWQgdGhlIGNoZWNrYm94J1xuXHQgICAgICogICAgICAgICB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ3NlZSBtb3JlJyxcblx0ICAgICAqICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuXHQgICAgICogICAgICAgICAgICAgc3VibWVudTogW1xuXHQgICAgICogICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdzdWJtZW51IDEnLCBkYXRhOiAnaGVsbG8gZnJvbSBzdWJtZW51JyB9XG5cdCAgICAgKiAgICAgICAgICAgICBdXG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICBdXG5cdCAgICAgKiAgICAgZmluLm1lLnNob3dQb3B1cE1lbnUoeyB0ZW1wbGF0ZSwgeDogZS54LCB5OiBlLnkgfSkudGhlbihyID0+IHtcblx0ICAgICAqICAgICAgICAgaWYgKHIucmVzdWx0ID09PSAnY2xvc2VkJykge1xuXHQgICAgICogICAgICAgICAgICAgY29uc29sZS5sb2coJ25vdGhpbmcgaGFwcGVuZWQnKTtcblx0ICAgICAqICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKHIuZGF0YSlcblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgIH0pXG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHNob3dQb3B1cE1lbnUob3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctcG9wdXAtbWVudScsIHsgb3B0aW9ucywgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDbG9zZXMgdGhlIHdpbmRvdydzIHBvcHVwIG1lbnUsIGlmIG9uZSBleGlzdHMuXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgT25seSBvbmUgcG9wdXAgbWVudSB3aWxsIGV2ZXIgYmUgc2hvd2luZyBhdCBhIHRpbWUuIENhbGxpbmcgYHNob3dQb3B1cE1lbnVgIHdpbGwgYXV0b21hdGljYWxseSBjbG9zZVxuXHQgICAgICogYW55IGV4aXN0aW5nIHBvcHVwIG1lbnUuXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gY2xvc2UgYSBwb3B1cCBtZW51IGlmIHRoZSB1c2VyJ3MgbW91c2UgbGVhdmVzIGFuIGVsZW1lbnQgZm9yIGV4YW1wbGUuXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5jbG9zZVBvcHVwTWVudSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGNsb3NlUG9wdXBNZW51KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xvc2UtcG9wdXAtbWVudScsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIERpc3BhdGNoIGEgcmVzdWx0IHRvIHRoZSBjYWxsZXIgb2YgYHNob3dQb3B1cFdpbmRvd2AuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSWYgdGhpcyB3aW5kb3cgaXNuJ3QgY3VycmVudGx5IGJlaW5nIHNob3duIGFzIGEgcG9wdXAsIHRoaXMgY2FsbCB3aWxsIHNpbGVudGx5IGZhaWwuXG5cdCAgICAgKiBAcGFyYW0gZGF0YSBTZXJpYWxpemFibGUgZGF0YSB0byBzZW5kIHRvIHRoZSBjYWxsZXIgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXdhaXQgZmluLm1lLmRpc3BhdGNoUG9wdXBSZXN1bHQoe1xuXHQgICAgICogICAgIGZvbzogJ2Jhcidcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGRpc3BhdGNoUG9wdXBSZXN1bHQoZGF0YSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZGlzcGF0Y2gtcG9wdXAtcmVzdWx0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rpc3BhdGNoLXBvcHVwLXJlc3VsdCcsIHsgZGF0YSwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJpbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBwcmludCB0YXNrLlxuXHQgICAgICogQHJlbWFya3MgV2hlbiBgc2lsZW50YCBpcyBzZXQgdG8gYHRydWVgLCB0aGUgQVBJIHdpbGwgcGljayB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBwcmludGVyIGlmIGRldmljZU5hbWUgaXMgZW1wdHlcblx0ICAgICAqIGFuZCB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgcHJpbnRpbmcuXG5cdCAgICAgKlxuXHQgICAgICogVXNlIHRoZSBDU1Mgc3R5bGUgYHBhZ2UtYnJlYWstYmVmb3JlOiBhbHdheXM7YCB0byBmb3JjZSBwcmludCB0byBhIG5ldyBwYWdlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICpcblx0ICAgICAqIHdpbi5wcmludCh7IHNpbGVudDogZmFsc2UsIGRldmljZU5hbWU6ICdzeXN0ZW0tcHJpbnRlci1uYW1lJyB9KS50aGVuKCgpID0+IHtcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygncHJpbnQgY2FsbCBoYXMgYmVlbiBzZW50IHRvIHRoZSBzeXN0ZW0nKTtcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogSWYgYSB3aW5kb3cgaGFzIGVtYmVkZGVkIHZpZXdzLCB0aG9zZSB2aWV3cyB3aWxsIG5vdCBwcmludCBieSBkZWZhdWx0LiAgVG8gcHJpbnQgYSB3aW5kb3cncyBjb250ZW50cyBpbmNsdWRpbmcgZW1iZWRkZWQgdmlld3MsXG5cdCAgICAgKiB1c2UgdGhlIGBjb250ZW50YCBvcHRpb246XG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBQcmludCBlbWJlZGRlZCB2aWV3c1xuXHQgICAgICogd2luLnByaW50KHsgY29udGVudDogJ3ZpZXdzJyB9KTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBQcmludCBzY3JlZW5zaG90IG9mIGN1cnJlbnQgd2luZG93XG5cdCAgICAgKiB3aW4ucHJpbnQoeyBjb250ZW50OiAnc2NyZWVuc2hvdCcgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIFdoZW4gYGNvbnRlbnRgIGlzIHNldCB0byBgdmlld3NgLCB0aGUgZW1iZWRkZWQgdmlld3MgaW4gdGhlIHBsYXRmb3JtIHdpbmRvdyB3aWxsIGJlIGNvbmNhdGVuYXRlZCBhbmQgcHJpbnRlZCBhc1xuXHQgICAgICogaW5kaXZpZHVhbCBwYWdlcy4gIElmIGBpbmNsdWRlU2VsZmAgaXMgc2V0IHRvIGB0cnVlYCwgdGhlIHBsYXRmb3JtIHdpbmRvdyBpdHNlbGYgd2lsbCBiZSBwcmludGVkIGFzIHRoZSBmaXJzdFxuXHQgICAgICogcGFnZSAtIGJlIGF3YXJlIHRoYXQgdGhpcyBwYWdlIHdpbGwgKm5vdCogaW5jbHVkZSB0aGUgZW1iZWRkZWQgdmlld3MgLSBpdCB3aWxsIG9ubHkgaW5jbHVkZSB0aGUgY29udGVudHMgb2Zcblx0ICAgICAqIHRoZSBwbGF0Zm9ybSB3aW5kb3cgaXRzZWxmIChlLmcuIHRhYiBzdGFja3MpLCB3aXRoIGJsYW5rIHNwYWNlcyB3aGVyZSB0aGUgdmlldyBjb250ZW50cyB3b3VsZCBiZSBlbWJlZGRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBEdWUgdG8gYSBrbm93biBpc3N1ZSwgdmlldyBjb250ZW50cyB0aGF0IGFyZSBub3QgdmlzaWJsZSBhdCB0aGUgdGltZSBgcHJpbnRgIGlzIGNhbGxlZCB3aWxsIG5vdCBhcHBlYXIgd2hlblxuXHQgICAgICogcHJpbnRpbmcgYGNvbnRlbnRzOiB2aWV3c2AuICBUaGlzIGluY2x1ZGVzIHZpZXdzIHRoYXQgYXJlIG9ic2N1cmVkIGJlaGluZCBvdGhlciBhY3RpdmUgVUkgZWxlbWVudHMuXG5cdCAgICAgKlxuXHQgICAgICogVG8gcHJpbnQgdGhlIHZpZXdzIGVtYmVkZGVkIGluIHRoZWlyIHBhZ2UgY29udGV4dCwgc2V0IGBjb250ZW50YCB0byBgc2NyZWVuc2hvdGAuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHByaW50KG9wdGlvbnMgPSB7IGNvbnRlbnQ6ICdzZWxmJyB9KSB7XG5cdCAgICAgICAgc3dpdGNoIChvcHRpb25zLmNvbnRlbnQpIHtcblx0ICAgICAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG5cdCAgICAgICAgICAgIGNhc2UgJ3NlbGYnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnByaW50KG9wdGlvbnMpO1xuXHQgICAgICAgICAgICBjYXNlICdzY3JlZW5zaG90Jzpcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncHJpbnQtc2NyZWVuc2hvdCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgICAgICAgICAgY2FzZSAndmlld3MnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwcmludC12aWV3cycsIHsgLi4udGhpcy5pZGVudGl0eSwgb3B0aW9ucyB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fVxuXHRJbnN0YW5jZSQ3Ll9XaW5kb3cgPSBfV2luZG93O1xuXHRyZXR1cm4gSW5zdGFuY2UkNztcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeSQxO1xuXG5mdW5jdGlvbiByZXF1aXJlRmFjdG9yeSQxICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkRmFjdG9yeSQxKSByZXR1cm4gRmFjdG9yeSQ4O1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkkMSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDgsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDguX1dpbmRvd01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgYmFzZV8xID0gYmFzZTtcblx0Y29uc3QgdmFsaWRhdGVfMSA9IHZhbGlkYXRlO1xuXHRjb25zdCBJbnN0YW5jZV8xID0gcmVxdWlyZUluc3RhbmNlKCk7XG5cdC8qKlxuXHQgKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIF9XaW5kb3d9IGNsYXNzLCBhdmFpbGFibGUgdW5kZXIgYGZpbi5XaW5kb3dgLlxuXHQgKi9cblx0Y2xhc3MgX1dpbmRvd01vZHVsZSBleHRlbmRzIGJhc2VfMS5CYXNlIHtcblx0ICAgIC8qKlxuXHQgICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBBUEkgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gV2luZG93IGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGEgV2luZG93IGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYSBXaW5kb3cgdGhyb3VnaG91dCBpdHMgZW50aXJlIGxpZmVjeWNsZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LndyYXAuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGNyZWF0ZVdpbigpLnRoZW4oKCkgPT4gZmluLldpbmRvdy53cmFwKHsgdXVpZDogJ2FwcC0xJywgbmFtZTogJ215QXBwJyB9KSlcblx0ICAgICAqIC50aGVuKHdpbiA9PiBjb25zb2xlLmxvZygnd3JhcHBlZCB3aW5kb3cnKSlcblx0ICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctd3JhcCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGVycm9yTXNnID0gKDAsIHZhbGlkYXRlXzEudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuXHQgICAgICAgIGlmIChlcnJvck1zZykge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gbmV3IEluc3RhbmNlXzEuX1dpbmRvdyh0aGlzLndpcmUsIGlkZW50aXR5KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBXaW5kb3cgaWRlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBXaW5kb3cgaWRlbnRpdHkgdGhhdCBkb2VzIG5vdCB5ZXQgZXhpc3Qgd2lsbCAqbm90KiB0aHJvdyBhbiBlcnJvciwgYW5kIGluc3RlYWRcblx0ICAgICAqIHJldHVybnMgYSBzdHViIG9iamVjdCB0aGF0IGNhbm5vdCB5ZXQgcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGx1bWJpbmcgZXZlbnRpbmdcblx0ICAgICAqIGZvciBhIFdpbmRvdyB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cud3JhcFN5bmMuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogbGV0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyB1dWlkOiAnYXBwLTEnLCBuYW1lOiAnbXlBcHAnIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy13cmFwLXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLl9XaW5kb3codGhpcy53aXJlLCBpZGVudGl0eSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYSBuZXcgV2luZG93LlxuXHQgICAgICogQHBhcmFtIG9wdGlvbnMgLSBXaW5kb3cgY3JlYXRpb24gb3B0aW9uc1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbk9wdGlvbiA9IHtcblx0ICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuXHQgICAgICogICAgICAgICBkZWZhdWx0V2lkdGg6IDMwMCxcblx0ICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmNyZWF0ZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgZnJhbWU6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjcmVhdGVXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgaXMgY3JlYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY3JlYXRlKG9wdGlvbnMpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLXdpbmRvdycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHdpbiA9IG5ldyBJbnN0YW5jZV8xLl9XaW5kb3codGhpcy53aXJlLCB7IHV1aWQ6IHRoaXMubWUudXVpZCwgbmFtZTogb3B0aW9ucy5uYW1lIH0pO1xuXHQgICAgICAgIHJldHVybiB3aW4uY3JlYXRlV2luZG93KG9wdGlvbnMpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgV2luZG93IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgd2luZG93XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uV2luZG93LmdldEN1cnJlbnQoKVxuXHQgICAgICogLnRoZW4od25kID0+IGNvbnNvbGUubG9nKCdjdXJyZW50IHdpbmRvdycpKVxuXHQgICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqXG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0Q3VycmVudCgpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWN1cnJlbnQtd2luZG93JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKCF0aGlzLndpcmUubWUuaXNXaW5kb3cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFdpbmRvdyBjb250ZXh0Jyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIHJldHVybiB0aGlzLndyYXAoeyB1dWlkLCBuYW1lIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYSBXaW5kb3cgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCB3aW5kb3dcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHduZCA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqIGNvbnN0IGluZm8gPSBhd2FpdCB3bmQuZ2V0SW5mbygpO1xuXHQgICAgICogY29uc29sZS5sb2coaW5mbyk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY3VycmVudC13aW5kb3ctc3luYycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICghdGhpcy53aXJlLm1lLmlzV2luZG93KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgaW4gYSBXaW5kb3cgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQ4Ll9XaW5kb3dNb2R1bGUgPSBfV2luZG93TW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQ4O1xufVxuXG52YXIgaGFzUmVxdWlyZWRXaW5kb3c7XG5cbmZ1bmN0aW9uIHJlcXVpcmVXaW5kb3cgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRXaW5kb3cpIHJldHVybiB3aW5kb3ckMTtcblx0aGFzUmVxdWlyZWRXaW5kb3cgPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHRcdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHRcdCAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG5cdFx0ICAgIH1cblx0XHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0XHR9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICBvW2syXSA9IG1ba107XG5cdFx0fSkpO1xuXHRcdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdFx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0XHR9O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludHMgZm9yIHRoZSBPcGVuRmluIGBXaW5kb3dgIEFQSSAoYGZpbi5XaW5kb3dgKS5cblx0XHQgKlxuXHRcdCAqICoge0BsaW5rIF9XaW5kb3dNb2R1bGV9IGNvbnRhaW5zIHN0YXRpYyBtZW1iZXJzIG9mIHRoZSBgV2luZG93YCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLldpbmRvd2AuXG5cdFx0ICogKiB7QGxpbmsgX1dpbmRvd30gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gV2luZG93LCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uV2luZG93LmdldEN1cnJlbnRgLlxuXHRcdCAqXG5cdFx0ICogVGhlc2UgYXJlIHNlcGFyYXRlIGNvZGUgZW50aXRpZXMsIGFuZCBhcmUgZG9jdW1lbnRlZCBzZXBhcmF0ZWx5LiAgSW4gdGhlIFtwcmV2aW91cyB2ZXJzaW9uIG9mIHRoZSBBUEkgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvMzIuMTE0Ljc2LjEwL2luZGV4Lmh0bWwpLFxuXHRcdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdFx0ICpcblx0XHQgKiBVbmRlcnNjb3JlIHByZWZpeGluZyBvZiBPcGVuRmluIHR5cGVzIHRoYXQgYWxpYXMgRE9NIGVudGl0aWVzIHdpbGwgYmUgZml4ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQxKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UoKSwgZXhwb3J0cyk7IFxuXHR9ICh3aW5kb3ckMSkpO1xuXHRyZXR1cm4gd2luZG93JDE7XG59XG5cbi8qKlxuICogRW50cnkgcG9pbnQgZm9yIHRoZSBPcGVuRmluIGBTeXN0ZW1gIEFQSSAoYGZpbi5TeXN0ZW1gKS5cbiAqXG4gKiAqIHtAbGluayBTeXN0ZW19IGNvbnRhaW5zIHN0YXRpYyBtZW1iZXJzIG9mIHRoZSBgU3lzdGVtYCBBUEkgKGF2YWlsYWJsZSB1bmRlciBgZmluLlN5c3RlbWApXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzeXN0ZW0sIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3lzdGVtLlN5c3RlbSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSRpID0gYmFzZTtcbmNvbnN0IHRyYW5zcG9ydF9lcnJvcnNfMSQxID0gdHJhbnNwb3J0RXJyb3JzO1xuY29uc3Qgd2luZG93XzEgPSByZXF1aXJlV2luZG93KCk7XG5jb25zdCBldmVudHNfMSQ2ID0gcmVxdWlyZSQkMDtcbi8qKlxuICogQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29yZSBvZiBPcGVuRmluIFJ1bnRpbWUuIEFsbG93cyB0aGUgZGV2ZWxvcGVyXG4gKiB0byBwZXJmb3JtIHN5c3RlbS1sZXZlbCBhY3Rpb25zLCBzdWNoIGFzIGFjY2Vzc2luZyBsb2dzLCB2aWV3aW5nIHByb2Nlc3NlcyxcbiAqIGNsZWFyaW5nIHRoZSBjYWNoZSBhbmQgZXhpdGluZyB0aGUgcnVudGltZSBhcyB3ZWxsIGFzIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5TeXN0ZW1FdmVudHMgc3lzdGVtIGV2ZW50c30uXG4gKlxuICovXG5jbGFzcyBTeXN0ZW0gZXh0ZW5kcyBiYXNlXzEkaS5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlLCAnc3lzdGVtJyk7XG4gICAgfVxuICAgIHNlbmRFeHRlcm5hbFByb2Nlc3NSZXF1ZXN0KGFjdGlvbiwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhpdEV2ZW50S2V5ID0gJ2V4dGVybmFsLXByb2Nlc3MtZXhpdGVkJztcbiAgICAgICAgICAgIGxldCBwcm9jZXNzVXVpZDtcbiAgICAgICAgICAgIGxldCBleGl0UGF5bG9hZDtcbiAgICAgICAgICAgIGxldCBleHRlcm5hbFByb2Nlc3NFeGl0SGFuZGxlcjtcbiAgICAgICAgICAgIGxldCBvZldpbmRvdztcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5saXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGV4dGVybmFsUHJvY2Vzc0V4aXRIYW5kbGVyID0gKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHBheWxvYWQgfHwge307XG4gICAgICAgICAgICAgICAgICAgIGV4aXRQYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9waWM6ICdleGl0ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXVpZDogZGF0YS5wcm9jZXNzVXVpZCB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXRDb2RlOiBkYXRhLmV4aXRDb2RlIHx8IDBcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NVdWlkID09PSBwYXlsb2FkLnByb2Nlc3NVdWlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmxpc3RlbmVyKGV4aXRQYXlsb2FkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mV2luZG93LnJlbW92ZUxpc3RlbmVyKGV4aXRFdmVudEtleSwgZXh0ZXJuYWxQcm9jZXNzRXhpdEhhbmRsZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAvLyB3aW5kb3cgY29uc3RydWN0b3IgZXhwZWN0cyB0aGUgbmFtZSBpcyBub3QgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLndpcmUubWUubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpcmUubWUubmFtZSA9IHRoaXMud2lyZS5tZS51dWlkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvZldpbmRvdyA9IG5ldyB3aW5kb3dfMS5fV2luZG93KHRoaXMud2lyZSwgdGhpcy53aXJlLm1lKTtcbiAgICAgICAgICAgICAgICBvZldpbmRvdy5vbihleGl0RXZlbnRLZXksIGV4dGVybmFsUHJvY2Vzc0V4aXRIYW5kbGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2lyZVxuICAgICAgICAgICAgICAgIC5zZW5kQWN0aW9uKGFjdGlvbiwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzVXVpZCA9IHBheWxvYWQuZGF0YS51dWlkO1xuICAgICAgICAgICAgICAgIHJlc29sdmUocGF5bG9hZC5kYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoZXhpdFBheWxvYWQgJiYgcHJvY2Vzc1V1aWQgPT09IGV4aXRQYXlsb2FkLnV1aWQpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5saXN0ZW5lcihleGl0UGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgICAgIG9mV2luZG93LnJlbW92ZUxpc3RlbmVyKGV4aXRFdmVudEtleSwgZXh0ZXJuYWxQcm9jZXNzRXhpdEhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAob2ZXaW5kb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgb2ZXaW5kb3cucmVtb3ZlTGlzdGVuZXIoZXhpdEV2ZW50S2V5LCBleHRlcm5hbFByb2Nlc3NFeGl0SGFuZGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBydW50aW1lLiBUaGUgdmVyc2lvbiBjb250YWlucyB0aGUgbWFqb3IsIG1pbm9yLFxuICAgICAqIGJ1aWxkIGFuZCByZXZpc2lvbiBudW1iZXJzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0VmVyc2lvbigpLnRoZW4odiA9PiBjb25zb2xlLmxvZyh2KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFZlcnNpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXZlcnNpb24nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGNhY2hlZCBkYXRhIGNvbnRhaW5pbmcgYXBwbGljYXRpb24gcmVzb3VyY2VcbiAgICAgKiBmaWxlcyAoaW1hZ2VzLCBIVE1MLCBKYXZhU2NyaXB0IGZpbGVzKSwgY29va2llcywgYW5kIGl0ZW1zIHN0b3JlZCBpbiB0aGVcbiAgICAgKiBMb2NhbCBTdG9yYWdlLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gU2VlIGJlbG93IGZvciBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIGFjY2VwdGVkIG9wdGlvbnMsIHNlZSB0aGUgZm9sbG93aW5nIHBhZ2VzOlxuICAgICAqICogY2FjaGU6IGJyb3dzaW5nIGRhdGEgY2FjaGUgZm9yIGh0bWwgZmlsZXMgYW5kIGltYWdlcyAoW2NhY2hpbmddKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvQ2FjaGluZykpXG4gICAgICogKiBjb29raWVzOiBicm93c2VyIFtjb29raWVzXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Nvb2tpZXMpXG4gICAgICogKiBsb2NhbFN0b3JhZ2U6IGJyb3dzZXIgZGF0YSB0aGF0IGNhbiBiZSB1c2VkIGFjcm9zcyBzZXNzaW9ucyAoW2xvY2FsIHN0b3JhZ2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvbG9jYWxTdG9yYWdlKSlcbiAgICAgKiAqIGFwcGNhY2hlOiBodG1sNSBbYXBwbGljYXRpb24gY2FjaGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvVXNpbmdfdGhlX2FwcGxpY2F0aW9uX2NhY2hlKVxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBjbGVhckNhY2hlT3B0aW9ucyA9IHtcbiAgICAgKiAgICAgYXBwY2FjaGU6IHRydWUsXG4gICAgICogICAgIGNhY2hlOiB0cnVlLFxuICAgICAqICAgICBjb29raWVzOiB0cnVlLFxuICAgICAqICAgICBsb2NhbFN0b3JhZ2U6IHRydWVcbiAgICAgKiB9O1xuICAgICAqIGZpbi5TeXN0ZW0uY2xlYXJDYWNoZShjbGVhckNhY2hlT3B0aW9ucykudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ2FjaGUgY2xlYXJlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKi9cbiAgICBjbGVhckNhY2hlKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGVhci1jYWNoZScsIG9wdGlvbnMpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGFsbCBjYWNoZWQgZGF0YSB3aGVuIE9wZW5GaW4gUnVudGltZSBleGl0cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmRlbGV0ZUNhY2hlT25FeGl0KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnRGVsZXRlZCBDYWNoZScpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGVsZXRlQ2FjaGVPbkV4aXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZGVsZXRlLWNhY2hlLXJlcXVlc3QnKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEV4aXRzIHRoZSBSdW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZXhpdCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ2V4aXQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4aXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZXhpdC1kZXNrdG9wJykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIGEgSlNPTiBtYW5pZmVzdCB1c2luZyB0aGUgYnJvd3NlciBwcm9jZXNzIGFuZCByZXR1cm5zIGEgSmF2YXNjcmlwdCBvYmplY3QuXG4gICAgICogQHBhcmFtIG1hbmlmZXN0VXJsIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRvIGZldGNoLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5mZXRjaE1hbmlmZXN0KCdodHRwczovL3d3dy5wYXRoLXRvLW1hbmlmZXN0LmNvbScpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBmZXRjaE1hbmlmZXN0KG1hbmlmZXN0VXJsKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZXRjaC1tYW5pZmVzdCcsIHsgbWFuaWZlc3RVcmwgfSk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgYW55IHVud3JpdHRlbiBjb29raWVzIGRhdGEgdG8gZGlzay5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmZsdXNoQ29va2llU3RvcmUoKVxuICAgICAqICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnc3VjY2VzcycpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZmx1c2hDb29raWVTdG9yZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmbHVzaC1jb29raWUtc3RvcmUnKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBkYXRhIChuYW1lLCBpZHMsIGJvdW5kcykgZm9yIGFsbCBhcHBsaWNhdGlvbiB3aW5kb3dzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0QWxsV2luZG93cygpLnRoZW4od2lucyA9PiBjb25zb2xlLmxvZyh3aW5zKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEFsbFdpbmRvd3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWFsbC13aW5kb3dzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBkYXRhIGZvciBhbGwgYXBwbGljYXRpb25zLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0QWxsQXBwbGljYXRpb25zKCkudGhlbihhcHBzID0+IGNvbnNvbGUubG9nKGFwcHMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0QWxsQXBwbGljYXRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1hbGwtYXBwbGljYXRpb25zJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50IHN0cmluZyB0aGF0IHN0YXJ0ZWQgT3BlbkZpbiBSdW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0Q29tbWFuZExpbmVBcmd1bWVudHMoKS50aGVuKGFyZ3MgPT4gY29uc29sZS5sb2coYXJncykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRDb21tYW5kTGluZUFyZ3VtZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY29tbWFuZC1saW5lLWFyZ3VtZW50cycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGNyYXNoIHJlcG9ydGVyLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0Q3Jhc2hSZXBvcnRlclN0YXRlKCkudGhlbihzdGF0ZSA9PiBjb25zb2xlLmxvZyhzdGF0ZSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRDcmFzaFJlcG9ydGVyU3RhdGUoKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhOiB7IGRpYWdub3N0aWNNb2RlLCBpc1J1bm5pbmcgfSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWNyYXNoLXJlcG9ydGVyLXN0YXRlJyk7XG4gICAgICAgIGNvbnNvbGUud2FybignZGlhZ25vc3RpY01vZGUgcHJvcGVydHkgaXMgZGVwcmVjYXRlZC4gSXQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24nKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWNNb2RlIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uXG4gICAgICAgICAgICBkaWFnbm9zdGljTW9kZSxcbiAgICAgICAgICAgIGRpYWdub3N0aWNzTW9kZTogZGlhZ25vc3RpY01vZGUsXG4gICAgICAgICAgICBpc1J1bm5pbmdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGNyYXNoIHJlcG9ydGVyIGlmIG5vdCBhbHJlYWR5IHJ1bm5pbmcuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBjb25maWd1cmUgY3Jhc2ggcmVwb3J0ZXJcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFlvdSBjYW4gb3B0aW9uYWxseSBzcGVjaWZ5IGBkaWFnbm9zdGljc01vZGVgIHRvIGhhdmUgdGhlIGxvZ3Mgc2VudCB0b1xuICAgICAqIE9wZW5GaW4gb24gcnVudGltZSBjbG9zZS4gKE5PVEU6IGBkaWFnbm9zdGljc01vZGVgIHdpbGwgdHVybiBvbiB2ZXJib3NlIGxvZ2dpbmcgYW5kIGRpc2FibGUgdGhlIHNhbmRib3hcbiAgICAgKiBmb3IgbmV3bHkgbGF1bmNoZWQgcmVuZGVyZXIgcHJvY2Vzc2VzLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2RlYnVnZ2luZyNkaWFnbm9zdGljcy1tb2RlIGZvclxuICAgICAqIG1vcmUgZGV0YWlscy4pXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5zdGFydENyYXNoUmVwb3J0ZXIoe2RpYWdub3N0aWNzTW9kZTogdHJ1ZX0pLnRoZW4ocmVwb3J0ZXIgPT4gY29uc29sZS5sb2cocmVwb3J0ZXIpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgc3RhcnRDcmFzaFJlcG9ydGVyKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IG5ld09wdHMgPSB7IC4uLm9wdHMsIGRpYWdub3N0aWNNb2RlOiBvcHRzLmRpYWdub3N0aWNzTW9kZSB8fCBvcHRzLmRpYWdub3N0aWNNb2RlIH07XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhOiB7IGRpYWdub3N0aWNNb2RlLCBpc1J1bm5pbmcgfSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3RhcnQtY3Jhc2gtcmVwb3J0ZXInLCBuZXdPcHRzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWNNb2RlIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uXG4gICAgICAgICAgICBkaWFnbm9zdGljTW9kZSxcbiAgICAgICAgICAgIGRpYWdub3N0aWNzTW9kZTogZGlhZ25vc3RpY01vZGUsXG4gICAgICAgICAgICBpc1J1bm5pbmdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGhleCBlbmNvZGVkIGhhc2ggb2YgdGhlIG1hY2hpbmUgaWQgYW5kIHRoZSBjdXJyZW50bHkgbG9nZ2VkIGluIHVzZXIgbmFtZS5cbiAgICAgKiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCB3YXkgdG8gdW5pcXVlbHkgaWRlbnRpZnkgYSB1c2VyIC8gbWFjaGluZSBjb21iaW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEZvciBXaW5kb3dzIHN5c3RlbXMgdGhpcyBpcyBhIHNoYTI1NiBoYXNoIG9mIHRoZSBtYWNoaW5lIElEIHNldCBpbiB0aGUgcmVnaXN0cnkga2V5OlxuICAgICAqIGBIS0VZX0xPQ0FMX01BQ0hJTkVcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXENyeXB0b2dyYXBoeVxcTWFjaGluZUd1aWRgIGFuZCBgVVNFUk5BTUVgLlxuICAgICAqXG4gICAgICogRm9yIE9TWCBzeXN0ZW1zLCBhIG5hdGl2ZS1sZXZlbCBjYWxsIGlzIHVzZWQgdG8gZ2V0IHRoZSBtYWNoaW5lIElELlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0VW5pcXVlVXNlcklkKCkudGhlbihpZCA9PiBjb25zb2xlLmxvZyhpZCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRVbmlxdWVVc2VySWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXVuaXF1ZS11c2VyLWlkJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIGZyYW1lIGluZm8gb2JqZWN0IGZvciB0aGUgdXVpZCBhbmQgbmFtZSBwYXNzZWQgaW5cbiAgICAgKiBAcGFyYW0gdXVpZCAtIFRoZSBVVUlEIG9mIHRoZSB0YXJnZXQuXG4gICAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlIHBvc3NpYmxlIHR5cGVzIGFyZSAnd2luZG93JywgJ2lmcmFtZScsICdleHRlcm5hbCBjb25uZWN0aW9uJyBvciAndW5rbm93bicuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGVudGl0eVV1aWQgPSAnT3BlbmZpblBPQyc7XG4gICAgICogY29uc3QgZW50aXR5TmFtZSA9ICc0MGM3NGI1ZC1lZDk4LTQwZjctODUzZi1lM2QzYzI2OTkxNzUnO1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0RW50aXR5SW5mbyhlbnRpdHlVdWlkLCBlbnRpdHlOYW1lKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIC8vIGV4YW1wbGUgaW5mbyBzaGFwZVxuICAgICAqIHtcbiAgICAgKiAgICAgXCJ1dWlkXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICBcIm5hbWVcIjogXCI0MGM3NGI1ZC1lZDk4LTQwZjctODUzZi1lM2QzYzI2OTkxNzVcIixcbiAgICAgKiAgICAgXCJwYXJlbnRcIjoge1xuICAgICAqICAgICAgICAgXCJ1dWlkXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICAgICAgXCJuYW1lXCI6IFwiT3BlbmZpblBPQ1wiXG4gICAgICogICAgIH0sXG4gICAgICogICAgIFwiZW50aXR5VHlwZVwiOiBcImlmcmFtZVwiXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEVudGl0eUluZm8odXVpZCwgbmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1lbnRpdHktaW5mbycsIHsgdXVpZCwgbmFtZSB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBnaXZlbiBlbnZpcm9ubWVudCB2YXJpYWJsZSBvbiB0aGUgY29tcHV0ZXIgb24gd2hpY2ggdGhlIHJ1bnRpbWUgaXMgaW5zdGFsbGVkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRFbnZpcm9ubWVudFZhcmlhYmxlKCdIT01FJykudGhlbihlbnYgPT4gY29uc29sZS5sb2coZW52KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEVudmlyb25tZW50VmFyaWFibGUoZW52TmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlXG4gICAgICAgICAgICAuc2VuZEFjdGlvbignZ2V0LWVudmlyb25tZW50LXZhcmlhYmxlJywge1xuICAgICAgICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IGVudk5hbWVcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGN1cnJlbnRseSBmb2N1c2VkIFdpbmRvdy5cbiAgICAgKiBJZiBhIFZpZXcgY3VycmVudGx5IGhhcyBmb2N1cywgcmV0dXJucyB0aGUgaWRlbnRpdHkgb2YgVmlldydzIHBhcmVudCBXaW5kb3cuXG4gICAgICogVXNlIHtAbGluayBXaW5kb3cuX1dpbmRvdyNnZXRGb2N1c2VkQ29udGVudCBXaW5kb3cuZ2V0Rm9jdXNlZENvbnRlbnR9IHRvIGRpcmVjdGx5IGFjY2VzcyBjdXJyZW50bHkgZm9jdXNlZCBXaW5kb3cgb3IgVmlldy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldEZvY3VzZWRXaW5kb3coKS50aGVuKHdpbkluZm8gPT4gY29uc29sZS5sb2cod2luSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRGb2N1c2VkV2luZG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1mb2N1c2VkLXdpbmRvdycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY3VycmVudGx5IGZvY3VzZWQgY29udGVudC4gUmV0dXJucyBpZGVudGl0eSBvZiBlbnRpdHkgd2l0aCBgZW50aXR5VHlwZWAuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRGb2N1c2VkQ29udGVudCgpLnRoZW4oY29udGVudElkZW50aXR5ID0+IGNvbnNvbGUubG9nKGNvbnRlbnRJZGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRGb2N1c2VkQ29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZm9jdXNlZC1jb250ZW50JykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGdpdmVuIGFwcCdzIGNlcnRpZmljYXRpb24gc3RhdHVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3RVcmwgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6MTIzNC9hcHAuanNvblwiXG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgY2VydGlmaWNhdGlvbkluZm8gPSBhd2FpdCBmaW4uU3lzdGVtLmlzQXBwQ2VydGlmaWVkKG1hbmlmZXN0VXJsKTtcbiAgICAgKiB9IGNhdGNoKGVycikge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgaXNBcHBDZXJ0aWZpZWQobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGE6IHsgY2VydGlmaWVkSW5mbyB9IH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpcy1hcHAtY2VydGlmaWVkJywgeyBtYW5pZmVzdFVybCB9KTtcbiAgICAgICAgcmV0dXJuIGNlcnRpZmllZEluZm87XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIHRoZSBpbnN0YWxsZWQgcnVudGltZSB2ZXJzaW9ucyBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRJbnN0YWxsZWRSdW50aW1lcygpLnRoZW4ocnVudGltZXMgPT4gY29uc29sZS5sb2cocnVudGltZXMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gaW5jb21wYXRpYmxlIHdpdGggc3RhbmRhbG9uZSBub2RlIHByb2Nlc3MuXG4gICAgZ2V0SW5zdGFsbGVkUnVudGltZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWluc3RhbGxlZC1ydW50aW1lcycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEucnVudGltZXMpO1xuICAgIH1cbiAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCBzdGFuZGFsb25lIG5vZGUgcHJvY2Vzcy5cbiAgICBhc3luYyBnZXRJbnN0YWxsZWRBcHBzKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgZGF0YTogeyBpbnN0YWxsZWRBcHBzIH0gfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1pbnN0YWxsZWQtYXBwcycpO1xuICAgICAgICByZXR1cm4gaW5zdGFsbGVkQXBwcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBjb250ZW50cyBvZiB0aGUgbG9nIHdpdGggdGhlIHNwZWNpZmllZCBmaWxlbmFtZS5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIG9iamVjdCB0aGF0IGlkIGRlZmluZWQgYnkgdGhlIEdldExvZ1JlcXVlc3RUeXBlIGludGVyZmFjZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldExvZygpIHtcbiAgICAgKiAgICAgY29uc3QgbG9ncyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0TG9nTGlzdCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZmluLlN5c3RlbS5nZXRMb2cobG9nc1swXSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZ2V0TG9nKCkudGhlbihsb2cgPT4gY29uc29sZS5sb2cobG9nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldExvZyhvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndmlldy1sb2cnLCBvcHRpb25zKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHVuaXF1ZSBpZGVudGlmaWVyIChVVUlEKSBwcm92aWRlZCBieSB0aGUgbWFjaGluZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldE1hY2hpbmVJZCgpLnRoZW4oaWQgPT4gY29uc29sZS5sb2coaWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TWFjaGluZUlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1tYWNoaW5lLWlkJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gKGluY2x1c2l2ZSkgbG9nZ2luZyBsZXZlbCB0aGF0IGlzIGN1cnJlbnRseSBiZWluZyB3cml0dGVuIHRvIHRoZSBsb2cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRNaW5Mb2dMZXZlbCgpLnRoZW4obGV2ZWwgPT4gY29uc29sZS5sb2cobGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TWluTG9nTGV2ZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LW1pbi1sb2ctbGV2ZWwnKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gZm9yIGVhY2ggbG9nIGZpbGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRMb2dMaXN0KCkudGhlbihsb2dMaXN0ID0+IGNvbnNvbGUubG9nKGxvZ0xpc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TG9nTGlzdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsaXN0LWxvZ3MnKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGRhdGEgYWJvdXQgdGhlIG1vbml0b3Igc2V0dXAgb2YgdGhlXG4gICAgICogY29tcHV0ZXIgdGhhdCB0aGUgcnVudGltZSBpcyBydW5uaW5nIG9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0TW9uaXRvckluZm8oKS50aGVuKG1vbml0b3JJbmZvID0+IGNvbnNvbGUubG9nKG1vbml0b3JJbmZvKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldE1vbml0b3JJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1tb25pdG9yLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbW91c2UgaW4gdmlydHVhbCBzY3JlZW4gY29vcmRpbmF0ZXMgKGxlZnQsIHRvcCkuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRNb3VzZVBvc2l0aW9uKCkudGhlbihtb3VzZVBvc2l0aW9uID0+IGNvbnNvbGUubG9nKG1vdXNlUG9zaXRpb24pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TW91c2VQb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtbW91c2UtcG9zaXRpb24nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGFsbCBvZiB0aGUgcnVudGltZSBwcm9jZXNzZXMgdGhhdCBhcmUgY3VycmVudGx5XG4gICAgICogcnVubmluZy4gRWFjaCBlbGVtZW50IGluIHRoZSBhcnJheSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdXVpZFxuICAgICAqIGFuZCB0aGUgbmFtZSBvZiB0aGUgYXBwbGljYXRpb24gdG8gd2hpY2ggdGhlIHByb2Nlc3MgYmVsb25ncy5cbiAgICAgKiBAZGVwcmVjYXRlZCBQbGVhc2UgdXNlIG91ciBuZXcgc2V0IG9mIHByb2Nlc3MgQVBJczpcbiAgICAgKiB7QGxpbmsgV2luZG93Ll9XaW5kb3cjZ2V0UHJvY2Vzc0luZm8gV2luZG93LmdldFByb2Nlc3NJbmZvfVxuICAgICAqIHtAbGluayBWaWV3LlZpZXcjZ2V0UHJvY2Vzc0luZm8gVmlldy5nZXRQcm9jZXNzSW5mb31cbiAgICAgKiB7QGxpbmsgQXBwbGljYXRpb24uQXBwbGljYXRpb24jZ2V0UHJvY2Vzc0luZm8gQXBwbGljYXRpb24uZ2V0UHJvY2Vzc0luZm99XG4gICAgICoge0BsaW5rIFN5c3RlbSNnZXRBbGxQcm9jZXNzSW5mbyBTeXN0ZW0uZ2V0QWxsUHJvY2Vzc0luZm99XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRQcm9jZXNzTGlzdCgpLnRoZW4oUHJvY2Vzc0xpc3QgPT4gY29uc29sZS5sb2coUHJvY2Vzc0xpc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0UHJvY2Vzc0xpc3QoKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUud2FybignU3lzdGVtLmdldFByb2Nlc3NMaXN0IGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBsZWFzZSBjb25zaWRlciB1c2luZyBvdXIgbmV3IHByb2Nlc3MgQVBJczogV2luZG93LmdldFByb2Nlc3NJbmZvLCBWaWV3LmdldFByb2Nlc3NJbmZvLCBBcHBsaWNhdGlvbi5nZXRQcm9jZXNzSW5mbywgU3lzdGVtLmdldEFsbFByb2Nlc3NJbmZvJyk7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncHJvY2Vzcy1zbmFwc2hvdCcpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYWxsIHByb2Nlc3MgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGlzIGluY2x1ZGVzIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIGV2ZXJ5IHByb2Nlc3MgYXNzb2NpYXRlZCB0byBhbGwgZW50aXRpZXMgKHdpbmRvd3MgYW5kIHZpZXdzKS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBhbGxQcm9jZXNzSW5mbyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0QWxsUHJvY2Vzc0luZm8oKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QWxsUHJvY2Vzc0luZm8oKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLXByb2Nlc3MtaW5mbycsIHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBQcm94eSBzZXR0aW5ncy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldFByb3h5U2V0dGluZ3MoKS50aGVuKFByb3h5U2V0dGluZyA9PiBjb25zb2xlLmxvZyhQcm94eVNldHRpbmcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICpcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICBjb25maWc6IHtcbiAgICAgKiAgICAgICAgIHByb3h5QWRkcmVzczogXCJwcm94eUFkZHJlc3NcIiwgLy90aGUgY29uZmlndXJlZCBQcm94eSBBZGRyZXNzXG4gICAgICogICAgICAgICBwcm94eVBvcnQ6IDAsIC8vdGhlIGNvbmZpZ3VyZWQgUHJveHkgcG9ydFxuICAgICAqICAgICAgICAgdHlwZTogXCJzeXN0ZW1cIiAvL1Byb3h5IFR5cGVcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgc3lzdGVtOiB7XG4gICAgICogICAgICAgICBhdXRvQ29uZmlnVXJsOiBcIlwiLFxuICAgICAqICAgICAgICAgYnlwYXNzOiBcIlwiLFxuICAgICAqICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICogICAgICAgICBwcm94eTogXCJcIlxuICAgICAqICAgICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFByb3h5U2V0dGluZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByb3h5LXNldHRpbmdzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJ1bm5pbmcgUnVudGltZSBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRSdW50aW1lSW5mbygpLnRoZW4oUnVudGltZUluZm8gPT4gY29uc29sZS5sb2coUnVudGltZUluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0UnVudGltZUluZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXJ1bnRpbWUtaW5mbycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBydW5uaW5nIFJWTSBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRSdm1JbmZvKCkudGhlbihSdm1JbmZvID0+IGNvbnNvbGUubG9nKFJ2bUluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gaW5jb21wYXRpYmxlIHdpdGggc3RhbmRhbG9uZSBub2RlIHByb2Nlc3MuXG4gICAgZ2V0UnZtSW5mbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtcnZtLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGdlbmVyYWwgc3lzdGVtIGluZm9ybWF0aW9uLiBJZiB5b3UgbmVlZCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZVxuICAgICAqIE9TIGFuZCB0aGUgY3VycmVudGx5IGxvZ2dlZCBpbiB1c2VyLCB1c2UgYGZpbi5TeXN0ZW0uZ2V0T1NJbmZvKClgIGluc3RlYWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRIb3N0U3BlY3MoKS50aGVuKHNwZWNzID0+IGNvbnNvbGUubG9nKHNwZWNzKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEhvc3RTcGVjcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtaG9zdC1zcGVjcycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIE9TIGFuZCB0aGUgY3VycmVudGx5IGxvZ2dlZCBpbiB1c2VyLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0T1NJbmZvKCkudGhlbihzcGVjcyA9PiBjb25zb2xlLmxvZyhzcGVjcykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRPU0luZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LW9zLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUnVucyBhbiBleGVjdXRhYmxlIG9yIGJhdGNoIGZpbGUuIEEgcGF0aCB0byB0aGUgZmlsZSBtdXN0IGJlIGluY2x1ZGVkIGluIG9wdGlvbnMuXG4gICAgICogPGJyPiBBIHV1aWQgbWF5IGJlIG9wdGlvbmFsbHkgcHJvdmlkZWQuIElmIG5vdCBwcm92aWRlZCwgT3BlbkZpbiB3aWxsIGNyZWF0ZSBhIHV1aWQgZm9yIHRoZSBuZXcgcHJvY2Vzcy5cbiAgICAgKiA8YnI+IE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIDxhIGhyZWY9XCJodHRwczovL2RldmVsb3BlcnMub3BlbmZpbi5jby9kb2NzL2FwaS1zZWN1cml0eVwiPkFQSSBzZWN1cml0eSBzZXR0aW5nczwvYT4uIEFsc28sIHRoaXMgYXBpIGhhcyBhbiBlbmhhbmNlZCBwZXJtaXNzaW9uIHNldCB0byBtYWtlIGl0IGxlc3MgZGFuZ2Vyb3VzLiBTbyBhcHBsaWNhdGlvbiBvd25lcnMgY2FuIG9ubHkgYWxsb3cgdG8gbGF1bmNoIHRoZSBhc3NldHMgb3duZWQgYnkgdGhlIGFwcGxpY2F0aW9uLCB0aGUgZW5hYmxlZCBkb3dubG9hZGVkIGZpbGVzIG9yIHRoZSByZXN0cmljdGVkIGV4ZWN1dGFibGVzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEEgb2JqZWN0IHRoYXQgaXMgZGVmaW5lZCBpbiB0aGUgRXh0ZXJuYWxQcm9jZXNzUmVxdWVzdFR5cGUgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJZiBhbiB1bnVzZWQgVVVJRCBpcyBwcm92aWRlZCBpbiBvcHRpb25zLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vIFVVSUQgaXMgcHJvdmlkZWQsIE9wZW5GaW4gd2lsbCBhc3NpZ24gb25lLlxuICAgICAqIFRoaXMgYXBpIGhhcyBhbiBlbmhhbmNlZCBwZXJtaXNzaW9uIHNldCB0byBtYWtlIGl0IGxlc3MgZGFuZ2Vyb3VzLiBTbyBhcHBsaWNhdGlvbiBvd25lcnMgY2FuIG9ubHkgYWxsb3cgdG8gbGF1bmNoIHRoZVxuICAgICAqIGFzc2V0cyBvd25lZCBieSB0aGUgYXBwbGljYXRpb24sIHRoZSBlbmFibGVkIGRvd25sb2FkZWQgZmlsZXMgb3IgdGhlIHJlc3RyaWN0ZWQgZXhlY3V0YWJsZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogU2luY2UgX2FwcEFzc2V0c18gcmVsaWVzIG9uIHRoZSBSVk0sIHdoaWNoIGlzIG1pc3Npbmcgb24gTUFDX09TLCAnYWxpYXMnIGlzIG5vdCBhdmFpbGFibGUuIEluc3RlYWQgcHJvdmlkZVxuICAgICAqIHRoZSBmdWxsIHBhdGggZS5nLiBfL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcC9Db250ZW50cy9NYWNPUy9DYWxjdWxhdG9yXy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogQmFzaWMgRXhhbXBsZTpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ25vdGVwYWQnLFxuICAgICAqICAgICBhcmd1bWVudHM6ICcnLFxuICAgICAqICAgICBsaXN0ZW5lcjogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUHJvbWlzZSByZXNvbHV0aW9uOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICB1dWlkOiBcIkZCM0U2RTM2LTA5NzYtNEMyQi05QTA5LUZCMkU1NEQyRjFCQlwiIC8vIFRoZSBtYXBwZWQgVVVJRCB3aGljaCBpZGVudGlmaWVzIHRoZSBsYXVuY2hlZCBwcm9jZXNzXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTGlzdGVuZXIgY2FsbGJhY2s6XG4gICAgICogYGBganNcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICB0b3BpYzogXCJleGl0ZWRcIiwgLy8gT3IgXCJyZWxlYXNlZFwiIG9uIGEgY2FsbCB0byByZWxlYXNlRXh0ZXJuYWxQcm9jZXNzXG4gICAgICogICAgIHV1aWQ6IFwiRkIzRTZFMzYtMDk3Ni00QzJCLTlBMDktRkIyRTU0RDJGMUJCXCIsIC8vIFRoZSBtYXBwZWQgVVVJRCB3aGljaCBpZGVudGlmaWVzIHRoZSBsYXVuY2hlZCBwcm9jZXNzXG4gICAgICogICAgIGV4aXRDb2RlOiAwIC8vIFByb2Nlc3MgZXhpdCBjb2RlXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQnkgc3BlY2lmeWluZyBhIGxpZmV0aW1lLCBhbiBleHRlcm5hbCBwcm9jZXNzIGNhbiBsaXZlIGFzIGxvbmcgdGhlIHdpbmRvdy9hcHBsaWNhdGlvbiB0aGF0IGxhdW5jaGVkIGl0IG9yXG4gICAgICogcGVyc2lzdCBhZnRlciB0aGUgYXBwbGljYXRpb24gZXhpdHMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG51bGwsIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gJ3BlcnNpc3QnLCBtZWFuaW5nXG4gICAgICogdGhlIHByb2Nlc3MgbGl2ZXMgb24gYWZ0ZXIgdGhlIGFwcGxpY2F0aW9uIGV4aXRzOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmxhdW5jaEV4dGVybmFsUHJvY2Vzcyh7XG4gICAgICogICAgIHBhdGg6ICdub3RlcGFkJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnJyxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbGlmZXRpbWU6ICd3aW5kb3cnXG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTm90ZTogQSBwcm9jZXNzIHRoYXQgZXhpdHMgd2hlbiB0aGUgd2luZG93L2FwcGxpY2F0aW9uIGV4aXRzIGNhbm5vdCBiZSByZWxlYXNlZCB2aWEgZmluLmRlc2t0b3AuU3lzdGVtLnJlbGVhc2VFeHRlcm5hbFByb2Nlc3MuXG4gICAgICpcbiAgICAgKiBCeSBzcGVjaWZ5aW5nIGEgY3dkLCBpdCB3aWxsIHNldCBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IHdoZW4gbGF1bmNoaW5nIGFuIGV4dGVybmFsIHByb2Nlc3M6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ2NtZC5leGUnLFxuICAgICAqICAgICBjd2Q6ICdjOlxcXFx0ZW1wJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnJyxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvY2Vzc0lkZW50aXR5KTtcbiAgICAgKiB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEV4YW1wbGUgdXNpbmcgYW4gYWxpYXMgZnJvbSBhcHAuanNvbiBhcHBBc3NldHMgcHJvcGVydHk6XG4gICAgICpcbiAgICAgKiBgYGBqc29uXG4gICAgICogXCJhcHBBc3NldHNcIjogW1xuICAgICAqICAgICB7XG4gICAgICogICAgICAgICBcInNyY1wiOiBcImV4ZS56aXBcIixcbiAgICAgKiAgICAgICAgIFwiYWxpYXNcIjogXCJteUFwcFwiLFxuICAgICAqICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNC4xMi44XCIsXG4gICAgICogICAgICAgICBcInRhcmdldFwiOiBcIm15QXBwLmV4ZVwiLFxuICAgICAqICAgICAgICAgXCJhcmdzXCI6IFwiYSBiIGMgZFwiXG4gICAgICogICAgIH0sXG4gICAgICogXVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvLyAgV2hlbiBjYWxsZWQsIGlmIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkIHRoZW4gdGhlIGFyZ3VtZW50cyAoaWYgYW55KVxuICAgICAqIC8vICBhcmUgdGFrZW4gZnJvbSB0aGUgJ2FwcC5qc29uJyBmaWxlLCBmcm9tIHRoZSAgJ2FyZ3MnIHBhcmFtZXRlclxuICAgICAqIC8vICBvZiB0aGUgJ2FwcEFzc2V0cycgT2JqZWN0IHdpdGggdGhlIHJlbGV2YW50ICdhbGlhcycuXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICAvL0FkZGl0aW9uYWxseSBub3RlIHRoYXQgdGhlIGV4ZWN1dGFibGUgZm91bmQgaW4gdGhlIHppcCBmaWxlIHNwZWNpZmllZCBpbiBhcHBBc3NldHNcbiAgICAgKiAgICAgLy93aWxsIGRlZmF1bHQgdG8gdGhlIG9uZSBtZW50aW9uZWQgYnkgYXBwQXNzZXRzLnRhcmdldFxuICAgICAqICAgICAvL0lmIHRoZSB0aGUgcGF0aCBiZWxvdyByZWZlcnMgdG8gYSBzcGVjaWZpYyBwYXRoIGl0IHdpbGwgb3ZlcnJpZGUgdGhpcyBkZWZhdWx0XG4gICAgICogICAgIGFsaWFzOiAnbXlBcHAnLFxuICAgICAqICAgICBsaXN0ZW5lcjogKHJlc3VsdCkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhhbXBsZSB1c2luZyBhbiBhbGlhcyBidXQgb3ZlcnJpZGluZyB0aGUgYXJndW1lbnRzOlxuICAgICAqXG4gICAgICogYGBganNvblxuICAgICAqIFwiYXBwQXNzZXRzXCI6IFtcbiAgICAgKiAgICAge1xuICAgICAqICAgICAgICAgXCJzcmNcIjogXCJleGUuemlwXCIsXG4gICAgICogICAgICAgICBcImFsaWFzXCI6IFwibXlBcHBcIixcbiAgICAgKiAgICAgICAgIFwidmVyc2lvblwiOiBcIjQuMTIuOFwiLFxuICAgICAqICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcC5leGVcIixcbiAgICAgKiAgICAgICAgIFwiYXJnc1wiOiBcImEgYiBjIGRcIlxuICAgICAqICAgICB9LFxuICAgICAqIF1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogLy8gIElmICdhcmd1bWVudHMnIGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciBpdCB0YWtlcyBwcmVjZWRlbmNlXG4gICAgICogLy8gIG92ZXIgYW55ICdhcmdzJyBzZXQgaW4gdGhlICdhcHAuanNvbicuXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICBhbGlhczogJ215QXBwJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnZSBmIGcnLFxuICAgICAqICAgICBsaXN0ZW5lcjogKHJlc3VsdCkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSXQgaXMgbm93IHBvc3NpYmxlIHRvIG9wdGlvbmFsbHkgcGVyZm9ybSBhbnkgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyBjZXJ0aWZpY2F0ZSBjaGVja3NcbiAgICAgKiBhZ2FpbnN0IGFuIGFic29sdXRlIHRhcmdldCB2aWEgYGZpbi5kZXNrdG9wLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKWA6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIFwiY2VydGlmaWNhdGVcIjoge1xuICAgICAqICAgICBcInNlcmlhbFwiOiBcIjNjIGE1IC4uLlwiLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgaGV4IHN0cmluZyB3aXRoIG9yIHdpdGhvdXQgc3BhY2VzXG4gICAgICogICAgIFwic3ViamVjdFwiOiBcIk89T3BlbkZpbiBJTkMuLCBMPU5ldyBZb3JrLCAuLi5cIiwgLy8gQW4gaW50ZXJuYWxseSB0b2tlbml6ZWQgYW5kIGNvbW1hIGRlbGltaXRlZCBzdHJpbmcgYWxsb3dpbmcgcGFydGlhbCBvciBmdWxsIGNoZWNrcyBvZiB0aGUgc3ViamVjdCBmaWVsZHNcbiAgICAgKiAgICAgXCJwdWJsaWNrZXlcIjogXCIzYyBhNSAuLi5cIiwgICAgICAgICAgICAgICAgICAgICAvLyBBIGhleCBzdHJpbmcgd2l0aCBvciB3aXRob3V0IHNwYWNlc1xuICAgICAqICAgICBcInRodW1icHJpbnRcIjogXCIzYyBhNSAuLi5cIiwgICAgICAgICAgICAgICAgICAgIC8vIEEgaGV4IHN0cmluZyB3aXRoIG9yIHdpdGhvdXQgc3BhY2VzXG4gICAgICogICAgIFwidHJ1c3RlZFwiOiB0cnVlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHRoYXQgdGhlIGNlcnRpZmljYXRlIGlzIHRydXN0ZWQgYW5kIG5vdCByZXZva2VkXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUHJvdmlkaW5nIHRoaXMgaW5mb3JtYXRpb24gYXMgcGFydCBvZiB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9ucyBmb3IgYXNzZXRzIGluIGFuIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3RcbiAgICAgKiB3aWxsIGJlIGFkZGVkIGluIGEgZnV0dXJlIFJWTSB1cGRhdGU6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ0M6XFxcXFVzZXJzXFxcXEV4YW1wbGVVc2VyXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcT3BlbkZpblxcXFxPcGVuRmluUlZNLmV4ZScsXG4gICAgICogICAgIGFyZ3VtZW50czogJy0tdmVyc2lvbicsXG4gICAgICogICAgIGNlcnRpZmljYXRlOiB7XG4gICAgICogICAgICAgICB0cnVzdGVkOiB0cnVlLFxuICAgICAqICAgICAgICAgc3ViamVjdDogJ089T3BlbkZpbiBJTkMuLCBMPU5ldyBZb3JrLCBTPU5ZLCBDPVVTJyxcbiAgICAgKiAgICAgICAgIHRodW1icHJpbnQ6ICfigI4zYyBhNSAyOCAxOSA4MyAwNSBmZSA2OSA4OCBlNiA4ZiA0YiAzYSBhZiBjNSBjNSAxYiAwNyA4MCA1YidcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvY2Vzc0lkZW50aXR5KTtcbiAgICAgKiB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEl0IGlzIHBvc3NpYmxlIHRvIGxhdW5jaCBmaWxlcyB0aGF0IGhhdmUgYmVlbiBkb3dubG9hZGVkIGJ5IHRoZSB1c2VyIGJ5IGxpc3RlbmluZyB0byB0aGUgd2luZG93XG4gICAgICogYGZpbGUtZG93bmxvYWQtY29tcGxldGVkYCBldmVudCBhbmQgdXNpbmcgdGhlIGBmaWxlVXVpZGAgcHJvdmlkZWQgYnkgdGhlIGV2ZW50OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogd2luLmFkZExpc3RlbmVyKCdmaWxlLWRvd25sb2FkLWNvbXBsZXRlZCcsIChldnQpID0+IHtcbiAgICAgKiAgICAgaWYgKGV2dC5zdGF0ZSA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgKiAgICAgICAgIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgICAgICAgICBmaWxlVXVpZDogZXZ0LmZpbGVVdWlkLFxuICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50czogJycsXG4gICAgICogICAgICAgICAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgYXNzZXRzIHNwZWNpZmllZCBpbiB0aGUgYXBwIG1hbmlmZXN0OlxuICAgICAqXG4gICAgICogU2FtcGxlIGFwcEFzc2V0cyBzZWN0aW9uIGluIGFwcC5qc29uXG4gICAgICogYGBganNcbiAgICAgKiAgICAgXCJhcHBBc3NldHNcIjogW1xuICAgICAqICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgIFwic3JjXCI6IFwiaHR0cDovL2ZpbGVzYW1wbGVzLmNvbS9leGUuemlwXCIsXG4gICAgICogICAgICAgICAgICAgXCJhbGlhc1wiOiBcIm15QXBwXCIsXG4gICAgICogICAgICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNC4xMi44XCIsXG4gICAgICogICAgICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcC5leGVcIixcbiAgICAgKiAgICAgICAgICAgICBcImFyZ3NcIjogXCJhIGIgYyBkXCJcbiAgICAgKiAgICAgICAgIH0sXG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgXCJzcmNcIjogXCJodHRwOi8vZXhhbXBsZXMuY29tL2V4ZS56aXBcIixcbiAgICAgKiAgICAgICAgICAgICBcImFsaWFzXCI6IFwibXlBcHAyXCIsXG4gICAgICogICAgICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNS4xMi44XCIsXG4gICAgICogICAgICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcDIuZXhlXCIsXG4gICAgICogICAgICAgICAgICAgXCJhcmdzXCI6IFwiYSBiIGNcIlxuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICBdXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBUaGlzIHBlcm1pc3Npb24gYWxsb3dzIGZvciBsYXVuY2hpbmcgb2YgYWxsIGFzc2V0cyBzcGVjaWZpZWQgaW4gdGhlIGFib3ZlIGFwcEFzc2V0cyBzZWN0aW9uLiAoXCJteUFwcFwiIGFuZCBcIm15QXBwMlwiKTpcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIFwicGVybWlzc2lvbnNcIjoge1xuICAgICAqICAgICAgICBcIlN5c3RlbVwiOiB7XG4gICAgICogICAgICAgICAgICBcImxhdW5jaEV4dGVybmFsUHJvY2Vzc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgICAgICBcImFzc2V0c1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZVxuICAgICAqICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRoaXMgcGVybWlzc2lvbiBhbGxvd3MgZm9yIGxhdW5jaGluZyBvZiBfb25seV8gdGhlIFwibXlBcHBcIiBhc3NldCBpbiB0aGUgYWJvdmUgYXBwQXNzZXRzIHNlY3Rpb24sIGFzIGRlZmluZWQgaW4gYHNyY1J1bGVzYDpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJsYXVuY2hFeHRlcm5hbFByb2Nlc3NcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJhc3NldHNcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgXCJlbmFibGVkXCI6IHRydWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwic3JjUnVsZXNcIjogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIio6Ly9maWxlc2FtcGxlcy5jb20vKlwiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYmVoYXZpb3JcIjogXCJhbGxvd1wiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibWF0Y2hcIjogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI8YWxsX3VybHM+XCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJiZWhhdmlvclwiOiBcImJsb2NrXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTGF1bmNoaW5nIGRvd25sb2FkZWQgZmlsZXM6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgXCJwZXJtaXNzaW9uc1wiOiB7XG4gICAgICogICAgICAgIFwiU3lzdGVtXCI6IHtcbiAgICAgKiAgICAgICAgICAgIFwibGF1bmNoRXh0ZXJuYWxQcm9jZXNzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJlbmFibGVkXCI6IHRydWUsXG4gICAgICogICAgICAgICAgICAgICAgIFwiZG93bmxvYWRzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVGhpcyBwZXJtaXNzaW9uIGFsbG93cyB0byBsYXVuY2ggYWxsIHRoZSBleGVjdXRhYmxlczpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJsYXVuY2hFeHRlcm5hbFByb2Nlc3NcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJleGVjdXRhYmxlc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZVxuICAgICAqICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqXG4gICAgICogVGhpcyBwZXJtaXNzaW9uIG9ubHkgYWxsb3dzIGxhdW5jaGluZyBvZiBleGVjdXRhYmxlcyB3aG9zZSBmaWxlIHBhdGhzIG1hdGNoIHRoZSBjb3JyZXNwb25kaW5nIGBwYXRoUnVsZXNgOlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIFwicGVybWlzc2lvbnNcIjoge1xuICAgICAqICAgICAgICBcIlN5c3RlbVwiOiB7XG4gICAgICogICAgICAgICAgICBcImxhdW5jaEV4dGVybmFsUHJvY2Vzc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgICAgICBcImV4ZWN1dGFibGVzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlXG4gICAgICogICAgICAgICAgICAgICAgICAgICBcInBhdGhSdWxlc1wiOiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiL1dpbmRvd3MvU3lzdGVtMzIvKi5leGVcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwiYWxsb3dcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKi5leGVcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwiYmxvY2tcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgbGF1bmNoRXh0ZXJuYWxQcm9jZXNzKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZEV4dGVybmFsUHJvY2Vzc1JlcXVlc3QoJ2xhdW5jaC1leHRlcm5hbC1wcm9jZXNzJywgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1vbml0b3JzIGEgcnVubmluZyBwcm9jZXNzLiBBIHBpZCBmb3IgdGhlIHByb2Nlc3MgbXVzdCBiZSBpbmNsdWRlZCBpbiBvcHRpb25zLlxuICAgICAqIDxicj4gQSB1dWlkIG1heSBiZSBvcHRpb25hbGx5IHByb3ZpZGVkLiBJZiBub3QgcHJvdmlkZWQsIE9wZW5GaW4gd2lsbCBjcmVhdGUgYSB1dWlkIGZvciB0aGUgbmV3IHByb2Nlc3MuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJZiBhbiB1bnVzZWQgdXVpZCBpcyBwcm92aWRlZCBpbiBvcHRpb25zLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vIHV1aWQgaXMgcHJvdmlkZWQsIE9wZWZpbkZpbiB3aWxsIGFzc2lnbiBhIHV1aWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubW9uaXRvckV4dGVybmFsUHJvY2Vzcyh7XG4gICAgICogICAgIHBpZDogMTAyMDgsXG4gICAgICogICAgIHV1aWQ6ICdteS1leHRlcm5hbC1wcm9jZXNzJywgLy8gb3B0aW9uYWxcbiAgICAgKiAgICAgbGlzdGVuZXI6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IGNvbnNvbGUubG9nKHByb2Nlc3NJZGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBtb25pdG9yRXh0ZXJuYWxQcm9jZXNzKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZEV4dGVybmFsUHJvY2Vzc1JlcXVlc3QoJ21vbml0b3ItZXh0ZXJuYWwtcHJvY2VzcycsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgdGhlIHBhc3NlZCBtZXNzYWdlIGludG8gYm90aCB0aGUgbG9nIGZpbGUgYW5kIHRoZSBjb25zb2xlLlxuICAgICAqIEBwYXJhbSBsZXZlbCBUaGUgbG9nIGxldmVsIGZvciB0aGUgZW50cnkuIENhbiBiZSBlaXRoZXIgXCJpbmZvXCIsIFwid2FybmluZ1wiIG9yIFwiZXJyb3JcIlxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZSB0ZXh0XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sb2coXCJpbmZvXCIsIFwiQW4gZXhhbXBsZSBsb2cgbWVzc2FnZVwiKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdMb2cgaW5mbyBtZXNzYWdlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBsb2cobGV2ZWwsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3cml0ZS10by1sb2cnLCB7IGxldmVsLCBtZXNzYWdlIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIHBhc3NlZCBVUkwgaW4gdGhlIGRlZmF1bHQgd2ViIGJyb3dzZXIuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJdCBvbmx5IHN1cHBvcnRzIGh0dHAocykgYW5kIGZpbihzKSBwcm90b2NvbHMgYnkgZGVmYXVsdC5cbiAgICAgKiBJbiBvcmRlciB0byB1c2Ugb3RoZXIgY3VzdG9tIHByb3RvY29scywgdGhleSBoYXZlIHRvIGJlIGVuYWJsZWQgdmlhXG4gICAgICogW0FQSSBzZWN1cml0eSBzZXR0aW5nc10oaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9hcGktc2VjdXJpdHkpLlxuICAgICAqIEZpbGUgcHJvdG9jb2wgYW5kIGZpbGUgcGF0aCBhcmUgbm90IHN1cHBvcnRlZC5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSBVUkwgdG8gb3BlblxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ub3BlblVybFdpdGhCcm93c2VyKCdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtU3lzdGVtLm9wZW5VcmxXaXRoQnJvd3Nlci5odG1sJylcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnT3BlbmVkIFVSTCcpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBFeGFtcGxlIG9mIHBlcm1pc3Npb24gZGVmaW5pdGlvbiB0byBlbmFibGUgbm9uLWRlZmF1bHQgcHJvdG9jb2xzOlxuICAgICAqXG4gICAgICogTm90ZTogcGVybWlzc2lvbiBkZWZpbml0aW9uIHNob3VsZCBiZSBzcGVjaWZpZWQgaW4gYW4gYXBwIG1hbmlmZXN0IGZpbGUgaWYgdGhlcmUgaXMgbm8gRE9TIHNldHRpbmdzLlxuICAgICAqIE90aGVyd2lzZSBpdCBoYXMgdG8gYmUgc3BlY2lmaWVkIGluIGJvdGggRE9TIGFuZCBhcHAgbWFuaWZlc3QgZmlsZXMuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJvcGVuVXJsV2l0aEJyb3dzZXJcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJwcm90b2NvbHNcIjogWyBcIm1zdGVhbXNcIiwgXCJzbGFja1wiXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgb3BlblVybFdpdGhCcm93c2VyKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ29wZW4tdXJsLXdpdGgtYnJvd3NlcicsIHsgdXJsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyByZWdpc3RyeSBlbnRyeSB1bmRlciB0aGUgSEtDVSByb290IFdpbmRvd3MgcmVnaXN0cnkga2V5IGlmIHRoZSBnaXZlbiBjdXN0b20gcHJvdG9jb2wgbmFtZSBkb2Vzbid0IGV4aXN0IG9yXG4gICAgICogb3ZlcndyaXRlcyB0aGUgZXhpc3RpbmcgcmVnaXN0cnkgZW50cnkgaWYgdGhlIGdpdmVuIGN1c3RvbSBwcm90b2NvbCBuYW1lIGFscmVhZHkgZXhpc3RzLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5IEFQSSBzZWN1cml0eSBzZXR0aW5nc30uIEl0IHJlcXVpcmVzIFJWTSAxMiBvciBoaWdoZXIgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlc2UgcHJvdG9jb2xzIGFyZSByZXNlcnZlZCBhbmQgY2Fubm90IGJlIHJlZ2lzdGVyZWQ6XG4gICAgICogLSBmaW5cbiAgICAgKiAtIGZpbnNcbiAgICAgKiAtIG9wZW5maW5cbiAgICAgKiAtIFVSSSBTY2hlbWVzIHJlZ2lzdGVyZWQgd2l0aCB7QGxpbmsgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9VUklfc2NoZW1lcyNPZmZpY2lhbF9JQU5BLXJlZ2lzdGVyZWRfc2NoZW1lcyBJQU5BfVxuICAgICAqXG4gICAgICogQHRocm93cyBpZiBhIGdpdmVuIGN1c3RvbSBwcm90b2NvbCBmYWlsZWQgdG8gYmUgcmVnaXN0ZXJlZC5cbiAgICAgKiBAdGhyb3dzIGlmIGEgbWFuaWZlc3QgVVJMIGNvbnRhaW5zIHRoZSAnJTEnIHN0cmluZy5cbiAgICAgKiBAdGhyb3dzIGlmIGEgbWFuaWZlc3QgVVJMIGNvbnRhaW5zIGEgcXVlcnkgc3RyaW5nIHBhcmFtZXRlciB3aGljaCBuYW1lIGVxdWFscyB0byB0aGUgUHJvdG9jb2wgTGF1bmNoIFJlcXVlc3QgUGFyYW1ldGVyIE5hbWUuXG4gICAgICogQHRocm93cyBpZiB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIGNvbW1hbmQgc3RyaW5nIHRoYXQgaXMgdG8gYmUgd3JpdHRlbiB0byB0aGUgcmVnaXN0cnkgZXhjZWVkcyAyMDQ4IGJ5dGVzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ucmVnaXN0ZXJDdXN0b21Qcm90b2NvbCh7cHJvdG9jb2xOYW1lOidwcm90b2NvbDEnfSkudGhlbihjb25zb2xlLmxvZykuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXJDdXN0b21Qcm90b2NvbChvcHRpb25zKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTXVzdCBwcm92aWRlIGFuIG9iamVjdCB3aXRoIGEgYHByb3RvY29sTmFtZWAgcHJvcGVydHkgaGF2aW5nIGEgc3RyaW5nIHZhbHVlLicpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdyZWdpc3Rlci1jdXN0b20tcHJvdG9jb2wnLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcmVnaXN0cnkgZW50cnkgZm9yIGEgZ2l2ZW4gY3VzdG9tIHByb3RvY29sLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5IEFQSSBzZWN1cml0eSBzZXR0aW5nc30uIEl0IHJlcXVpcmVzIFJWTSAxMiBvciBoaWdoZXIgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlc2UgcHJvdG9jb2xzIGFyZSByZXNlcnZlZCBhbmQgY2Fubm90IGJlIHVucmVnaXN0ZXJlZDpcbiAgICAgKiAtIGZpblxuICAgICAqIC0gZmluc1xuICAgICAqIC0gb3BlbmZpblxuICAgICAqIC0gVVJJIFNjaGVtZXMgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX1VSSV9zY2hlbWVzI09mZmljaWFsX0lBTkEtcmVnaXN0ZXJlZF9zY2hlbWVzIElBTkF9XG4gICAgICpcbiAgICAgKiBAdGhyb3dzIGlmIGEgcHJvdG9jb2wgZW50cnkgZmFpbGVkIHRvIGJlIHJlbW92ZWQgaW4gcmVnaXN0cnkuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXdhaXQgZmluLlN5c3RlbS51bnJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2woJ3Byb3RvY29sMScpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXJDdXN0b21Qcm90b2NvbChwcm90b2NvbE5hbWUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3VucmVnaXN0ZXItY3VzdG9tLXByb3RvY29sJywgeyBwcm90b2NvbE5hbWUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgcmVnaXN0cmF0aW9uIHN0YXRlIGZvciBhIGdpdmVuIGN1c3RvbSBwcm90b2NvbC5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIHtAbGluayBodHRwczovL2RldmVsb3BlcnMub3BlbmZpbi5jby9kb2NzL2FwaS1zZWN1cml0eSBBUEkgc2VjdXJpdHkgc2V0dGluZ3N9LiBJdCByZXF1aXJlcyBSVk0gMTIgb3IgaGlnaGVyIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGVzZSBwcm90b2NvbHMgYXJlIHJlc2VydmVkIGFuZCBjYW5ub3QgZ2V0IHN0YXRlcyBmb3IgdGhlbTpcbiAgICAgKiAtIGZpblxuICAgICAqIC0gZmluc1xuICAgICAqIC0gb3BlbmZpblxuICAgICAqIC0gVVJJIFNjaGVtZXMgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX1VSSV9zY2hlbWVzI09mZmljaWFsX0lBTkEtcmVnaXN0ZXJlZF9zY2hlbWVzIElBTkF9XG4gICAgICpcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwcm90b2NvbFN0YXRlID0gYXdhaXQgZmluLlN5c3RlbS5nZXRDdXN0b21Qcm90b2NvbFN0YXRlKCdwcm90b2NvbDEnKTtcbiAgICAgKi9cbiAgICBhc3luYyBnZXRDdXN0b21Qcm90b2NvbFN0YXRlKHByb3RvY29sTmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jdXN0b20tcHJvdG9jb2wtc3RhdGUnLCB7IHByb3RvY29sTmFtZSB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcHJvY2VzcyBlbnRyeSBmb3IgdGhlIHBhc3NlZCBVVUlEIG9idGFpbmVkIGZyb20gYSBwcmlvciBjYWxsXG4gICAgICogb2YgZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKS5cbiAgICAgKiBAcGFyYW0gdXVpZCBUaGUgVVVJRCBmb3IgYSBwcm9jZXNzIG9idGFpbmVkIGZyb20gYSBwcmlvciBjYWxsIHRvIGZpbi5kZXNrdG9wLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogXCJub3RlcGFkXCIsXG4gICAgICogICAgIGxpc3RlbmVyOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhcIlRoZSBleGl0IGNvZGVcIiwgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pXG4gICAgICogLnRoZW4oaWRlbnRpdHkgPT4gZmluLlN5c3RlbS5yZWxlYXNlRXh0ZXJuYWxQcm9jZXNzKGlkZW50aXR5LnV1aWQpKVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQcm9jZXNzIGhhcyBiZWVuIHVubWFwcGVkIScpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVsZWFzZUV4dGVybmFsUHJvY2Vzcyh1dWlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVsZWFzZS1leHRlcm5hbC1wcm9jZXNzJywgeyB1dWlkIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29scyBmb3IgdGhlIHNwZWNpZmllZCB3aW5kb3dcbiAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhpcyBpcyBhIG9iamVjdCB0aGF0IGlzIGRlZmluZWQgYnkgdGhlIElkZW50aXR5IGludGVyZmFjZVxuICAgICAqXG4gICAgICogQHR1dG9yaWFsIFN5c3RlbS5zaG93RGV2ZWxvcGVyVG9vbHNcbiAgICAgKi9cbiAgICBzaG93RGV2ZWxvcGVyVG9vbHMoaWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzaG93LWRldmVsb3Blci10b29scycsIGlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEF0dGVtcHQgdG8gY2xvc2UgYW4gZXh0ZXJuYWwgcHJvY2Vzcy4gVGhlIHByb2Nlc3Mgd2lsbCBiZSB0ZXJtaW5hdGVkIGlmIGl0XG4gICAgICogaGFzIG5vdCBjbG9zZWQgYWZ0ZXIgdGhlIGVsYXBzZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGlzIG1ldGhvZCBpcyByZXN0cmljdGVkIGJ5IGRlZmF1bHQgYW5kIG11c3QgYmUgZW5hYmxlZCB2aWFcbiAgICAgKiA8YSBocmVmPVwiaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9hcGktc2VjdXJpdHlcIj5BUEkgc2VjdXJpdHkgc2V0dGluZ3M8L2E+LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEEgb2JqZWN0IGRlZmluZWQgaW4gdGhlIFRlcm1pbmF0ZUV4dGVybmFsUmVxdWVzdFR5cGUgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICBwYXRoOiBcIm5vdGVwYWRcIixcbiAgICAgKiAgICAgbGlzdGVuZXI6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKFwiVGhlIGV4aXQgY29kZVwiLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSlcbiAgICAgKiAudGhlbihpZGVudGl0eSA9PiBmaW4uU3lzdGVtLnRlcm1pbmF0ZUV4dGVybmFsUHJvY2Vzcyh7dXVpZDogaWRlbnRpdHkudXVpZCwgdGltZW91dDoyMDAwLCBraWxsVHJlZTogZmFsc2V9KSlcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnVGVybWluYXRlIHRoZSBwcm9jZXNzJykpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB0ZXJtaW5hdGVFeHRlcm5hbFByb2Nlc3Mob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Rlcm1pbmF0ZS1leHRlcm5hbC1wcm9jZXNzJywgb3B0aW9ucykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIE9wZW5GaW4gUnVudGltZSBQcm94eSBzZXR0aW5ncy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIGNvbmZpZyBvYmplY3QgZGVmaW5lZCBpbiB0aGUgUHJveHlDb25maWcgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS51cGRhdGVQcm94eVNldHRpbmdzKHtwcm94eUFkZHJlc3M6JzEyNy4wLjAuMScsIHByb3h5UG9ydDo4MDgwLCB0eXBlOidodHRwJ30pXG4gICAgICogLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1VwZGF0ZSBwcm94eSBzdWNjZXNzZnVsbHknKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgdXBkYXRlUHJveHlTZXR0aW5ncyhvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndXBkYXRlLXByb3h5Jywgb3B0aW9ucykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgdGhlIGdpdmVuIGFwcGxpY2F0aW9uIGFzc2V0LlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cbiAgICAgKiBAcGFyYW0gYXBwQXNzZXQgQXBwIGFzc2V0IG9iamVjdFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkQXNzZXQoKSB7XG4gICAgICogICAgIGNvbnN0IGFwcEFzc2V0ID0ge1xuICAgICAqICAgICAgICAgc3JjOiBgJHsgbG9jYXRpb24ub3JpZ2luIH0vYXNzZXRzLnppcGAsXG4gICAgICogICAgICAgICBhbGlhczogJ2RpckFwcCcsXG4gICAgICogICAgICAgICB2ZXJzaW9uOiAnMS4yMy4yNCcsXG4gICAgICogICAgICAgICB0YXJnZXQ6ICdhc3NldHMvcnVuLmJhdCdcbiAgICAgKiAgICAgfTtcbiAgICAgKlxuICAgICAqICAgICByZXR1cm4gZmluLlN5c3RlbS5kb3dubG9hZEFzc2V0KGFwcEFzc2V0LCAocHJvZ3Jlc3MgPT4ge1xuICAgICAqICAgICAvL1ByaW50IHByb2dyZXNzIGFzIHdlIGRvd25sb2FkIHRoZSBhc3NldC5cbiAgICAgKiAgICAgICAgIGNvbnN0IGRvd25sb2FkZWRQZXJjZW50ID0gTWF0aC5mbG9vcigocHJvZ3Jlc3MuZG93bmxvYWRlZEJ5dGVzIC8gcHJvZ3Jlc3MudG90YWxCeXRlcykgKiAxMDApO1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coYERvd25sb2FkZWQgJHtkb3dubG9hZGVkUGVyY2VudH0lYCk7XG4gICAgICogICAgIH0pKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBkb3dubG9hZEFzc2V0KClcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3VjY2VzcycpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIC8vIGluY29tcGF0aWJsZSB3aXRoIHN0YW5kYWxvbmUgbm9kZSBwcm9jZXNzLlxuICAgIGFzeW5jIGRvd25sb2FkQXNzZXQoYXBwQXNzZXQsIHByb2dyZXNzTGlzdGVuZXIpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1mdW5jdGlvbi1yZXR1cm4tdHlwZSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgICAgIGNvbnN0IG5vb3AgPSAoKSA9PiB7IH07XG4gICAgICAgIGxldCByZXNvbHZlID0gbm9vcDtcbiAgICAgICAgbGV0IHJlamVjdCA9IG5vb3A7XG4gICAgICAgIGNvbnN0IGRvd25sb2FkQ29tcGxldGVQcm9taXNlID0gbmV3IFByb21pc2UoKHksIG4pID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUgPSB5O1xuICAgICAgICAgICAgcmVqZWN0ID0gbjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG5vZGUuanMgZW52aXJvbm1lbnQgbm90IHN1cHBvcnRlZFxuICAgICAgICBpZiAodGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgIT09ICdvcGVuZmluJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLk5vdFN1cHBvcnRlZEVycm9yKCdkb3dubG9hZEFzc2V0IG9ubHkgc3VwcG9ydGVkIGluIGFuIE9wZW5GaW4gUmVuZGVyIHByb2Nlc3MnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYWxsU2l0ZSA9IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgpO1xuICAgICAgICBjb25zdCBkb3dubG9hZElkID0gdGhpcy53aXJlLmVudmlyb25tZW50LmdldE5leHRNZXNzYWdlSWQoKS50b1N0cmluZygpO1xuICAgICAgICBjb25zdCBkbFByb2dyZXNzS2V5ID0gYGFzc2V0LWRvd25sb2FkLXByb2dyZXNzLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbEVycm9yS2V5ID0gYGFzc2V0LWRvd25sb2FkLWVycm9yLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbENvbXBsZXRlS2V5ID0gYGFzc2V0LWRvd25sb2FkLWNvbXBsZXRlLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbFByb2dyZXNzID0gKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwID0ge1xuICAgICAgICAgICAgICAgIGRvd25sb2FkZWRCeXRlczogcHJvZ3Jlc3MuZG93bmxvYWRlZEJ5dGVzLFxuICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXM6IHByb2dyZXNzLnRvdGFsQnl0ZXNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVyKHApO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjbGVhbkxpc3RlbmVycyA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihkbFByb2dyZXNzS2V5LCBkbFByb2dyZXNzKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGxFcnJvciA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgY29uc3QgeyByZWFzb24sIGVycjogZXJyb3IgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICByZWplY3QobmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvcih7IHJlYXNvbiwgZXJyb3IgfSwgY2FsbFNpdGUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGxDb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGNsZWFuTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbihkbFByb2dyZXNzS2V5LCBkbFByb2dyZXNzKSxcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbmNlKGRsRXJyb3JLZXksIGRsRXJyb3IpLFxuICAgICAgICAgICAgLy8gVE9ETzogZml4IGludGVybmFsIHR5cGVzXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICB0aGlzLm9uY2UoZGxDb21wbGV0ZUtleSwgZGxDb21wbGV0ZSlcbiAgICAgICAgXSk7XG4gICAgICAgIGNvbnN0IGRvd25sb2FkT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oYXBwQXNzZXQsIHsgZG93bmxvYWRJZCB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rvd25sb2FkLWFzc2V0JywgZG93bmxvYWRPcHRpb25zKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGRvd25sb2FkQ29tcGxldGVQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgYSB2ZXJzaW9uIG9mIHRoZSBydW50aW1lLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gRG93bmxvYWQgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gcHJvZ3Jlc3NMaXN0ZW5lciAtIGNhbGxlZCBhcyB0aGUgcnVudGltZSBpcyBkb3dubG9hZGVkIHdpdGggcHJvZ3Jlc3MgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBPbmx5IHN1cHBvcnRlZCBpbiBhbiBPcGVuRmluIFJlbmRlciBwcm9jZXNzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIHZhciBkb3dubG9hZE9wdGlvbnMgPSB7XG4gICAgICogICAgIC8vU3BlY2lmaWMgdmVyc2lvbiBudW1iZXIgcmVxdWlyZWQsIGlmIGdpdmVuIGEgcmVsZWFzZSBjaGFubmVsIHRoZSBjYWxsIHdpbGwgcHJvZHVjZSBhbiBlcnJvci5cbiAgICAgKiAgICAgdmVyc2lvbjogJzkuNjEuMzAuMSdcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZnVuY3Rpb24gb25Qcm9ncmVzcyhwcm9ncmVzcykge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgJHtNYXRoLmZsb29yKChwcm9ncmVzcy5kb3dubG9hZGVkQnl0ZXMgLyBwcm9ncmVzcy50b3RhbEJ5dGVzKSAqIDEwMCl9JWApO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZpbi5TeXN0ZW0uZG93bmxvYWRSdW50aW1lKGRvd25sb2FkT3B0aW9ucywgb25Qcm9ncmVzcykudGhlbigoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdEb3dubG9hZCBjb21wbGV0ZScpO1xuICAgICAqIH0pLmNhdGNoKGVyciA9PiAgICB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBEb3dubG9hZCBGYWlsZWQsIHdlIGNvdWxkIHJldHJ5OiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGRvd25sb2FkUnVudGltZShvcHRpb25zLCBwcm9ncmVzc0xpc3RlbmVyKSB7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlcyA9IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgpO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgLy8gbm9kZS5qcyBlbnZpcm9ubWVudCBub3Qgc3VwcG9ydGVkXG4gICAgICAgICAgICBpZiAodGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgIT09ICdvcGVuZmluJykge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgdHJhbnNwb3J0X2Vycm9yc18xJDEuTm90U3VwcG9ydGVkRXJyb3IoJ2Rvd25sb2FkUnVudGltZSBvbmx5IHN1cHBvcnRlZCBpbiBhbiBPcGVuRmluIFJlbmRlciBwcm9jZXNzJykpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRvd25sb2FkSWQgPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCBkbFByb2dyZXNzS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtcHJvZ3Jlc3MtJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbEVycm9yS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtZXJyb3ItJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbENvbXBsZXRlS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtY29tcGxldGUtJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbFByb2dyZXNzID0gKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEJ5dGVzOiBwcm9ncmVzcy5kb3dubG9hZGVkQnl0ZXMsXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXM6IHByb2dyZXNzLnRvdGFsQnl0ZXNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHByb2dyZXNzTGlzdGVuZXIocCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY2xlYW5MaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogZml4IGludGVybmFsIHR5cGVzXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZGxQcm9ncmVzc0tleSwgZGxQcm9ncmVzcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZGxFcnJvciA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgY2xlYW5MaXN0ZW5lcnMoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJlYXNvbiwgZXJyOiBlcnJvciB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvcih7IHJlYXNvbiwgZXJyb3IgfSwgY2FsbHNpdGVzKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZGxDb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggaW50ZXJuYWwgdHlwZXNcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHRoaXMub24oZGxQcm9ncmVzc0tleSwgZGxQcm9ncmVzcyk7XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggaW50ZXJuYWwgdHlwZXNcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHRoaXMub25jZShkbEVycm9yS2V5LCBkbEVycm9yKTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbmNlKGRsQ29tcGxldGVLZXksIGRsQ29tcGxldGUpO1xuICAgICAgICAgICAgY29uc3QgZG93bmxvYWRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7IGRvd25sb2FkSWQgfSk7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZG93bmxvYWQtcnVudGltZScsIGRvd25sb2FkT3B0aW9ucykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFuTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERvd25sb2FkIHByZWxvYWQgc2NyaXB0cyBmcm9tIGdpdmVuIFVSTHNcbiAgICAgKiBAcGFyYW0gc2NyaXB0cyAtIFVSTHMgb2YgcHJlbG9hZCBzY3JpcHRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHNjcmlwdHMgPSBbXG4gICAgICogICAgIHsgdXJsOiAnaHR0cDovLy4uLi9wcmVsb2FkLmpzJyB9LFxuICAgICAqICAgICB7IHVybDogJ2h0dHA6Ly8uLi4vcHJlbG9hZDIuanMnIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogZmluLlN5c3RlbS5kb3dubG9hZFByZWxvYWRTY3JpcHRzKHNjcmlwdHMpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICogICAgIHJlc3VsdHMuZm9yRWFjaCgoe3VybCwgc3VjY2VzcywgZXJyb3J9KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhgVVJMOiAke3VybH1gKTtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzOiAke3N1Y2Nlc3N9YCk7XG4gICAgICogICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRXJyb3I6ICR7ZXJyb3J9YCk7XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGRvd25sb2FkUHJlbG9hZFNjcmlwdHMoc2NyaXB0cykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rvd25sb2FkLXByZWxvYWQtc2NyaXB0cycsIHsgc2NyaXB0cyB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGRhdGEgKG5hbWUsIGlkcywgYm91bmRzKSBmb3IgYWxsIGFwcGxpY2F0aW9uIHdpbmRvd3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRBbGxFeHRlcm5hbEFwcGxpY2F0aW9ucygpXG4gICAgICogLnRoZW4oZXh0ZXJuYWxBcHBzID0+IGNvbnNvbGUubG9nKCdUb3RhbCBleHRlcm5hbCBhcHBzOiAnICsgZXh0ZXJuYWxBcHBzLmxlbmd0aCkpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRBbGxFeHRlcm5hbEFwcGxpY2F0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWV4dGVybmFsLWFwcGxpY2F0aW9ucycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYXBwIGFzc2V0IGluZm9ybWF0aW9uLlxuICAgICAqIEBwYXJhbSBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRBcHBBc3NldEluZm8oe2FsaWFzOidwcm9jZXhwJ30pLnRoZW4oYXNzZXRJbmZvID0+IGNvbnNvbGUubG9nKGFzc2V0SW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRBcHBBc3NldEluZm8ob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1hcHAtYXNzZXQtaW5mbycsIG9wdGlvbnMpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWRkaXRpb25hbCBpbmZvIG9mIGNvb2tpZXMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRDb29raWVzKHtuYW1lOiAnbXlDb29raWUnfSkudGhlbihjb29raWVzID0+IGNvbnNvbGUubG9nKGNvb2tpZXMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q29va2llcyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXRVcmwoKTtcbiAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgeyB1cmwgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWNvb2tpZXMnLCBuZXdPcHRpb25zKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBtaW5pbXVtIGxvZyBsZXZlbCBhYm92ZSB3aGljaCBsb2dzIHdpbGwgYmUgd3JpdHRlbiB0byB0aGUgT3BlbkZpbiBsb2dcbiAgICAgKiBAcGFyYW0gVGhlIG1pbmltdW0gbGV2ZWwgKGluY2x1c2l2ZSkgYWJvdmUgd2hpY2ggYWxsIGNhbGxzIHRvIGxvZyB3aWxsIGJlIHdyaXR0ZW5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnNldE1pbkxvZ0xldmVsKFwidmVyYm9zZVwiKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKFwibG9nIGxldmVsIGlzIHNldCB0byB2ZXJib3NlXCIpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgc2V0TWluTG9nTGV2ZWwobGV2ZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtbWluLWxvZy1sZXZlbCcsIHsgbGV2ZWwgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIFVVSUQgb2YgdGhlIGNvbXB1dGVyIG9uIHdoaWNoIHRoZSBydW50aW1lIGlzIGluc3RhbGxlZFxuICAgICAqIEBwYXJhbSB1dWlkIFRoZSB1dWlkIG9mIHRoZSBydW5uaW5nIGFwcGxpY2F0aW9uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5yZXNvbHZlVXVpZCgnT3BlbmZpblBPQycpLnRoZW4oZW50aXR5ID0+IGNvbnNvbGUubG9nKGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICByZXNvbHZlVXVpZCh1dWlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdyZXNvbHZlLXV1aWQnLCB7XG4gICAgICAgICAgICBlbnRpdHlLZXk6IHV1aWRcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGRhdGEgZm9yIGFsbCBleHRlcm5hbCBhcHBsaWNhdGlvbnNcbiAgICAgKiBAcGFyYW0gcmVxdWVzdGluZ0lkZW50aXR5IFRoaXMgb2JqZWN0IGlzIGRlc2NyaWJlZCBpbiB0aGUgSWRlbnRpdHkgdHlwZWRlZlxuICAgICAqIEBwYXJhbSBkYXRhIEFueSBkYXRhIHR5cGUgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICpcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgZXhlY3V0ZU9uUmVtb3RlKHJlcXVlc3RpbmdJZGVudGl0eSwgZGF0YSkge1xuICAgICAgICBkYXRhLnJlcXVlc3RpbmdJZGVudGl0eSA9IHJlcXVlc3RpbmdJZGVudGl0eTtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5mZXJyeUFjdGlvbihkYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZHMgdGhlIHNwZWNpZmVkIHZhbHVlIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIFtBUEkgc2VjdXJpdHkgc2V0dGluZ3NdKGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5KS5cbiAgICAgKiBAcGFyYW0gcm9vdEtleSAtIFRoZSByZWdpc3RyeSByb290IGtleS5cbiAgICAgKiBAcGFyYW0gc3Via2V5IC0gVGhlIHJlZ2lzdHJ5IGtleS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgcmVnaXN0cnkgdmFsdWUgbmFtZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnJlYWRSZWdpc3RyeVZhbHVlKFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsIFwiSEFSRFdBUkVcXFxcREVTQ1JJUFRJT05cXFxcU3lzdGVtXCIsIFwiQm9vdEFyY2hpdGVjdHVyZVwiKS50aGVuKHZhbCA9PiBjb25zb2xlLmxvZyh2YWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvd2luZG93cy9kZXNrdG9wL21zNjgxMzgyKHY9dnMuODUpLmFzcHggaGVyZX0gZm9yIFdpbmRvdydzIGVycm9yIGNvZGUgZGVmaW5pdGlvbnMuXG4gICAgICpcbiAgICAgKiBFeGFtcGxlIHBheWxvYWRzIG9mIGRpZmZlcmVudCByZWdpc3RyeSB0eXBlczpcbiAgICAgKlxuICAgICAqIFNlZSBsaXN0IG9mIHR5cGVzIHtAbGluayBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L3dpbmRvd3MvZGVza3RvcC9tczcyNDg4NCh2PXZzLjg1KS5hc3B4IGhlcmV9LlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvLyBSRUdfRFdPUkRcbiAgICAgKiB7XG4gICAgICogICAgIGRhdGE6IDEsXG4gICAgICogICAgIHJvb3RLZXk6IFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19EV09SRFwiLFxuICAgICAqICAgICB2YWx1ZTogXCJCYXpcIlxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIFJFR19RV09SRFxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogMTMxMDgxNDY2NzEzMzQxMTIsXG4gICAgICogICAgIHJvb3RLZXk6IFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19RV09SRFwiLFxuICAgICAqICAgICB2YWx1ZTogXCJCYXpcIlxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIFJFR19TWlxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogXCJGb29CYXJCYXpcIixcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0xPQ0FMX01BQ0hJTkVcIixcbiAgICAgKiAgICAgc3Via2V5OiBcIkZvb1xcQmFyXCIsXG4gICAgICogICAgIHR5cGU6IFwiUkVHX1NaXCIsXG4gICAgICogICAgIHZhbHVlOiBcIkJhelwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogLy8gUkVHX0VYUEFORF9TWlxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogXCJDOlxcVXNlclxcSm9obkRvZVxcQXBwRGF0YVxcTG9jYWxcIixcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0NVUlJFTlRfVVNFUlwiLFxuICAgICAqICAgICBzdWJrZXk6IFwiRm9vXFxCYXJcIixcbiAgICAgKiAgICAgdHlwZTogXCJSRUdfRVhQQU5EX1NaXCIsXG4gICAgICogICAgIHZhbHVlOiBcIkJhelwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogLy8gUkVHX01VTFRJX1NaXG4gICAgICoge1xuICAgICAqICAgICBkYXRhOiBbXG4gICAgICogICAgICAgICBcIkZvb1wiLFxuICAgICAqICAgICAgICAgXCJCYXJcIixcbiAgICAgKiAgICAgICAgIFwiQmF6XCJcbiAgICAgKiAgICAgXSxcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0NVUlJFTlRfVVNFUlwiLFxuICAgICAqICAgICBzdWJrZXk6IFwiRm9vXFxCYXJcIixcbiAgICAgKiAgICAgdHlwZTogXCJSRUdfTVVMVElfU1pcIixcbiAgICAgKiAgICAgdmFsdWU6IFwiQmF6XCJcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiAvLyBSRUdfQklOQVJZXG4gICAgICoge1xuICAgICAqICAgICBkYXRhOiB7XG4gICAgICogICAgICAgICBkYXRhOiBbXG4gICAgICogICAgICAgICAgICAgMjU1LFxuICAgICAqICAgICAgICAgICAgIDI1NSxcbiAgICAgKiAgICAgICAgICAgICAwLFxuICAgICAqICAgICAgICAgICAgIDQzLFxuICAgICAqICAgICAgICAgICAgIDU1LFxuICAgICAqICAgICAgICAgICAgIDAsXG4gICAgICogICAgICAgICAgICAgMCxcbiAgICAgKiAgICAgICAgICAgICAyNTUsXG4gICAgICogICAgICAgICAgICAgMjU1XG4gICAgICogICAgICAgICBdLFxuICAgICAqICAgICAgICAgdHlwZTogXCJCdWZmZXJcIlxuICAgICAqICAgICB9LFxuICAgICAqICAgICByb290S2V5OiBcIkhLRVlfQ1VSUkVOVF9VU0VSXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19CSU5BUllcIixcbiAgICAgKiAgICAgdmFsdWU6IFwiQmF6XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVhZFJlZ2lzdHJ5VmFsdWUocm9vdEtleSwgc3Via2V5LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlXG4gICAgICAgICAgICAuc2VuZEFjdGlvbigncmVhZC1yZWdpc3RyeS12YWx1ZScsIHtcbiAgICAgICAgICAgIHJvb3RLZXksXG4gICAgICAgICAgICBzdWJrZXksXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNhbGwgd2lsbCByZWdpc3RlciBhIHVuaXF1ZSBpZCBhbmQgcHJvZHVjZSBhIHRva2VuLlxuICAgICAqIFRoZSB0b2tlbiBjYW4gYmUgdXNlZCB0byBicm9rZXIgYW4gZXh0ZXJuYWwgY29ubmVjdGlvbi5cbiAgICAgKiBAcGFyYW0gdXVpZCAtIEEgVVVJRCBmb3IgdGhlIHJlbW90ZSBjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ucmVnaXN0ZXJFeHRlcm5hbENvbm5lY3Rpb24oXCJyZW1vdGUtY29ubmVjdGlvbi11dWlkXCIpLnRoZW4oY29ubiA9PiBjb25zb2xlLmxvZyhjb25uKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICpcbiAgICAgKiAvLyBvYmplY3QgY29tZXMgYmFjayB3aXRoXG4gICAgICogLy8gICAgIHRva2VuOiBcIjA0ODlFQUM1LTY0MDQtNEYwRC05OTNCLTkyQkI4RUFCNDQ1RFwiLCAvLyB0aGlzIHdpbGwgYmUgdW5pcXVlIGVhY2ggdGltZVxuICAgICAqIC8vICAgICB1dWlkOiBcInJlbW90ZS1jb25uZWN0aW9uLXV1aWRcIlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVnaXN0ZXJFeHRlcm5hbENvbm5lY3Rpb24odXVpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlZ2lzdGVyLWV4dGVybmFsLWNvbm5lY3Rpb24nLCB7IHV1aWQgfSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGpzb24gYmxvYiBmb3VuZCBpbiB0aGUgW2Rlc2t0b3Agb3duZXIgc2V0dGluZ3NdKGh0dHBzOi8vb3BlbmZpbi5jby9kb2N1bWVudGF0aW9uL2Rlc2t0b3Atb3duZXItc2V0dGluZ3MvKVxuICAgICAqIGZvciB0aGUgc3BlY2lmaWVkIHNlcnZpY2UuXG4gICAgICogQHBhcmFtIHNlcnZpY2VJZGVudGlmaWVyIEFuIG9iamVjdCBjb250YWluaW5nIGEgbmFtZSBrZXkgdGhhdCBpZGVudGlmaWVzIHRoZSBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgTW9yZSBpbmZvcm1hdGlvbiBhYm91dCBkZXNrdG9wIHNlcnZpY2VzIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9kZXNrdG9wLXNlcnZpY2VzKS5cbiAgICAgKiBUaGlzIGNhbGwgd2lsbCByZWplY3QgaWYgdGhlIGRlc2t0b3Agb3duZXIgc2V0dGluZ3MgZmlsZSBpcyBub3QgcHJlc2VudCwgbm90IGNvcnJlY3RseSBmb3JtYXR0ZWQsIG9yIGlmIHRoZSBzZXJ2aWNlIHJlcXVlc3RlZCBpcyBub3QgY29uZmlndXJlZCBvciBjb25maWd1cmVkIGluY29ycmVjdGx5LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEhlcmUgd2UgYXJlIHVzaW5nIHRoZSBbbGF5b3V0c10oaHR0cHM6Ly9naXRodWIuY29tL0hhZG91a2VuSU8vbGF5b3V0cy1zZXJ2aWNlKSBzZXJ2aWNlLlxuICAgICAqIGZpbi5TeXN0ZW0uZ2V0U2VydmljZUNvbmZpZ3VyYXRpb24oe25hbWU6J2xheW91dHMnfSkudGhlbihjb25zb2xlLmxvZykuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U2VydmljZUNvbmZpZ3VyYXRpb24oc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXJ2aWNlSWRlbnRpZmllci5uYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdXN0IHByb3ZpZGUgYW4gb2JqZWN0IHdpdGggYSBgbmFtZWAgcHJvcGVydHkgaGF2aW5nIGEgc3RyaW5nIHZhbHVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtc2VydmljZS1jb25maWd1cmF0aW9uJywgeyBuYW1lIH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICBhc3luYyBnZXRTeXN0ZW1BcHBDb25maWcobmFtZSkge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ011c3QgcHJvdmlkZSBhIHN0cmluZyB2YWx1ZSBmb3IgbmFtZSBvZiBzeXN0ZW0gYXBwJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtc3lzdGVtLWFwcC1jb25maWd1cmF0aW9uJywgeyBuYW1lIH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSBzeXN0ZW0gc2h1dGRvd24gaGFuZGxlciBzbyB1c2VyIGNhbiBkbyBzb21lIGNsZWFudXAgYmVmb3JlIHN5c3RlbSBpcyBzaHV0dGluZyBkb3duLlxuICAgICAqIEByZW1hcmtzIE9uY2Ugc3lzdGVtIHNodXRkb3duIHN0YXJ0cywgeW91IGFyZSB1bmFibGUgdG8gY2FuY2VsIGl0LlxuICAgICAqIEBwYXJhbSBoYW5kbGVyIHN5c3RlbSBzaHV0ZG93biBoYW5kbGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5yZWdpc3RlclNodXRkb3duSGFuZGxlcigoc2h1dGRvd25FdmVudCkgPT4ge1xuICAgICAqICAgICAgICAgLy8gc2F2ZSBzdGF0ZSBvciBjbGVhbnVwXG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnZG8gc29tZSBjbGVhbnVwIGJlZm9yZSBzaHV0ZG93bicpO1xuICAgICAqICAgICAgICAgLy8gTm90aWZ5IGFwcCBpcyByZWFkeSBmb3IgdGVybWluYXRpb24uXG4gICAgICogICAgICAgICBzaHV0ZG93bkV2ZW50LnByb2NlZWQoKTtcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTaHV0ZG93biBoYW5kbGVyIHJlZ2lzdGVyZWQhJykpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXJTaHV0ZG93bkhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLXJlZ2lzdGVyLXNodXRkb3duLWhhbmRsZXInKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBTeXN0ZW1TaHV0ZG93bkV2ZW50TmFtZSA9ICdzeXN0ZW0tc2h1dGRvd24nO1xuICAgICAgICBjb25zdCBTeXN0ZW1TaHV0ZG93bkhhbmRsZWRFdmVudE5hbWUgPSAnc3lzdGVtLXNodXRkb3duLWhhbmRsZWQnO1xuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcbiAgICAgICAgY29uc3Qgc2h1dGRvd25IYW5kbGVyID0gKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb2NlZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gbm90aWZ5IGNvcmUgdGhhdCB0aGUgYXBwIGlzIHJlYWR5IGZvciBzaHV0ZG93blxuICAgICAgICAgICAgICAgIHRoaXMud2lyZS5lbnZpcm9ubWVudC5yYWlzZUV2ZW50KGBhcHBsaWNhdGlvbi8ke1N5c3RlbVNodXRkb3duSGFuZGxlZEV2ZW50TmFtZX1gLCB7XG4gICAgICAgICAgICAgICAgICAgIHV1aWQsXG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHRvcGljOiAnYXBwbGljYXRpb24nXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaGFuZGxlcih7IHByb2NlZWQgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMub24oU3lzdGVtU2h1dGRvd25FdmVudE5hbWUsIHNodXRkb3duSGFuZGxlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNpZ25hbHMgdGhlIFJWTSB0byBwZXJmb3JtIGEgaGVhbHRoIGNoZWNrIGFuZCByZXR1cm5zIHRoZSByZXN1bHRzIGFzIGpzb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBSZXF1aXJlcyBSVk0gNS41K1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIHRyeSB7XG4gICAgICogICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBmaW4uU3lzdGVtLnJ1blJ2bUhlYWx0aENoZWNrKCk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcnVuUnZtSGVhbHRoQ2hlY2soKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncnVuLXJ2bS1oZWFsdGgtY2hlY2snKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF1bmNoIGFwcGxpY2F0aW9uIHVzaW5nIGEgbWFuaWZlc3QgVVJML3BhdGguIEl0IGRpZmZlcnMgZnJvbSBBcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdCBpbiB0aGF0IHRoaXMgQVBJIGNhbiBhY2NlcHQgYSBtYW5pZmVzdCB1c2luZyB0aGUgZmluIHByb3RvY29sLlxuICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBtYW5pZmVzdCdzIFVSTCBvciBwYXRoLlxuICAgICAqIEBwYXJhbSBvcHRzIC0gUGFyYW1ldGVycyB0aGF0IHRoZSBSVk0gd2lsbCB1c2UuXG4gICAgICpcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHJlbWFya3MgU3VwcG9ydHMgcHJvdG9jb2xzIGh0dHAvcyBhbmQgZmluL3MsIGFuZCBhbHNvIGEgbG9jYWwgcGF0aC5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgQVBJIGlzIFdpbmRvd3Mgb25seS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBUaGlzIEFQSSBjYW4gaGFuZGxlIG1vc3QgbWFuaWZlc3QgdHlwZXMuIFNvbWUgZXhhbXBsZXMgYmVsb3cuXG4gICAgICpcbiAgICAgKiBUcmFkaXRpb25hbDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdChcbiAgICAgKiAgICdodHRwczovL2RlbW9hcHBkaXJlY3Rvcnkub3BlbmYuaW4vZGVza3RvcC9jb25maWcvYXBwcy9PcGVuRmluL0hlbGxvT3BlbkZpbi9hcHAuanNvbicpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFBsYXRmb3JtOlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3QgPSBhd2FpdCBmaW4uU3lzdGVtLmxhdW5jaE1hbmlmZXN0KCdodHRwczovL29wZW5maW4uZ2l0aHViLmlvL3BsYXRmb3JtLWFwaS1wcm9qZWN0LXNlZWQvcHVibGljLmpzb24nKTtcbiAgICAgKiBjb25zb2xlLmxvZyhtYW5pZmVzdCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgdHJhZGl0aW9uYWwgbWFuaWZlc3QgaW50byBhIHBsYXRmb3JtOlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3QgPSBhd2FpdCBmaW4uU3lzdGVtLmxhdW5jaE1hbmlmZXN0KFxuICAgICAqICAgJ2h0dHBzOi8vb3BlbmZpbi5naXRodWIuaW8vcGxhdGZvcm0tYXBpLXByb2plY3Qtc2VlZC9wdWJsaWMuanNvbj9cXFxuICAgICAqICAgJCRhcHBNYW5pZmVzdFVybD1odHRwczovL2RlbW9hcHBkaXJlY3Rvcnkub3BlbmYuaW4vZGVza3RvcC9jb25maWcvXFxcbiAgICAgKiAgIGFwcHMvT3BlbkZpbi9IZWxsb09wZW5GaW4vYXBwLmpzb24nKTtcbiAgICAgKiBjb25zb2xlLmxvZyhtYW5pZmVzdCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgd2l0aCBSVk0gb3B0aW9uczpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdCgnaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9wbGF0Zm9ybS1hcGktcHJvamVjdC1zZWVkL3B1YmxpYy5qc29uJyxcbiAgICAgKiAgICAgeyBub1VpOiB0cnVlLCB1c2VyQXBwQ29uZmlnQXJnczogeyBhYmM6ICcxMjMnLCB4eXo6ICc3ODknIH0gfSk7XG4gICAgICogY29uc29sZS5sb2cobWFuaWZlc3QpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTG9jYWwgUGF0aDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gIGF3YWl0IGZpbi5TeXN0ZW0ubGF1bmNoTWFuaWZlc3QoJ2ZpbGU6Ly9jOlxcXFxwYXRoXFxcXHRvXFxcXG1hbmlmZXN0XFxcXGZpbGUuanNvbicpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIExhdW5jaGluZyB3aXRoIFJWTSAnc3Vic2NyaWJlJyBvcHRpb246XG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiBhbGxvd3MgdXNlcnMgdG8gc3Vic2NyaWJlIHRvIGFwcCB2ZXJzaW9uIHJlc29sdmVyIGV2ZW50cyB3aGVuXG4gICAgICogY2FsbGluZyBsYXVuY2hNYW5pZmVzdCB3aXRoIGZhbGxiYWNrTWFuaWZlc3RzIHNwZWNpZmllZC5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdCgnZmluczovL3N5c3RlbS1hcHBzL25vdGlmaWNhdGlvbnMvYXBwLmpzb24nLCB7IHN1YnNjcmliZTogKGxhdW5jaCkgPT4ge1xuICAgICAqIFx0XHRsYXVuY2gub24oJ2FwcC12ZXJzaW9uLXByb2dyZXNzJywgKHByb2dyZXNzKSA9PiB7XG4gICAgICogXHRcdFx0Y29uc29sZS5sb2coXCJUcnlpbmcgbWFuaWZlc3QgXCIgKyBwcm9ncmVzcy5tYW5pZmVzdClcbiAgICAgKiBcdFx0fSk7XG4gICAgICpcbiAgICAgKiBcdFx0bGF1bmNoLm9uKCdydW50aW1lLXN0YXR1cycsIChzdGF0dXMpID0+IHtcbiAgICAgKiBcdFx0XHRjb25zb2xlLmxvZyhcIlJ1bnRpbWUgc3RhdHVzOiBcIiArIEpTT04uc3RyaW5naWZ5KHN0YXR1cykpO1xuICAgICAqIFx0XHR9KTtcbiAgICAgKlxuICAgICAqIFx0XHQvLyBSVk0gaGFzIHN1Y2Nlc3NmdWxseSBmb3VuZCB0aGUgdGFyZ2V0IHJ1bnRpbWUgdmVyc2lvblxuICAgICAqIFx0XHRsYXVuY2gub24oJ2FwcC12ZXJzaW9uLWNvbXBsZXRlJywgKGNvbXBsZXRlKSA9PiB7XG4gICAgICogXHRcdFx0Y29uc29sZS5sb2coXCJQYXJlbnQgYXBwIFwiICsgY29tcGxldGUuc3JjTWFuaWZlc3QgKyBcIiByZXNvbHZlZCB0byBcIiArIGNvbXBsZXRlLm1hbmlmZXN0KTtcbiAgICAgKiBcdFx0XHRsYXVuY2gucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICogXHRcdH0pO1xuICAgICAqXG4gICAgICogXHRcdC8vIFJWTSBmYWlsZWQgdG8gZmluZCBhbiBhdmFpbGFibGUgcnVudGltZSB2ZXJzaW9uXG4gICAgICogXHRcdGxhdW5jaC5vbignYXBwLXZlcnNpb24tZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgKiBcdFx0XHRjb25zb2xlLmxvZyhcIkZhaWxlZCB0byByZXNvbHZlIFwiICsgZXJyb3Iuc3JjTWFuaWZlc3QgKyBcIiBmcm9tIHRoZSBmYWxsYmFja01hbmlmZXN0c1wiKTtcbiAgICAgKiBcdFx0XHRsYXVuY2gucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICogXHRcdH0pO1xuICAgICAqIFx0fVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGxhdW5jaE1hbmlmZXN0KG1hbmlmZXN0VXJsLCBvcHRzID0ge30pIHtcbiAgICAgICAgY29uc3QgeyBzdWJzY3JpYmUsIC4uLl9zZW5kT3B0cyB9ID0gb3B0cztcbiAgICAgICAgY29uc3Qgc2VuZE9wdHMgPSBfc2VuZE9wdHM7XG4gICAgICAgIGlmIChzdWJzY3JpYmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhdW5jaEVtaXR0ZXIgPSBuZXcgZXZlbnRzXzEkNi5FdmVudEVtaXR0ZXIoKTtcbiAgICAgICAgICAgIHN1YnNjcmliZShsYXVuY2hFbWl0dGVyKTtcbiAgICAgICAgICAgIGNvbnN0IEFwcFZlcnNpb25Qcm9ncmVzc0V2ZW50TmFtZSA9ICdhcHAtdmVyc2lvbi1wcm9ncmVzcyc7XG4gICAgICAgICAgICBjb25zdCBSdW50aW1lU3RhdHVzRXZlbnROYW1lID0gJ3J1bnRpbWUtc3RhdHVzJztcbiAgICAgICAgICAgIGNvbnN0IEFwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZSA9ICdhcHAtdmVyc2lvbi1jb21wbGV0ZSc7XG4gICAgICAgICAgICBjb25zdCBBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWUgPSAnYXBwLXZlcnNpb24tZXJyb3InO1xuICAgICAgICAgICAgLy8gYWRkIGlkIHRvIGF2b2lkIG11bHRpcGxlIGFwaSBjYWxscyBnZXR0aW5nIGR1cGxpY2F0ZWQgZXZlbnRzXG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHNlbmRPcHRzLmFwcFZlcnNpb25JZCA9IGlkO1xuICAgICAgICAgICAgY29uc3Qgc3VwcG9ydGVkRXZlbnRzID0gW1xuICAgICAgICAgICAgICAgIEFwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZSxcbiAgICAgICAgICAgICAgICBBcHBWZXJzaW9uUHJvZ3Jlc3NFdmVudE5hbWUsXG4gICAgICAgICAgICAgICAgUnVudGltZVN0YXR1c0V2ZW50TmFtZSxcbiAgICAgICAgICAgICAgICBBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWVcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBjb25zdCBjbGVhbkV2ZW50UGF5bG9hZCA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBkbyB0eXBlIGNhc3RpbmdzIGJlbG93IHRvIG1ha2Ugc3VyZSB0aGUgcmV0dXJuIHR5cGUgaXMgY29ycmVjdC5cbiAgICAgICAgICAgICAgICBjb25zdCB7IGFwcFZlcnNpb25JZCwgdG9waWMsIHR5cGU6IHR5cGVXaXRoSWQsIC4uLnJlc3QgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IHN1cHBvcnRlZEV2ZW50cy5maW5kKCh4KSA9PiB0eXBlV2l0aElkLmluY2x1ZGVzKHgpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAuLi5yZXN0LFxuICAgICAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBhcHBWZXJzaW9uTGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuUGF5bG9hZCA9IGNsZWFuRXZlbnRQYXlsb2FkKHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGxhdW5jaEVtaXR0ZXIuZW1pdChjbGVhblBheWxvYWQudHlwZSwgY2xlYW5QYXlsb2FkKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCByZW1vdmVBbGxMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihgJHtBcHBWZXJzaW9uUHJvZ3Jlc3NFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke1J1bnRpbWVTdGF0dXNFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke0FwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoYCR7QXBwVmVyc2lvbkVycm9yRXZlbnROYW1lfS4ke2lkfWAsIGFwcFZlcnNpb25MaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihgJHtBcHBWZXJzaW9uQ29tcGxldGVFdmVudE5hbWV9LiR7aWR9YCwgcmVtb3ZlQWxsTGlzdGVuZXJzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke0FwcFZlcnNpb25FcnJvckV2ZW50TmFtZX0uJHtpZH1gLCByZW1vdmVBbGxMaXN0ZW5lcnMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICB0aGlzLm9uKGAke0FwcFZlcnNpb25Qcm9ncmVzc0V2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpLFxuICAgICAgICAgICAgICAgIHRoaXMub24oYCR7UnVudGltZVN0YXR1c0V2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpLFxuICAgICAgICAgICAgICAgIHRoaXMub25jZShgJHtBcHBWZXJzaW9uQ29tcGxldGVFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKSxcbiAgICAgICAgICAgICAgICB0aGlzLm9uY2UoYCR7QXBwVmVyc2lvbkVycm9yRXZlbnROYW1lfS4ke2lkfWAsIGFwcFZlcnNpb25MaXN0ZW5lciksXG4gICAgICAgICAgICAgICAgdGhpcy5vbmNlKGAke0FwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZX0uJHtpZH1gLCByZW1vdmVBbGxMaXN0ZW5lcnMpLFxuICAgICAgICAgICAgICAgIHRoaXMub25jZShgJHtBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWV9LiR7aWR9YCwgcmVtb3ZlQWxsTGlzdGVuZXJzKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF1bmNoLW1hbmlmZXN0Jywge1xuICAgICAgICAgICAgbWFuaWZlc3RVcmwsXG4gICAgICAgICAgICBvcHRzOiBzZW5kT3B0c1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnBheWxvYWQuZGF0YS5tYW5pZmVzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUXVlcnkgcGVybWlzc2lvbiBvZiBhIHNlY3VyZWQgYXBpIGluIGN1cnJlbnQgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhcGlOYW1lIC0gVGhlIGZ1bGwgbmFtZSBvZiBhIHNlY3VyZWQgQVBJLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgYSBmdW5jdGlvbiBoYXMgYSBzdHJ1Y3R1cmVkIHBlcm1pc3Npb24gdmFsdWUsIHRoZSB2YWx1ZSBvZiBgZ3JhbnRlZGAgd2lsbCByZWZsZWN0IHRoZSBgZW5hYmxlZGAga2V5XG4gICAgICogb2YgdGhlIGNhbGwncyBwZXJtaXNzaW9ucyBsaXRlcmFsLiAgSW4gdGhpcyBjYXNlLCAqcGVybWlzc2lvbiBtYXkgc3RpbGwgYmUgZGVuaWVkIHRvIGEgY2FsbCogcGVuZGluZyBhcmd1bWVudHMgb3Igb3RoZXJcbiAgICAgKiBydW50aW1lIHN0YXRlLiAgVGhpcyBpcyBpbmRpY2F0ZWQgd2l0aCBgc3RhdGU6IHVuYXZhaWxhYmxlYC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnF1ZXJ5UGVybWlzc2lvbkZvckN1cnJlbnRDb250ZXh0KCdTeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzJykudGhlbihyZXN1bHQgPT4gY29uc29sZS5sb2cocmVzdWx0KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogLy9UaGlzIHJlc3BvbnNlIGhhcyB0aGUgZm9sbG93aW5nIHNoYXBlOlxuICAgICAqIHtcbiAgICAgKiAgICBwZXJtaXNzaW9uOiAnU3lzdGVtLmxhdW5jaEV4dGVybmFsUHJvY2VzcycsIC8vIGFwaSBmdWxsIG5hbWVcbiAgICAgKiAgICBzdGF0ZTogJ2dyYW50ZWQnLCAvLyBzdGF0ZSBvZiBwZXJtaXNzaW9uXG4gICAgICogICAgZ3JhbnRlZDogdHJ1ZVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBxdWVyeVBlcm1pc3Npb25Gb3JDdXJyZW50Q29udGV4dChhcGlOYW1lKSB7XG4gICAgICAgIGNvbnN0IGlkZW50aXR5ID0geyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCwgbmFtZTogdGhpcy53aXJlLm1lLm5hbWUgfTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncXVlcnktcGVybWlzc2lvbi1mb3ItY3VycmVudC1jb250ZXh0Jywge1xuICAgICAgICAgICAgYXBpTmFtZSxcbiAgICAgICAgICAgIGlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UucGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvLyBOb3QgZG9jdW1lbnRpbmcsIGludGVybmFsIHVzZSBvbmx5LlxuICAgIGFzeW5jIGVuYWJsZU5hdGl2ZVdpbmRvd0ludGVncmF0aW9uUHJvdmlkZXIocGVybWlzc2lvbnMpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZW5hYmxlLW5hdGl2ZS13aW5kb3ctaW50ZWdyYXRpb24tcHJvdmlkZXInLCB7IHBlcm1pc3Npb25zIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAoSW50ZXJuYWwpIFJlZ2lzdGVyIHRoZSB1c2FnZSBvZiBhIGNvbXBvbmVudCB3aXRoIGEgcGxhdGZvcm1cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9iamVjdCB3aXRoIGRhdGEgYW5kIHR5cGVcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWdpc3RlclVzYWdlKCkge1xuICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uU3lzdGVtLmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGZpbi5TeXN0ZW0ucmVnaXN0ZXJVc2FnZSh7XG4gICAgICogICAgICAgICB0eXBlOiAnd29ya3NwYWNlLWxpY2Vuc2luZycsXG4gICAgICogICAgICAgICAvLyBleGFtcGxlIHZhbHVlcyBmb3IgdGhlIGZvbGxvd2luZyBkYXRhIG9iamVjdFxuICAgICAqICAgICAgICAgZGF0YToge1xuICAgICAqICAgICAgICAgICAgIGFwaVZlcnNpb246ICcxLjAnLFxuICAgICAqICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdob21lJyxcbiAgICAgKiAgICAgICAgICAgICBjb21wb25lbnRWZXJzaW9uOiAnMS4wJyxcbiAgICAgKiAgICAgICAgICAgICBhbGxvd2VkOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgIHJlamVjdGlvbkNvZGU6ICcnXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHJlZ2lzdGVyVXNhZ2UoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBjb21wb25lbnQgYXBwbGljYXRpb24nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlZ2lzdGVyVXNhZ2UoeyBkYXRhLCB0eXBlIH0pIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlZ2lzdGVyLXVzYWdlJywgeyBkYXRhLCB0eXBlIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggYWxsIHByaW50ZXJzIG9mIHRoZSBjYWxsZXIgYW5kIG5vdCBhbGwgdGhlIHByaW50ZXJzIG9uIHRoZSBkZXNrdG9wLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0UHJpbnRlcnMoKVxuICAgICAqICAgICAudGhlbigocHJpbnRlcnMpID0+IHtcbiAgICAgKiAgICAgICAgIHByaW50ZXJzLmZvckVhY2goKHByaW50ZXIpID0+IHtcbiAgICAgKiAgICAgICAgICAgICBpZiAocHJpbnRlci5pc0RlZmF1bHQpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocHJpbnRlcik7XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH0pXG4gICAgICogICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRQcmludGVycygpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLWdldC1wcmludGVycycpO1xuICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIFByb2Nlc3MgTG9nZ2luZyB2YWx1ZXM6IHBlcmlvZGljIGludGVydmFsIGFuZCBvdXRsaWVyIGRldGVjdGlvbiBlbnRyaWVzIGFuZCBpbnRlcnZhbC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBQcm9jZXNzIExvZ2dpbmcgdXBkYXRhYmxlIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXaGVuIGVuYWJsaW5nIHZlcmJvc2UgbW9kZSwgYWRkaXRpb25hbCBwcm9jZXNzIGluZm9ybWF0aW9uIGlzIGxvZ2dlZCB0byB0aGUgZGVidWcubG9nOlxuICAgICAqXG4gICAgICogMS4gUGVyaW9kaWNhbGx5IHByb2Nlc3MgdXNhZ2UgKG1lbW9yeSwgY3B1LCBldGMpIHdpbGwgYmUgbG9nZ2VkIGZvciBlYWNoIFBJRCBhbG9uZyB3aXRoIHRoZSB3aW5kb3dzLCB2aWV3cyBhbmRcbiAgICAgKiBpZnJhbWVzIHRoYXQgYmVsb25nIHRvIHRoZW0uIFRoZSBkZWZhdWx0IGlzIGV2ZXJ5IDMwIHNlY29uZHMuIFVwZGF0YWJsZSBieSBwYXNzaW5nIHRoZSBpbnRlcnZhbCBvcHRpb24uXG4gICAgICogMi4gV2hlbiBXaW5kb3dzIGFuZCBWaWV3cyBhcmUgY3JlYXRlZCBvciBuYXZpZ2F0ZWQgdGhlIFBJRCB0aGV5IGJlbG9uZyB0byBhbmQgdGhlaXIgb3B0aW9ucyB3aWxsIGJlIGxvZ2dlZC5cbiAgICAgKiAzLiBXaGVuIFdpbmRvd3MgYW5kIFZpZXdzIGFyZSBkZXN0cm95ZWQgdGhlaXIgbGFzdCBrbm93biBwcm9jZXNzIHVzYWdlIHdpbGwgYmUgbG9nZ2VkLlxuICAgICAqIDQuIFdoZW5ldmVyIGFuIG91dGxpZXIgbWVtb3J5IHVzYWdlIGlzIGRldGVjdGVkIGl0IHdpbGwgYmUgbG9nZ2VkLiBCeSBkZWZhdWx0LCBvbiBhbiBpbnRlcnZhbCBvZiA1IHNlY29uZHMgd2Ugd2lsbFxuICAgICAqIGNvbGxlY3QgcHJvY2VzcyB1c2FnZSBmb3IgYWxsIFBJRHMgYW5kIHdoZW4gMTQ0IHN1Y2ggZW50cmllcyBhcmUgY29sbGVjdGVkLCB3ZSB3aWxsIHN0YXJ0IGFuYWx5emluZyB0aGUgZGF0YSBmb3IgYW55XG4gICAgICogcG9zc2libGUgb3V0bGllcnMgaW4gdGhlIGZvbGxvd2luZyBlbnRyaWVzLiBUaGUgaW50ZXJ2YWwgYW5kIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgc3RvcmVkIGluIHRoZSBydW5uaW5nIGJ1ZmZlclxuICAgICAqIGNhbiBiZSB1cGRhdGFibGUgYnkgcGFzc2luZyB0aGUgb3V0bGllckRldGVjdGlvbi5pbnRlcnZhbCBhbmQgb3V0bGllckRldGVjdGlvbi5lbnRyaWVzIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBhd2FpdCBmaW4uU3lzdGVtLnVwZGF0ZVByb2Nlc3NMb2dnaW5nT3B0aW9ucyh7XG4gICAgICogICAgIGludGVydmFsOiAxMCxcbiAgICAgKiAgICAgb3V0bGllckRldGVjdGlvbjoge1xuICAgICAqICAgICAgICAgaW50ZXJ2YWw6IDE1LFxuICAgICAqICAgICAgICAgZW50cmllczogMjAwXG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVQcm9jZXNzTG9nZ2luZ09wdGlvbnMob3B0aW9ucykge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLXVwZGF0ZS1wcm9jZXNzLWxvZ2dpbmctb3B0aW9ucycsIHsgb3B0aW9ucyB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBkb21haW4gc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLlxuICAgICAqIEluaXRpYWwgc2V0dGluZ3MgYXJlIGNvbmZpZ3VyZWQgd2l0aCB0aGUgZGVmYXVsdERvbWFpblNldHRpbmdzIGFwcGxpY2F0aW9uIG9wdGlvbiB2aWEgbWFuaWZlc3QuXG4gICAgICogRG9tYWluIHNldHRpbmdzIGNhbiBiZSBvdmVyd3JpdHRlbiBkdXJpbmcgcnVudGltZSB3aXRoIFN5c3RlbS5zZXREb21haW5TZXR0aW5ncy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZG9tYWluU2V0dGluZ3MgPSBhd2FpdCBmaW4uU3lzdGVtLmdldERvbWFpblNldHRpbmdzKCk7XG4gICAgICogLy8ge1xuICAgICAqIC8vICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJodHRwczovL29wZW5maW4uY29cIlxuICAgICAqIC8vICAgICAgICAgICAgIF0sXG4gICAgICogLy8gICAgICAgICAgICAgXCJvcHRpb25zXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJkb3dubG9hZFNldHRpbmdzXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgIFwicnVsZXNcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjxhbGxfdXJscz5cIlxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwicHJvbXB0XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgKiAvLyAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICB9XG4gICAgICogLy8gICAgIF1cbiAgICAgKiAvLyB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0RG9tYWluU2V0dGluZ3MoKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZG9tYWluLXNldHRpbmdzJywgdGhpcy5pZGVudGl0eSk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBkb21haW4gc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLlxuICAgICAqIEBwYXJhbSBkb21haW5TZXR0aW5ncyAtIGRvbWFpbiBzZXR0aW5ncyBvYmplY3RcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZG9tYWluU2V0dGluZ3MgPSBhd2FpdCBmaW4uU3lzdGVtLmdldERvbWFpblNldHRpbmdzKCk7XG4gICAgICogLy8ge1xuICAgICAqIC8vICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJodHRwczovL29wZW5maW4uY29cIlxuICAgICAqIC8vICAgICAgICAgICAgIF0sXG4gICAgICogLy8gICAgICAgICAgICAgXCJvcHRpb25zXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJkb3dubG9hZFNldHRpbmdzXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgIFwicnVsZXNcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjxhbGxfdXJscz5cIlxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwicHJvbXB0XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgKiAvLyAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICB9XG4gICAgICogLy8gICAgIF1cbiAgICAgKiAvLyB9XG4gICAgICpcbiAgICAgKiAvLyBWYWxpZCBydWxlIGJlaGF2aW9ycyBhcmUgJ3Byb21wdCcgYW5kICduby1wcm9tcHQnXG4gICAgICogZG9tYWluU2V0dGluZ3MucnVsZXNbMF0ub3B0aW9ucy5kb3dubG9hZFNldHRpbmdzLnJ1bGVzWzBdLmJlaGF2aW9yID0gJ25vLXByb21wdCc7XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4uU3lzdGVtLnNldERvbWFpblNldHRpbmdzKGRvbWFpblNldHRpbmdzKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IG5ld0RvbWFpblNldHRpbmdzID0gYXdhaXQgZmluLlN5c3RlbS5nZXREb21haW5TZXR0aW5ncygpO1xuICAgICAqIC8vIHtcbiAgICAgKiAvLyAgICAgXCJydWxlc1wiOiBbXG4gICAgICogLy8gICAgICAgICB7XG4gICAgICogLy8gICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgIFwiaHR0cHM6Ly9vcGVuZmluLmNvXCJcbiAgICAgKiAvLyAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgIFwib3B0aW9uc1wiOiB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgIFwiZG93bmxvYWRTZXR0aW5nc1wiOiB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibWF0Y2hcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI8YWxsX3VybHM+XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJiZWhhdmlvclwiOiBcIm5vLXByb21wdFwiXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAqIC8vICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgfVxuICAgICAqIC8vICAgICAgICAgfVxuICAgICAqIC8vICAgICBdXG4gICAgICogLy8gfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHNldERvbWFpblNldHRpbmdzKGRvbWFpblNldHRpbmdzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtZG9tYWluLXNldHRpbmdzJywgeyBkb21haW5TZXR0aW5ncywgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIGV4dGVuc2lvbnMgZm9yIHRoZSBzZWN1cml0eSByZWFsbS4gIFVzZXJzIG1heSB3YW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbiBpbiByZXNwb25zZVxuICAgICAqIHRvIGFuIGBleHRlbnNpb25zLWluc3RhbGwtZmFpbGVkYCBldmVudC4gIE9ubHkgZXh0ZW5zaW9ucyBhbGxvd2VkIGJ5IGV2ZXJ5IGFwcGxpY2F0aW9uIG9uIHRoZSBjdXJyZW50IHNlY3VyaXR5IHJlYWxtXG4gICAgICogd2lsbCBiZSBpbnN0YWxsZWQvZW5hYmxlZC5cbiAgICAgKi9cbiAgICBhc3luYyByZWZyZXNoRXh0ZW5zaW9ucygpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVmcmVzaC1leHRlbnNpb25zJyk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGN1cnJlbnRseS1pbnN0YWxsZWRcbiAgICAgKi9cbiAgICBhc3luYyBnZXRJbnN0YWxsZWRFeHRlbnNpb25zKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtaW5zdGFsbGVkLWV4dGVuc2lvbnMnKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG59XG5zeXN0ZW0uU3lzdGVtID0gU3lzdGVtO1xuXG52YXIgaW50ZXJhcHBidXMgPSB7fTtcblxudmFyIHJlZkNvdW50ZXIgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlZkNvdW50ZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xucmVmQ291bnRlci5SZWZDb3VudGVyID0gdm9pZCAwO1xuY2xhc3MgUmVmQ291bnRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudG9waWNSZWZNYXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIC8vIHJldHVybnMgdGhlIHJlZiBjb3VudCBhZnRlciBpbmNyZW1lbnRpbmdcbiAgICBpbmNSZWZDb3VudChrZXkpIHtcbiAgICAgICAgY29uc3QgcmVmQ291bnQgPSB0aGlzLnRvcGljUmVmTWFwLmdldChrZXkpO1xuICAgICAgICBsZXQgcmV0dXJuQ291bnQ7XG4gICAgICAgIGlmICghcmVmQ291bnQpIHtcbiAgICAgICAgICAgIHRoaXMudG9waWNSZWZNYXAuc2V0KGtleSwgMSk7XG4gICAgICAgICAgICByZXR1cm5Db3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWZDb3VudCA9IHJlZkNvdW50ICsgMTtcbiAgICAgICAgICAgIHJldHVybkNvdW50ID0gbmV3UmVmQ291bnQ7XG4gICAgICAgICAgICB0aGlzLnRvcGljUmVmTWFwLnNldChrZXksIG5ld1JlZkNvdW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuQ291bnQ7XG4gICAgfVxuICAgIC8vIHJldHVybnMgdGhlIHJlZiBjb3VudCBhZnRlciBkZWNyZW1lbnRpbmcsIG9yIC0xIGlmIHRoZSBrZXkgYWxyZWFkeSBoYWQgbm8gcmVmZXJlbmNlc1xuICAgIGRlY1JlZkNvdW50KGtleSkge1xuICAgICAgICBjb25zdCByZWZDb3VudCA9IHRoaXMudG9waWNSZWZNYXAuZ2V0KGtleSk7XG4gICAgICAgIGxldCByZXR1cm5Db3VudDtcbiAgICAgICAgaWYgKHJlZkNvdW50KSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWZDb3VudCA9IHJlZkNvdW50IC0gMTtcbiAgICAgICAgICAgIHRoaXMudG9waWNSZWZNYXAuc2V0KGtleSwgbmV3UmVmQ291bnQpO1xuICAgICAgICAgICAgcmV0dXJuQ291bnQgPSBuZXdSZWZDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybkNvdW50ID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldHVybkNvdW50O1xuICAgIH1cbiAgICAvLyBFeGVjdXRlIGZpcnN0QWN0aW9uIGlmIGl0IGlzIHRoZSBmaXJzdCBzdWNoIHJlZiwgZWxzZSBleGVjdXRlIG5vbkZpcnN0QWN0aW9uLlxuICAgIC8vIEluIGVpdGhlciBjYXNlIHRoZSByZXR1cm4gdmFsdWUgaXMgdGhhdCBvZiB0aGUgYWN0aW9uIGV4ZWN1dGVkXG4gICAgYWN0T25GaXJzdChrZXksIGZpcnN0QWN0aW9uLCBub25GaXJzdEFjdGlvbikge1xuICAgICAgICBjb25zdCBudW1SZWZzID0gdGhpcy5pbmNSZWZDb3VudChrZXkpO1xuICAgICAgICBjb25zdCBpc0ZpcnN0UmVmID0gbnVtUmVmcyA9PT0gMTtcbiAgICAgICAgcmV0dXJuIGlzRmlyc3RSZWYgPyBmaXJzdEFjdGlvbigpIDogbm9uRmlyc3RBY3Rpb24oKTtcbiAgICB9XG4gICAgLy8gRXhlY3V0ZSBsYXN0QWN0aW9uIGlmIGl0IGlzIHRoZSBmaXJzdCBzdWNoIHJlZiwgZWxzZSBleGVjdXRlIG5vbkxhc3RBY3Rpb24uXG4gICAgLy8gSW4gZWl0aGVyIGNhc2UgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGF0IG9mIHRoZSBhY3Rpb24gZXhlY3V0ZWRcbiAgICBhY3RPbkxhc3Qoa2V5LCBsYXN0QWN0aW9uLCBub25MYXN0QWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IG51bVJlZnMgPSB0aGlzLmRlY1JlZkNvdW50KGtleSk7XG4gICAgICAgIGNvbnN0IGlzTGFzdFJlZiA9IG51bVJlZnMgPT09IDA7XG4gICAgICAgIHJldHVybiBpc0xhc3RSZWYgPyBsYXN0QWN0aW9uKCkgOiBub25MYXN0QWN0aW9uKCk7XG4gICAgfVxufVxucmVmQ291bnRlci5SZWZDb3VudGVyID0gUmVmQ291bnRlcjtcblxudmFyIGNoYW5uZWwkMSA9IHt9O1xuXG52YXIgY2xpZW50ID0ge307XG5cbnZhciBjaGFubmVsID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWwuQ2hhbm5lbEJhc2UgPSBjaGFubmVsLlByb3RlY3RlZEl0ZW1zID0gdm9pZCAwO1xuY29uc3QgcmVzdWx0T3JQYXlsb2FkID0gKGZ1bmMpID0+IGFzeW5jICh0b3BpYywgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBmdW5jKHRvcGljLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSk7XG4gICAgcmV0dXJuIHJlcyA9PT0gdW5kZWZpbmVkID8gcGF5bG9hZCA6IHJlcztcbn07XG5jbGFzcyBQcm90ZWN0ZWRJdGVtcyB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY29uc3RydWN0b3JcbiAgICBjb25zdHJ1Y3Rvcihwcm92aWRlcklkZW50aXR5LCBjbG9zZSkge1xuICAgICAgICB0aGlzLnByb3ZpZGVySWRlbnRpdHkgPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICB0aGlzLmNsb3NlID0gY2xvc2U7XG4gICAgfVxufVxuY2hhbm5lbC5Qcm90ZWN0ZWRJdGVtcyA9IFByb3RlY3RlZEl0ZW1zO1xuY2xhc3MgQ2hhbm5lbEJhc2Uge1xuICAgIHN0YXRpYyBkZWZhdWx0QWN0aW9uKHRvcGljKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gYWN0aW9uIHJlZ2lzdGVyZWQgYXQgdGFyZ2V0IGZvciAke3RvcGljfWApO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBhc3luYyBwcm9jZXNzQWN0aW9uKHRvcGljLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbWFpbkFjdGlvbiA9IHRoaXMuc3Vic2NyaXB0aW9ucy5oYXModG9waWMpXG4gICAgICAgICAgICAgICAgPyB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KHRvcGljKVxuICAgICAgICAgICAgICAgIDogKGN1cnJlbnRQYXlsb2FkLCBpZCkgPT4gKHRoaXMuZGVmYXVsdEFjdGlvbiA/PyBDaGFubmVsQmFzZS5kZWZhdWx0QWN0aW9uKSh0b3BpYywgY3VycmVudFBheWxvYWQsIGlkKTtcbiAgICAgICAgICAgIGNvbnN0IHByZUFjdGlvblByb2Nlc3NlZCA9IHRoaXMucHJlQWN0aW9uID8gYXdhaXQgdGhpcy5wcmVBY3Rpb24odG9waWMsIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KSA6IHBheWxvYWQ7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25Qcm9jZXNzZWQgPSBhd2FpdCBtYWluQWN0aW9uKHByZUFjdGlvblByb2Nlc3NlZCwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucG9zdEFjdGlvbiA/IGF3YWl0IHRoaXMucG9zdEFjdGlvbih0b3BpYywgYWN0aW9uUHJvY2Vzc2VkLCBzZW5kZXJJZGVudGl0eSkgOiBhY3Rpb25Qcm9jZXNzZWQ7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVycm9yTWlkZGxld2FyZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yTWlkZGxld2FyZSh0b3BpYywgZSwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBtaWRkbGV3YXJlIHRoYXQgZmlyZXMgYmVmb3JlIHRoZSBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZnVuY1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIENoYW5uZWwgUHJvdmlkZXI6XG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBwcm92aWRlci5iZWZvcmVBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vVGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBiZWZvcmUgaGFuZGxpbmcgdGhlIGFjdGlvbi5cbiAgICAgKiAgICAgICAgIHBheWxvYWQucmVjZWl2ZWQgPSBEYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNsaWVudC5iZWZvcmVBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vVGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBiZWZvcmUgaGFuZGxpbmcgdGhlIGFjdGlvbi5cbiAgICAgKiAgICAgICAgIHBheWxvYWQucmVjZWl2ZWQgPSBEYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3Byb3ZpZGVyLWFjdGlvbicsIHsgbWVzc2FnZTogJ0hlbGxvIEZyb20gdGhlIGNsaWVudCcgfSk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHByb3ZpZGVyUmVzcG9uc2UpO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYmVmb3JlQWN0aW9uKGZ1bmMpIHtcbiAgICAgICAgaWYgKHRoaXMucHJlQWN0aW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FscmVhZHkgcmVnaXN0ZXJlZCBiZWZvcmVBY3Rpb24gbWlkZGxld2FyZScpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJlQWN0aW9uID0gcmVzdWx0T3JQYXlsb2FkKGZ1bmMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBlcnJvciBoYW5kbGVyLiBUaGlzIGlzIGNhbGxlZCBiZWZvcmUgcmVzcG9uZGluZyBvbiBhbnkgZXJyb3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZnVuY1xuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAgICAgKiAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGVycm9yJyk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uRXJyb3IoKGFjdGlvbiwgZXJyb3IsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygndW5jYXVnaHQgRXhjZXB0aW9uIGluIGFjdGlvbjonLCBhY3Rpb24pO1xuICAgICAqICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAgICAgKiAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGVycm9yJyk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNsaWVudC5vbkVycm9yKChhY3Rpb24sIGVycm9yLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3VuY2F1Z2h0IEV4Y2VwdGlvbiBpbiBhY3Rpb246JywgYWN0aW9uKTtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIG9uRXJyb3IoZnVuYykge1xuICAgICAgICBpZiAodGhpcy5lcnJvck1pZGRsZXdhcmUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWxyZWFkeSByZWdpc3RlcmVkIGVycm9yIG1pZGRsZXdhcmUnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVycm9yTWlkZGxld2FyZSA9IGZ1bmM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIG1pZGRsZXdhcmUgdGhhdCBmaXJlcyBhZnRlciB0aGUgYWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZ1bmNcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIElmIHRoZSBhY3Rpb24gZG9lcyBub3QgcmV0dXJuIHRoZSBwYXlsb2FkLCB0aGVuIHRoZSBhZnRlckFjdGlvbiB3aWxsIG5vdCBoYXZlIGFjY2VzcyB0byB0aGUgcGF5bG9hZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHByb3ZpZGVyLmFmdGVyQWN0aW9uKChhY3Rpb24sIHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICAvL3RoZSBwYXlsb2FkIGNhbiBiZSBhbHRlcmVkIGhlcmUgYWZ0ZXIgaGFuZGxpbmcgdGhlIGFjdGlvbiBidXQgYmVmb3JlIHNlbmRpbmcgYW4gYWNrbm93bGVkZ2VtZW50LlxuICAgICAqICAgICAgICAgcGF5bG9hZC5zZW50ID0gZGF0ZS5ub3coKTtcbiAgICAgKiAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBDaGFubmVsIENsaWVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IGNsaWVudC5yZWdpc3RlcignY2xpZW50LWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBjbGllbnQuYWZ0ZXJBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vdGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBhZnRlciBoYW5kbGluZyB0aGUgYWN0aW9uIGJ1dCBiZWZvcmUgc2VuZGluZyBhbiBhY2tub3dsZWRnZW1lbnQuXG4gICAgICogICAgICAgICBwYXlsb2FkLnNlbnQgPSBkYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhZnRlckFjdGlvbihmdW5jKSB7XG4gICAgICAgIGlmICh0aGlzLnBvc3RBY3Rpb24pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWxyZWFkeSByZWdpc3RlcmVkIGFmdGVyQWN0aW9uIG1pZGRsZXdhcmUnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBvc3RBY3Rpb24gPSByZXN1bHRPclBheWxvYWQoZnVuYyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBhY3Rpb24gYnkgYWN0aW9uIG5hbWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHByb3ZpZGVyLnJlbW92ZSgncHJvdmlkZXItYWN0aW9uJyk7XG4gICAgICpcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHJlbW92ZShhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShhY3Rpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSBkZWZhdWx0IGFjdGlvbi4gVGhpcyBpcyB1c2VkIGFueSB0aW1lIGFuIGFjdGlvbiB0aGF0IGhhcyBub3QgYmVlbiByZWdpc3RlcmVkIGlzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5zZXREZWZhdWx0QWN0aW9uKChhY3Rpb24sIHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhgQ2xpZW50IHdpdGggaWRlbnRpdHkgJHtKU09OLnN0cmluZ2lmeShpZGVudGl0eSl9IGhhcyBhdHRlbXB0ZWQgdG8gZGlzcGF0Y2ggdW5yZWdpc3RlcmVkIGFjdGlvbjogJHthY3Rpb259LmApO1xuICAgICAqXG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50LnNldERlZmF1bHRBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGBQcm92aWRlciB3aXRoIGlkZW50aXR5ICR7SlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpfSBoYXMgYXR0ZW1wdGVkIHRvIGRpc3BhdGNoIHVucmVnaXN0ZXJlZCBhY3Rpb246ICR7YWN0aW9ufS5gKTtcbiAgICAgKlxuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICogQHBhcmFtIGZ1bmNcbiAgICAgKi9cbiAgICBzZXREZWZhdWx0QWN0aW9uKGZ1bmMpIHtcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdEFjdGlvbikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZWZhdWx0IGFjdGlvbiBjYW4gb25seSBiZSBzZXQgb25jZScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0QWN0aW9uID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBhY3Rpb24gdG8gYmUgY2FsbGVkIGJ5IGRpc3BhdGNoaW5nIGZyb20gYW55IGNoYW5uZWxDbGllbnQgb3IgY2hhbm5lbFByb3ZpZGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRvcGljXG4gICAgICogQHBhcmFtIGxpc3RlbmVyXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgYmUgc2VudCBiYWNrIGFzIGFuIGFja25vd2xlZGdlbWVudCB0byB0aGUgb3JpZ2luYWwgY2FsbGVyLiBZb3UgY2FuIHRocm93IGFuXG4gICAgICogZXJyb3IgdG8gc2VuZCBhIG5lZ2F0aXZlLWFja25vd2xlZGdlbWVudCBhbmQgdGhlIGVycm9yIHdpbGwgcmVqZWN0IHRoZSBwcm9taXNlIHJldHVybmVkIHRvIHRoZSBzZW5kZXIgYnkgdGhlXG4gICAgICogZGlzcGF0Y2ggY2FsbC4gIE9uY2UgYSBsaXN0ZW5lciBpcyByZWdpc3RlcmVkIGZvciBhIHBhcnRpY3VsYXIgYWN0aW9uLCBpdCBzdGF5cyBpbiBwbGFjZSByZWNlaXZpbmcgYW5kIHJlc3BvbmRpbmdcbiAgICAgKiB0byBpbmNvbWluZyBtZXNzYWdlcyB1bnRpbCBpdCBpcyByZW1vdmVkLiAgVGhpcyBtZXNzYWdpbmcgbWVjaGFuaXNtIHdvcmtzIGV4YWN0bHkgdGhlIHNhbWUgd2hlbiBtZXNzYWdlcyBhcmVcbiAgICAgKiBkaXNwYXRjaGVkIGZyb20gdGhlIHByb3ZpZGVyIHRvIGEgY2xpZW50LiAgSG93ZXZlciwgdGhlIHByb3ZpZGVyIGhhcyBhbiBhZGRpdGlvbmFsIHB1Ymxpc2ggbWV0aG9kIHRoYXQgc2VuZHMgbWVzc2FnZXNcbiAgICAgKiB0byBhbGwgY29ubmVjdGVkIGNsaWVudHMuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIG11bHRpcGxlIGNsaWVudHMgY2FuIHNoYXJlIHRoZSBzYW1lIGBuYW1lYCBhbmQgYHV1aWRgLCBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGluZGl2aWR1YWwgY2xpZW50cyxcbiAgICAgKiB0aGUgYGlkZW50aXR5YCBhcmd1bWVudCBpbiBhIHByb3ZpZGVyJ3MgcmVnaXN0ZXJlZCBhY3Rpb24gY2FsbGJhY2sgY29udGFpbnMgYW4gYGVuZHBvaW50SWRgIHByb3BlcnR5LiBXaGVuIGRpc3BhdGNoaW5nXG4gICAgICogZnJvbSBhIHByb3ZpZGVyIHRvIGEgY2xpZW50LCB0aGUgYGVuZHBvaW50SWRgIHByb3BlcnR5IG11c3QgYmUgcHJvdmlkZWQgaW4gb3JkZXIgdG8gc2VuZCBhbiBhY3Rpb24gdG8gYSBzcGVjaWZpYyBjbGllbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdBY3Rpb24gZGlzcGF0Y2hlZCBieSBjbGllbnQ6ICcsIGlkZW50aXR5KTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgcGF5bG9hZCk7XG4gICAgICpcbiAgICAgKiAgICAgICAgcmV0dXJuIHsgZWNobzogcGF5bG9hZCB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBDaGFubmVsIENsaWVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IGNsaWVudC5yZWdpc3RlcignY2xpZW50LWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICBjb25zb2xlLmxvZygnQWN0aW9uIGRpc3BhdGNoZWQgYnkgY2xpZW50OiAnLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdQYXlsb2FkIHNlbnQgaW4gZGlzcGF0Y2g6ICcsIHBheWxvYWQpO1xuICAgICAqXG4gICAgICogICAgICAgIHJldHVybiB7IGVjaG86IHBheWxvYWQgfTtcbiAgICAgKiAgICB9KTtcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHJlZ2lzdGVyKHRvcGljLCBsaXN0ZW5lcikge1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25zLmhhcyh0b3BpYykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3Vic2NyaXB0aW9uIGFscmVhZHkgcmVnaXN0ZXJlZCBmb3IgYWN0aW9uOiAke3RvcGljfS4gVW5zdWJzY3JpYmUgYmVmb3JlIGFkZGluZyBuZXcgc3Vic2NyaXB0aW9uYCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KHRvcGljLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmNoYW5uZWwuQ2hhbm5lbEJhc2UgPSBDaGFubmVsQmFzZTtcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgX0NoYW5uZWxDbGllbnRfY2xvc2U7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY2xpZW50LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNsaWVudC5DaGFubmVsQ2xpZW50ID0gdm9pZCAwO1xuY29uc3QgY2hhbm5lbF8xJDEgPSBjaGFubmVsO1xuY29uc3QgY2hhbm5lbENsaWVudHNCeUVuZHBvaW50SWQgPSBuZXcgTWFwKCk7XG4vKipcbiAqIEluc3RhbmNlIGNyZWF0ZWQgdG8gZW5hYmxlIHVzZSBvZiBhIGNoYW5uZWwgYXMgYSBjbGllbnQuICBBbGxvd3MgZm9yIGNvbW11bmljYXRpb24gd2l0aCB0aGVcbiAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIgQ2hhbm5lbFByb3ZpZGVyfSBieSBpbnZva2luZyBhbiBhY3Rpb24gb24gdGhlXG4gKiBwcm92aWRlciB2aWEge0BsaW5rIENoYW5uZWxDbGllbnQjZGlzcGF0Y2ggZGlzcGF0Y2h9IGFuZCB0byBsaXN0ZW4gZm9yIGNvbW11bmljYXRpb25cbiAqIGZyb20gdGhlIHByb3ZpZGVyIGJ5IHJlZ2lzdGVyaW5nIGFuIGFjdGlvbiB2aWEge0BsaW5rIENoYW5uZWxDbGllbnQjcmVnaXN0ZXIgcmVnaXN0ZXJ9LlxuICpcbiAqICMjIyBTeW5jaHJvbm91cyBNZXRob2RzOlxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjb25EaXNjb25uZWN0aW9uIG9uRGlzY29ubmVjdGlvbihsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbENsaWVudCNyZWdpc3RlciByZWdpc3RlcihhY3Rpb24sIGxpc3RlbmVyKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I3JlbW92ZSByZW1vdmUoYWN0aW9uKX1cbiAqXG4gKiAjIyMgQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbENsaWVudCNkaXNjb25uZWN0IGRpc2Nvbm5lY3QoKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I2Rpc3BhdGNoIGRpc3BhdGNoKGFjdGlvbiwgcGF5bG9hZCl9XG4gKlxuICogIyMjIE1pZGRsZXdhcmU6XG4gKiBNaWRkbGV3YXJlIGZ1bmN0aW9ucyByZWNlaXZlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOiAoYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZCkuXG4gKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIG9uIGFzIHRoZSBwYXlsb2FkIGZyb20gYmVmb3JlQWN0aW9uLCB0byB0aGUgYWN0aW9uIGxpc3RlbmVyLCB0byBhZnRlckFjdGlvblxuICogdW5sZXNzIGl0IGlzIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB0aGUgb3JpZ2luYWwgcGF5bG9hZCBpcyB1c2VkLiAgTWlkZGxld2FyZSBjYW4gYmUgdXNlZCBmb3Igc2lkZSBlZmZlY3RzLlxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjc2V0RGVmYXVsdEFjdGlvbiBzZXREZWZhdWx0QWN0aW9uKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjb25FcnJvciBvbkVycm9yKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjYmVmb3JlQWN0aW9uIGJlZm9yZUFjdGlvbihtaWRkbGV3YXJlKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I2FmdGVyQWN0aW9uIGFmdGVyQWN0aW9uKG1pZGRsZXdhcmUpfVxuICovXG5jbGFzcyBDaGFubmVsQ2xpZW50IGV4dGVuZHMgY2hhbm5lbF8xJDEuQ2hhbm5lbEJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHN0YXRpYyBjbG9zZUNoYW5uZWxCeUVuZHBvaW50SWQoaWQpIHtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IGNoYW5uZWxDbGllbnRzQnlFbmRwb2ludElkLmdldChpZCk7XG4gICAgICAgIGlmIChjaGFubmVsKSB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGMoY2hhbm5lbCwgX0NoYW5uZWxDbGllbnRfY2xvc2UsIFwiZlwiKS5jYWxsKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqIGNsb3NlcyB0aGUgY29ycmVzcG9uZGluZyBjaGFubmVsIGFuZCBpbnZva2VzIHRoZSBkaXNjb25uZWN0IGxpc3RlbmVyIGlmIGFuIGV2ZW50IHBheWxvYWQgaXMgcGFzc2VkLlxuICAgICAqL1xuICAgIHN0YXRpYyBoYW5kbGVQcm92aWRlckRpc2Nvbm5lY3QoZXZlbnRQYXlsb2FkKSB7XG4gICAgICAgIGZvciAoY29uc3QgY2hhbm5lbENsaWVudCBvZiBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxDbGllbnQucHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQgPT09IGV2ZW50UGF5bG9hZC5jaGFubmVsSWQpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ2xpZW50LmRpc2Nvbm5lY3RMaXN0ZW5lcihldmVudFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyhjaGFubmVsQ2xpZW50LCBfQ2hhbm5lbENsaWVudF9jbG9zZSwgXCJmXCIpLmNhbGwoY2hhbm5lbENsaWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iocm91dGluZ0luZm8sIGNsb3NlLCBzdHJhdGVneSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBfQ2hhbm5lbENsaWVudF9wcm90ZWN0ZWRPYmouc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIF9DaGFubmVsQ2xpZW50X3N0cmF0ZWd5LnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICAvLyBuZWVkcyB0byBiZSBib3VuZDtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWN0aW9uID0gKGFjdGlvbiwgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpID0+IHN1cGVyLnByb2Nlc3NBY3Rpb24oYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSk7XG4gICAgICAgIF9DaGFubmVsQ2xpZW50X2Nsb3NlLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC5kZWxldGUodGhpcy5lbmRwb2ludElkKTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyh0aGlzLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgXCJmXCIpLmNsb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JGEodGhpcywgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBuZXcgY2hhbm5lbF8xJDEuUHJvdGVjdGVkSXRlbXMocm91dGluZ0luZm8sIGNsb3NlKSwgXCJmXCIpO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RMaXN0ZW5lciA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5lbmRwb2ludElkID0gcm91dGluZ0luZm8uZW5kcG9pbnRJZDtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCRhKHRoaXMsIF9DaGFubmVsQ2xpZW50X3N0cmF0ZWd5LCBzdHJhdGVneSwgXCJmXCIpO1xuICAgICAgICBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC5zZXQodGhpcy5lbmRwb2ludElkLCB0aGlzKTtcbiAgICAgICAgc3RyYXRlZ3kucmVjZWl2ZSh0aGlzLnByb2Nlc3NBY3Rpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBhIHJlYWQtb25seSBwcm92aWRlciBpZGVudGl0eVxuICAgICAqL1xuICAgIGdldCBwcm92aWRlcklkZW50aXR5KCkge1xuICAgICAgICBjb25zdCBwcm90ZWN0ZWRPYmogPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBcImZcIik7XG4gICAgICAgIHJldHVybiBwcm90ZWN0ZWRPYmoucHJvdmlkZXJJZGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2ggdGhlIGdpdmVuIGFjdGlvbiB0byB0aGUgY2hhbm5lbCBwcm92aWRlci4gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSByZXNwb25zZSBmcm9tXG4gICAgICogdGhlIHByb3ZpZGVyIGZvciB0aGF0IGFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb25cbiAgICAgKiBAcGFyYW0gcGF5bG9hZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3Byb3ZpZGVyLWFjdGlvbicsIHsgbWVzc2FnZTogJ0hlbGxvIEZyb20gdGhlIGNsaWVudCd9KTtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvdmlkZXJSZXNwb25zZSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBkaXNwYXRjaChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyh0aGlzLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgXCJmXCIpLmlzRW5kcG9pbnRDb25uZWN0ZWQodGhpcy5wcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfc3RyYXRlZ3ksIFwiZlwiKS5zZW5kKHRoaXMucHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQsIGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY2xpZW50IHlvdSBhcmUgdHJ5aW5nIHRvIGRpc3BhdGNoIGZyb20gaXMgZGlzY29ubmVjdGVkIGZyb20gdGhlIHRhcmdldCBwcm92aWRlci4nKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCBvbiBwcm92aWRlciBkaXNjb25uZWN0aW9uLiBJdCBpcyBwYXNzZWQgdGhlIGRpc2Nvbm5lY3Rpb24gZXZlbnQgb2YgdGhlXG4gICAgICogZGlzY29ubmVjdGluZyBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsaXN0ZW5lclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50Lm9uRGlzY29ubmVjdGlvbihldnQgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1Byb3ZpZGVyIGRpc2Nvbm5lY3RlZCcsIGB1dWlkOiAke2V2dC51dWlkfSwgbmFtZTogJHtldnQubmFtZX1gKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0TGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcihwYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdoaWxlIGNhbGxpbmcgdGhlIG9uRGlzY29ubmVjdGlvbiBjYWxsYmFjazogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEaXNjb25uZWN0cyB0aGUgY2xpZW50IGZyb20gdGhlIGNoYW5uZWwuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdCgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBjbGllbnQuZGlzY29ubmVjdCgpO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZGlzY29ubmVjdCgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zZW5kRGlzY29ubmVjdEFjdGlvbigpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfY2xvc2UsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGlzY29ubmVjdEFjdGlvbigpIHtcbiAgICAgICAgY29uc3QgcHJvdGVjdGVkT2JqID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRjKHRoaXMsIF9DaGFubmVsQ2xpZW50X3Byb3RlY3RlZE9iaiwgXCJmXCIpO1xuICAgICAgICBhd2FpdCBwcm90ZWN0ZWRPYmouY2xvc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICogV3JpdGluZyB0aGlzIGFzIGEgc3RhdGljIHRvIGtlZXAgY29kZSB0b2dldGhlciwgYnV0IGluIGVudmlyb25tZW50cyB3aXRoIGEgd2lyZSwgdGhpcyB3aWxsIGJlIERJJ2QgaW50byB0aGUgcHJvdGVjdGVkT2JqZWN0IGNsYXNzIGFzIGNsb3NlLlxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyB3aXJlQ2xvc2Uod2lyZSwgcHJvdmlkZXJJZGVudGl0eSwgZW5kcG9pbnRJZCkge1xuICAgICAgICBjb25zdCB7IGNoYW5uZWxOYW1lLCB1dWlkLCBuYW1lIH0gPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICBhd2FpdCB3aXJlLnNlbmRBY3Rpb24oJ2Rpc2Nvbm5lY3QtZnJvbS1jaGFubmVsJywge1xuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgICB1dWlkLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGVuZHBvaW50SWRcbiAgICAgICAgfSk7XG4gICAgfVxufVxuY2xpZW50LkNoYW5uZWxDbGllbnQgPSBDaGFubmVsQ2xpZW50O1xuX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqID0gbmV3IFdlYWtNYXAoKSwgX0NoYW5uZWxDbGllbnRfc3RyYXRlZ3kgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbENsaWVudF9jbG9zZSA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBjb25uZWN0aW9uTWFuYWdlciA9IHt9O1xuXG52YXIgZXhoYXVzdGl2ZSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhoYXVzdGl2ZSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leGhhdXN0aXZlLmV4aGF1c3RpdmVDaGVjayA9IHZvaWQgMDtcbmZ1bmN0aW9uIGV4aGF1c3RpdmVDaGVjayh2YWx1ZSwgYWxsb3dlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdmFsdWU6ICR7dmFsdWV9JHthbGxvd2VkID8gYFxcbiBTdXBwb3J0ZWQgdmFsdWVzIGFyZTogJHthbGxvd2VkLmpvaW4oJycpfWAgOiAnJ31gKTtcbn1cbmV4aGF1c3RpdmUuZXhoYXVzdGl2ZUNoZWNrID0gZXhoYXVzdGl2ZUNoZWNrO1xuXG52YXIgc3RyYXRlZ3kkMyA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ5ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfQ2xhc3NpY1N0cmF0ZWd5X3dpcmUsIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCwgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQ7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RyYXRlZ3kkMywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5zdHJhdGVneSQzLkNsYXNzaWNJbmZvID0gc3RyYXRlZ3kkMy5DbGFzc2ljU3RyYXRlZ3kgPSB2b2lkIDA7XG4vKlxuVGhpcyBpcyB1c2VkIHRvIGFic3RyYWN0IG91dCBpcGMgbWVzc2FnaW5nIGZyb20gdGhlIGNoYW5uZWxzIGltcGxlbWVudGF0aW9uLiBJdCBpcyBvbmx5IGNvbmNlcm5lZCB3aXRoIHNlbmRpbmcgbWVzc2FnZXMgYW5kIHJlZ2lzdHJhdGlvbiB3aXRoIHRoZSBNZXNzYWdlUmVjZWl2ZXJcbiovXG5jbGFzcyBDbGFzc2ljU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIG1lc3NhZ2VSZWNlaXZlciwgZW5kcG9pbnRJZCwgLy8gUHJvdmlkZXIgZW5kcG9pbnRJZCBpcyBjaGFubmVsSWRcbiAgICBwcm92aWRlcklkZW50aXR5KSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVyID0gbWVzc2FnZVJlY2VpdmVyO1xuICAgICAgICB0aGlzLmVuZHBvaW50SWQgPSBlbmRwb2ludElkO1xuICAgICAgICB0aGlzLnByb3ZpZGVySWRlbnRpdHkgPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICBfQ2xhc3NpY1N0cmF0ZWd5X3dpcmUuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8vIFN0b3JlIGZ1bGwgZW5kcG9pbnRJZGVudGl0eSBieSBlbmRwb2ludElkIG9mIGFsbCBrbm93biBlbmRwb2ludHMgZm9yIHRoaXMgc3RyYXRlZ3kgaW5zdGFuY2UuXG4gICAgICAgIC8vIChjbGllbnRzIHdpbGwgb25seSBoYXZlIDE6IHRoZSBwcm92aWRlciwgdGhlIHByb3ZpZGVyIHdpbGwgaGF2ZSBhbGwgY2xpZW50cylcbiAgICAgICAgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLnNldCh0aGlzLCBuZXcgTWFwKCkpO1xuICAgICAgICAvLyBTdG9yZSBhIHNldCBvZiBjYW5jZWxsYWJsZSBwcm9taXNlcyB0byBiZSBhYmxlIHRvIHJlamVjdCB0aGVtIHdoZW4gY2xpZW50XG4gICAgICAgIC8vIGNvbm5lY3Rpb24gcHJvYmxlbXMgb2NjdXJcbiAgICAgICAgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQuc2V0KHRoaXMsIG5ldyBNYXApO1xuICAgICAgICB0aGlzLnNlbmQgPSBhc3luYyAoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0byA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYih0aGlzLCBfQ2xhc3NpY1N0cmF0ZWd5X2VuZHBvaW50SWRlbnRpdHlNYXAsIFwiZlwiKS5nZXQoZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBpZiAoIXRvKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgbG9jYXRlIHJvdXRpbmcgaW5mbyBmb3IgZW5kcG9pbnQgJHtlbmRwb2ludElkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gYXMgY2FzdGluZyB0byBhbnkgYmVjYXVzZSB0eXBlc2NyaXB0IGNvbXBsYWlucy4gVGhlIGZvbGxvd2luZyBpcyBvbmx5IHJlbGV2YW50IGlmIHRoaXMgaXMgYSBsb2NhbGx5IHNldCBlbmRwb2ludElkIG9uIGEgQ2xpZW50SWRlbnRpdHkuXG4gICAgICAgICAgICAvLyBXZSBkZWxldGUgdGhlc2UgcHJvcGVydGllcyB0byBub3QgY2hhbmdlIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuICAgICAgICAgICAgY29uc3QgY2xlYW5JZCA9IHsgLi4udG8gfTtcbiAgICAgICAgICAgIGlmIChjbGVhbklkLmlzTG9jYWxFbmRwb2ludElkKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNsZWFuSWQuZW5kcG9pbnRJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBjbGVhbklkLmlzTG9jYWxFbmRwb2ludElkO1xuICAgICAgICAgICAgLy8gZ3JhYiB0aGUgcHJvbWlzZSBiZWZvcmUgYXdhaXRpbmcgaXQgdG8gc2F2ZSBpbiBvdXIgcGVuZGluZyBtZXNzYWdlcyBtYXBcbiAgICAgICAgICAgIGNvbnN0IHAgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV93aXJlLCBcImZcIilcbiAgICAgICAgICAgICAgICAuc2VuZEFjdGlvbignc2VuZC1jaGFubmVsLW1lc3NhZ2UnLCB7XG4gICAgICAgICAgICAgICAgLi4uY2xlYW5JZCxcbiAgICAgICAgICAgICAgICBwcm92aWRlcklkZW50aXR5OiB0aGlzLnByb3ZpZGVySWRlbnRpdHksXG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpPy5hZGQocCk7XG4gICAgICAgICAgICBjb25zdCByYXcgPSBhd2FpdCBwLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGNsZWFuIHVwIHRoZSBwZW5kaW5nIHByb21pc2VcbiAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQsIFwiZlwiKS5nZXQoZW5kcG9pbnRJZCk/LmRlbGV0ZShwKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJhdy5wYXlsb2FkLmRhdGEucmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNsb3NlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlUmVjZWl2ZXIucmVtb3ZlRW5kcG9pbnQodGhpcy5wcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCwgdGhpcy5lbmRwb2ludElkKTtcbiAgICAgICAgICAgIFsuLi5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikua2V5cygpXS5mb3JFYWNoKChpZCkgPT4gdGhpcy5jbG9zZUVuZHBvaW50KGlkKSk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDkodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBuZXcgTWFwKCksIFwiZlwiKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ5KHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfd2lyZSwgd2lyZSwgXCJmXCIpO1xuICAgIH1cbiAgICBvbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCBsaXN0ZW5lcikge1xuICAgICAgICAvLyBOZXZlciBmaXJlcyBmb3IgJ2NsYXNzaWMnLlxuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVyLmFkZEVuZHBvaW50KGxpc3RlbmVyLCB0aGlzLnByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkLCB0aGlzLmVuZHBvaW50SWQpO1xuICAgIH1cbiAgICBhc3luYyBjbG9zZUVuZHBvaW50KGVuZHBvaW50SWQpIHtcbiAgICAgICAgY29uc3QgaWQgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuZGVsZXRlKGVuZHBvaW50SWQpO1xuICAgICAgICBjb25zdCBwZW5kaW5nU2V0ID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpO1xuICAgICAgICBwZW5kaW5nU2V0Py5mb3JFYWNoKChwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IGBDaGFubmVsIGNvbm5lY3Rpb24gd2l0aCBpZGVudGl0eSB1dWlkOiAke2lkPy51dWlkfSAvIG5hbWU6ICR7aWQ/Lm5hbWV9IC8gZW5kcG9pbnRJZDogJHtlbmRwb2ludElkfSBubyBsb25nZXIgY29ubmVjdGVkLmA7XG4gICAgICAgICAgICBwLmNhbmNlbChuZXcgRXJyb3IoZXJyb3JNc2cpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkge1xuICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCwgXCJmXCIpLmhhcyhlbmRwb2ludElkKTtcbiAgICB9XG4gICAgYWRkRW5kcG9pbnQoZW5kcG9pbnRJZCwgcGF5bG9hZCkge1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuc2V0KGVuZHBvaW50SWQsIHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eSk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYih0aGlzLCBfQ2xhc3NpY1N0cmF0ZWd5X3BlbmRpbmdNZXNzYWdlc0J5RW5kcG9pbnRJZCwgXCJmXCIpLnNldChlbmRwb2ludElkLCBuZXcgU2V0KCkpO1xuICAgIH1cbiAgICBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuICh0eXBlb2YgcGF5bG9hZD8uZW5kcG9pbnRJZGVudGl0eT8uZW5kcG9pbnRJZCA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgICAgIHR5cGVvZiBwYXlsb2FkPy5lbmRwb2ludElkZW50aXR5Py5jaGFubmVsSWQgPT09ICdzdHJpbmcnKTtcbiAgICB9XG59XG5zdHJhdGVneSQzLkNsYXNzaWNTdHJhdGVneSA9IENsYXNzaWNTdHJhdGVneTtcbl9DbGFzc2ljU3RyYXRlZ3lfd2lyZSA9IG5ldyBXZWFrTWFwKCksIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCA9IG5ldyBXZWFrTWFwKCksIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkID0gbmV3IFdlYWtNYXAoKTtcbi8vIEFyYml0cmFyaWx5IHN0YXJ0aW5nIGF0IDUgdG8gbGVhdmUgdGhlIGRvb3Igb3BlbiB0byBiYWNrZmlsbGluZyBwcmUgZW5kcG9pbnRJZCBldGMuXG5zdHJhdGVneSQzLkNsYXNzaWNJbmZvID0geyB2ZXJzaW9uOiA1LCBtaW5pbXVtVmVyc2lvbjogMCwgdHlwZTogJ2NsYXNzaWMnIH07XG5cbnZhciBzdHJhdGVneSQyID0ge307XG5cbnZhciBlbmRwb2ludCA9IHt9O1xuXG52YXIgZXJyb3JzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlcnJvcnMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXJyb3JzLmVycm9yVG9QT0pPID0gdm9pZCAwO1xuZnVuY3Rpb24gZXJyb3JUb1BPSk8oZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFjazogZXJyb3Iuc3RhY2ssXG4gICAgICAgIG5hbWU6IGVycm9yLm5hbWUsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgIC8vIHN1cHBvcnQgdGhlIGNhc2Ugd2hlcmUgc3RhY2sgaXMgZW1wdHkgb3IgbWlzc2luZ1xuICAgICAgICB0b1N0cmluZzogKCkgPT4gZXJyb3Iuc3RhY2sgfHwgZXJyb3IudG9TdHJpbmcoKVxuICAgIH07XG59XG5lcnJvcnMuZXJyb3JUb1BPSk8gPSBlcnJvclRvUE9KTztcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkOCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24sIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZW5kcG9pbnQsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZW5kcG9pbnQuUlRDRW5kcG9pbnQgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IGVycm9yc18xJDEgPSBlcnJvcnM7XG4vKlxuVGhpcyBoYW5kbGVzIHNlbmRpbmcgUlRDIG1lc3NhZ2VzIGJldHdlZW4gUlRDIGNvbm5lY3Rpb25zIG92ZXIgdGhlIHJlcXVlc3QgYW5kIHJlc3BvbnNlIGRhdGEgY2hhbm5lbHMuXG4qL1xuY2xhc3MgUlRDRW5kcG9pbnQge1xuICAgIHN0YXRpYyBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgaXNPYmplY3QgPSAoeCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnb2JqZWN0JyAmJiB4ICE9PSBudWxsO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAvLyBUT0RPIGluIGZhY3RvcnkgUFI6XG4gICAgICAgIC8vIHBheWxvYWQudHlwZSA9PT0gJ3J0YycgJiZcbiAgICAgICAgaXNPYmplY3QocGF5bG9hZCkgJiZcbiAgICAgICAgICAgIGlzT2JqZWN0KHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eSkgJiZcbiAgICAgICAgICAgIGlzT2JqZWN0KHBheWxvYWQucnRjKSAmJlxuICAgICAgICAgICAgdHlwZW9mIHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eS5lbmRwb2ludElkID09PSAnc3RyaW5nJyk7XG4gICAgfVxuICAgIGNvbnN0cnVjdG9yKHsgcnRjLCBlbmRwb2ludElkZW50aXR5IH0pIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZU1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24uc2V0KHRoaXMsIG51bGwpO1xuICAgICAgICBfUlRDRW5kcG9pbnRfZGlzY29ubmVjdExpc3RlbmVyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnJ0Yy5ydGNDbGllbnQuY29ubmVjdGlvblN0YXRlICE9PSAnY29ubmVjdGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCRhKHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIFwiZlwiKSkge1xuICAgICAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X2Rpc2Nvbm5lY3RMaXN0ZW5lciwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNlbmQgPSBhc3luYyAoYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlSWQgPSBgbWVzc2FnZS0ke01hdGgucmFuZG9tKCl9YDtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNwb25zZU1hcC5zZXQobWVzc2FnZUlkLCB7IHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVxdWVzdC5zZW5kKEpTT04uc3RyaW5naWZ5KHsgYWN0aW9uLCBwYXlsb2FkLCBtZXNzYWdlSWQgfSkpO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2xvc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwLmZvckVhY2goKHJlc3BvbnNlKSA9PiByZXNwb25zZS5yZWplY3QoJ0Nvbm5lY3Rpb24gaGFzIGNsb3NlZC4nKSk7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVxdWVzdC5jbG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5jbG9zZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJ0YyA9IHJ0YztcbiAgICAgICAgdGhpcy5lbmRwb2ludElkZW50aXR5ID0gZW5kcG9pbnRJZGVudGl0eTtcbiAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIChlKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkYXRhIH0gPSBlO1xuICAgICAgICAgICAgaWYgKGUuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShlLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBtZXNzYWdlSWQsIHBheWxvYWQsIHN1Y2Nlc3MsIGVycm9yIH0gPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgICAgY29uc3QgeyByZXNvbHZlLCByZWplY3QgfSA9IHRoaXMucmVzcG9uc2VNYXAuZ2V0KG1lc3NhZ2VJZCkgPz8ge307XG4gICAgICAgICAgICBpZiAocmVzb2x2ZSAmJiByZWplY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwLmRlbGV0ZShtZXNzYWdlSWQpO1xuICAgICAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDb3VsZCBub3QgZmluZCBpZCBpbiByZXNwb25zZU1hcC4nKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucnRjLmNoYW5uZWxzLnJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkYXRhIH0gPSBlO1xuICAgICAgICAgICAgaWYgKGUuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShlLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBtZXNzYWdlSWQsIGFjdGlvbiwgcGF5bG9hZCB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpLmNhbGwodGhpcywgYWN0aW9uLCBwYXlsb2FkLCBlbmRwb2ludElkZW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2Uuc2VuZChKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiByZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFJUQ0RhdGFDaGFubmVsIGlzIG9wZW4gYmVmb3JlIHNlbmRpbmcsIGVycm9yIGdldHMgc3dhbGxvd2VkIGhlcmUgaW4gdGhlIGNhc2Ugd2hlcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xpZW50IGRpc3BhdGNoZWQgdGhlbiBjbG9zZWQgb3IgZGlzY29ubmVjdGVkIGJlZm9yZSB0aGUgZGlzcGF0Y2ggcmVzb2x2ZXMuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJ0Yy5jaGFubmVscy5yZXNwb25zZS5yZWFkeVN0YXRlID09PSAnb3BlbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucnRjLmNoYW5uZWxzLnJlc3BvbnNlLnNlbmQoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKDAsIGVycm9yc18xJDEuZXJyb3JUb1BPSk8pKGVycm9yKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFJUQ0RhdGFDaGFubmVsIGlzIG9wZW4gZm9yIHNhbWUgcmVhc29uIGFzIGNhdGNoIGJsb2NrIGFib3ZlLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2Uuc2VuZChKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiAnQ29ubmVjdGlvbiBub3QgcmVhZHkuJ1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5hZGRFdmVudExpc3RlbmVyKCdjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIpO1xuICAgICAgICAvLyBEaXNjb25uZWN0IGlmIGRhdGEgY2hhbm5lbHMgY2xvc2UgdW5leHBlY3RlZGx5LCBlLmcuIGNhbiBoYXBwZW4gZHVlIHRvIG1lc3NhZ2Ugc2l6ZSA+IH4yNTVrQiAoUlRDUGVlckNvbm5lY3Rpb24uc2N0cC5tYXhNZXNzYWdlU2l6ZUxpbWl0OiAyNjIxNDQpXG4gICAgICAgIE9iamVjdC52YWx1ZXModGhpcy5ydGMuY2hhbm5lbHMpLmZvckVhY2goKGRhdGFjaGFubmVsKSA9PiB7XG4gICAgICAgICAgICBkYXRhY2hhbm5lbC5vbmNsb3NlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICBbLi4udGhpcy5yZXNwb25zZU1hcC52YWx1ZXMoKV0uZm9yRWFjaCgocHJvbWlzZSkgPT4gcHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdSVENEYXRhQ2hhbm5lbCBjbG9zZWQgdW5leHBlY3RlZGx5LCB0aGlzIGlzIG1vc3QgY29tbW9ubHkgY2F1c2VkIGJ5IG1lc3NhZ2Ugc2l6ZS4gTm90ZTogUlRDIENoYW5uZWxzIGhhdmUgYSBtZXNzYWdlIHNpemUgbGltaXQgb2YgfjI1NWtCLicpKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X2Rpc2Nvbm5lY3RMaXN0ZW5lciwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfZGlzY29ubmVjdExpc3RlbmVyLCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgb25EaXNjb25uZWN0KGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCRhKHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIFwiZlwiKSkge1xuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ4KHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIGxpc3RlbmVyLCBcImZcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JUQ0VuZHBvaW50IGRpc2Nvbm5lY3RMaXN0ZW5lciBjYW5ub3QgYmUgc2V0IHR3aWNlLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlY2VpdmUobGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBoYXZlIGFscmVhZHkgc2V0IGEgbGlzdGVuZXIgZm9yIHRoaXMgUlRDIEVuZHBvaW50LicpO1xuICAgICAgICB9XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkOCh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgbGlzdGVuZXIsIFwiZlwiKTtcbiAgICB9XG4gICAgZ2V0IGNvbm5lY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucnRjLnJ0Y0NsaWVudC5jb25uZWN0aW9uU3RhdGUgPT09ICdjb25uZWN0ZWQnO1xuICAgIH1cbn1cbmVuZHBvaW50LlJUQ0VuZHBvaW50ID0gUlRDRW5kcG9pbnQ7XG5fUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgc3RyYXRlZ3kkMSA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ3ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0cmF0ZWd5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3RyYXRlZ3kkMS5FbmRwb2ludFN0cmF0ZWd5ID0gdm9pZCAwO1xuY2xhc3MgRW5kcG9pbnRTdHJhdGVneSB7XG4gICAgLy8gTmVlZCB0byBwYXNzIGluIHZhbGlkYXRlIGVuZHBvaW50IHNlcGFyYXRlbHkgZnJvbSBjb25zdHJ1Y3RvciBiZWNhdXNlIHRzIGludGVyZmFjZXMgZG9uJ3QgZG8gd2VsbCB3aXRoIHN0YXRpYyBtZXRob2RzXG4gICAgY29uc3RydWN0b3IoRW5kcG9pbnRUeXBlLCB2YWxpZGF0ZUVuZHBvaW50LCBTdHJhdGVneU5hbWUpIHtcbiAgICAgICAgdGhpcy5FbmRwb2ludFR5cGUgPSBFbmRwb2ludFR5cGU7XG4gICAgICAgIHRoaXMuU3RyYXRlZ3lOYW1lID0gU3RyYXRlZ3lOYW1lO1xuICAgICAgICBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLnNldCh0aGlzLCBudWxsKTtcbiAgICAgICAgX0VuZHBvaW50U3RyYXRlZ3lfZW5kcG9pbnRNYXAuc2V0KHRoaXMsIG5ldyBNYXAoKSk7XG4gICAgICAgIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZC5zZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2VuZCA9IGFzeW5jIChlbmRwb2ludElkLCBhY3Rpb24sIHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVuZHBvaW50QnlJZChlbmRwb2ludElkKS5zZW5kKGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2xvc2UgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuZm9yRWFjaCgoZW5kcG9pbnQpID0+IGVuZHBvaW50LmNsb3NlKCkpO1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNyh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgbmV3IE1hcCgpLCBcImZcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDcodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkLCBmYWxzZSwgXCJmXCIpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmlzVmFsaWRFbmRwb2ludFBheWxvYWQgPSB2YWxpZGF0ZUVuZHBvaW50O1xuICAgIH1cbiAgICBvbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmdldEVuZHBvaW50QnlJZChlbmRwb2ludElkKS5vbkRpc2Nvbm5lY3QobGlzdGVuZXIpO1xuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDkodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdSBoYXZlIGFscmVhZHkgc2V0IGEgbGlzdGVuZXIgZm9yIHRoaXMgJHt0aGlzLlN0cmF0ZWd5TmFtZX0gU3RyYXRlZ3lgKTtcbiAgICAgICAgfVxuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDcodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiwgbGlzdGVuZXIsIFwiZlwiKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuZm9yRWFjaCgoZW5kcG9pbnQpID0+IGVuZHBvaW50LnJlY2VpdmUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSkpO1xuICAgIH1cbiAgICBnZXRFbmRwb2ludEJ5SWQoZW5kcG9pbnRJZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgXCJmXCIpLmdldChlbmRwb2ludElkKTtcbiAgICAgICAgaWYgKCFlbmRwb2ludCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBlbmRwb2ludCBpZCAke2VuZHBvaW50SWR9IGlzIG5vdCBjb25uZWN0ZWRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW5kcG9pbnQ7XG4gICAgfVxuICAgIGdldCBjb25uZWN0ZWQoKSB7XG4gICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDkodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkLCBcImZcIik7XG4gICAgfVxuICAgIGlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkge1xuICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuaGFzKGVuZHBvaW50SWQpO1xuICAgIH1cbiAgICBhZGRFbmRwb2ludChlbmRwb2ludElkLCBwYXlsb2FkKSB7XG4gICAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEFkZGluZyBlbmRwb2ludCB0byBkaXNjb25uZWN0ZWQgJHt0aGlzLlN0cmF0ZWd5TmFtZX0gU3RyYXRlZ3lgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGllbnRTdHJhdCA9IG5ldyB0aGlzLkVuZHBvaW50VHlwZShwYXlsb2FkKTtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLCBcImZcIikpIHtcbiAgICAgICAgICAgIGNsaWVudFN0cmF0LnJlY2VpdmUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuc2V0KGVuZHBvaW50SWQsIGNsaWVudFN0cmF0KTtcbiAgICB9XG4gICAgYXN5bmMgY2xvc2VFbmRwb2ludChlbmRwb2ludElkKSB7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgXCJmXCIpLmRlbGV0ZShlbmRwb2ludElkKTtcbiAgICB9XG59XG5zdHJhdGVneSQxLkVuZHBvaW50U3RyYXRlZ3kgPSBFbmRwb2ludFN0cmF0ZWd5O1xuX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwID0gbmV3IFdlYWtNYXAoKSwgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkID0gbmV3IFdlYWtNYXAoKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0cmF0ZWd5JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3RyYXRlZ3kkMi5SVENJbmZvID0gc3RyYXRlZ3kkMi5SVENTdHJhdGVneSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuLyogZXNsaW50LWRpc2FibGUgY2xhc3MtbWV0aG9kcy11c2UtdGhpcyAqL1xuY29uc3QgZW5kcG9pbnRfMSA9IGVuZHBvaW50O1xuY29uc3Qgc3RyYXRlZ3lfMSQxID0gc3RyYXRlZ3kkMTtcbi8qXG5UaGlzIGlzIHVzZWQgdG8gYWJzdHJhY3Qgb3V0IHJ0YyBtZXNzYWdpbmcgZnJvbSB0aGUgY2hhbm5lbHMgaW1wbGVtZW50YXRpb24gdXNpbmcgUlRDRW5kcG9pbnRzLlxuKi9cbmNsYXNzIFJUQ1N0cmF0ZWd5IGV4dGVuZHMgc3RyYXRlZ3lfMSQxLkVuZHBvaW50U3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihlbmRwb2ludF8xLlJUQ0VuZHBvaW50LCBlbmRwb2ludF8xLlJUQ0VuZHBvaW50LmlzVmFsaWRFbmRwb2ludFBheWxvYWQsICdSVEMnKTtcbiAgICB9XG59XG5zdHJhdGVneSQyLlJUQ1N0cmF0ZWd5ID0gUlRDU3RyYXRlZ3k7XG5zdHJhdGVneSQyLlJUQ0luZm8gPSB7IHZlcnNpb246IDIsIG1pbmltdW1WZXJzaW9uOiAwLCB0eXBlOiAncnRjJyB9O1xuXG52YXIgaWNlTWFuYWdlciA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoaWNlTWFuYWdlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5pY2VNYW5hZ2VyLlJUQ0lDRU1hbmFnZXIgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEkaCA9IGJhc2U7XG4vKlxuU2luZ2xldG9uIHRoYXQgZmFjaWxpdGF0ZXMgT2ZmZXIgYW5kIEFuc3dlciBleGNoYW5nZSByZXF1aXJlZCBmb3IgZXN0YWJsaXNoaW5nIFJUQyBjb25uZWN0aW9ucy5cbiovXG5jbGFzcyBSVENJQ0VNYW5hZ2VyIGV4dGVuZHMgYmFzZV8xJGguRW1pdHRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgJ2NoYW5uZWwnKTtcbiAgICAgICAgdGhpcy5lbnN1cmVDaGFubmVsT3BlbmVkID0gKGNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNoYW5uZWwucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hhbm5lbC5yZWFkeVN0YXRlID09PSAnY29ubmVjdGluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29wZW4nLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWwuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1RoaXMgQ2hhbm5lbCBoYXMgYWxyZWFkeSBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UobGFiZWwsIHJ0Y0NsaWVudCkge1xuICAgICAgICBsZXQgcmVzb2x2ZXI7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZXIgPSByZXNvbHZlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3Blbkxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGUuY2hhbm5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdvcGVuJywgb3Blbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlcihlLmNoYW5uZWwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChlLmNoYW5uZWwubGFiZWwgPT09IGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgZS5jaGFubmVsLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBvcGVuTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHJ0Y0NsaWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdkYXRhY2hhbm5lbCcsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcnRjQ2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RhdGFjaGFubmVsJywgbGlzdGVuZXIpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgYXN5bmMgbGlzdGVuRm9yUHJvdmlkZXJJY2UocnRjQ29ubmVjdGlvbklkLCBsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKHRoaXMuY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSwgbGlzdGVuZXIsIHsgdGltZXN0YW1wOiBEYXRlLm5vdygpIH0pO1xuICAgIH1cbiAgICBhc3luYyByYWlzZVByb3ZpZGVySWNlKHJ0Y0Nvbm5lY3Rpb25JZCwgcGF5bG9hZCkge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuZW52aXJvbm1lbnQucmFpc2VFdmVudCh0aGlzLmNyZWF0ZVJvdXRlU3RyaW5nKHRoaXMuY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSksIHBheWxvYWQpO1xuICAgIH1cbiAgICBhc3luYyBsaXN0ZW5Gb3JDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKHRoaXMuY3JlYXRlQ2xpZW50RXZlbnROYW1lKHJ0Y0Nvbm5lY3Rpb25JZCksIGxpc3RlbmVyLCB7IHRpbWVzdGFtcDogRGF0ZS5ub3coKSB9KTtcbiAgICB9XG4gICAgYXN5bmMgcmFpc2VDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBwYXlsb2FkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5yYWlzZUV2ZW50KHRoaXMuY3JlYXRlUm91dGVTdHJpbmcodGhpcy5jcmVhdGVDbGllbnRFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSksIHBheWxvYWQpO1xuICAgIH1cbiAgICBjbGVhbnVwSWNlTGlzdGVuZXJzKHJ0Y0Nvbm5lY3Rpb25JZCkge1xuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyh0aGlzLmNyZWF0ZUNsaWVudEV2ZW50TmFtZShydGNDb25uZWN0aW9uSWQpKTtcbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnModGhpcy5jcmVhdGVQcm92aWRlckV2ZW50TmFtZShydGNDb25uZWN0aW9uSWQpKTtcbiAgICB9XG4gICAgY3JlYXRlQ2xpZW50RXZlbnROYW1lKHJ0Y0Nvbm5lY3Rpb25JZCkge1xuICAgICAgICByZXR1cm4gYGljZS1jbGllbnQtJHtydGNDb25uZWN0aW9uSWR9YDtcbiAgICB9XG4gICAgY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSB7XG4gICAgICAgIHJldHVybiBgaWNlLXByb3ZpZGVyLSR7cnRjQ29ubmVjdGlvbklkfWA7XG4gICAgfVxuICAgIGNyZWF0ZVJvdXRlU3RyaW5nKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGBjaGFubmVsLyR7bmFtZX1gO1xuICAgIH1cbiAgICBjcmVhdGVSdGNQZWVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LmdldFJ0Y1BlZXIoKTtcbiAgICB9XG4gICAgYXN5bmMgc3RhcnRDbGllbnRPZmZlcigpIHtcbiAgICAgICAgLy8gVE9ETyByZXBsYWNlIHdpdGggcmVhbCBndWlkLlxuICAgICAgICBjb25zdCBydGNDb25uZWN0aW9uSWQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IHJ0Y0NsaWVudCA9IHRoaXMuY3JlYXRlUnRjUGVlcigpO1xuICAgICAgICBydGNDbGllbnQuYWRkRXZlbnRMaXN0ZW5lcignaWNlY2FuZGlkYXRlJywgYXN5bmMgKGUpID0+IHtcbiAgICAgICAgICAgIGlmIChlLmNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmFpc2VDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCB7IGNhbmRpZGF0ZTogZS5jYW5kaWRhdGU/LnRvSlNPTigpIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5saXN0ZW5Gb3JQcm92aWRlckljZShydGNDb25uZWN0aW9uSWQsIGFzeW5jIChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBydGNDbGllbnQuYWRkSWNlQ2FuZGlkYXRlKHBheWxvYWQuY2FuZGlkYXRlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0ge1xuICAgICAgICAgICAgcmVxdWVzdDogcnRjQ2xpZW50LmNyZWF0ZURhdGFDaGFubmVsKCdyZXF1ZXN0JyksXG4gICAgICAgICAgICByZXNwb25zZTogcnRjQ2xpZW50LmNyZWF0ZURhdGFDaGFubmVsKCdyZXNwb25zZScpXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG9mZmVyID0gYXdhaXQgcnRjQ2xpZW50LmNyZWF0ZU9mZmVyKCk7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgY29uc3QgY2hhbm5lbHNPcGVuZWQgPSBQcm9taXNlLmFsbChbY2hhbm5lbHMucmVxdWVzdCwgY2hhbm5lbHMucmVzcG9uc2VdLm1hcCh0aGlzLmVuc3VyZUNoYW5uZWxPcGVuZWQpKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiB7IHJ0Y0NsaWVudCwgY2hhbm5lbHMsIG9mZmVyLCBydGNDb25uZWN0aW9uSWQsIGNoYW5uZWxzT3BlbmVkIH07XG4gICAgfVxuICAgIGFzeW5jIGZpbmlzaENsaWVudE9mZmVyKHJ0Y0NsaWVudCwgYW5zd2VyLCBwcm92aWRlclJlYWR5KSB7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpO1xuICAgICAgICBhd2FpdCBwcm92aWRlclJlYWR5O1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlUHJvdmlkZXJBbnN3ZXIocnRjQ29ubmVjdGlvbklkLCBvZmZlcikge1xuICAgICAgICBjb25zdCBydGNDbGllbnQgPSB0aGlzLmNyZWF0ZVJ0Y1BlZXIoKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdENoYW5uZWxQcm9taXNlID0gUlRDSUNFTWFuYWdlci5jcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UoJ3JlcXVlc3QnLCBydGNDbGllbnQpO1xuICAgICAgICBjb25zdCByZXNwb25zZUNoYW5uZWxQcm9taXNlID0gUlRDSUNFTWFuYWdlci5jcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UoJ3Jlc3BvbnNlJywgcnRjQ2xpZW50KTtcbiAgICAgICAgcnRjQ2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2ljZWNhbmRpZGF0ZScsIGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBpZiAoZS5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJhaXNlUHJvdmlkZXJJY2UocnRjQ29ubmVjdGlvbklkLCB7IGNhbmRpZGF0ZTogZS5jYW5kaWRhdGU/LnRvSlNPTigpIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5saXN0ZW5Gb3JDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBhc3luYyAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgcnRjQ2xpZW50LmFkZEljZUNhbmRpZGF0ZShwYXlsb2FkLmNhbmRpZGF0ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBydGNDbGllbnQuc2V0UmVtb3RlRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICBjb25zdCBhbnN3ZXIgPSBhd2FpdCBydGNDbGllbnQuY3JlYXRlQW5zd2VyKCk7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcik7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gUHJvbWlzZS5hbGwoW3JlcXVlc3RDaGFubmVsUHJvbWlzZSwgcmVzcG9uc2VDaGFubmVsUHJvbWlzZV0pLnRoZW4oKFtyZXF1ZXN0LCByZXNwb25zZV0pID0+IHtcbiAgICAgICAgICAgIC8vIENsZWFuIHVwIGljZSBldmVudHMuXG4gICAgICAgICAgICB0aGlzLmNsZWFudXBJY2VMaXN0ZW5lcnMocnRjQ29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHJldHVybiB7IHJlcXVlc3QsIHJlc3BvbnNlIH07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcnRjQ2xpZW50LFxuICAgICAgICAgICAgYW5zd2VyLFxuICAgICAgICAgICAgY2hhbm5lbHNcbiAgICAgICAgfTtcbiAgICB9XG59XG5pY2VNYW5hZ2VyLlJUQ0lDRU1hbmFnZXIgPSBSVENJQ0VNYW5hZ2VyO1xuXG52YXIgcHJvdmlkZXIgPSB7fTtcblxudmFyIHJ1bnRpbWVWZXJzaW9uaW5nID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShydW50aW1lVmVyc2lvbmluZywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5ydW50aW1lVmVyc2lvbmluZy5ydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uID0gcnVudGltZVZlcnNpb25pbmcucGFyc2VSdW50aW1lVXVpZCA9IHJ1bnRpbWVWZXJzaW9uaW5nLm1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uID0gdm9pZCAwO1xuZnVuY3Rpb24gdk51bSh4KSB7XG4gICAgcmV0dXJuIFsuLi54LnNwbGl0KCcuJykucmV2ZXJzZSgpLmVudHJpZXMoKV0ucmVkdWNlKChwLCBbaSwgdl0pID0+IHAgKyArdiAqIDEwMDAwICoqIGksIDApO1xufVxuLypcbiAgQ29tcGFyZXMgcnVudGltZSB2ZXJzaW9ucyB0byBzZWUgaWYgdGhlIGN1cnJlbnQgcnVudGltZSBtZWV0cyB5b3VyIGRlc2lyZWQgbWluaW11bS5cbiovXG5mdW5jdGlvbiBtZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbihjdXJyZW50VmVyc2lvbiwgbWluVmVyc2lvbikge1xuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uUGFyc2VkID0gdk51bShjdXJyZW50VmVyc2lvbik7XG4gICAgY29uc3QgbWluVmVyc2lvblBhcnNlZCA9IHZOdW0obWluVmVyc2lvbik7XG4gICAgcmV0dXJuIGN1cnJlbnRWZXJzaW9uUGFyc2VkID49IG1pblZlcnNpb25QYXJzZWQ7XG59XG5ydW50aW1lVmVyc2lvbmluZy5tZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbiA9IG1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uO1xuLy8gU3RyaXBzIHRoZSBwb3J0IGluZm8gZnJvbSB0aGUgcnVudGltZVV1aWQsIGxlYXZpbmcganVzdCB0aGUgcnVudGltZSB2ZXJzaW9uLlxuZnVuY3Rpb24gcGFyc2VSdW50aW1lVXVpZChydW50aW1lVXVpZCkge1xuICAgIHJldHVybiBydW50aW1lVXVpZC5zcGxpdCgnLycpWzBdO1xufVxucnVudGltZVZlcnNpb25pbmcucGFyc2VSdW50aW1lVXVpZCA9IHBhcnNlUnVudGltZVV1aWQ7XG5mdW5jdGlvbiBydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uKHJ1bnRpbWVVdWlkLCBtaW5WZXJzaW9uKSB7XG4gICAgY29uc3QgcnVudGltZVZlcnNpb24gPSBwYXJzZVJ1bnRpbWVVdWlkKHJ1bnRpbWVVdWlkKTtcbiAgICByZXR1cm4gbWVldHNNaW5pbXVtUnVudGltZVZlcnNpb24ocnVudGltZVZlcnNpb24sIG1pblZlcnNpb24pO1xufVxucnVudGltZVZlcnNpb25pbmcucnVudGltZVV1aWRNZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbiA9IHJ1bnRpbWVVdWlkTWVldHNNaW5pbXVtUnVudGltZVZlcnNpb247XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDggPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIF9DaGFubmVsUHJvdmlkZXJfcHJvdGVjdGVkT2JqLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBfQ2hhbm5lbFByb3ZpZGVyX3JlbW92ZUVuZHBvaW50LCBfQ2hhbm5lbFByb3ZpZGVyX2Nsb3NlO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3ZpZGVyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnByb3ZpZGVyLkNoYW5uZWxQcm92aWRlciA9IHZvaWQgMDtcbmNvbnN0IGNoYW5uZWxfMSA9IGNoYW5uZWw7XG5jb25zdCBydW50aW1lVmVyc2lvbmluZ18xID0gcnVudGltZVZlcnNpb25pbmc7XG4vKipcbiAqIEluc3RhbmNlIGNyZWF0ZWQgdG8gZW5hYmxlIHVzZSBvZiBhIGNoYW5uZWwgYXMgYSBwcm92aWRlci4gQWxsb3dzIGZvciBjb21tdW5pY2F0aW9uIHdpdGggdGhlIHtAbGluayBDaGFubmVsQ2xpZW50IENoYW5uZWxDbGllbnRzfSBieSBpbnZva2luZyBhbiBhY3Rpb24gb25cbiAqIGEgc2luZ2xlIGNsaWVudCB2aWEge0BsaW5rIENoYW5uZWxQcm92aWRlciNkaXNwYXRjaCBkaXNwYXRjaH0gb3IgYWxsIGNsaWVudHMgdmlhIHtAbGluayBDaGFubmVsUHJvdmlkZXIjcHVibGlzaCBwdWJsaXNofVxuICogYW5kIHRvIGxpc3RlbiBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIGNsaWVudHMgYnkgcmVnaXN0ZXJpbmcgYW4gYWN0aW9uIHZpYSB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI3JlZ2lzdGVyIHJlZ2lzdGVyfS5cbiAqXG4gKiAjIyMgU3luY2hyb25vdXMgTWV0aG9kczpcbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjb25Db25uZWN0aW9uIG9uQ29ubmVjdGlvbihsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI29uRGlzY29ubmVjdGlvbiBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNwdWJsaXNoIHB1Ymxpc2goYWN0aW9uLCBwYXlsb2FkKX1cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjcmVnaXN0ZXIgcmVnaXN0ZXIoYWN0aW9uLCBsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI3JlbW92ZSByZW1vdmUoYWN0aW9uKX1cbiAqXG4gKiAjIyMgQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2Rlc3Ryb3kgZGVzdHJveSgpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNkaXNwYXRjaCBkaXNwYXRjaCh0bywgYWN0aW9uLCBwYXlsb2FkKX1cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjZ2V0QWxsQ2xpZW50SW5mbyBnZXRBbGxDbGllbnRJbmZvKCl9XG4gKlxuICogIyMjIE1pZGRsZXdhcmU6XG4gKiBNaWRkbGV3YXJlIGZ1bmN0aW9ucyByZWNlaXZlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOiAoYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZCkuXG4gKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIG9uIGFzIHRoZSBwYXlsb2FkIGZyb20gYmVmb3JlQWN0aW9uLCB0byB0aGUgYWN0aW9uIGxpc3RlbmVyLCB0byBhZnRlckFjdGlvblxuICogdW5sZXNzIGl0IGlzIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB0aGUgbW9zdCByZWNlbnRseSBkZWZpbmVkIHBheWxvYWQgaXMgdXNlZC4gIE1pZGRsZXdhcmUgY2FuIGJlIHVzZWQgZm9yIHNpZGUgZWZmZWN0cy5cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjc2V0RGVmYXVsdEFjdGlvbiBzZXREZWZhdWx0QWN0aW9uKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNvbkVycm9yIG9uRXJyb3IobWlkZGxld2FyZSl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2JlZm9yZUFjdGlvbiBiZWZvcmVBY3Rpb24obWlkZGxld2FyZSl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2FmdGVyQWN0aW9uIGFmdGVyQWN0aW9uKG1pZGRsZXdhcmUpfVxuICovXG5jbGFzcyBDaGFubmVsUHJvdmlkZXIgZXh0ZW5kcyBjaGFubmVsXzEuQ2hhbm5lbEJhc2Uge1xuICAgIC8qKlxuICAgICAqIGEgcmVhZC1vbmx5IGFycmF5IGNvbnRhaW5pbmcgYWxsIHRoZSBpZGVudGl0aWVzIG9mIGNvbm5lY3RpbmcgY2xpZW50cy5cbiAgICAgKi9cbiAgICBnZXQgY29ubmVjdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiBbLi4uX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIFwiZlwiKV07XG4gICAgfVxuICAgIHN0YXRpYyBoYW5kbGVDbGllbnREaXNjb25uZWN0aW9uKGNoYW5uZWwsIHBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgcmVtb3ZlQnlJZCA9IGNoYW5uZWwuY29ubmVjdGlvbnMuZmluZCgoaWRlbnRpdHkpID0+IGlkZW50aXR5LmVuZHBvaW50SWQgPT09IHBheWxvYWQuZW5kcG9pbnRJZCk7XG4gICAgICAgIGlmIChyZW1vdmVCeUlkKSB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgoY2hhbm5lbCwgX0NoYW5uZWxQcm92aWRlcl9yZW1vdmVFbmRwb2ludCwgXCJmXCIpLmNhbGwoY2hhbm5lbCwgcmVtb3ZlQnlJZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtdWx0aXBsZVJlbW92ZXMgPSBjaGFubmVsLmNvbm5lY3Rpb25zLmZpbHRlcigoaWRlbnRpdHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWRlbnRpdHkudXVpZCA9PT0gcGF5bG9hZC51dWlkICYmIGlkZW50aXR5Lm5hbWUgPT09IHBheWxvYWQubmFtZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbXVsdGlwbGVSZW1vdmVzLmZvckVhY2goX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KGNoYW5uZWwsIF9DaGFubmVsUHJvdmlkZXJfcmVtb3ZlRW5kcG9pbnQsIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2hhbm5lbC5kaXNjb25uZWN0TGlzdGVuZXIocGF5bG9hZCk7XG4gICAgfVxuICAgIHN0YXRpYyBzZXRQcm92aWRlclJlbW92YWwocHJvdmlkZXIsIHJlbW92ZSkge1xuICAgICAgICBDaGFubmVsUHJvdmlkZXIucmVtb3ZhbE1hcC5zZXQocHJvdmlkZXIsIHJlbW92ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByb3ZpZGVySWRlbnRpdHksIGNsb3NlLCBzdHJhdGVneSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX2Nvbm5lY3Rpb25zLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iai5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneS5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0NoYW5uZWxQcm92aWRlcl9yZW1vdmVFbmRwb2ludC5zZXQodGhpcywgKGlkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdDb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjbGllbnRJZGVudGl0eSkgPT4gY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAhPT0gaWRlbnRpdHkuZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneSwgXCJmXCIpLmNsb3NlRW5kcG9pbnQoaWRlbnRpdHkuZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYodGhpcywgX0NoYW5uZWxQcm92aWRlcl9jb25uZWN0aW9ucywgcmVtYWluaW5nQ29ubmVjdGlvbnMsIFwiZlwiKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIE11c3QgYmUgYm91bmQuXG4gICAgICAgIHRoaXMucHJvY2Vzc0FjdGlvbiA9IGFzeW5jIChhY3Rpb24sIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBpZiAoQ2hhbm5lbFByb3ZpZGVyLmNsaWVudElzTXVsdGlSdW50aW1lKHNlbmRlcklkZW50aXR5KSAmJlxuICAgICAgICAgICAgICAgICEoMCwgcnVudGltZVZlcnNpb25pbmdfMS5ydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uKShzZW5kZXJJZGVudGl0eS5ydW50aW1lVXVpZCwgJzE4Ljg3LjU2LjAnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTXVsdGlSdW50aW1lTGVnYWN5Q2xpZW50KHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tGb3JDbGllbnRDb25uZWN0aW9uKHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBlci5wcm9jZXNzQWN0aW9uKGFjdGlvbiwgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICB9O1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX2Nsb3NlLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneSwgXCJmXCIpLmNsb3NlKCk7XG4gICAgICAgICAgICBjb25zdCByZW1vdmUgPSBDaGFubmVsUHJvdmlkZXIucmVtb3ZhbE1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYodGhpcywgX0NoYW5uZWxQcm92aWRlcl9wcm90ZWN0ZWRPYmosIG5ldyBjaGFubmVsXzEuUHJvdGVjdGVkSXRlbXMocHJvdmlkZXJJZGVudGl0eSwgY2xvc2UpLCBcImZcIik7XG4gICAgICAgIHRoaXMuY29ubmVjdExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RMaXN0ZW5lciA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ2KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIFtdLCBcImZcIik7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNih0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBzdHJhdGVneSwgXCJmXCIpO1xuICAgICAgICBzdHJhdGVneS5yZWNlaXZlKHRoaXMucHJvY2Vzc0FjdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc3BhdGNoIGFuIGFjdGlvbiB0byBhIHNwZWNpZmllZCBjbGllbnQuIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGF0IGFjdGlvbiBvbiB0aGUgY2xpZW50IHNpZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG8gLSBJZGVudGl0eSBvZiB0aGUgdGFyZ2V0IGNsaWVudC5cbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gTmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGludm9rZWQgYnkgdGhlIGNsaWVudC5cbiAgICAgKiBAcGFyYW0gcGF5bG9hZCAtIFBheWxvYWQgdG8gYmUgc2VudCBhbG9uZyB3aXRoIHRoZSBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqXG4gICAgICogQmVjYXVzZSBtdWx0aXBsZSBjbGllbnRzIGNhbiBzaGFyZSB0aGUgc2FtZSBgbmFtZWAgYW5kIGB1dWlkYCwgd2hlbiBkaXNwYXRjaGluZyBmcm9tIGEgcHJvdmlkZXIgdG8gYSBjbGllbnQsXG4gICAgICogdGhlIGBpZGVudGl0eWAgeW91IHByb3ZpZGUgbXVzdCBpbmNsdWRlIHRoZSBjbGllbnQncyB1bmlxdWUgYGVuZHBvaW50SWRgIHByb3BlcnR5LiBUaGlzIGBlbmRwb2ludElkYCBpc1xuICAgICAqIHBhc3NlZCB0byB0aGUgcHJvdmlkZXIgaW4gYm90aCB0aGUgYFByb3ZpZGVyLm9uQ29ubmVjdGlvbmAgY2FsbGJhY2sgYW5kIGluIGFueSByZWdpc3RlcmVkIGFjdGlvbiBjYWxsYmFja3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIGFzeW5jIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIGF3YWl0IHByb3ZpZGVyLmRpc3BhdGNoKGlkZW50aXR5LCAnY2xpZW50LWFjdGlvbicsICdIZWxsbywgV29ybGQhJyk7XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGlzcGF0Y2godG8sIGFjdGlvbiwgcGF5bG9hZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludElkID0gdG8uZW5kcG9pbnRJZCA/PyB0aGlzLmdldEVuZHBvaW50SWRGb3JPcGVuRmluSWQodG8sIGFjdGlvbik7XG4gICAgICAgIGlmIChlbmRwb2ludElkICYmIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBcImZcIikuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBcImZcIikuc2VuZChlbmRwb2ludElkLCBhY3Rpb24sIHBheWxvYWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYENsaWVudCBjb25uZWN0aW9uIHdpdGggaWRlbnRpdHkgdXVpZDogJHt0by51dWlkfSAvIG5hbWU6ICR7dG8ubmFtZX0gLyBlbmRwb2ludElkOiAke2VuZHBvaW50SWR9IG5vIGxvbmdlciBjb25uZWN0ZWQuYCkpO1xuICAgIH1cbiAgICBhc3luYyBwcm9jZXNzQ29ubmVjdGlvbihzZW5kZXJJZCwgcGF5bG9hZCkge1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9jb25uZWN0aW9ucywgXCJmXCIpLnB1c2goc2VuZGVySWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0TGlzdGVuZXIoc2VuZGVySWQsIHBheWxvYWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIGFuIGFjdGlvbiBhbmQgcGF5bG9hZCB0byBldmVyeSBjb25uZWN0ZWQgY2xpZW50LlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBmb3IgZWFjaCBhY3Rpb24gKHNlZSBkaXNwYXRjaCkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uXG4gICAgICogQHBhcmFtIHBheWxvYWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIGFzeW5jIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKHByb3ZpZGVyLnB1Ymxpc2goJ2NsaWVudC1hY3Rpb24nLCB7IG1lc3NhZ2U6ICdCcm9hZGNhc3QgZnJvbSBwcm92aWRlcid9KSk7XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGlzaChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMubWFwKCh0bykgPT4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfc3RyYXRlZ3ksIFwiZlwiKS5zZW5kKHRvLmVuZHBvaW50SWQsIGFjdGlvbiwgcGF5bG9hZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIGxpc3RlbmVyIHRoYXQgaXMgY2FsbGVkIG9uIGV2ZXJ5IG5ldyBjbGllbnQgY29ubmVjdGlvbi5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEl0IGlzIHBhc3NlZCB0aGUgaWRlbnRpdHkgb2YgdGhlIGNvbm5lY3RpbmcgY2xpZW50IGFuZCBhIHBheWxvYWQgaWYgaXQgd2FzIHByb3ZpZGVkIHRvIENoYW5uZWwuY29ubmVjdC5cbiAgICAgKiBJZiB5b3Ugd2lzaCB0byByZWplY3QgdGhlIGNvbm5lY3Rpb24sIHRocm93IGFuIGVycm9yLiBCZSBzdXJlIHRvIHN5bmNocm9ub3VzbHkgcHJvdmlkZSBhbiBvbkNvbm5lY3Rpb24gdXBvbiByZWNlaXB0IG9mXG4gICAgICogdGhlIGNoYW5uZWxQcm92aWRlciB0byBlbnN1cmUgYWxsIHBvdGVudGlhbCBjbGllbnQgY29ubmVjdGlvbnMgYXJlIGNhdWdodCBieSB0aGUgbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIG11bHRpcGxlIGNsaWVudHMgY2FuIGV4aXN0IGF0IHRoZSBzYW1lIGBuYW1lYCBhbmQgYHV1aWRgLCBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGluZGl2aWR1YWwgY2xpZW50cyxcbiAgICAgKiB0aGUgYGlkZW50aXR5YCBhcmd1bWVudCBpbiBhIHByb3ZpZGVyJ3MgYG9uQ29ubmVjdGlvbmAgY2FsbGJhY2sgY29udGFpbnMgYW4gYGVuZHBvaW50SWRgIHByb3BlcnR5LiBXaGVuIGRpc3BhdGNoaW5nIGZyb20gYVxuICAgICAqIHByb3ZpZGVyIHRvIGEgY2xpZW50LCB0aGUgYGVuZHBvaW50SWRgIHByb3BlcnR5IG11c3QgYmUgcHJvdmlkZWQgaW4gb3JkZXIgdG8gc2VuZCBhbiBhY3Rpb24gdG8gYSBzcGVjaWZpYyBjbGllbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uQ29ubmVjdGlvbihpZGVudGl0eSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGNvbm5lY3RlZCcsIGlkZW50aXR5KTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFJlamVjdCBjb25uZWN0aW9uOlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uQ29ubmVjdGlvbihpZGVudGl0eSA9PiB7XG4gICAgICogICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gUmVqZWN0ZWQnKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBvbkNvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0TGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCBvbiBjbGllbnQgZGlzY29ubmVjdGlvbi4gSXQgaXMgcGFzc2VkIHRoZSBkaXNjb25uZWN0aW9uIGV2ZW50IG9mIHRoZSBkaXNjb25uZWN0aW5nXG4gICAgICogY2xpZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIGxpc3RlbmVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIub25EaXNjb25uZWN0aW9uKGV2dCA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGRpc2Nvbm5lY3RlZCcsIGB1dWlkOiAke2V2dC51dWlkfSwgbmFtZTogJHtldnQubmFtZX1gKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0TGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzdHJveSB0aGUgY2hhbm5lbCwgcmFpc2VzIGBkaXNjb25uZWN0ZWRgIGV2ZW50cyBvbiBhbGwgY29ubmVjdGVkIGNoYW5uZWwgY2xpZW50cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5kZXN0cm95KCk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBkZXN0cm95KCkge1xuICAgICAgICBjb25zdCBwcm90ZWN0ZWRPYmogPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9wcm90ZWN0ZWRPYmosIFwiZlwiKTtcbiAgICAgICAgcHJvdGVjdGVkT2JqLnByb3ZpZGVySWRlbnRpdHk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNih0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX2Nvbm5lY3Rpb25zLCBbXSwgXCJmXCIpO1xuICAgICAgICBhd2FpdCBwcm90ZWN0ZWRPYmouY2xvc2UoKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY2xvc2UsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggaW5mbyBvbiBldmVyeSBDbGllbnQgY29ubmVjdGVkIHRvIHRoZSBQcm92aWRlclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnb3BlbmZpbicpO1xuICAgICAqIGNvbnN0IGNsaWVudCA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdCgnb3BlbmZpbicpO1xuICAgICAqIGNvbnN0IGNsaWVudEluZm8gPSBhd2FpdCBwcm92aWRlci5nZXRBbGxDbGllbnRJbmZvKCk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhjbGllbnRJbmZvKTtcbiAgICAgKlxuICAgICAqIC8vIFtcbiAgICAgKiAvLyAgICB7XG4gICAgICogLy8gICAgICAgIFwidXVpZFwiOiBcIm9wZW5maW5cIixcbiAgICAgKiAvLyAgICAgICAgXCJuYW1lXCI6IFwib3BlbmZpbi12aWV3XCIsXG4gICAgICogLy8gICAgICAgIFwiZW5kcG9pbnRJZFwiOiBcIjZkNGM3Y2E4LTRhNzQtNDYzNC04N2Y4LTc2MDU1ODIyOTYxM1wiLFxuICAgICAqIC8vICAgICAgICBcImVudGl0eVR5cGVcIjogXCJ2aWV3XCIsXG4gICAgICogLy8gICAgICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9vcGVuZmluLmNvXCJcbiAgICAgKiAvLyAgICB9LFxuICAgICAqIC8vICAgIHtcbiAgICAgKiAvLyAgICAgICAgXCJ1dWlkXCI6IFwib3BlbmZpbjJcIixcbiAgICAgKiAvLyAgICAgICAgXCJuYW1lXCI6IFwib3BlbmZpbi12aWV3MlwiLFxuICAgICAqIC8vICAgICAgICBcImVuZHBvaW50SWRcIjogXCI0ejVkOGFiOS0yYjgxLTM2OTEtOTFleC0xNDIxNzkzODI1MTFcIixcbiAgICAgKiAvLyAgICAgICAgXCJlbnRpdHlUeXBlXCI6IFwidmlld1wiLFxuICAgICAqIC8vICAgICAgICBcInVybFwiOiBcImh0dHBzOi8vZXhhbXBsZS5jb21cIlxuICAgICAqIC8vICAgIH1cbiAgICAgKiAvL11cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGxDbGllbnRJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5tYXAoKGNsaWVudEluZm8pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSwgZW5kcG9pbnRJZCwgZW50aXR5VHlwZSwgY29ubmVjdGlvblVybCB9ID0gY2xpZW50SW5mbztcbiAgICAgICAgICAgIHJldHVybiB7IHV1aWQsIG5hbWUsIGVuZHBvaW50SWQsIGVudGl0eVR5cGUsIGNvbm5lY3Rpb25VcmwgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNoZWNrRm9yQ2xpZW50Q29ubmVjdGlvbihjbGllbnRJZGVudGl0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNDbGllbnRDb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoaXMgYWN0aW9uIHdhcyBzZW50IGZyb20gYSBjbGllbnQgdGhhdCBpcyBub3QgY29ubmVjdGVkIHRvIHRoZSBwcm92aWRlci5cbiAgICAgICAgICAgICAgICAgICAgQ2xpZW50IElkZW50aXR5OiB7dXVpZDogJHtjbGllbnRJZGVudGl0eS51dWlkfSwgbmFtZTogJHtjbGllbnRJZGVudGl0eS5uYW1lfSwgZW5kcG9pbnRJZDogJHtjbGllbnRJZGVudGl0eS5lbmRwb2ludElkfX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc0NsaWVudENvbm5lY3RlZChjbGllbnRJZGVudGl0eSkge1xuICAgICAgICBpZiAoQ2hhbm5lbFByb3ZpZGVyLmNsaWVudElkZW50aXR5SW5jbHVkZXNFbmRwb2ludElkKGNsaWVudElkZW50aXR5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMuc29tZSgoaWRlbnRpdHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIC8vIE1pZ2h0IGJlIHJlZHVuZGFudCB0byBjaGVjayBmb3IgdXVpZCBhbmQgbmFtZSBoZXJlIGFmdGVyIHdlIGdldCBhbiBlbmRwb2ludElkIG1hdGNoLCBidXQganVzdCBpbiBjYXNlXG4gICAgICAgICAgICAgICAgaWRlbnRpdHkuZW5kcG9pbnRJZCA9PT0gY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAmJlxuICAgICAgICAgICAgICAgICAgICBpZGVudGl0eS51dWlkID09PSBjbGllbnRJZGVudGl0eS51dWlkICYmXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5Lm5hbWUgPT09IGNsaWVudElkZW50aXR5Lm5hbWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaXNMZWdhY3lDbGllbnRDb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpO1xuICAgIH1cbiAgICBpc0xlZ2FjeUNsaWVudENvbm5lY3RlZChjbGllbnRJZGVudGl0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5zb21lKChpZGVudGl0eSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGlkZW50aXR5LnV1aWQgPT09IGNsaWVudElkZW50aXR5LnV1aWQgJiYgaWRlbnRpdHkubmFtZSA9PT0gY2xpZW50SWRlbnRpdHkubmFtZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGhhbmRsZU11bHRpUnVudGltZUxlZ2FjeUNsaWVudChzZW5kZXJJZGVudGl0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNMZWdhY3lDbGllbnRDb25uZWN0ZWQoc2VuZGVySWRlbnRpdHkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoaXMgYWN0aW9uIHdhcyBzZW50IGZyb20gYSBjbGllbnQgdGhhdCBpcyBub3QgY29ubmVjdGVkIHRvIHRoZSBwcm92aWRlci4gQ2xpZW50IElkZW50aXR5OlxuICAgICAgICAgICAgICAgICAgICB7dXVpZDogJHtzZW5kZXJJZGVudGl0eS51dWlkfSwgbmFtZTogJHtzZW5kZXJJZGVudGl0eS5uYW1lfSwgZW5kcG9pbnRJZDogJHtzZW5kZXJJZGVudGl0eS5lbmRwb2ludElkfX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRFbmRwb2ludElkRm9yT3BlbkZpbklkKGNsaWVudElkZW50aXR5LCBhY3Rpb24pIHtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjKSA9PiBjLm5hbWUgPT09IGNsaWVudElkZW50aXR5Lm5hbWUgJiYgYy51dWlkID09PSBjbGllbnRJZGVudGl0eS51dWlkKTtcbiAgICAgICAgaWYgKG1hdGNoaW5nQ29ubmVjdGlvbnMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb3RlY3RlZE9iaiA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iaiwgXCJmXCIpO1xuICAgICAgICAgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSBjbGllbnRJZGVudGl0eTtcbiAgICAgICAgICAgIGNvbnN0IHByb3ZpZGVyVXVpZCA9IHByb3RlY3RlZE9iaj8ucHJvdmlkZXJJZGVudGl0eS51dWlkO1xuICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJOYW1lID0gcHJvdGVjdGVkT2JqPy5wcm92aWRlcklkZW50aXR5Lm5hbWU7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBXQVJOSU5HOiBEaXNwYXRjaCBjYWxsIG1heSBoYXZlIHVuaW50ZW5kZWQgcmVzdWx0cy4gVGhlIFwidG9cIiBhcmd1bWVudCBvZiB5b3VyIGRpc3BhdGNoIGNhbGwgaXMgbWlzc2luZyB0aGVcbiAgICAgICAgICAgICAgICBcImVuZHBvaW50SWRcIiBwYXJhbWV0ZXIuIFRoZSBpZGVudGl0eSB5b3UgYXJlIGRpc3BhdGNoaW5nIHRvICh7dXVpZDogJHt1dWlkfSwgbmFtZTogJHtuYW1lfX0pXG4gICAgICAgICAgICAgICAgaGFzIG11bHRpcGxlIGNoYW5uZWxDbGllbnRzIGZvciB0aGlzIGNoYW5uZWwuIFlvdXIgZGlzcGF0Y2hlZCBhY3Rpb246ICgke2FjdGlvbn0pIGZyb20gdGhlIHByb3ZpZGVyOlxuICAgICAgICAgICAgICAgICh7dXVpZDogJHtwcm92aWRlclV1aWR9LCBuYW1lOiAke3Byb3ZpZGVyTmFtZX19KSB3aWxsIG9ubHkgYmUgcHJvY2Vzc2VkIGJ5IHRoZSBtb3N0IHJlY2VudGx5LWNyZWF0ZWQgY2xpZW50LmApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFBvcCB0byByZXR1cm4gdGhlIG1vc3QgcmVjZW50bHkgY3JlYXRlZCBlbmRwb2ludElkLlxuICAgICAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9ucy5wb3AoKT8uZW5kcG9pbnRJZDtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBzdGF0aWMgY2xpZW50SWRlbnRpdHlJbmNsdWRlc0VuZHBvaW50SWQoc3Vic2NyaXB0aW9uSWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbklkZW50aXR5LmVuZHBvaW50SWQgIT09IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBzdGF0aWMgY2xpZW50SXNNdWx0aVJ1bnRpbWUoc3Vic2NyaXB0aW9uSWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbklkZW50aXR5LnJ1bnRpbWVVdWlkICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyB3aXJlQ2xvc2Uod2lyZSwgY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgYXdhaXQgd2lyZS5zZW5kQWN0aW9uKCdkZXN0cm95LWNoYW5uZWwnLCB7IGNoYW5uZWxOYW1lIH0pO1xuICAgIH1cbn1cbnByb3ZpZGVyLkNoYW5uZWxQcm92aWRlciA9IENoYW5uZWxQcm92aWRlcjtcbl9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iaiA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsUHJvdmlkZXJfc3RyYXRlZ3kgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbFByb3ZpZGVyX3JlbW92ZUVuZHBvaW50ID0gbmV3IFdlYWtNYXAoKSwgX0NoYW5uZWxQcm92aWRlcl9jbG9zZSA9IG5ldyBXZWFrTWFwKCk7XG4vLyBUaGUgZm9sbG93aW5nIGxpbmUgc2hvdWxkIGJlIGNoYW5nZWQgZm9sbG93aW5nIGEgdHlwZXNjcmlwdCB1cGRhdGUuXG4vLyBzdGF0aWMgI3JlbW92YWxNYXAgPSBuZXcgV2Vha01hcDxDaGFubmVsUHJvdmlkZXIsIEZ1bmN0aW9uPigpO1xuQ2hhbm5lbFByb3ZpZGVyLnJlbW92YWxNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgbWVzc2FnZVJlY2VpdmVyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXNzYWdlUmVjZWl2ZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xubWVzc2FnZVJlY2VpdmVyLk1lc3NhZ2VSZWNlaXZlciA9IHZvaWQgMDtcbmNvbnN0IGNsaWVudF8xJDEgPSBjbGllbnQ7XG5jb25zdCBiYXNlXzEkZyA9IGJhc2U7XG4vKlxuVGhpcyBpcyBhIHNpbmdsZXRvbiAocGVyIGZpbiBvYmplY3QpIHRhc2tlZCB3aXRoIHJvdXRpbmcgbWVzc2FnZXMgY29taW5nIG9mZiB0aGUgaXBjIHRvIHRoZSBjb3JyZWN0IGVuZHBvaW50LlxuSXQgbmVlZHMgdG8gYmUgYSBzaW5nbGV0b24gYmVjYXVzZSB0aGVyZSBjYW4gb25seSBiZSBvbmUgcGVyIHdpcmUuIEl0IHRyYWNrcyBib3RoIGNsaWVudHMgYW5kIHByb3ZpZGVycycgcHJvY2Vzc0FjdGlvbiBwYXNzZWQgaW4gdmlhIHRoZSBzdHJhdGVneS5cbklmIGZ1bmN0aW9uYWxpdHkgaXMgbm90IGFib3V0IHJlY2VpdmluZyBtZXNzYWdlcywgaXQgZG9lcyBub3QgYmVsb25nIGhlcmUuXG4qL1xuY2xhc3MgTWVzc2FnZVJlY2VpdmVyIGV4dGVuZHMgYmFzZV8xJGcuQmFzZSB7XG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgdGhpcy5vbm1lc3NhZ2UgPSAobXNnKSA9PiB7XG4gICAgICAgICAgICBpZiAobXNnLmFjdGlvbiA9PT0gJ3Byb2Nlc3MtY2hhbm5lbC1tZXNzYWdlJykge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0NoYW5uZWxNZXNzYWdlKG1zZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW5kcG9pbnRNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkID0gbmV3IE1hcCgpO1xuICAgICAgICB3aXJlLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5vbm1lc3NhZ2UuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIGFzeW5jIHByb2Nlc3NDaGFubmVsTWVzc2FnZShtc2cpIHtcbiAgICAgICAgY29uc3QgeyBzZW5kZXJJZGVudGl0eSwgcHJvdmlkZXJJZGVudGl0eSwgYWN0aW9uLCBhY2tUb1NlbmRlciwgcGF5bG9hZCwgaW50ZW5kZWRUYXJnZXRJZGVudGl0eSB9ID0gbXNnLnBheWxvYWQ7XG4gICAgICAgIGNvbnN0IGtleSA9IGludGVuZGVkVGFyZ2V0SWRlbnRpdHkuY2hhbm5lbElkID8/IC8vIFRoZSByZWNpcGllbnQgaXMgYSBwcm92aWRlclxuICAgICAgICAgICAgaW50ZW5kZWRUYXJnZXRJZGVudGl0eS5lbmRwb2ludElkID8/IC8vIFRoZSByZWNpcGllbnQgaXMgYSBjbGllbnRcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmdldChwcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCk7IC8vIE5vIGVuZHBvaW50SWQgd2FzIHBhc3NlZCwgbWFrZSBiZXN0IGF0dGVtcHRcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuZW5kcG9pbnRNYXAuZ2V0KGtleSk7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5zdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnJlYXNvbiA9IGBDbGllbnQgY29ubmVjdGlvbiB3aXRoIGlkZW50aXR5IHV1aWQ6ICR7dGhpcy53aXJlLm1lLnV1aWR9IC8gbmFtZTogJHt0aGlzLndpcmUubWUubmFtZX0gLyBlbmRwb2ludElkOiAke2tleX0gbm8gbG9uZ2VyIGNvbm5lY3RlZC5gO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgaGFuZGxlcihhY3Rpb24sIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCA9IGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCB8fCB7fTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZC5yZXN1bHQgPSByZXM7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRSYXcoYWNrVG9TZW5kZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnN1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucmVhc29uID0gZS5tZXNzYWdlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRFbmRwb2ludChoYW5kbGVyLCBjaGFubmVsSWQsIGVuZHBvaW50SWQpIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludE1hcC5zZXQoZW5kcG9pbnRJZCwgaGFuZGxlcik7XG4gICAgICAgIC8vIFByb3ZpZGVycyBoYXZlIHRoZSBzYW1lIGVuZHBvaW50SWQgYW5kIGNoYW5uZWxJZC5cbiAgICAgICAgLy8gVGhpcyBpcyBvbmx5IHVzZWQgd2hlbiBjbGllbnRzIGFyZSByZWNlaXZpbmcgbWVzc2FnZXMgZnJvbSBwcm92aWRlcnMsIHNvIHdlIHNob3VsZG4ndCBzYXZlIHByb3ZpZGVyIGVuZHBvaW50SWQgaGVyZS5cbiAgICAgICAgaWYgKGNoYW5uZWxJZCAhPT0gZW5kcG9pbnRJZCkge1xuICAgICAgICAgICAgdGhpcy5sYXRlc3RFbmRwb2ludElkQnlDaGFubmVsSWQuc2V0KGNoYW5uZWxJZCwgZW5kcG9pbnRJZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlRW5kcG9pbnQoY2hhbm5lbElkLCBlbmRwb2ludElkKSB7XG4gICAgICAgIHRoaXMuZW5kcG9pbnRNYXAuZGVsZXRlKGVuZHBvaW50SWQpO1xuICAgICAgICBpZiAodGhpcy5sYXRlc3RFbmRwb2ludElkQnlDaGFubmVsSWQuZ2V0KGNoYW5uZWxJZCkgPT09IGVuZHBvaW50SWQpIHtcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmRlbGV0ZShjaGFubmVsSWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrRm9yUHJldmlvdXNDbGllbnRDb25uZWN0aW9uKGNoYW5uZWxJZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludElkRnJvbVByZXZpb3VzQ29ubmVjdGlvbiA9IHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmdldChjaGFubmVsSWQpO1xuICAgICAgICBpZiAoZW5kcG9pbnRJZEZyb21QcmV2aW91c0Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIC8vIE5vdCBjb252aW5jZWQgYnkgdGhpcyB3YXkgb2YgZG9pbmcgdGhpbmdzLCBidXQgcHVzaGluZyB1cCBmb3Igbm93LlxuICAgICAgICAgICAgY2xpZW50XzEkMS5DaGFubmVsQ2xpZW50LmNsb3NlQ2hhbm5lbEJ5RW5kcG9pbnRJZChlbmRwb2ludElkRnJvbVByZXZpb3VzQ29ubmVjdGlvbik7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdZb3UgaGF2ZSBjcmVhdGVkIGEgc2Vjb25kIGNvbm5lY3Rpb24gdG8gYW4gb2xkZXIgcHJvdmlkZXIuIEZpcnN0IGNvbm5lY3Rpb24gaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBjbGllbnRNYXAnKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0lmIHRoZSBwcm92aWRlciBjYWxscyBwdWJsaXNoKCksIHlvdSBtYXkgcmVjZWl2ZSBtdWx0aXBsZSBtZXNzYWdlcy4nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbm1lc3NhZ2VSZWNlaXZlci5NZXNzYWdlUmVjZWl2ZXIgPSBNZXNzYWdlUmVjZWl2ZXI7XG5cbnZhciBwcm90b2NvbE1hbmFnZXIgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvY29sTWFuYWdlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5wcm90b2NvbE1hbmFnZXIuUHJvdG9jb2xNYW5hZ2VyID0gdm9pZCAwO1xuLypcblRoaXMgc2hvdWxkIGJlIGFnbm9zdGljIG9mIGFueSBhY3R1YWwgb3BlbmZpbiBjb2RlIHRvIGJlIHVuaXQgdGVzdGFibGUuXG5EZXBlbmRlbmNpZXMgb24gdGhlIGFjdHVhbCBzcmF0ZWdpZXMgc2hvdWxkIGJlIGhhbmRsZWQgaW4gQ29ubmVjdGlvbk1hbmFnZXJcbiovXG5jbGFzcyBQcm90b2NvbE1hbmFnZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNvbnN0cnVjdG9yXG4gICAgY29uc3RydWN0b3IoUHJvdG9jb2xzSW5QcmVmZXJlbmNlT3JkZXIpIHtcbiAgICAgICAgdGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlciA9IFByb3RvY29sc0luUHJlZmVyZW5jZU9yZGVyO1xuICAgICAgICB0aGlzLkRlZmF1bHRDbGllbnRQcm90b2NvbHMgPSBbJ2NsYXNzaWMnXTtcbiAgICAgICAgdGhpcy5EZWZhdWx0UHJvdmlkZXJQcm90b2NvbHMgPSBbJ2NsYXNzaWMnXTtcbiAgICAgICAgdGhpcy5nZXRDbGllbnRQcm90b2NvbHMgPSAocHJvdG9jb2xzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdXBwb3J0ZWQgPSBwcm90b2NvbHNcbiAgICAgICAgICAgICAgICA/IHRoaXMuUHJvdG9jb2xzSW5QcmVmZXJlbmNlT3JkZXIuZmlsdGVyKCh4KSA9PiBwcm90b2NvbHMuaW5jbHVkZXMoeCkpXG4gICAgICAgICAgICAgICAgOiB0aGlzLkRlZmF1bHRDbGllbnRQcm90b2NvbHM7XG4gICAgICAgICAgICBpZiAoIXN1cHBvcnRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHZhbGlkIHByb3RvY29scyB3ZXJlIHBhc3NlZCBpbi4gQWNjZXB0ZWQgdmFsdWVzIGFyZTogJHt0aGlzLlByb3RvY29sc0luUHJlZmVyZW5jZU9yZGVyLmpvaW4oJywgJyl9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN1cHBvcnRlZDtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRQcm92aWRlclByb3RvY29scyA9IChwcm90b2NvbHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1cHBvcnRlZCA9IHByb3RvY29sc1xuICAgICAgICAgICAgICAgID8gdGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlci5maWx0ZXIoKHgpID0+IHByb3RvY29scy5pbmNsdWRlcyh4KSlcbiAgICAgICAgICAgICAgICA6IHRoaXMuRGVmYXVsdFByb3ZpZGVyUHJvdG9jb2xzO1xuICAgICAgICAgICAgaWYgKCFzdXBwb3J0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB2YWxpZCBwcm90b2NvbHMgd2VyZSBwYXNzZWQgaW4uIEFjY2VwdGVkIHZhbHVlcyBhcmU6ICR7dGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlci5qb2luKCcsICcpfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBwb3J0ZWQ7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0Q29tcGF0aWJsZVByb3RvY29scyA9IChwcm92aWRlclByb3RvY29scywgY2xpZW50T2ZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1cHBvcnRlZCA9IGNsaWVudE9mZmVyLnN1cHBvcnRlZFByb3RvY29scy5maWx0ZXIoKGNsaWVudFByb3RvY29sKSA9PiBwcm92aWRlclByb3RvY29scy5zb21lKChwcm92aWRlclByb3RvY29sKSA9PiBwcm92aWRlclByb3RvY29sLnR5cGUgPT09IGNsaWVudFByb3RvY29sLnR5cGUgJiZcbiAgICAgICAgICAgICAgICBjbGllbnRQcm90b2NvbC52ZXJzaW9uID49IHByb3ZpZGVyUHJvdG9jb2wubWluaW11bVZlcnNpb24gJiZcbiAgICAgICAgICAgICAgICBwcm92aWRlclByb3RvY29sLnZlcnNpb24gPj0gKGNsaWVudFByb3RvY29sLm1pbmltdW1WZXJzaW9uID8/IDApKSk7XG4gICAgICAgICAgICByZXR1cm4gc3VwcG9ydGVkLnNsaWNlKDAsIGNsaWVudE9mZmVyLm1heFByb3RvY29scyk7XG4gICAgICAgIH07XG4gICAgfVxufVxucHJvdG9jb2xNYW5hZ2VyLlByb3RvY29sTWFuYWdlciA9IFByb3RvY29sTWFuYWdlcjtcblxudmFyIHN0cmF0ZWd5ID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdHJhdGVneSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jbGFzcyBDb21iaW5lZFN0cmF0ZWd5IHtcbiAgICAvLyBNYWtpbmcgdGhpcyBhIHN0YXRpYyBtZXRob2QgYmVjYXVzZSB0aGUgY29uc3RydWN0b3IgY2FuJ3QgYmUgdHlwZWQuXG4gICAgLy8gT3RoZXJ3aXNlIGl0IHdpbGwgZXJyb3Igd2hlbiBjYWxsaW5nIGFkZEVuZHBvaW50IGJ1dCBJJ2QgcmF0aGVyIHRoZSB3aG9sZSBpbnN0YW5jZSBiZSB0eXBlZCBhcyBuZXZlci5cbiAgICBzdGF0aWMgY29tYmluZShhLCBiKSB7XG4gICAgICAgIHJldHVybiBuZXcgQ29tYmluZWRTdHJhdGVneShhLCBiKTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY29uc3RydWN0b3JcbiAgICBjb25zdHJ1Y3RvcihwcmltYXJ5LCBzZWNvbmRhcnkpIHtcbiAgICAgICAgdGhpcy5wcmltYXJ5ID0gcHJpbWFyeTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkgPSBzZWNvbmRhcnk7XG4gICAgfVxuICAgIG9uRW5kcG9pbnREaXNjb25uZWN0KGVuZHBvaW50SWQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucHJpbWFyeS5vbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vjb25kYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkub25FbmRwb2ludERpc2Nvbm5lY3QoZW5kcG9pbnRJZCwgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnByaW1hcnkuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJpbWFyeS5pc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHx8IHRoaXMuc2Vjb25kYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCk7XG4gICAgfVxuICAgIGFzeW5jIGNsb3NlRW5kcG9pbnQoZW5kcG9pbnRJZCkge1xuICAgICAgICBhd2FpdCB0aGlzLnByaW1hcnkuY2xvc2VFbmRwb2ludChlbmRwb2ludElkKTtcbiAgICAgICAgYXdhaXQgdGhpcy5zZWNvbmRhcnkuY2xvc2VFbmRwb2ludChlbmRwb2ludElkKTtcbiAgICB9XG4gICAgaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcmltYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnQpIHx8IHRoaXMuc2Vjb25kYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnQpO1xuICAgIH1cbiAgICBhc3luYyBhZGRFbmRwb2ludChlbmRwb2ludCwgcGF5bG9hZCkge1xuICAgICAgICBpZiAodGhpcy5wcmltYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucHJpbWFyeS5hZGRFbmRwb2ludChlbmRwb2ludCwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2Vjb25kYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2Vjb25kYXJ5LmFkZEVuZHBvaW50KGVuZHBvaW50LCBwYXlsb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucHJpbWFyeS5yZWNlaXZlKGxpc3RlbmVyKTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkucmVjZWl2ZShsaXN0ZW5lcik7XG4gICAgfVxuICAgIHNlbmQoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKSB7XG4gICAgICAgIGlmICh0aGlzLnByaW1hcnkuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJpbWFyeS5zZW5kKGVuZHBvaW50SWQsIGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vjb25kYXJ5LnNlbmQoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKTtcbiAgICB9XG4gICAgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLnByaW1hcnkuY2xvc2UoKSwgdGhpcy5zZWNvbmRhcnkuY2xvc2UoKV0pO1xuICAgIH1cbn1cbnN0cmF0ZWd5LmRlZmF1bHQgPSBDb21iaW5lZFN0cmF0ZWd5O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ1ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2ltcG9ydERlZmF1bHQkMSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2ltcG9ydERlZmF1bHQpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcbn07XG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgX0Nvbm5lY3Rpb25NYW5hZ2VyX3J0Y0Nvbm5lY3Rpb25NYW5hZ2VyO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbm5lY3Rpb25NYW5hZ2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbm5lY3Rpb25NYW5hZ2VyLkNvbm5lY3Rpb25NYW5hZ2VyID0gdm9pZCAwO1xuY29uc3QgZXhoYXVzdGl2ZV8xID0gZXhoYXVzdGl2ZTtcbmNvbnN0IGJhc2VfMSRmID0gYmFzZTtcbmNvbnN0IHN0cmF0ZWd5XzEgPSBzdHJhdGVneSQzO1xuY29uc3Qgc3RyYXRlZ3lfMiA9IHN0cmF0ZWd5JDI7XG5jb25zdCBpY2VfbWFuYWdlcl8xID0gaWNlTWFuYWdlcjtcbmNvbnN0IHByb3ZpZGVyXzEkMSA9IHByb3ZpZGVyO1xuY29uc3QgbWVzc2FnZV9yZWNlaXZlcl8xID0gbWVzc2FnZVJlY2VpdmVyO1xuY29uc3QgcHJvdG9jb2xfbWFuYWdlcl8xID0gcHJvdG9jb2xNYW5hZ2VyO1xuY29uc3Qgc3RyYXRlZ3lfMyA9IF9faW1wb3J0RGVmYXVsdCQxKHN0cmF0ZWd5KTtcbmNsYXNzIENvbm5lY3Rpb25NYW5hZ2VyIGV4dGVuZHMgYmFzZV8xJGYuQmFzZSB7XG4gICAgc3RhdGljIGdldFByb3RvY29sT3B0aW9uc0Zyb21TdHJpbmdzKHByb3RvY29scykge1xuICAgICAgICByZXR1cm4gcHJvdG9jb2xzLm1hcCgocHJvdG9jb2wpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAocHJvdG9jb2wpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdydGMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyYXRlZ3lfMi5SVENJbmZvO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NsYXNzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyYXRlZ3lfMS5DbGFzc2ljSW5mbztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKDAsIGV4aGF1c3RpdmVfMS5leGhhdXN0aXZlQ2hlY2spKHByb3RvY29sLCBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlci5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0Nvbm5lY3Rpb25NYW5hZ2VyX3J0Y0Nvbm5lY3Rpb25NYW5hZ2VyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICB0aGlzLnJlbW92ZUNoYW5uZWxGcm9tUHJvdmlkZXJNYXAgPSAoY2hhbm5lbElkKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVyTWFwLmRlbGV0ZShjaGFubmVsSWQpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9ubWVzc2FnZSA9IChtc2cpID0+IHtcbiAgICAgICAgICAgIGlmIChtc2cuYWN0aW9uID09PSAncHJvY2Vzcy1jaGFubmVsLWNvbm5lY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ2hhbm5lbENvbm5lY3Rpb24obXNnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcm92aWRlck1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5wcm90b2NvbE1hbmFnZXIgPSBuZXcgcHJvdG9jb2xfbWFuYWdlcl8xLlByb3RvY29sTWFuYWdlcih0aGlzLndpcmUuZW52aXJvbm1lbnQudHlwZSA9PT0gJ25vZGUnID8gWydjbGFzc2ljJ10gOiBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDUodGhpcywgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgbmV3IG1lc3NhZ2VfcmVjZWl2ZXJfMS5NZXNzYWdlUmVjZWl2ZXIod2lyZSksIFwiZlwiKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ1KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9ydGNDb25uZWN0aW9uTWFuYWdlciwgbmV3IGljZV9tYW5hZ2VyXzEuUlRDSUNFTWFuYWdlcih3aXJlKSwgXCJmXCIpO1xuICAgICAgICB3aXJlLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5vbm1lc3NhZ2UuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIGNyZWF0ZVByb3ZpZGVyKG9wdGlvbnMsIHByb3ZpZGVySWRlbnRpdHkpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IE9iamVjdC5hc3NpZ24odGhpcy53aXJlLmVudmlyb25tZW50LmdldERlZmF1bHRDaGFubmVsT3B0aW9ucygpLmNyZWF0ZSwgb3B0aW9ucyB8fCB7fSk7XG4gICAgICAgIGNvbnN0IHByb3RvY29scyA9IHRoaXMucHJvdG9jb2xNYW5hZ2VyLmdldFByb3ZpZGVyUHJvdG9jb2xzKG9wdHM/LnByb3RvY29scyk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVNpbmdsZVN0cmF0ZWd5ID0gKHN0cmF0VHlwZSkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChzdHJhdFR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdydGMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3koKTtcbiAgICAgICAgICAgICAgICBjYXNlICdjbGFzc2ljJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBzdHJhdGVneV8xLkNsYXNzaWNTdHJhdGVneSh0aGlzLndpcmUsIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfbWVzc2FnZVJlY2VpdmVyLCBcImZcIiksIFxuICAgICAgICAgICAgICAgICAgICAvLyBQcm92aWRlcnMgZG8gbm90IGhhdmUgYW4gZW5kcG9pbnRJZCwgdXNlIGNoYW5uZWxJZCBhcyBlbmRwb2ludElkIGluIHRoZSBzdHJhdGVneS5cbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQsIHByb3ZpZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoMCwgZXhoYXVzdGl2ZV8xLmV4aGF1c3RpdmVDaGVjaykoc3RyYXRUeXBlLCBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzdHJhdGVnaWVzID0gcHJvdG9jb2xzLm1hcChjcmVhdGVTaW5nbGVTdHJhdGVneSk7XG4gICAgICAgIGxldCBzdHJhdGVneTtcbiAgICAgICAgaWYgKHN0cmF0ZWdpZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjb25zdCBbYSwgYl0gPSBzdHJhdGVnaWVzO1xuICAgICAgICAgICAgc3RyYXRlZ3kgPSBzdHJhdGVneV8zLmRlZmF1bHQuY29tYmluZShhLCBiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdHJhdGVnaWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgW3N0cmF0ZWd5XSA9IHN0cmF0ZWdpZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTaG91bGQgYmUgaW1wb3NzaWJsZS5cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIGNvbWJpbmUgc3RyYXRlZ2llcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgcHJvdmlkZXJfMSQxLkNoYW5uZWxQcm92aWRlcihwcm92aWRlcklkZW50aXR5LCAoKSA9PiBwcm92aWRlcl8xJDEuQ2hhbm5lbFByb3ZpZGVyLndpcmVDbG9zZSh0aGlzLndpcmUsIHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbE5hbWUpLCBzdHJhdGVneSk7XG4gICAgICAgIGNvbnN0IGtleSA9IHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkO1xuICAgICAgICB0aGlzLnByb3ZpZGVyTWFwLnNldChrZXksIHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBjaGFubmVsLFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHM6IENvbm5lY3Rpb25NYW5hZ2VyLmdldFByb3RvY29sT3B0aW9uc0Zyb21TdHJpbmdzKHByb3RvY29scylcbiAgICAgICAgfSk7XG4gICAgICAgIHByb3ZpZGVyXzEkMS5DaGFubmVsUHJvdmlkZXIuc2V0UHJvdmlkZXJSZW1vdmFsKGNoYW5uZWwsIHRoaXMucmVtb3ZlQ2hhbm5lbEZyb21Qcm92aWRlck1hcC5iaW5kKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIGNoYW5uZWw7XG4gICAgfVxuICAgIGFzeW5jIGNyZWF0ZUNsaWVudE9mZmVyKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgcHJvdG9jb2xzID0gdGhpcy5wcm90b2NvbE1hbmFnZXIuZ2V0Q2xpZW50UHJvdG9jb2xzKG9wdGlvbnM/LnByb3RvY29scyk7XG4gICAgICAgIGxldCBydGNQYWNrZXQ7XG4gICAgICAgIGNvbnN0IHN1cHBvcnRlZFByb3RvY29scyA9IGF3YWl0IFByb21pc2UuYWxsKHByb3RvY29scy5tYXAoYXN5bmMgKHR5cGUpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3J0Yyc6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBydGNDbGllbnQsIGNoYW5uZWxzLCBvZmZlciwgcnRjQ29ubmVjdGlvbklkLCBjaGFubmVsc09wZW5lZCB9ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ3KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9ydGNDb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLnN0YXJ0Q2xpZW50T2ZmZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgcnRjUGFja2V0ID0geyBydGNDbGllbnQsIGNoYW5uZWxzLCBjaGFubmVsc09wZW5lZCB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3J0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzdHJhdGVneV8yLlJUQ0luZm8udmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgb2ZmZXIsIHJ0Y0Nvbm5lY3Rpb25JZCB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgJ2NsYXNzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnY2xhc3NpYycsIHZlcnNpb246IHN0cmF0ZWd5XzEuQ2xhc3NpY0luZm8udmVyc2lvbiB9O1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoMCwgZXhoYXVzdGl2ZV8xLmV4aGF1c3RpdmVDaGVjaykodHlwZSwgWydydGMnLCAnY2xhc3NpYyddKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2ZmZXI6IHtcbiAgICAgICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHMsXG4gICAgICAgICAgICAgICAgbWF4UHJvdG9jb2xzOiAyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnRjOiBydGNQYWNrZXRcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlQ2xpZW50U3RyYXRlZ3kocnRjUGFja2V0LCByb3V0aW5nSW5mbykge1xuICAgICAgICBpZiAoIXJvdXRpbmdJbmZvLmVuZHBvaW50SWQpIHtcbiAgICAgICAgICAgIHJvdXRpbmdJbmZvLmVuZHBvaW50SWQgPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpO1xuICAgICAgICAgICAgLy8gRm9yIE5ldyBDbGllbnRzIGNvbm5lY3RpbmcgdG8gT2xkIFByb3ZpZGVycy4gVG8gcHJldmVudCBtdWx0aS1kaXNwYXRjaGluZyBhbmQgcHVibGlzaGluZywgd2UgZGVsZXRlIHByZXZpb3VzbHktY29ubmVjdGVkXG4gICAgICAgICAgICAvLyBjbGllbnRzIHRoYXQgYXJlIGluIHRoZSBzYW1lIGNvbnRleHQgYXMgdGhlIG5ld2x5LWNvbm5lY3RlZCBjbGllbnQuXG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDcodGhpcywgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgXCJmXCIpLmNoZWNrRm9yUHJldmlvdXNDbGllbnRDb25uZWN0aW9uKHJvdXRpbmdJbmZvLmNoYW5uZWxJZCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYW5zd2VyID0gcm91dGluZ0luZm8uYW5zd2VyID8/IHtcbiAgICAgICAgICAgIHN1cHBvcnRlZFByb3RvY29sczogW3sgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiAxIH1dXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNyZWF0ZVN0cmF0ZWd5RnJvbUFuc3dlciA9IGFzeW5jIChwcm90b2NvbCkgPT4ge1xuICAgICAgICAgICAgaWYgKHByb3RvY29sLnR5cGUgPT09ICdydGMnICYmIHJ0Y1BhY2tldCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5maW5pc2hDbGllbnRPZmZlcihydGNQYWNrZXQucnRjQ2xpZW50LCBwcm90b2NvbC5wYXlsb2FkLmFuc3dlciwgcnRjUGFja2V0LmNoYW5uZWxzT3BlbmVkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3koKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcm90b2NvbC50eXBlID09PSAnY2xhc3NpYycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzEuQ2xhc3NpY1N0cmF0ZWd5KHRoaXMud2lyZSwgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ3KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9tZXNzYWdlUmVjZWl2ZXIsIFwiZlwiKSwgcm91dGluZ0luZm8uZW5kcG9pbnRJZCwgcm91dGluZ0luZm8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFsbFByb3RvY29scyA9IChhd2FpdCBQcm9taXNlLmFsbChhbnN3ZXIuc3VwcG9ydGVkUHJvdG9jb2xzLm1hcChjcmVhdGVTdHJhdGVneUZyb21BbnN3ZXIpKSkuZmlsdGVyKCh4KSA9PiB4ICE9PSBudWxsKTtcbiAgICAgICAgLy8gQ2xlYW4gdXAgbG9naWMgaWYgcHJvdmlkZXIgZGlkbid0IHN1cHBvcnQgcnRjLlxuICAgICAgICBpZiAocnRjUGFja2V0ICYmICFhbGxQcm90b2NvbHMuc29tZSgoeCkgPT4geCBpbnN0YW5jZW9mIHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3kpKSB7XG4gICAgICAgICAgICBpZiAocnRjUGFja2V0KSB7XG4gICAgICAgICAgICAgICAgcnRjUGFja2V0LnJ0Y0NsaWVudC5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBzdHJhdGVneTtcbiAgICAgICAgaWYgKGFsbFByb3RvY29scy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgc3RyYXRlZ3kgPSBzdHJhdGVneV8zLmRlZmF1bHQuY29tYmluZShhbGxQcm90b2NvbHNbMF0sIGFsbFByb3RvY29sc1sxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWxsUHJvdG9jb2xzLmxlbmd0aCkge1xuICAgICAgICAgICAgW3N0cmF0ZWd5XSA9IGFsbFByb3RvY29scztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNob3VsZCBiZSBpbXBvc3NpYmxlLlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb21wYXRpYmxlIHByb3RvY29scycpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFzIGNhc3RpbmcgcnRjUGFja2V0IGJlY2F1c2Ugd2Ugd29uJ3QgaGF2ZSBhbiBydGNTdHJhdGVneSBpZiBydGNQYWNrZXQgaXMgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBlbmRwb2ludFBheWxvYWQgPSB7IGVuZHBvaW50SWRlbnRpdHk6IHJvdXRpbmdJbmZvLCBydGM6IHJ0Y1BhY2tldCB9O1xuICAgICAgICBzdHJhdGVneS5hZGRFbmRwb2ludChyb3V0aW5nSW5mby5jaGFubmVsSWQsIGVuZHBvaW50UGF5bG9hZCk7XG4gICAgICAgIHJldHVybiBzdHJhdGVneTtcbiAgICB9XG4gICAgYXN5bmMgcHJvY2Vzc0NoYW5uZWxDb25uZWN0aW9uKG1zZykge1xuICAgICAgICBjb25zdCB7IGNsaWVudElkZW50aXR5LCBwcm92aWRlcklkZW50aXR5LCBhY2tUb1NlbmRlciwgcGF5bG9hZCwgb2ZmZXI6IGNsaWVudE9mZmVyIH0gPSBtc2cucGF5bG9hZDtcbiAgICAgICAgaWYgKCFjbGllbnRJZGVudGl0eS5lbmRwb2ludElkKSB7XG4gICAgICAgICAgICAvLyBTaG91bGQgYmUgcG9seWZpbGxlZCBieSBjb3JlIGJ1dCBub3QgaW4gY2FzZXMgb2Ygbm9kZSBjb25uZWN0aW5nIHRvIGFuIG9sZCBydW50aW1lLlxuICAgICAgICAgICAgY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCk7XG4gICAgICAgICAgICBjbGllbnRJZGVudGl0eS5pc0xvY2FsRW5kcG9pbnRJZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjbGllbnRJZGVudGl0eS5pc0xvY2FsRW5kcG9pbnRJZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkO1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLnByb3ZpZGVyTWFwLmdldChrZXkpO1xuICAgICAgICBpZiAoIWJ1cykge1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5zdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnJlYXNvbiA9IGBDaGFubmVsIFwiJHtwcm92aWRlcklkZW50aXR5LmNoYW5uZWxOYW1lfVwiIGhhcyBiZWVuIGRlc3Ryb3llZC5gO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHByb3ZpZGVyLCBzdHJhdGVneSwgc3VwcG9ydGVkUHJvdG9jb2xzIH0gPSBidXM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIShwcm92aWRlciBpbnN0YW5jZW9mIHByb3ZpZGVyXzEkMS5DaGFubmVsUHJvdmlkZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0Nhbm5vdCBjb25uZWN0IHRvIGEgY2hhbm5lbCBjbGllbnQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyID0gY2xpZW50T2ZmZXIgPz8ge1xuICAgICAgICAgICAgICAgIHN1cHBvcnRlZFByb3RvY29sczogW3sgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiAxIH1dLFxuICAgICAgICAgICAgICAgIG1heFByb3RvY29sczogMVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IG92ZXJsYXBwaW5nUHJvdG9jb2xzID0gdGhpcy5wcm90b2NvbE1hbmFnZXIuZ2V0Q29tcGF0aWJsZVByb3RvY29scyhzdXBwb3J0ZWRQcm90b2NvbHMsIG9mZmVyKTtcbiAgICAgICAgICAgIGlmICghb3ZlcmxhcHBpbmdQcm90b2NvbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHByb3ZpZGVyIGRvZXMgbm90IHN1cHBvcnQgYW55IG9mIHRoZSBvZmZlcmVkIHByb3RvY29scy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHByb3ZpZGVyLnByb2Nlc3NDb25uZWN0aW9uKGNsaWVudElkZW50aXR5LCBwYXlsb2FkKTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCA9IGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCB8fCB7fTtcbiAgICAgICAgICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgc3VwcG9ydGVkIHByb3RvY29scyBhbmQgYWNjdW11bGF0ZSB0aGVtIGludG8gdGhlIGFuc3dlclxuICAgICAgICAgICAgLy8gYWRkRW5kcG9pbnQgaXMgdHJpY2t5IGJ1dCB3ZSBuZWVkIHRvIHdhaXQgZm9yIGNoYW5uZWwgcmVzb2x1dGlvbiBiZWZvcmUgYWRkaW5nIHRoZSBlbmRwb2ludC5cbiAgICAgICAgICAgIGxldCBjbGllbnRBbnN3ZXIgPSB7XG4gICAgICAgICAgICAgICAgc3VwcG9ydGVkUHJvdG9jb2xzOiBbXSxcbiAgICAgICAgICAgICAgICBlbmRwb2ludFBheWxvYWRQcm9taXNlOiBQcm9taXNlLnJlc29sdmUoeyBlbmRwb2ludElkZW50aXR5OiBjbGllbnRJZGVudGl0eSB9KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNsaWVudEFuc3dlciA9IGF3YWl0IG92ZXJsYXBwaW5nUHJvdG9jb2xzLnJlZHVjZShhc3luYyAoYWNjdW1QLCBwcm90b2NvbFRvVXNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYW5zd2VyID0gYXdhaXQgYWNjdW1QO1xuICAgICAgICAgICAgICAgIGlmIChwcm90b2NvbFRvVXNlLnR5cGUgPT09ICdydGMnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgYW5zd2VyOiBydGNBbnN3ZXIsIHJ0Y0NsaWVudCwgY2hhbm5lbHMgfSA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5jcmVhdGVQcm92aWRlckFuc3dlcihwcm90b2NvbFRvVXNlLnBheWxvYWQucnRjQ29ubmVjdGlvbklkLCBwcm90b2NvbFRvVXNlLnBheWxvYWQub2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICBhbnN3ZXIuc3VwcG9ydGVkUHJvdG9jb2xzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3J0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzdHJhdGVneV8yLlJUQ0luZm8udmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnN3ZXI6IHJ0Y0Fuc3dlclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgYW5zd2VyLmVuZHBvaW50UGF5bG9hZFByb21pc2UgPSBhbnN3ZXIuZW5kcG9pbnRQYXlsb2FkUHJvbWlzZS50aGVuKChlbmRwb2ludFBheWxvYWQpID0+IGNoYW5uZWxzLnRoZW4oKHJlc29sdmVkQ2hhbm5lbHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZW5kcG9pbnRQYXlsb2FkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ0Yzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGNDbGllbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzOiByZXNvbHZlZENoYW5uZWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYW5zd2VyLnN1cHBvcnRlZFByb3RvY29scy5wdXNoKHsgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiBzdHJhdGVneV8xLkNsYXNzaWNJbmZvLnZlcnNpb24gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICAgICAgICB9LCBQcm9taXNlLnJlc29sdmUoY2xpZW50QW5zd2VyKSk7XG4gICAgICAgICAgICAvLyBOZWVkIHRvIGFzIGNhc3QgaGVyZS5cbiAgICAgICAgICAgIGNsaWVudEFuc3dlci5lbmRwb2ludFBheWxvYWRQcm9taXNlLnRoZW4oKGVuZHBvaW50UGF5bG9hZCkgPT4gc3RyYXRlZ3kuYWRkRW5kcG9pbnQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCwgZW5kcG9pbnRQYXlsb2FkKSk7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnBheWxvYWQucmVzdWx0ID0gcmVzO1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5wYXlsb2FkLmFuc3dlciA9IGNsaWVudEFuc3dlcjtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZFJhdyhhY2tUb1NlbmRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQuc3VjY2VzcyA9IGZhbHNlO1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5yZWFzb24gPSBlLm1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRSYXcoYWNrVG9TZW5kZXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuY29ubmVjdGlvbk1hbmFnZXIuQ29ubmVjdGlvbk1hbmFnZXIgPSBDb25uZWN0aW9uTWFuYWdlcjtcbl9Db25uZWN0aW9uTWFuYWdlcl9tZXNzYWdlUmVjZWl2ZXIgPSBuZXcgV2Vha01hcCgpLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIgPSBuZXcgV2Vha01hcCgpO1xuXG4vKipcbiAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIGBDaGFubmVsYCBzdWJzZXQgb2YgdGhlIGBJbnRlckFwcGxpY2F0aW9uQnVzYCBBUEkgKGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsYCkuXG4gKlxuICogKiB7QGxpbmsgQ2hhbm5lbH0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBDaGFubmVsYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbGAuXG4gKiAqIHtAbGluayBPcGVuRmluLkNoYW5uZWxDbGllbnR9IGRlc2NyaWJlcyBhIGNsaWVudCBvZiBhIGNoYW5uZWwsIGUuZy4gYXMgcmV0dXJuZWQgYnkgYGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdGAuXG4gKiAqIHtAbGluayBPcGVuRmluLkNoYW5uZWxQcm92aWRlcn0gZGVzY3JpYmVzIGEgcHJvdmlkZXIgb2YgYSBjaGFubmVsLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZWAuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNiA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWwkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jaGFubmVsJDEuQ2hhbm5lbCA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmNvbnN0IGV2ZW50c18xJDUgPSByZXF1aXJlJCQwO1xuY29uc3QgbGF6eV8xJDEgPSBsYXp5O1xuY29uc3QgYmFzZV8xJGUgPSBiYXNlO1xuY29uc3QgY2xpZW50XzEgPSBjbGllbnQ7XG5jb25zdCBjb25uZWN0aW9uX21hbmFnZXJfMSA9IGNvbm5lY3Rpb25NYW5hZ2VyO1xuY29uc3QgcHJvdmlkZXJfMSA9IHByb3ZpZGVyO1xuZnVuY3Rpb24gcmV0cnlEZWxheShjb3VudCkge1xuICAgIGNvbnN0IGludGVydmFsID0gNTAwOyAvLyBiYXNlIGRlbGF5XG4gICAgY29uc3Qgc3RlcHMgPSAxMDsgLy8gSG93IG1hbnkgcmV0cmllcyB0byBkbyBiZWZvcmUgaW5jcmVtZW50aW5nIHRoZSBkZWxheVxuICAgIGNvbnN0IGJhc2UgPSAyOyAvLyBIb3cgbXVjaCB0byBtdWx0aXBseSB0aGUgcHJldmlvdXMgZGVsYXkgYnlcbiAgICBjb25zdCBtYXggPSAzMDAwMDsgLy8gbWF4IGRlbGF5XG4gICAgY29uc3Qgc3RlcCA9IE1hdGguZmxvb3IoY291bnQgLyBzdGVwcyk7XG4gICAgY29uc3QgZGVsYXkgPSBNYXRoLm1pbihtYXgsIGludGVydmFsICogYmFzZSAqKiBzdGVwKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfSwgZGVsYXkpO1xuICAgIH0pO1xufVxuLyoqXG4gKiBUaGUgQ2hhbm5lbCBBUEkgYWxsb3dzIGFuIE9wZW5GaW4gYXBwbGljYXRpb24gdG8gY3JlYXRlIGEgY2hhbm5lbCBhcyBhIHtAbGluayBDaGFubmVsUHJvdmlkZXIgQ2hhbm5lbFByb3ZpZGVyfSxcbiAqIG9yIGNvbm5lY3QgdG8gYSBjaGFubmVsIGFzIGEge0BsaW5rIENoYW5uZWxDbGllbnQgQ2hhbm5lbENsaWVudH0uXG4gKiBAcmVtYXJrcyBUaGUgXCJoYW5kc2hha2VcIiBiZXR3ZWVuIHRoZSBjb21tdW5pY2F0aW9uIHBhcnRuZXJzIGlzXG4gKiBzaW1wbGlmaWVkIHdoZW4gdXNpbmcgYSBjaGFubmVsLiAgQSByZXF1ZXN0IHRvIGNvbm5lY3QgdG8gYSBjaGFubmVsIGFzIGEgY2xpZW50IHdpbGwgcmV0dXJuIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGlmL3doZW4gdGhlIGNoYW5uZWwgaGFzIGJlZW4gY3JlYXRlZC4gQm90aCB0aGVcbiAqIHByb3ZpZGVyIGFuZCBjbGllbnQgY2FuIGRpc3BhdGNoIGFjdGlvbnMgdGhhdCBoYXZlIGJlZW4gcmVnaXN0ZXJlZCBvbiB0aGVpciBvcHBvc2l0ZXMsIGFuZCBkaXNwYXRjaCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYSBwYXlsb2FkIGZyb20gdGhlIG90aGVyXG4gKiBjb21tdW5pY2F0aW9uIHBhcnRpY2lwYW50LiBUaGVyZSBjYW4gYmUgb25seSBvbmUgcHJvdmlkZXIgcGVyIGNoYW5uZWwsIGJ1dCBtYW55IGNsaWVudHMuICBWZXJzaW9uIGA5LjYxLjM1LipgIG9yIGxhdGVyIGlzIHJlcXVpcmVkIGZvciBib3RoIGNvbW11bmljYXRpb24gcGFydG5lcnMuXG4gKlxuICogQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbC5jcmVhdGUgY3JlYXRlKGNoYW5uZWxOYW1lLCBvcHRpb25zKX1cbiAqICAqIHtAbGluayBDaGFubmVsLmNvbm5lY3QgY29ubmVjdChjaGFubmVsTmFtZSwgb3B0aW9ucyl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbC5vbkNoYW5uZWxDb25uZWN0IG9uQ2hhbm5lbENvbm5lY3QobGlzdGVuZXIpfVxuICogICoge0BsaW5rIENoYW5uZWwub25DaGFubmVsRGlzY29ubmVjdCBvbkNoYW5uZWxEaXNjb25uZWN0KGxpc3RlbmVyKX1cbiAqL1xuY2xhc3MgQ2hhbm5lbCBleHRlbmRzIGJhc2VfMSRlLkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlKSB7XG4gICAgICAgIHN1cGVyKHdpcmUsICdjaGFubmVsJyk7XG4gICAgICAgIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIuc2V0KHRoaXMsIG5ldyBldmVudHNfMSQ1LkV2ZW50RW1pdHRlcigpKTtcbiAgICAgICAgLy8gT3BlbkZpbiBBUEkgaGFzIG5vdCBiZWVuIGluamVjdGVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lLCAqbXVzdCogd2FpdCBmb3IgQVBJIHRvIGJlIHJlYWR5LlxuICAgICAgICBfQ2hhbm5lbF9yZWFkeVRvQ29ubmVjdC5zZXQodGhpcywgbmV3IGxhenlfMSQxLkFzeW5jUmV0cnlhYmxlTGF6eShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpcy5vbignZGlzY29ubmVjdGVkJywgKGV2ZW50UGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjbGllbnRfMS5DaGFubmVsQ2xpZW50LmhhbmRsZVByb3ZpZGVyRGlzY29ubmVjdChldmVudFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMub24oJ2Nvbm5lY3RlZCcsICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5lbWl0KCdjb25uZWN0ZWQnLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSkuY2F0Y2goKCkgPT4gbmV3IEVycm9yKCdlcnJvciBzZXR0aW5nIHVwIGNoYW5uZWwgY29ubmVjdGlvbiBsaXN0ZW5lcnMnKSk7XG4gICAgICAgIH0pKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ0KHRoaXMsIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLCBuZXcgY29ubmVjdGlvbl9tYW5hZ2VyXzEuQ29ubmVjdGlvbk1hbmFnZXIod2lyZSksIFwiZlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGxDaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWNoYW5uZWxzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3RlbnMgZm9yIGNoYW5uZWwgY29ubmVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXIgLSBjYWxsYmFjayB0byBleGVjdXRlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbGlzdGVuZXIgPSAoY2hhbm5lbFBheWxvYWQpID0+IGNvbnNvbGUubG9nKGNoYW5uZWxQYXlsb2FkKTsgLy8gc2VlIHJldHVybiB2YWx1ZSBiZWxvd1xuICAgICAqXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5vbkNoYW5uZWxDb25uZWN0KGxpc3RlbmVyKTtcbiAgICAgKlxuICAgICAqIC8vIGV4YW1wbGUgc2hhcGVcbiAgICAgKiB7XG4gICAgICogICAgIFwidG9waWNcIjogXCJjaGFubmVsXCIsXG4gICAgICogICAgIFwidHlwZVwiOiBcImNvbm5lY3RlZFwiLFxuICAgICAqICAgICBcInV1aWRcIjogXCJPcGVuZmluUE9DXCIsXG4gICAgICogICAgIFwibmFtZVwiOiBcIk9wZW5maW5QT0NcIixcbiAgICAgKiAgICAgXCJjaGFubmVsTmFtZVwiOiBcImNvdW50ZXJcIixcbiAgICAgKiAgICAgXCJjaGFubmVsSWRcIjogXCJPcGVuZmluUE9DL09wZW5maW5QT0MvY291bnRlclwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgb25DaGFubmVsQ29ubmVjdChsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKCdjb25uZWN0ZWQnLCBsaXN0ZW5lcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3RlbiBmb3IgY2hhbm5lbCBkaXNjb25uZWN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsaXN0ZW5lciAtIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsaXN0ZW5lciA9IChjaGFubmVsUGF5bG9hZCkgPT4gY29uc29sZS5sb2coY2hhbm5lbFBheWxvYWQpOyAvLyBzZWUgcmV0dXJuIHZhbHVlIGJlbG93XG4gICAgICpcbiAgICAgKiBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLm9uQ2hhbm5lbERpc2Nvbm5lY3QobGlzdGVuZXIpO1xuICAgICAqXG4gICAgICogLy8gZXhhbXBsZSBzaGFwZVxuICAgICAqIHtcbiAgICAgKiAgICAgXCJ0b3BpY1wiOiBcImNoYW5uZWxcIixcbiAgICAgKiAgICAgXCJ0eXBlXCI6IFwiZGlzY29ubmVjdGVkXCIsXG4gICAgICogICAgIFwidXVpZFwiOiBcIk9wZW5maW5QT0NcIixcbiAgICAgKiAgICAgXCJuYW1lXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICBcImNoYW5uZWxOYW1lXCI6IFwiY291bnRlclwiLFxuICAgICAqICAgICBcImNoYW5uZWxJZFwiOiBcIk9wZW5maW5QT0MvT3BlbmZpblBPQy9jb3VudGVyXCJcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBvbkNoYW5uZWxEaXNjb25uZWN0KGxpc3RlbmVyKSB7XG4gICAgICAgIGF3YWl0IHRoaXMub24oJ2Rpc2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICB9XG4gICAgYXN5bmMgc2FmZUNvbm5lY3QoY2hhbm5lbE5hbWUsIHNob3VsZFdhaXQsIGNvbm5lY3RQYXlsb2FkKSB7XG4gICAgICAgIGNvbnN0IHJldHJ5SW5mbyA9IHsgY291bnQ6IDAgfTtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCwgbm8tY29uc3RhbnQtY29uZGl0aW9uICovXG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIC8vIHNldHVwIGEgbGlzdGVuZXIgYW5kIGEgY29ubmVjdGVkIHByb21pc2UgdG8gYXdhaXQgaW4gY2FzZSB3ZSBjb25uZWN0IGJlZm9yZSB0aGUgY2hhbm5lbCBpcyByZWFkeVxuICAgICAgICAgICAgbGV0IGNvbm5lY3RlZExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGVkTGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbE5hbWUgPT09IHBheWxvYWQuY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5vbignY29ubmVjdGVkJywgY29ubmVjdGVkTGlzdGVuZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChyZXRyeUluZm8uY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdhaXQgYmVmb3JlIHJldHJ5aW5nXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGF5IHJldHVybnMgZmFsc2UgY29ubmVjdGVkUHJvbWlzZSByZXR1cm5zIHRydWUgc28gd2UgY2FuIGtub3cgaWYgYSByZXRyeSBpcyBkdWUgdG8gY29ubmVjdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHJldHJ5SW5mby5nb3RDb25uZWN0ZWRFdmVudCA9IGF3YWl0IFByb21pc2UucmFjZShbcmV0cnlEZWxheShyZXRyeUluZm8uY291bnQpLCBjb25uZWN0ZWRQcm9taXNlXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjb25uZWN0LXRvLWNoYW5uZWwnLCB7IC4uLmNvbm5lY3RQYXlsb2FkLCByZXRyeUluZm8gfSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvZyBvbmx5IGlmIHRoZXJlIHdhcyBhIHJldHJ5XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzZnVsbHkgY29ubmVjdGVkIHRvIGNoYW5uZWxOYW1lOiAke2NoYW5uZWxOYW1lfWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnBheWxvYWQuZGF0YTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gU2VuZCByZXRyeUluZm8gdG8gdGhlIGNvcmUgZm9yIGRlYnVnIGxvZyBpbmNsdXNpb25cbiAgICAgICAgICAgICAgICBjb25zdCBzZW50TWVzc2FnZVByb21pc2UgPSB0aGlzLndpcmUuc2VuZEFjdGlvbignY29ubmVjdC10by1jaGFubmVsJywgY29ubmVjdFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIC8vIFNhdmUgbWVzc2FnZUlkIGZyb20gdGhlIGZpcnN0IGNvbm5lY3Rpb24gYXR0ZW1wdFxuICAgICAgICAgICAgICAgIHJldHJ5SW5mby5vcmlnaW5hbE1lc3NhZ2VJZCA9IHNlbnRNZXNzYWdlUHJvbWlzZS5tZXNzYWdlSWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VudE1lc3NhZ2VQcm9taXNlO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucGF5bG9hZC5kYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdpbnRlcm5hbC1uYWNrJykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90IGFuIGludGVybmFsIG5hY2ssIGJyZWFrIHRoZSBsb29wXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkV2FpdCAmJiByZXRyeUluZm8uY291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgd2FpdGluZyBvbiB0aGUgbmV4dCBpdGVyYXRpb24sIHdhcm4gdGhlIHVzZXJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBObyBjaGFubmVsIGZvdW5kIGZvciBjaGFubmVsTmFtZTogJHtjaGFubmVsTmFtZX0uIFdhaXRpbmcgZm9yIGNvbm5lY3Rpb24uLi5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICByZXRyeUluZm8uY291bnQgKz0gMTtcbiAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIG9mIG90aGVyIGVycm9ycywgcmVtb3ZlIG91ciBsaXN0ZW5lclxuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5yZW1vdmVMaXN0ZW5lcignY29ubmVjdGVkJywgY29ubmVjdGVkTGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IHdoaWxlIChzaG91bGRXYWl0KTsgLy8gSWYgd2UncmUgd2FpdGluZyB3ZSByZXRyeSB0aGUgYWJvdmUgbG9vcFxuICAgICAgICAvLyBTaG91bGQgd2FpdCB3YXMgZmFsc2UsIG5vIGNoYW5uZWwgd2FzIGZvdW5kLlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGNoYW5uZWwgZm91bmQgZm9yIGNoYW5uZWxOYW1lOiAke2NoYW5uZWxOYW1lfS5gKTtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1hd2FpdC1pbi1sb29wLCBuby1jb25zdGFudC1jb25kaXRpb24gKi9cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0byBhIGNoYW5uZWwuIElmIHlvdSB3aXNoIHRvIHNlbmQgYSBwYXlsb2FkIHRvIHRoZSBwcm92aWRlciwgYWRkIGEgcGF5bG9hZCBwcm9wZXJ0eSB0byB0aGUgb3B0aW9ucyBhcmd1bWVudC5cbiAgICAgKiBFWFBFUklNRU5UQUw6IHBhc3MgeyBwcm90b2NvbHM6IFsncnRjJ10gfSBhcyBvcHRpb25zIHRvIG9wdC1pbiB0byBIaWdoIFRocm91Z2hwdXQgQ2hhbm5lbHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hhbm5lbE5hbWUgLSBOYW1lIG9mIHRoZSB0YXJnZXQgY2hhbm5lbC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIENvbm5lY3Rpb24gb3B0aW9ucy5cbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENoYW5uZWxDbGllbnQgQ2hhbm5lbENsaWVudH0uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgY29ubmVjdGlvbiByZXF1ZXN0IHdpbGwgYmUgcm91dGVkIHRvIHRoZSBjaGFubmVsUHJvdmlkZXIgaWYvd2hlbiB0aGUgY2hhbm5lbCBpcyBjcmVhdGVkLiAgSWYgdGhlIGNvbm5lY3RcbiAgICAgKiByZXF1ZXN0IGlzIHNlbnQgcHJpb3IgdG8gY3JlYXRpb24sIHRoZSBwcm9taXNlIHdpbGwgbm90IHJlc29sdmUgb3IgcmVqZWN0IHVudGlsIHRoZSBjaGFubmVsIGlzIGNyZWF0ZWQgYnkgYSBjaGFubmVsUHJvdmlkZXJcbiAgICAgKiAod2hldGhlciBvciBub3QgdG8gd2FpdCBmb3IgY3JlYXRpb24gaXMgY29uZmlndXJhYmxlIGluIHRoZSBjb25uZWN0T3B0aW9ucykuXG4gICAgICpcbiAgICAgKiBUaGUgY29ubmVjdCBjYWxsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdpdGggYSBjaGFubmVsQ2xpZW50IGJ1cyBpZiBhY2NlcHRlZCBieSB0aGUgY2hhbm5lbFByb3ZpZGVyLCBvciByZWplY3QgaWZcbiAgICAgKiB0aGUgY2hhbm5lbFByb3ZpZGVyIHRocm93cyBhbiBlcnJvciB0byByZWplY3QgdGhlIGNvbm5lY3Rpb24uIFRoaXMgYnVzIGNhbiBjb21tdW5pY2F0ZSB3aXRoIHRoZSBQcm92aWRlciwgYnV0IG5vdCB0byBvdGhlclxuICAgICAqIGNsaWVudHMgb24gdGhlIGNoYW5uZWwuIFVzaW5nIHRoZSBidXMsIHRoZSBjaGFubmVsQ2xpZW50IGNhbiByZWdpc3RlciBhY3Rpb25zIGFuZCBtaWRkbGV3YXJlLiBDaGFubmVsIGxpZmVjeWNsZSBjYW4gYWxzbyBiZVxuICAgICAqIGhhbmRsZWQgd2l0aCBhbiBvbkRpc2Nvbm5lY3Rpb24gbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBtYWtlQ2xpZW50KGNoYW5uZWxOYW1lKSB7XG4gICAgICogICAgLy8gQSBwYXlsb2FkIGNhbiBiZSBzZW50IGFsb25nIHdpdGggY2hhbm5lbCBjb25uZWN0aW9uIHJlcXVlc3RzIHRvIGhlbHAgd2l0aCBhdXRoZW50aWNhdGlvblxuICAgICAqICAgIGNvbnN0IGNvbm5lY3RQYXlsb2FkID0geyBwYXlsb2FkOiAndG9rZW4nIH07XG4gICAgICpcbiAgICAgKiAgICAvLyBJZiB0aGUgY2hhbm5lbCBoYXMgYmVlbiBjcmVhdGVkIHRoaXMgcmVxdWVzdCB3aWxsIGJlIHNlbnQgdG8gdGhlIHByb3ZpZGVyLiAgSWYgbm90LCB0aGVcbiAgICAgKiAgICAvLyBwcm9taXNlIHdpbGwgbm90IGJlIHJlc29sdmVkIG9yIHJlamVjdGVkIHVudGlsIHRoZSBjaGFubmVsIGhhcyBiZWVuIGNyZWF0ZWQuXG4gICAgICogICAgY29uc3QgY2xpZW50QnVzID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxOYW1lLCBjb25uZWN0UGF5bG9hZCk7XG4gICAgICpcbiAgICAgKiAgICBjbGllbnRCdXMub25EaXNjb25uZWN0aW9uKGNoYW5uZWxJbmZvID0+IHtcbiAgICAgKiAgICAgICAgLy8gaGFuZGxlIHRoZSBjaGFubmVsIGxpZmVjeWNsZSBoZXJlIC0gd2UgY2FuIGNvbm5lY3QgYWdhaW4gd2hpY2ggd2lsbCByZXR1cm4gYSBwcm9taXNlXG4gICAgICogICAgICAgIC8vIHRoYXQgd2lsbCByZXNvbHZlIGlmL3doZW4gdGhlIGNoYW5uZWwgaXMgcmUtY3JlYXRlZC5cbiAgICAgKiAgICAgICAgbWFrZUNsaWVudChjaGFubmVsSW5mby5jaGFubmVsTmFtZSk7XG4gICAgICogICAgfSlcbiAgICAgKlxuICAgICAqICAgIGNsaWVudEJ1cy5yZWdpc3RlcigndG9waWMnLCAocGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgLy8gcmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgYSB0b3BpYyB0byB3aGljaCB0aGUgY2hhbm5lbCBwcm92aWRlciBjYW4gZGlzcGF0Y2ggYW4gYWN0aW9uXG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdBY3Rpb24gZGlzcGF0Y2hlZCBieSBwcm92aWRlcjogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgZWNobzogcGF5bG9hZFxuICAgICAqICAgICAgICB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIG1ha2VDbGllbnQoJ2NoYW5uZWxOYW1lJylcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ29ubmVjdGVkJykpXG4gICAgICogLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGNvbm5lY3QoY2hhbm5lbE5hbWUsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgY29ubmVjdCBiZWZvcmUgbGlzdGVuZXJzIGFyZSBzZXQgdXBcbiAgICAgICAgLy8gVGhpcyBhbHNvIGVycm9ycyBpZiB3ZSdyZSBub3QgaW4gT3BlbkZpbiwgZW5zdXJpbmcgd2UgZG9uJ3QgcnVuIHVubmVjZXNzYXJ5IGNvZGVcbiAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ2KHRoaXMsIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0LCBcImZcIikuZ2V0VmFsdWUoKTtcbiAgICAgICAgaWYgKCFjaGFubmVsTmFtZSB8fCB0eXBlb2YgY2hhbm5lbE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgY2hhbm5lbE5hbWUgc3RyaW5nIHRvIGNvbm5lY3QgdG8gYSBjaGFubmVsLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdHMgPSB7IHdhaXQ6IHRydWUsIC4uLnRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXREZWZhdWx0Q2hhbm5lbE9wdGlvbnMoKS5jb25uZWN0LCAuLi5vcHRpb25zIH07XG4gICAgICAgIGNvbnN0IHsgb2ZmZXIsIHJ0YzogcnRjUGFja2V0IH0gPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDYodGhpcywgX0NoYW5uZWxfY29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5jcmVhdGVDbGllbnRPZmZlcihvcHRzKTtcbiAgICAgICAgbGV0IGNvbm5lY3Rpb25Vcmw7XG4gICAgICAgIGlmICh0aGlzLmZpbi5tZS5pc0ZyYW1lIHx8IHRoaXMuZmluLm1lLmlzVmlldyB8fCB0aGlzLmZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgICAgY29ubmVjdGlvblVybCA9IChhd2FpdCB0aGlzLmZpbi5tZS5nZXRJbmZvKCkpLnVybDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb25uZWN0UGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgICAgLi4ub3B0cyxcbiAgICAgICAgICAgIG9mZmVyLFxuICAgICAgICAgICAgY29ubmVjdGlvblVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByb3V0aW5nSW5mbyA9IGF3YWl0IHRoaXMuc2FmZUNvbm5lY3QoY2hhbm5lbE5hbWUsIG9wdHMud2FpdCwgY29ubmVjdFBheWxvYWQpO1xuICAgICAgICBjb25zdCBzdHJhdGVneSA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLmNyZWF0ZUNsaWVudFN0cmF0ZWd5KHJ0Y1BhY2tldCwgcm91dGluZ0luZm8pO1xuICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IGNsaWVudF8xLkNoYW5uZWxDbGllbnQocm91dGluZ0luZm8sICgpID0+IGNsaWVudF8xLkNoYW5uZWxDbGllbnQud2lyZUNsb3NlKHRoaXMud2lyZSwgcm91dGluZ0luZm8sIHJvdXRpbmdJbmZvLmVuZHBvaW50SWQpLCBzdHJhdGVneSk7XG4gICAgICAgIC8vIEl0IGlzIHRoZSBjbGllbnQncyByZXNwb25zaWJpbGl0eSB0byBoYW5kbGUgZW5kcG9pbnQgZGlzY29ubmVjdGlvbiB0byB0aGUgcHJvdmlkZXIuXG4gICAgICAgIC8vIElmIHRoZSBlbmRwb2ludCBkaWVzLCB0aGUgY2xpZW50IHdpbGwgZm9yY2UgYSBkaXNjb25uZWN0aW9uIHRocm91Z2ggdGhlIGNvcmUuXG4gICAgICAgIC8vIFRoZSBwcm92aWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IGVuZHBvaW50IGRpc2Nvbm5lY3Rpb24uXG4gICAgICAgIHN0cmF0ZWd5Lm9uRW5kcG9pbnREaXNjb25uZWN0KHJvdXRpbmdJbmZvLmNoYW5uZWxJZCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjaGFubmVsLnNlbmREaXNjb25uZWN0QWN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFNvbWV0aGluZyB3ZW50IHdyb25nIGR1cmluZyBkaXNjb25uZWN0IGZvciBjbGllbnQgd2l0aCB1dWlkOiAke3JvdXRpbmdJbmZvLnV1aWR9IC8gbmFtZTogJHtyb3V0aW5nSW5mby5uYW1lfSAvIGVuZHBvaW50SWQ6ICR7cm91dGluZ0luZm8uZW5kcG9pbnRJZH0uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBjbGllbnRfMS5DaGFubmVsQ2xpZW50LmhhbmRsZVByb3ZpZGVyRGlzY29ubmVjdChyb3V0aW5nSW5mbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hhbm5lbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGNoYW5uZWwuXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBhIHVuaXF1ZSBjaGFubmVsTmFtZS4gSWYgYSBjaGFubmVsTmFtZSBpcyBub3QgcHJvdmlkZWQsIG9yIGl0IGlzIG5vdCB1bmlxdWUsIHRoZSBjcmVhdGlvbiB3aWxsIGZhaWwuXG4gICAgICogRVhQRVJJTUVOVEFMOiBwYXNzIHsgcHJvdG9jb2xzOiBbJ3J0YyddIH0gYXMgb3B0aW9ucyB0byBvcHQtaW4gdG8gSGlnaCBUaHJvdWdocHV0IENoYW5uZWxzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoYW5uZWxOYW1lIC0gTmFtZSBvZiB0aGUgY2hhbm5lbCB0byBiZSBjcmVhdGVkLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gQ3JlYXRpb24gb3B0aW9ucy5cbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENoYW5uZWxQcm92aWRlciBDaGFubmVsUHJvdmlkZXJ9LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgc3VjY2Vzc2Z1bCwgdGhlIGNyZWF0ZSBtZXRob2QgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBpbnN0YW5jZSBvZiB0aGUgY2hhbm5lbFByb3ZpZGVyIGJ1cy4gVGhlIGNhbGxlclxuICAgICAqIHRoZW4gYmVjb21lcyB0aGUg4oCcY2hhbm5lbCBwcm92aWRlcuKAnSBhbmQgY2FuIHVzZSB0aGUgY2hhbm5lbFByb3ZpZGVyIGJ1cyB0byByZWdpc3RlciBhY3Rpb25zIGFuZCBtaWRkbGV3YXJlLlxuICAgICAqXG4gICAgICogVGhlIGNhbGxlciBjYW4gYWxzbyBzZXQgYW4gb25Db25uZWN0aW9uIGFuZC9vciBvbkRpc2Nvbm5lY3Rpb24gbGlzdGVuZXIgdGhhdCB3aWxsIGV4ZWN1dGUgb24gYW55IG5ldyBjaGFubmVsXG4gICAgICogY29ubmVjdGlvbi9kaXNjb25uZWN0aW9uIGF0dGVtcHQgZnJvbSBhIGNoYW5uZWwgY2xpZW50LiBUbyByZWplY3QgYSBjb25uZWN0aW9uLCBzaW1wbHkgdGhyb3cgYW4gZXJyb3IgaW4gdGhlXG4gICAgICogb25Db25uZWN0aW9uIGxpc3RlbmVyLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gYWNjZXB0IGFsbCBuZXcgY29ubmVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBBIG1hcCBvZiBjbGllbnQgY29ubmVjdGlvbnMgaXMgdXBkYXRlZCBhdXRvbWF0aWNhbGx5IG9uIGNsaWVudCBjb25uZWN0aW9uIGFuZCBkaXNjb25uZWN0aW9uIGFuZCBzYXZlZCBpbiB0aGVcbiAgICAgKiBbcmVhZC1vbmx5XSBgY29ubmVjdGlvbnNgIHByb3BlcnR5IG9uIHRoZSBjaGFubmVsUHJvdmlkZXIgYnVzLiAgVGhlIGNoYW5uZWwgd2lsbCBleGlzdCB1bnRpbCB0aGUgcHJvdmlkZXJcbiAgICAgKiBkZXN0cm95cyBpdCBvciBkaXNjb25uZWN0cyBieSBjbG9zaW5nIG9yIGRlc3Ryb3lpbmcgdGhlIGNvbnRleHQgKG5hdmlnYXRpbmcgb3IgcmVsb2FkaW5nKS4gVG8gc2V0dXAgYSBjaGFubmVsXG4gICAgICogYXMgYSBjaGFubmVsUHJvdmlkZXIsIGNhbGwgYENoYW5uZWwuY3JlYXRlYCB3aXRoIGEgdW5pcXVlIGNoYW5uZWwgbmFtZS4gQSBtYXAgb2YgY2xpZW50IGNvbm5lY3Rpb25zIGlzIHVwZGF0ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5IG9uIGNsaWVudCBjb25uZWN0aW9uIGFuZCBkaXNjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgIC8vIGVudGl0eSBjcmVhdGVzIGEgY2hhbm5lbCBhbmQgYmVjb21lcyB0aGUgY2hhbm5lbFByb3ZpZGVyXG4gICAgICogICAgY29uc3QgcHJvdmlkZXJCdXMgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgIHByb3ZpZGVyQnVzLm9uQ29ubmVjdGlvbigoaWRlbnRpdHksIHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgLy8gY2FuIHJlamVjdCBhIGNvbm5lY3Rpb24gaGVyZSBieSB0aHJvd2luZyBhbiBlcnJvclxuICAgICAqICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGNvbm5lY3Rpb24gcmVxdWVzdCBpZGVudGl0eTogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ0NsaWVudCBjb25uZWN0aW9uIHJlcXVlc3QgcGF5bG9hZDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgIH0pO1xuICAgICAqXG4gICAgICogICAgcHJvdmlkZXJCdXMucmVnaXN0ZXIoJ3RvcGljJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgIC8vIHJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIGEgJ3RvcGljJyB0byB3aGljaCBjbGllbnRzIGNhbiBkaXNwYXRjaCBhbiBhY3Rpb25cbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ0FjdGlvbiBkaXNwYXRjaGVkIGJ5IGNsaWVudDogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgZWNobzogcGF5bG9hZFxuICAgICAqICAgICAgICB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlKGNoYW5uZWxOYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgYSBjaGFubmVsTmFtZSB0byBjcmVhdGUgYSBjaGFubmVsJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGE6IHByb3ZpZGVySWRlbnRpdHkgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NyZWF0ZS1jaGFubmVsJywgeyBjaGFubmVsTmFtZSB9KTtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLmNyZWF0ZVByb3ZpZGVyKG9wdGlvbnMsIHByb3ZpZGVySWRlbnRpdHkpO1xuICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICB0aGlzLm9uKCdjbGllbnQtZGlzY29ubmVjdGVkJywgKGV2ZW50UGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50UGF5bG9hZC5jaGFubmVsTmFtZSA9PT0gY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICBwcm92aWRlcl8xLkNoYW5uZWxQcm92aWRlci5oYW5kbGVDbGllbnREaXNjb25uZWN0aW9uKGNoYW5uZWwsIGV2ZW50UGF5bG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hhbm5lbDtcbiAgICB9XG59XG5jaGFubmVsJDEuQ2hhbm5lbCA9IENoYW5uZWw7XG5fQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsX2ludGVybmFsRW1pdHRlciA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0ID0gbmV3IFdlYWtNYXAoKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGludGVyYXBwYnVzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmludGVyYXBwYnVzLkludGVyQXBwUGF5bG9hZCA9IGludGVyYXBwYnVzLkludGVyQXBwbGljYXRpb25CdXMgPSB2b2lkIDA7XG4vKipcbiAqIEVudHJ5IHBvaW50IGZvciB0aGUgT3BlbkZpbiBgSW50ZXJBcHBsaWNhdGlvbkJ1c2AgQVBJIChgZmluLkludGVyQXBwbGljYXRpb25CdXNgKS5cbiAqXG4gKiAqIHtAbGluayBJbnRlckFwcGxpY2F0aW9uQnVzfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEludGVyQXBwbGljYXRpb25CdXNgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1c2AuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbmNvbnN0IGV2ZW50c18xJDQgPSByZXF1aXJlJCQwO1xuY29uc3QgYmFzZV8xJGQgPSBiYXNlO1xuY29uc3QgcmVmX2NvdW50ZXJfMSA9IHJlZkNvdW50ZXI7XG5jb25zdCBpbmRleF8xJDIgPSBjaGFubmVsJDE7XG5jb25zdCB2YWxpZGF0ZV8xJDMgPSB2YWxpZGF0ZTtcbi8qKlxuICogQSBtZXNzYWdpbmcgYnVzIHRoYXQgYWxsb3dzIGZvciBwdWIvc3ViIG1lc3NhZ2luZyBiZXR3ZWVuIGRpZmZlcmVudCBhcHBsaWNhdGlvbnMuXG4gKlxuICovXG5jbGFzcyBJbnRlckFwcGxpY2F0aW9uQnVzIGV4dGVuZHMgYmFzZV8xJGQuQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgdGhpcy5ldmVudHMgPSB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyQWRkZWQ6ICdzdWJzY3JpYmVyLWFkZGVkJyxcbiAgICAgICAgICAgIHN1YnNjcmliZXJSZW1vdmVkOiAnc3Vic2NyaWJlci1yZW1vdmVkJ1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJlZkNvdW50ZXIgPSBuZXcgcmVmX2NvdW50ZXJfMS5SZWZDb3VudGVyKCk7XG4gICAgICAgIHRoaXMuQ2hhbm5lbCA9IG5ldyBpbmRleF8xJDIuQ2hhbm5lbCh3aXJlKTtcbiAgICAgICAgdGhpcy5lbWl0dGVyID0gbmV3IGV2ZW50c18xJDQuRXZlbnRFbWl0dGVyKCk7XG4gICAgICAgIHdpcmUucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcih0aGlzLm9ubWVzc2FnZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5vbiA9IHRoaXMuZW1pdHRlci5vbi5iaW5kKHRoaXMuZW1pdHRlcik7XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzID0gdGhpcy5lbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycy5iaW5kKHRoaXMuZW1pdHRlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyBhIG1lc3NhZ2UgdG8gYWxsIGFwcGxpY2F0aW9ucyBydW5uaW5nIG9uIE9wZW5GaW4gUnVudGltZSB0aGF0XG4gICAgICogYXJlIHN1YnNjcmliZWQgdG8gdGhlIHNwZWNpZmllZCB0b3BpYy5cbiAgICAgKiBAcGFyYW0gdG9waWMgVGhlIHRvcGljIG9uIHdoaWNoIHRoZSBtZXNzYWdlIGlzIHNlbnRcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBiZSBwdWJsaXNoZWQuIENhbiBiZSBlaXRoZXIgYSBwcmltaXRpdmVcbiAgICAgKiBkYXRhIHR5cGUgKHN0cmluZywgbnVtYmVyLCBvciBib29sZWFuKSBvciBjb21wb3NpdGUgZGF0YSB0eXBlIChvYmplY3QsIGFycmF5KVxuICAgICAqIHRoYXQgaXMgY29tcG9zZWQgb2Ygb3RoZXIgcHJpbWl0aXZlIG9yIGNvbXBvc2l0ZSBkYXRhIHR5cGVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMucHVibGlzaCgndG9waWMnLCAnaGVsbG8nKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQdWJsaXNoZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHB1Ymxpc2godG9waWMsIG1lc3NhZ2UpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3B1Ymxpc2gtbWVzc2FnZScsIHtcbiAgICAgICAgICAgIHRvcGljLFxuICAgICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWU6IHRoaXMubWUubmFtZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBtZXNzYWdlIHRvIGEgc3BlY2lmaWMgYXBwbGljYXRpb24gb24gYSBzcGVjaWZpYyB0b3BpYy5cbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGlkZW50aXR5IG9mIHRoZSBhcHBsaWNhdGlvbiB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIHRvcGljIFRoZSB0b3BpYyBvbiB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gYmUgc2VudC4gQ2FuIGJlIGVpdGhlciBhIHByaW1pdGl2ZSBkYXRhXG4gICAgICogdHlwZSAoc3RyaW5nLCBudW1iZXIsIG9yIGJvb2xlYW4pIG9yIGNvbXBvc2l0ZSBkYXRhIHR5cGUgKG9iamVjdCwgYXJyYXkpIHRoYXRcbiAgICAgKiBpcyBjb21wb3NlZCBvZiBvdGhlciBwcmltaXRpdmUgb3IgY29tcG9zaXRlIGRhdGEgdHlwZXNcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5zZW5kKGZpbi5tZSwgJ3RvcGljJywgJ0hlbGxvIHRoZXJlIScpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01lc3NhZ2Ugc2VudCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgc2VuZChkZXN0aW5hdGlvbiwgdG9waWMsIG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMSQzLnZhbGlkYXRlSWRlbnRpdHkpKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZW5kLW1lc3NhZ2UnLCB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvblV1aWQ6IGRlc3RpbmF0aW9uLnV1aWQsXG4gICAgICAgICAgICBkZXN0aW5hdGlvbldpbmRvd05hbWU6IGRlc3RpbmF0aW9uLm5hbWUsXG4gICAgICAgICAgICB0b3BpYyxcbiAgICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICBzb3VyY2VXaW5kb3dOYW1lOiB0aGlzLm1lLm5hbWVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gbWVzc2FnZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGFwcGxpY2F0aW9uIG9uIHRoZSBzcGVjaWZpZWQgdG9waWMuXG4gICAgICogQHBhcmFtIHNvdXJjZSBUaGlzIG9iamVjdCBpcyBkZXNjcmliZWQgaW4gdGhlIElkZW50aXR5IGluIHRoZSB0eXBlZGVmXG4gICAgICogQHBhcmFtIHRvcGljIFRoZSB0b3BpYyBvbiB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIGxpc3RlbmVyIEEgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiBhIG1lc3NhZ2UgaGFzXG4gICAgICogYmVlbiByZWNlaXZlZC4gSXQgaXMgcGFzc2VkIHRoZSBtZXNzYWdlLCB1dWlkIGFuZCBuYW1lIG9mIHRoZSBzZW5kaW5nIGFwcGxpY2F0aW9uLlxuICAgICAqIFRoZSBtZXNzYWdlIGNhbiBiZSBlaXRoZXIgYSBwcmltaXRpdmUgZGF0YSB0eXBlIChzdHJpbmcsIG51bWJlciwgb3IgYm9vbGVhbikgb3JcbiAgICAgKiBjb21wb3NpdGUgZGF0YSB0eXBlIChvYmplY3QsIGFycmF5KSB0aGF0IGlzIGNvbXBvc2VkIG9mIG90aGVyIHByaW1pdGl2ZSBvciBjb21wb3NpdGVcbiAgICAgKiBkYXRhIHR5cGVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogLy8gc3Vic2NyaWJlIHRvIGEgc3BlY2lmaWVkIGFwcGxpY2F0aW9uXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMuc3Vic2NyaWJlKGZpbi5tZSwgJ3RvcGljJywgc3ViX21zZyA9PiBjb25zb2xlLmxvZyhzdWJfbXNnKSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3Vic2NyaWJlZCB0byB0aGUgc3BlY2lmaWVkIGFwcGxpY2F0aW9uJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIC8vIHN1YnNjcmliZSB0byB3aWxkY2FyZFxuICAgICAqIGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLnN1YnNjcmliZSh7IHV1aWQ6ICcqJyB9LCAndG9waWMnLCBzdWJfbXNnID0+IGNvbnNvbGUubG9nKHN1Yl9tc2cpKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTdWJzY3JpYmVkIHRvIConKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHN1YnNjcmliZShzb3VyY2UsIHRvcGljLCBsaXN0ZW5lcikge1xuICAgICAgICBjb25zdCBzdWJLZXkgPSB0aGlzLmNyZWF0ZVN1YnNjcmlwdGlvbktleShzb3VyY2UudXVpZCwgc291cmNlLm5hbWUgfHwgJyonLCB0b3BpYyk7XG4gICAgICAgIGNvbnN0IHNlbmRTdWJzY3JpcHRpb24gPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3Vic2NyaWJlJywge1xuICAgICAgICAgICAgICAgIHNvdXJjZVV1aWQ6IHNvdXJjZS51dWlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWU6IHNvdXJjZS5uYW1lIHx8ICcqJyxcbiAgICAgICAgICAgICAgICB0b3BpYyxcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbldpbmRvd05hbWU6IHRoaXMubWUubmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFscmVhZHlTdWJzY3JpYmVkID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmVtaXR0ZXIub24oc3ViS2V5LCBsaXN0ZW5lcik7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZkNvdW50ZXIuYWN0T25GaXJzdChzdWJLZXksIHNlbmRTdWJzY3JpcHRpb24sIGFscmVhZHlTdWJzY3JpYmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIHRvIG1lc3NhZ2VzIGZyb20gdGhlIHNwZWNpZmllZCBhcHBsaWNhdGlvbiBvbiB0aGUgc3BlY2lmaWVkIHRvcGljLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgeW91IGFyZSBsaXN0ZW5pbmcgdG8gYWxsIGFwcHMgb24gYSB0b3BpYywgKGkuZSB5b3UgcGFzc2VkIGB7IHV1aWQ6JyonIH1gIHRvIHRoZSBzdWJzY3JpYmUgZnVuY3Rpb24pXG4gICAgICogdGhlbiB5b3UgbmVlZCB0byBwYXNzIGB7IHV1aWQ6JyonIH1gIHRvIHVuc3Vic2NyaWJlIGFzIHdlbGwuIElmIHlvdSBhcmUgbGlzdGVuaW5nIHRvIGEgc3BlY2lmaWMgYXBwbGljYXRpb24sXG4gICAgICogKGkuZSB5b3UgcGFzc2VkIGB7IHV1aWQ6J3NvbWVfYXBwJyB9YCB0byB0aGUgc3Vic2NyaWJlIGZ1bmN0aW9uKSB0aGVuIHlvdSBuZWVkIHRvIHByb3ZpZGUgdGhlIHNhbWUgaWRlbnRpZmllciB0b1xuICAgICAqIHVuc3Vic2NyaWJlLCB1bnN1YnNjcmliaW5nIHRvIGAqYCBvbiB0aGF0IHNhbWUgdG9waWMgd2lsbCBub3QgdW5ob29rIHlvdXIgaW5pdGlhbCBsaXN0ZW5lciBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc291cmNlIFRoaXMgb2JqZWN0IGlzIGRlc2NyaWJlZCBpbiB0aGUgSWRlbnRpdHkgaW4gdGhlIHR5cGVkZWZcbiAgICAgKiBAcGFyYW0gdG9waWMgVGhlIHRvcGljIG9uIHdoaWNoIHRoZSBtZXNzYWdlIGlzIHNlbnRcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXIgQSBjYWxsYmFjayBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBzdWJzY3JpYmUoKVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGxpc3RlbmVyID0gY29uc29sZS5sb2c7XG4gICAgICpcbiAgICAgKiAvLyBJZiBhbnkgYXBwbGljYXRpb24gcHVibGlzaGVzIGEgbWVzc2FnZSBvbiB0b3BpYyBgZm9vYCwgb3VyIGxpc3RlbmVyIHdpbGwgYmUgY2FsbGVkLlxuICAgICAqIGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLnN1YnNjcmliZSh7IHV1aWQ6JyonIH0sICdmb28nLCBsaXN0ZW5lcilcbiAgICAgKlxuICAgICAqIC8vIFdoZW4geW91IHdhbnQgdG8gdW5zdWJzY3JpYmUsIHlvdSBuZWVkIHRvIHNwZWNpZnkgdGhlIHV1aWQgb2YgdGhlIGFwcCB5b3UnZCBsaWtlIHRvXG4gICAgICogLy8gdW5zdWJzY3JpYmUgZnJvbSAob3IgYCpgKSBhbmQgcHJvdmlkZSB0aGUgc2FtZSBmdW5jdGlvbiB5b3UgZ2F2ZSB0aGUgc3Vic2NyaWJlIGZ1bmN0aW9uXG4gICAgICogYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMudW5zdWJzY3JpYmUoeyB1dWlkOicqJyB9LCAnZm9vJywgbGlzdGVuZXIpXG4gICAgICogYGBgXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmUoc291cmNlLCB0b3BpYywgbGlzdGVuZXIpIHtcbiAgICAgICAgY29uc3Qgc291cmNlV2luZG93TmFtZSA9IHNvdXJjZS5uYW1lIHx8ICcqJztcbiAgICAgICAgY29uc3Qgc3ViS2V5ID0gdGhpcy5jcmVhdGVTdWJzY3JpcHRpb25LZXkoc291cmNlLnV1aWQsIHNvdXJjZVdpbmRvd05hbWUsIHRvcGljKTtcbiAgICAgICAgY29uc3Qgc2VuZFVuc3Vic2NyaXB0aW9uID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Vuc3Vic2NyaWJlJywge1xuICAgICAgICAgICAgICAgIHNvdXJjZVV1aWQ6IHNvdXJjZS51dWlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWUsXG4gICAgICAgICAgICAgICAgdG9waWMsXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25XaW5kb3dOYW1lOiB0aGlzLm1lLm5hbWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBkb250U2VuZFVuc3Vic2NyaXB0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyKSA9PiByKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihzdWJLZXksIGxpc3RlbmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVmQ291bnRlci5hY3RPbkxhc3Qoc3ViS2V5LCBzZW5kVW5zdWJzY3JpcHRpb24sIGRvbnRTZW5kVW5zdWJzY3JpcHRpb24pO1xuICAgIH1cbiAgICBwcm9jZXNzTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBtZXNzYWdlOiBwYXlsb2FkTWVzc2FnZSwgc291cmNlV2luZG93TmFtZSwgc291cmNlVXVpZCwgdG9waWMgfSB9ID0gbWVzc2FnZTtcbiAgICAgICAgY29uc3Qga2V5cyA9IFtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHNvdXJjZVV1aWQsIHNvdXJjZVdpbmRvd05hbWUsIHRvcGljKSxcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHNvdXJjZVV1aWQsICcqJywgdG9waWMpLFxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdWJzY3JpcHRpb25LZXkoJyonLCAnKicsIHRvcGljKVxuICAgICAgICBdO1xuICAgICAgICBjb25zdCBpZE9mU2VuZGVyID0geyB1dWlkOiBzb3VyY2VVdWlkLCBuYW1lOiBzb3VyY2VXaW5kb3dOYW1lIH07XG4gICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIuZW1pdChrZXksIHBheWxvYWRNZXNzYWdlLCBpZE9mU2VuZGVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtaXRTdWJzY3JpdmVyRXZlbnQodHlwZSwgbWVzc2FnZSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgdGFyZ2V0TmFtZTogbmFtZSwgdXVpZCwgdG9waWMgfSB9ID0gbWVzc2FnZTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHsgbmFtZSwgdXVpZCwgdG9waWMgfTtcbiAgICAgICAgdGhpcy5lbWl0dGVyLmVtaXQodHlwZSwgcGF5bG9hZCk7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG4gICAgY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHV1aWQsIG5hbWUsIHRvcGljKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuYW1lIHx8ICcqJztcbiAgICAgICAgaWYgKCEodXVpZCAmJiBuICYmIHRvcGljKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHV1aWQsIG5hbWUsIG9yIHRvcGljIHN0cmluZycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjcmVhdGVLZXkodXVpZCwgbiwgdG9waWMpO1xuICAgIH1cbiAgICBvbm1lc3NhZ2UobWVzc2FnZSkge1xuICAgICAgICBjb25zdCB7IGFjdGlvbiB9ID0gbWVzc2FnZTtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24pIHtcbiAgICAgICAgICAgIGNhc2UgJ3Byb2Nlc3MtbWVzc2FnZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzTWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgdGhpcy5ldmVudHMuc3Vic2NyaWJlckFkZGVkOlxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdFN1YnNjcml2ZXJFdmVudCh0aGlzLmV2ZW50cy5zdWJzY3JpYmVyQWRkZWQsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0aGlzLmV2ZW50cy5zdWJzY3JpYmVyUmVtb3ZlZDpcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRTdWJzY3JpdmVyRXZlbnQodGhpcy5ldmVudHMuc3Vic2NyaWJlclJlbW92ZWQsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmludGVyYXBwYnVzLkludGVyQXBwbGljYXRpb25CdXMgPSBJbnRlckFwcGxpY2F0aW9uQnVzO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgSW50ZXJBcHBQYXlsb2FkIHtcbn1cbmludGVyYXBwYnVzLkludGVyQXBwUGF5bG9hZCA9IEludGVyQXBwUGF5bG9hZDtcbmZ1bmN0aW9uIGNyZWF0ZUtleSguLi50b0hhc2gpIHtcbiAgICByZXR1cm4gdG9IYXNoXG4gICAgICAgIC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGAke2l0ZW19YCkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIH0pXG4gICAgICAgIC5qb2luKCcvJyk7XG59XG5cbnZhciBjbGlwYm9hcmQgPSB7fTtcblxuLyoqXG4gKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYENsaXBib2FyZGAgQVBJIChgZmluLkNsaXBib2FyZGApLlxuICpcbiAqICoge0BsaW5rIENsaXBib2FyZH0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBDbGlwYm9hcmRgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uQ2xpcGJvYXJkYC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNsaXBib2FyZCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jbGlwYm9hcmQuQ2xpcGJvYXJkID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJGMgPSBiYXNlO1xuLyoqXG4gKiBUaGUgQ2xpcGJvYXJkIEFQSSBhbGxvd3MgcmVhZGluZyBhbmQgd3JpdGluZyB0byB0aGUgY2xpcGJvYXJkIGluIG11bHRpcGxlIGZvcm1hdHMuXG4gKlxuICovXG5jbGFzcyBDbGlwYm9hcmQgZXh0ZW5kcyBiYXNlXzEkYy5CYXNlIHtcbiAgICAvKipcbiAgICAgKiBXcml0ZXMgZGF0YSBpbnRvIHRoZSBjbGlwYm9hcmQgYXMgcGxhaW4gdGV4dFxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZVRleHQoe1xuICAgICAqICAgICBkYXRhOiAnaGVsbG8sIHdvcmxkJ1xuICAgICAqIH0pLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1RleHQgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVRleHQod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS10ZXh0Jywgd3JpdGVPYmopO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjb250ZW50IG9mIHRoZSBjbGlwYm9hcmQgYXMgcGxhaW4gdGV4dFxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkVGV4dCgpLnRoZW4odGV4dCA9PiBjb25zb2xlLmxvZyh0ZXh0KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRUZXh0KHR5cGUpIHtcbiAgICAgICAgLy8gTk9URTogV2hlbiB3ZSBzdGFydCBzdXBwb3J0aW5nIGxpbnV4LCB3ZSBjb3VsZCBkZXRlY3QgdGhlIE9TIGFuZCBjaG9vc2UgJ3NlbGVjdGlvbicgYXV0b21hdGljYWxseSBmb3IgdGhlIHVzZXJcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXJlYWQtdGV4dCcsIHsgdHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIGFuIEltYWdlXG4gICAgICogQHBhcmFtIHdyaXRlUmVxdWVzdCBUaGUgb2JqZWN0IHRvIHdyaXRlIGFuIGltYWdlIHRvIHRoZSBjbGlwYm9hcmRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uQ2xpcGJvYXJkLndyaXRlSW1hZ2Uoe1xuICAgICAqICAgLy8gcmF3IGJhc2U2NCBzdHJpbmcsIG9yIGRhdGFVUkwgb2YgZWl0aGVyIGRhdGE6aW1hZ2UvcG5nIG9yIGRhdGE6aW1hZ2UvanBlZyB0eXBlXG4gICAgICogICBpbWFnZTogJy4uLidcbiAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdJbWFnZSB3cml0dGVuIHRvIGNsaXBib2FyZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JpdGVJbWFnZSh3cml0ZVJlcXVlc3QpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS1pbWFnZScsIHdyaXRlUmVxdWVzdCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZCBhcyBhIGJhc2U2NCBzdHJpbmcgb3IgYSBkYXRhVVJMIGJhc2VkIG9uIHRoZSBpbnB1dCBwYXJhbWV0ZXIgJ2Zvcm1hdCcsIGRlZmF1bHRzIHRvICdkYXRhVVJMJ1xuICAgICAqIEBwYXJhbSByZWFkUmVxdWVzdCBDbGlwYm9hcmQgUmVhZCBJbWFnZSByZXF1ZXN0IHdpdGggZm9ybWF0dGluZyBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogLy8gc2VlIFRTIHR5cGU6IE9wZW5GaW4uSW1hZ2VGb3JtYXRPcHRpb25zXG4gICAgICpcbiAgICAgKiBjb25zdCBwbmdPckRhdGFVUkxPckJtcE9wdGlvbnMgPSB7XG4gICAgICogICAgIGZvcm1hdDogJ3BuZycsIC8vIGNhbiBiZTogJ3BuZycgfCAnZGF0YVVSTCcgfCAnYm1wJ1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBjb25zdCBqcGdPcHRpb25zID0ge1xuICAgICAqICAgICBmb3JtYXQ6ICdqcGcnLFxuICAgICAqICAgICBxdWFsaXR5OiA4MCAvLyBvcHRpb25hbCwgaWYgb21pdHRlZCBkZWZhdWx0cyB0byAxMDBcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSW1hZ2UocG5nT3JEYXRhVVJMT3JCbXBPcHRpb25zKVxuICAgICAqICAgICAudGhlbihpbWFnZSA9PiBjb25zb2xlLmxvZygnSW1hZ2UgcmVhZCBmcm9tIGNsaXBib2FyZCBhcyBQTkcsIERhdGFVUkwgb3IgQk1QJywgaW1hZ2UpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSW1hZ2UoanBnT3B0aW9ucylcbiAgICAgKiAgICAgLnRoZW4oaW1hZ2UgPT4gY29uc29sZS5sb2coJ0ltYWdlIHJlYWQgZnJvbSBjbGlwYm9hcmQgYXMgSlBHJywgaW1hZ2UpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogLy8gZGVmYXVsdHMgdG8ge2Zvcm1hdDogJ2RhdGFVUkwnfVxuICAgICAqIGZpbi5DbGlwYm9hcmQucmVhZEltYWdlKClcbiAgICAgKiAgICAgLnRoZW4oaW1hZ2UgPT4gY29uc29sZS5sb2coJ0ltYWdlIHJlYWQgZnJvbSBjbGlwYm9hcmQgYXMgRGF0YVVSTCcsIGltYWdlKSlcbiAgICAgKiAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRJbWFnZShyZWFkUmVxdWVzdCA9IHsgZm9ybWF0OiAnZGF0YVVSTCcgfSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGlwYm9hcmQtcmVhZC1pbWFnZScsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIEh0bWxcbiAgICAgKiBAcGFyYW0gd3JpdGVPYmogVGhlIG9iamVjdCBmb3Igd3JpdGluZyBkYXRhIGludG8gdGhlIGNsaXBib2FyZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5DbGlwYm9hcmQud3JpdGVIdG1sKHtcbiAgICAgKiAgICAgICAgIGRhdGE6ICc8aDE+SGVsbG8sIFdvcmxkITwvaDE+J1xuICAgICAqIH0pLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0hUTUwgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZUh0bWwod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS1odG1sJywgd3JpdGVPYmopO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjb250ZW50IG9mIHRoZSBjbGlwYm9hcmQgYXMgSHRtbFxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSHRtbCgpLnRoZW4oaHRtbCA9PiBjb25zb2xlLmxvZyhodG1sKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRIdG1sKHR5cGUpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXJlYWQtaHRtbCcsIHsgdHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIFJ0ZlxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZVJ0Zih7XG4gICAgICogICAgICAgICBkYXRhOiAnc29tZSB0ZXh0IGdvZXMgaGVyZSdcbiAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdSVEYgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVJ0Zih3cml0ZU9iaikge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXdyaXRlLXJ0ZicsIHdyaXRlT2JqKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY29udGVudCBvZiB0aGUgY2xpcGJvYXJkIGFzIFJ0ZlxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3cml0ZU9iaiA9IHtcbiAgICAgKiAgICAgZGF0YTogJ3NvbWUgdGV4dCBnb2VzIGhlcmUnXG4gICAgICogfTtcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWFkUnRmKCkge1xuICAgICAqICAgICBhd2FpdCBmaW4uQ2xpcGJvYXJkLndyaXRlUnRmKHdyaXRlT2JqKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGZpbi5DbGlwYm9hcmQucmVhZFJ0ZigpO1xuICAgICAqIH1cbiAgICAgKiByZWFkUnRmKCkudGhlbihydGYgPT4gY29uc29sZS5sb2cocnRmKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRSdGYodHlwZSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGlwYm9hcmQtcmVhZC1ydGYnLCB7IHR5cGUgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyaXRlcyBkYXRhIGludG8gdGhlIGNsaXBib2FyZFxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZSh7XG4gICAgICogICBkYXRhOiB7XG4gICAgICogICAgIHRleHQ6ICdhJyxcbiAgICAgKiAgICAgaHRtbDogJ2InLFxuICAgICAqICAgICBydGY6ICdjJyxcbiAgICAgKiAgICAgLy8gQ2FuIGJlIGVpdGhlciBhIGJhc2U2NCBzdHJpbmcsIG9yIGEgRGF0YVVSTCBzdHJpbmcuIElmIHVzaW5nIERhdGFVUkwsIHRoZVxuICAgICAqICAgICAvLyBzdXBwb3J0ZWQgZm9ybWF0cyBhcmUgYGRhdGE6aW1hZ2UvcG5nWztiYXNlNjRdLGAgYW5kIGBkYXRhOmltYWdlL2pwZWdbO2Jhc2U2NF0sYC5cbiAgICAgKiAgICAgLy8gVXNpbmcgb3RoZXIgaW1hZ2UvPGZvcm1hdD4gRGF0YVVSTHMgd2lsbCB0aHJvdyBhbiBFcnJvci5cbiAgICAgKiAgICAgaW1hZ2U6ICcuLi4nXG4gICAgICogICB9XG4gICAgICogfSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnd3JpdGUgZGF0YSBpbnRvIGNsaXBib2FyZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JpdGUod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZScsIHdyaXRlT2JqKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZHMgYXZhaWxhYmxlIGZvcm1hdHMgZm9yIHRoZSBjbGlwYm9hcmQgdHlwZVxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5nZXRBdmFpbGFibGVGb3JtYXRzKCkudGhlbihmb3JtYXRzID0+IGNvbnNvbGUubG9nKGZvcm1hdHMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QXZhaWxhYmxlRm9ybWF0cyh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC1yZWFkLWZvcm1hdHMnLCB7IHR5cGUgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxufVxuY2xpcGJvYXJkLkNsaXBib2FyZCA9IENsaXBib2FyZDtcblxudmFyIGV4dGVybmFsQXBwbGljYXRpb24gPSB7fTtcblxudmFyIEZhY3RvcnkkNSA9IHt9O1xuXG52YXIgSW5zdGFuY2UkNCA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW5zdGFuY2UkNCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZSQ0LkV4dGVybmFsQXBwbGljYXRpb24gPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5jb25zdCBiYXNlXzEkYiA9IGJhc2U7XG4vKipcbiAqIEFuIEV4dGVybmFsQXBwbGljYXRpb24gb2JqZWN0IHJlcHJlc2VudGluZyBuYXRpdmUgbGFuZ3VhZ2UgYWRhcHRlciBjb25uZWN0aW9ucyB0byB0aGUgcnVudGltZS4gQWxsb3dzXG4gKiB0aGUgZGV2ZWxvcGVyIHRvIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzIGV4dGVybmFsIGFwcGxpY2F0aW9uIGV2ZW50c30uXG4gKiBEaXNjb3Zlcnkgb2YgY29ubmVjdGlvbnMgaXMgcHJvdmlkZWQgYnkge0BsaW5rIFN5c3RlbS5TeXN0ZW0uZ2V0QWxsRXh0ZXJuYWxBcHBsaWNhdGlvbnMgZ2V0QWxsRXh0ZXJuYWxBcHBsaWNhdGlvbnN9LjwvYT5cbiAqXG4gKiBQcm9jZXNzZXMgdGhhdCBjYW4gYmUgd3JhcHBlZCBhcyBgRXh0ZXJuYWxBcHBsaWNhdGlvbmBzIGluY2x1ZGUgdGhlIGZvbGxvd2luZzpcbiAqIC0gUHJvY2Vzc2VzIHdoaWNoIGhhdmUgY29ubmVjdGVkIHRvIGFuIE9wZW5GaW4gcnVudGltZSB2aWEgYW4gYWRhcHRlclxuICogLSBQcm9jZXNzZXMgc3RhcnRlZCB2aWEgYFN5c3RlbS5sYXVuY2hFeHRlcm5hbEFwcGxpY2F0aW9uYFxuICogLSBQcm9jZXNzZXMgbW9uaXRvcmVkIHZpYSBgU3lzdGVtLm1vbml0b3JFeHRlcm5hbFByb2Nlc3NgXG4gKi9cbmNsYXNzIEV4dGVybmFsQXBwbGljYXRpb24gZXh0ZW5kcyBiYXNlXzEkYi5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgJ2V4dGVybmFsLWFwcGxpY2F0aW9uJywgaWRlbnRpdHkudXVpZCk7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBleHRlcm5hbCBhcHBsaWNhdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRJbmZvKCkge1xuICAgICAqICAgICBjb25zdCBleHRBcHAgPSBhd2FpdCBmaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbi53cmFwKCdqYXZhQXBwLXV1aWQnKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGV4dEFwcC5nZXRJbmZvKCk7XG4gICAgICogfVxuICAgICAqIGdldEluZm8oKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1leHRlcm5hbC1hcHBsaWNhdGlvbi1pbmZvJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxufVxuSW5zdGFuY2UkNC5FeHRlcm5hbEFwcGxpY2F0aW9uID0gRXh0ZXJuYWxBcHBsaWNhdGlvbjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkNSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDUuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSRhID0gYmFzZTtcbmNvbnN0IEluc3RhbmNlXzEkNCA9IEluc3RhbmNlJDQ7XG4vKipcbiAqIFN0YXRpYyBuYW1lc3BhY2UgZm9yIE9wZW5GaW4gQVBJIG1ldGhvZHMgdGhhdCBpbnRlcmFjdCB3aXRoIHRoZSB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbn0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkV4dGVybmFsQXBwbGljYXRpb25gLlxuICovXG5jbGFzcyBFeHRlcm5hbEFwcGxpY2F0aW9uTW9kdWxlIGV4dGVuZHMgYmFzZV8xJGEuQmFzZSB7XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBFeHRlcm5hbCBBcHBsaWNhdGlvbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGFuIGV4dGVybmFsIGFwcGxpY2F0aW9uLlxuICAgICAqIDxicj5JdCBpcyBwb3NzaWJsZSB0byB3cmFwIGEgcHJvY2VzcyB0aGF0IGRvZXMgbm90IHlldCBleGlzdCwgKGZvciBleGFtcGxlLCB0byBsaXN0ZW4gZm9yIHN0YXJ0dXAtcmVsYXRlZCBldmVudHMpXG4gICAgICogcHJvdmlkZWQgaXRzIHV1aWQgaXMgYWxyZWFkeSBrbm93bi5cbiAgICAgKiBAcGFyYW0gdXVpZCBUaGUgVVVJRCBvZiB0aGUgZXh0ZXJuYWwgYXBwbGljYXRpb24gdG8gYmUgd3JhcHBlZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uLndyYXAoJ2phdmFBcHAtdXVpZCcpO1xuICAgICAqIC50aGVuKGV4dEFwcCA9PiBjb25zb2xlLmxvZygnd3JhcHBlZCBleHRlcm5hbCBhcHBsaWNhdGlvbicpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgd3JhcCh1dWlkKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdleHRlcm5hbC1hcHBsaWNhdGlvbi13cmFwJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgSW5zdGFuY2VfMSQ0LkV4dGVybmFsQXBwbGljYXRpb24odGhpcy53aXJlLCB7IHV1aWQgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gRXh0ZXJuYWwgQXBwbGljYXRpb24gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleHRlcm5hbCBhcHBsaWNhdGlvbi5cbiAgICAgKiA8YnI+SXQgaXMgcG9zc2libGUgdG8gd3JhcCBhIHByb2Nlc3MgdGhhdCBkb2VzIG5vdCB5ZXQgZXhpc3QsIChmb3IgZXhhbXBsZSwgdG8gbGlzdGVuIGZvciBzdGFydHVwLXJlbGF0ZWQgZXZlbnRzKVxuICAgICAqIHByb3ZpZGVkIGl0cyB1dWlkIGlzIGFscmVhZHkga25vd24uXG4gICAgICogQHBhcmFtIHV1aWQgVGhlIFVVSUQgb2YgdGhlIGV4dGVybmFsIGFwcGxpY2F0aW9uIHRvIGJlIHdyYXBwZWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBleHRBcHAgPSBmaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbi53cmFwU3luYygnamF2YUFwcC11dWlkJyk7XG4gICAgICogY29uc3QgaW5mbyA9IGF3YWl0IGV4dEFwcC5nZXRJbmZvKCk7XG4gICAgICogY29uc29sZS5sb2coaW5mbyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgd3JhcFN5bmModXVpZCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZXh0ZXJuYWwtYXBwbGljYXRpb24td3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDQuRXh0ZXJuYWxBcHBsaWNhdGlvbih0aGlzLndpcmUsIHsgdXVpZCB9KTtcbiAgICB9XG59XG5GYWN0b3J5JDUuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSA9IEV4dGVybmFsQXBwbGljYXRpb25Nb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgRXh0ZXJuYWxBcHBsaWNhdGlvbmAgQVBJIChgZmluLkV4dGVybmFsQXBwbGljYXRpb25gKS5cblx0ICpcblx0ICogKiB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBFeHRlcm5hbEFwcGxpY2F0aW9uYCB0eXBlLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uYC5cblx0ICogKiB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbn0gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gRXh0ZXJuYWxBcHBsaWNhdGlvbiwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLkV4dGVybmFsQXBwbGljYXRpb24uZ2V0Q3VycmVudGAuXG5cdCAqXG5cdCAqIFRoZXNlIGFyZSBzZXBhcmF0ZSBjb2RlIGVudGl0aWVzLCBhbmQgYXJlIGRvY3VtZW50ZWQgc2VwYXJhdGVseS4gIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdCAqL1xuXHRfX2V4cG9ydFN0YXIoRmFjdG9yeSQ1LCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKEluc3RhbmNlJDQsIGV4cG9ydHMpOyBcbn0gKGV4dGVybmFsQXBwbGljYXRpb24pKTtcblxudmFyIGZyYW1lID0ge307XG5cbnZhciBGYWN0b3J5JDQgPSB7fTtcblxudmFyIEluc3RhbmNlJDMgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuSW5zdGFuY2UkMy5fRnJhbWUgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5jb25zdCBiYXNlXzEkOSA9IGJhc2U7XG4vKipcbiAqIEFuIGlmcmFtZSByZXByZXNlbnRzIGFuIGVtYmVkZGVkIEhUTUwgcGFnZSB3aXRoaW4gYSBwYXJlbnQgSFRNTCBwYWdlLiBCZWNhdXNlIHRoaXMgZW1iZWRkZWQgcGFnZVxuICogaGFzIGl0cyBvd24gRE9NIGFuZCBnbG9iYWwgSlMgY29udGV4dCAod2hpY2ggbWF5IG9yIG1heSBub3QgYmUgbGlua2VkIHRvIHRoYXQgb2YgdGhlIHBhcmVudCBkZXBlbmRpbmdcbiAqIG9uIGlmIGl0IGlzIGNvbnNpZGVyZWQgb3V0IG9mIHRoZSByb290IGRvbWFpbiBvciBub3QpLCBpdCByZXByZXNlbnRzIGEgdW5pcXVlIGVuZHBvaW50IGFzIGFuIE9wZW5GaW5cbiAqIGNvbm5lY3Rpb24uIElmcmFtZXMgbWF5IGJlIGdlbmVyYXRlZCBkeW5hbWljYWxseSwgb3IgYmUgcHJlc2VudCBvbiBpbml0aWFsIHBhZ2UgbG9hZCBhbmQgZWFjaCBub24tQ09SU1xuICogaWZyYW1lIGhhcyB0aGUgT3BlbkZpbiBBUEkgaW5qZWN0ZWQgYnkgZGVmYXVsdC4gSXQgaXMgcG9zc2libGUgdG8gb3B0IGludG8gY3Jvc3Mtb3JpZ2luIGlmcmFtZXMgaGF2aW5nXG4gKiB0aGUgQVBJIGJ5IHNldHRpbmcgYXBpLmlmcmFtZS5jcm9zc09yaWdpbkluamVjdGlvbiB0byB0cnVlIGluIGEgd2luZG93J3Mgb3B0aW9ucy4gVG8gYmxvY2sgYWxsIGlmcmFtZXNcbiAqIGZyb20gZ2V0dGluZyB0aGUgQVBJIGluamVjdGVkIHlvdSBjYW4gc2V0IGFwaS5mcmFtZS5zYW1lT3JpZ2luSW5qZWN0aW9uXG4gKiB0byBmYWxzZSA8YSBocmVmPVwiV2luZG93Lmh0bWwjfm9wdGlvbnNcIiB0YXJnZXQ9XCJfYmxhbmtcIj4oe0BsaW5rIE9wZW5GaW4uV2luZG93Q3JlYXRpb25PcHRpb25zIHNlZSBXaW5kb3cgT3B0aW9uc30pPC9hPi5cbiAqXG4gKiBUbyBiZSBhYmxlIHRvIGRpcmVjdGx5IGFkZHJlc3MgdGhpcyBjb250ZXh0IGZvciBldmVudGluZyBhbmQgbWVzc2FnaW5nIHB1cnBvc2VzLCBpdCBuZWVkcyBhXG4gKiB1bmlxdWUgdXVpZCBuYW1lIHBhaXJpbmcuIEZvciBPcGVuRmluIGFwcGxpY2F0aW9ucyBhbmQgd2luZG93cyB0aGlzIGlzIHByb3ZpZGVkIHZpYSBhIGNvbmZpZ3VyYXRpb25cbiAqIG9iamVjdCBpbiB0aGUgZm9ybSBvZiBhIG1hbmlmZXN0IFVSTCBvciBvcHRpb25zIG9iamVjdCwgYnV0IHRoZXJlIGlzIG5vIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciBpZnJhbWVzLlxuICogSnVzdCBhcyBhIGNhbGwgdG8gd2luZG93Lm9wZW4gb3V0c2lkZSBvZiBvdXIgV2luZG93IEFQSSByZXR1cm5zIGEgbmV3IHdpbmRvdyB3aXRoIGEgcmFuZG9tIEdVSUQgYXNzaWduZWRcbiAqIGZvciB0aGUgbmFtZSwgZWFjaCBpZnJhbWUgdGhhdCBoYXMgdGhlIEFQSSBpbmplY3RlZCB3aWxsIGJlIGFzc2lnbmVkIGEgR1VJRCBhcyBpdHMgbmFtZSwgdGhlIFVVSUQgd2lsbCBiZVxuICogdGhlIHNhbWUgYXMgdGhlIHBhcmVudCB3aW5kb3cncy5cbiAqXG4gKiBUaGUgZmluLkZyYW1lIG5hbWVzcGFjZSByZXByZXNlbnRzIGEgd2F5IHRvIGludGVyYWN0IHdpdGggYGlmcmFtZXNgIGFuZCBmYWNpbGl0YXRlcyB0aGUgZGlzY292ZXJ5IG9mIGN1cnJlbnQgY29udGV4dFxuICogKGlmcmFtZSBvciBtYWluIHdpbmRvdykgYXMgd2VsbCBhcyB0aGUgYWJpbGl0eSB0byBsaXN0ZW4gZm9yIHtAbGluayBPcGVuRmluLkZyYW1lRXZlbnRzIGZyYW1lLXNwZWNpZmljIGV2ZW50c30uXG4gKi9cbmNsYXNzIF9GcmFtZSBleHRlbmRzIGJhc2VfMSQ5LkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlLCBpZGVudGl0eSkge1xuICAgICAgICBzdXBlcih3aXJlLCAnZnJhbWUnLCBpZGVudGl0eS51dWlkLCBpZGVudGl0eS5uYW1lKTtcbiAgICAgICAgdGhpcy5pZGVudGl0eSA9IGlkZW50aXR5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgZnJhbWUgaW5mbyBvYmplY3QgZm9yIHRoZSByZXByZXNlbnRlZCBmcmFtZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRJbmZvKCkge1xuICAgICAqICAgICBjb25zdCBmcm0gPSBhd2FpdCBmaW4uRnJhbWUuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZnJtLmdldEluZm8oKTtcbiAgICAgKiB9XG4gICAgICogZ2V0SW5mbygpLnRoZW4oaW5mbyA9PiBjb25zb2xlLmxvZyhpbmZvKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEluZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWZyYW1lLWluZm8nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGZyYW1lIGluZm8gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgd2luZG93IHRoYXQgdGhlIHJlZmVyZW5jZWQgaWZyYW1lIGlzXG4gICAgICogY3VycmVudGx5IGVtYmVkZGVkIGluLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgdGhlIGZyYW1lIGlzIGVtYmVkZGVkIGluIGEgdmlldywgdGhpcyB3aWxsIHJldHVybiBhbiBpbnZhbGlkIHN0dWIgd2l0aCBlbXB0eSBmaWVsZHMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50V2luZG93KCkge1xuICAgICAqICAgICBjb25zdCBmcm0gPSBhd2FpdCBmaW4uRnJhbWUuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZnJtLmdldFBhcmVudFdpbmRvdygpO1xuICAgICAqIH1cbiAgICAgKiBnZXRQYXJlbnRXaW5kb3coKS50aGVuKHdpbkluZm8gPT4gY29uc29sZS5sb2cod2luSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRQYXJlbnRXaW5kb3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXBhcmVudC13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG59XG5JbnN0YW5jZSQzLl9GcmFtZSA9IF9GcmFtZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkNCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDQuX0ZyYW1lTW9kdWxlID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJDggPSBiYXNlO1xuY29uc3QgdmFsaWRhdGVfMSQyID0gdmFsaWRhdGU7XG5jb25zdCBJbnN0YW5jZV8xJDMgPSBJbnN0YW5jZSQzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIF9GcmFtZX0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkZyYW1lYC5cbiAqL1xuY2xhc3MgX0ZyYW1lTW9kdWxlIGV4dGVuZHMgYmFzZV8xJDguQmFzZSB7XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBBUEkgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gRnJhbWUgaWRlbnRpdHkuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXcmFwcGluZyBhIEZyYW1lIGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG4gICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuICAgICAqIGZvciBhIEZyYW1lIHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkZyYW1lLndyYXAoeyB1dWlkOiAndGVzdEZyYW1lJywgbmFtZTogJ3Rlc3RGcmFtZScgfSlcbiAgICAgKiAudGhlbihmcm0gPT4gY29uc29sZS5sb2coJ3dyYXBwZWQgZnJhbWUnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHdyYXAoaWRlbnRpdHkpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZyYW1lLXdyYXAnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xJDIudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuICAgICAgICBpZiAoZXJyb3JNc2cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDMuX0ZyYW1lKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIEZyYW1lIGlkZW50aXR5LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBGcmFtZSBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuICAgICAqIHJldHVybnMgYSBzdHViIG9iamVjdCB0aGF0IGNhbm5vdCB5ZXQgcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGx1bWJpbmcgZXZlbnRpbmdcbiAgICAgKiBmb3IgYSBGcmFtZSB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGZybSA9IGZpbi5GcmFtZS53cmFwU3luYyh7IHV1aWQ6ICd0ZXN0RnJhbWUnLCBuYW1lOiAndGVzdEZyYW1lJyB9KTtcbiAgICAgKiBjb25zdCBpbmZvID0gYXdhaXQgZnJtLmdldEluZm8oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhpbmZvKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZnJhbWUtd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMSQyLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMSQzLl9GcmFtZSh0aGlzLndpcmUsIGlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBmcmFtZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5GcmFtZS5nZXRDdXJyZW50KClcbiAgICAgKiAudGhlbihmcm0gPT4gY29uc29sZS5sb2coJ2N1cnJlbnQgZnJhbWUnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmcmFtZS1nZXQtY3VycmVudCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEluc3RhbmNlXzEkMy5fRnJhbWUodGhpcy53aXJlLCB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0Q3VycmVudEVudGl0eUlkZW50aXR5KCkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IGZyYW1lXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZnJtID0gZmluLkZyYW1lLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgaW5mbyA9IGF3YWl0IGZybS5nZXRJbmZvKCk7XG4gICAgICogY29uc29sZS5sb2coaW5mbyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q3VycmVudFN5bmMoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmcmFtZS1nZXQtY3VycmVudC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDMuX0ZyYW1lKHRoaXMud2lyZSwgdGhpcy53aXJlLmVudmlyb25tZW50LmdldEN1cnJlbnRFbnRpdHlJZGVudGl0eSgpKTtcbiAgICB9XG59XG5GYWN0b3J5JDQuX0ZyYW1lTW9kdWxlID0gX0ZyYW1lTW9kdWxlO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0LyoqXG5cdCAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIE9wZW5GaW4gYEZyYW1lYCBBUEkgKGBmaW4uRnJhbWVgKS5cblx0ICpcblx0ICogKiB7QGxpbmsgX0ZyYW1lTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEZyYW1lYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLkZyYW1lYC5cblx0ICogKiB7QGxpbmsgX0ZyYW1lfSBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gT3BlbkZpbiBGcmFtZSwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLkZyYW1lLmdldEN1cnJlbnRgLlxuXHQgKlxuXHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogVW5kZXJzY29yZSBwcmVmaXhpbmcgb2YgT3BlbkZpbiB0eXBlcyB0aGF0IGFsaWFzIERPTSBlbnRpdGllcyB3aWxsIGJlIGZpeGVkIGluIGEgZnV0dXJlIHZlcnNpb24uXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnkkNCwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihJbnN0YW5jZSQzLCBleHBvcnRzKTsgXG59IChmcmFtZSkpO1xuXG52YXIgZ2xvYmFsSG90a2V5ID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxIb3RrZXksIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZ2xvYmFsSG90a2V5Lkdsb2JhbEhvdGtleSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSQ3ID0gYmFzZTtcbi8qKlxuICogVGhlIEdsb2JhbEhvdGtleSBtb2R1bGUgY2FuIHJlZ2lzdGVyL3VucmVnaXN0ZXIgYSBnbG9iYWwgaG90a2V5cy5cbiAqXG4gKi9cbmNsYXNzIEdsb2JhbEhvdGtleSBleHRlbmRzIGJhc2VfMSQ3LkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlKSB7XG4gICAgICAgIHN1cGVyKHdpcmUsICdnbG9iYWwtaG90a2V5Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVycyBhIGdsb2JhbCBob3RrZXkgd2l0aCB0aGUgb3BlcmF0aW5nIHN5c3RlbS5cbiAgICAgKiBAcGFyYW0gaG90a2V5IGEgaG90a2V5IHN0cmluZ1xuICAgICAqIEBwYXJhbSBsaXN0ZW5lciBjYWxsZWQgd2hlbiB0aGUgcmVnaXN0ZXJlZCBob3RrZXkgaXMgcHJlc3NlZCBieSB0aGUgdXNlci5cbiAgICAgKiBAdGhyb3dzIElmIHRoZSBgaG90a2V5YCBpcyByZXNlcnZlZCwgc2VlIGxpc3QgYmVsb3cuXG4gICAgICogQHRocm93cyBpZiB0aGUgYGhvdGtleWAgaXMgYWxyZWFkeSByZWdpc3RlcmVkIGJ5IGFub3RoZXIgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgYGhvdGtleWAgcGFyYW1ldGVyIGV4cGVjdHMgYW4gZWxlY3Ryb24gY29tcGF0aWJsZSBbYWNjZWxlcmF0b3JdKGh0dHBzOi8vZ2l0aHViLmNvbS9lbGVjdHJvbi9lbGVjdHJvbi9ibG9iL21hc3Rlci9kb2NzL2FwaS9hY2NlbGVyYXRvci5tZCkgYW5kIHRoZSBgbGlzdGVuZXJgIHdpbGwgYmUgY2FsbGVkIGlmIHRoZSBgaG90a2V5YCBpcyBwcmVzc2VkIGJ5IHRoZSB1c2VyLlxuICAgICAqIElmIHN1Y2Nlc3NmdWxsLCB0aGUgaG90a2V5IHdpbGwgYmUgJ2NsYWltZWQnIGJ5IHRoZSBhcHBsaWNhdGlvbiwgbWVhbmluZyB0aGF0IHRoaXMgcmVnaXN0ZXIgY2FsbCBjYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGZyb20gd2l0aGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGJ1dCB3aWxsIGZhaWwgaWYgYW5vdGhlciBhcHBsaWNhdGlvbiBoYXMgcmVnaXN0ZXJlZCB0aGUgaG90a2V5LlxuICAgICAqIDxicj5UaGUgcmVnaXN0ZXIgY2FsbCB3aWxsIGZhaWwgaWYgZ2l2ZW4gYW55IG9mIHRoZXNlIHJlc2VydmVkIEhvdGtleXM6XG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCswYFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrPWBcbiAgICAgKiAqIGBDb21tYW5kT3JDb250cm9sK1BsdXNgXG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCstYFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrX2BcbiAgICAgKiAqIGBDb21tYW5kT3JDb250cm9sK1NoaWZ0K0lgXG4gICAgICogKiBgRjVgXG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCtSYFxuICAgICAqICogYFNoaWZ0K0Y1YFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrU2hpZnQrUmBcbiAgICAgKlxuICAgICAqIFJhaXNlcyB0aGUgYHJlZ2lzdGVyZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGhvdGtleSA9ICdDb21tYW5kT3JDb250cm9sK1gnO1xuICAgICAqXG4gICAgICogZmluLkdsb2JhbEhvdGtleS5yZWdpc3Rlcihob3RrZXksICgpID0+IHtcbiAgICAgKiBjb25zb2xlLmxvZyhgJHtob3RrZXl9IHByZXNzZWRgKTtcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ1N1Y2Nlc3MnKTtcbiAgICAgKiB9KVxuICAgICAqIC5jYXRjaChlcnIgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnRXJyb3IgcmVnaXN0ZXJpbmcgdGhlIGhvdGtleScsIGVycik7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXIoaG90a2V5LCBsaXN0ZW5lcikge1xuICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChob3RrZXkgZXZlbnRzIGFyZSBub3QgdHlwZWQpXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgYXdhaXQgdGhpcy5vbihob3RrZXksIGxpc3RlbmVyKTtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dsb2JhbC1ob3RrZXktcmVnaXN0ZXInLCB7IGhvdGtleSB9KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5yZWdpc3RlcnMgYSBnbG9iYWwgaG90a2V5IHdpdGggdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICogQHBhcmFtIGhvdGtleSBhIGhvdGtleSBzdHJpbmdcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIHdpbGwgdW5yZWdpc3RlciBhbGwgZXhpc3RpbmcgcmVnaXN0cmF0aW9ucyBvZiB0aGUgaG90a2V5IHdpdGhpbiB0aGUgYXBwbGljYXRpb24uXG4gICAgICogUmFpc2VzIHRoZSBgdW5yZWdpc3RlcmVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBob3RrZXkgPSAnQ29tbWFuZE9yQ29udHJvbCtYJztcbiAgICAgKlxuICAgICAqIGZpbi5HbG9iYWxIb3RrZXkudW5yZWdpc3Rlcihob3RrZXkpXG4gICAgICogLnRoZW4oKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnU3VjY2VzcycpO1xuICAgICAqIH0pXG4gICAgICogLmNhdGNoKGVyciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnJlZ2lzdGVyaW5nIHRoZSBob3RrZXknLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXIoaG90a2V5KSB7XG4gICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGhvdGtleSBldmVudHMgYXJlIG5vdCB0eXBlZClcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhob3RrZXkpO1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2xvYmFsLWhvdGtleS11bnJlZ2lzdGVyJywgeyBob3RrZXkgfSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVucmVnaXN0ZXJzIGFsbCBnbG9iYWwgaG90a2V5cyBmb3IgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBSYWlzZXMgdGhlIGB1bnJlZ2lzdGVyZWRgIGV2ZW50IGZvciBlYWNoIGhvdGtleSB1bnJlZ2lzdGVyZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkdsb2JhbEhvdGtleS51bnJlZ2lzdGVyQWxsKClcbiAgICAgKiAudGhlbigoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdTdWNjZXNzJyk7XG4gICAgICogfSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0Vycm9yIHVucmVnaXN0ZXJpbmcgYWxsIGhvdGtleXMgZm9yIHRoaXMgYXBwbGljYXRpb24nLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXJBbGwoKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMuZXZlbnROYW1lcygpXG4gICAgICAgICAgICAuZmlsdGVyKChuYW1lKSA9PiAhKG5hbWUgPT09ICdyZWdpc3RlcmVkJyB8fCBuYW1lID09PSAndW5yZWdpc3RlcmVkJykpXG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChob3RrZXkgZXZlbnRzIGFyZSBub3QgdHlwZWQpXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAubWFwKChuYW1lKSA9PiB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhuYW1lKSkpO1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2xvYmFsLWhvdGtleS11bnJlZ2lzdGVyLWFsbCcsIHt9KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgZ2l2ZW4gaG90a2V5IGhhcyBiZWVuIHJlZ2lzdGVyZWQgYnkgYW4gYXBwbGljYXRpb24gd2l0aGluIHRoZSBjdXJyZW50IHJ1bnRpbWUuXG4gICAgICogQHBhcmFtIGhvdGtleSBhIGhvdGtleSBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBob3RrZXkgPSAnQ29tbWFuZE9yQ29udHJvbCtYJztcbiAgICAgKlxuICAgICAqIGZpbi5HbG9iYWxIb3RrZXkuaXNSZWdpc3RlcmVkKGhvdGtleSlcbiAgICAgKiAudGhlbigocmVnaXN0ZXJlZCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgaG90a2V5ICR7aG90a2V5fSBpcyByZWdpc3RlcmVkID8gJHtyZWdpc3RlcmVkfWApO1xuICAgICAqIH0pXG4gICAgICogLmNhdGNoKGVyciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnJlZ2lzdGVyaW5nIHRoZSBob3RrZXknLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGlzUmVnaXN0ZXJlZChob3RrZXkpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGEgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dsb2JhbC1ob3RrZXktaXMtcmVnaXN0ZXJlZCcsIHsgaG90a2V5IH0pO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG59XG5nbG9iYWxIb3RrZXkuR2xvYmFsSG90a2V5ID0gR2xvYmFsSG90a2V5O1xuXG52YXIgcGxhdGZvcm0gPSB7fTtcblxudmFyIEZhY3RvcnkkMyA9IHt9O1xuXG52YXIgSW5zdGFuY2UkMiA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ1ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX1BsYXRmb3JtX2Nvbm5lY3RUb1Byb3ZpZGVyO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuSW5zdGFuY2UkMi5QbGF0Zm9ybSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9wcmVmZXItZGVmYXVsdC1leHBvcnQsIG5vLXVuZGVmICovXG5jb25zdCBiYXNlXzEkNiA9IGJhc2U7XG5jb25zdCB2YWxpZGF0ZV8xJDEgPSB2YWxpZGF0ZTtcbi8vIFJldXNlIGNsaWVudHMgdG8gYXZvaWQgb3ZlcndyaXRpbmcgYWxyZWFkeS1yZWdpc3RlcmVkIGNsaWVudCBpbiBwcm92aWRlclxuY29uc3QgY2xpZW50TWFwID0gbmV3IE1hcCgpO1xuLyoqIE1hbmFnZXMgdGhlIGxpZmUgY3ljbGUgb2Ygd2luZG93cyBhbmQgdmlld3MgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICpcbiAqIEVuYWJsZXMgdGFraW5nIHNuYXBzaG90cyBvZiBpdHNlbGYgYW5kIGFwcGx5aW5nIHRoZW0gdG8gcmVzdG9yZSBhIHByZXZpb3VzIGNvbmZpZ3VyYXRpb25cbiAqIGFzIHdlbGwgYXMgbGlzdGVuIHRvIHtAbGluayBPcGVuRmluLlBsYXRmb3JtRXZlbnRzIHBsYXRmb3JtIGV2ZW50c30uXG4gKi9cbmNsYXNzIFBsYXRmb3JtIGV4dGVuZHMgYmFzZV8xJDYuRW1pdHRlckJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdHJ1Y3RvcihpZGVudGl0eSwgY2hhbm5lbCkge1xuICAgICAgICAvLyB3ZSBwaWdneWJhY2sgb2ZmIG9mIGFwcGxpY2F0aW9uIGV2ZW50IGVtaXR0ZXIgYmVjYXVzZSBmcm9tIHRoZSBjb3JlJ3MgcGVyc3BlY3RpdmUgcGxhdGZvcm0gaXMganVzdCBhbiBhcHAuXG4gICAgICAgIHN1cGVyKGNoYW5uZWwud2lyZSwgJ2FwcGxpY2F0aW9uJywgaWRlbnRpdHkudXVpZCk7XG4gICAgICAgIHRoaXMuZ2V0Q2xpZW50ID0gKGlkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tZ2V0LWNsaWVudCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGlkZW50aXR5IHx8IHRoaXMuaWRlbnRpdHk7XG4gICAgICAgICAgICBjb25zdCB7IHV1aWQgfSA9IHRhcmdldDtcbiAgICAgICAgICAgIGlmICghY2xpZW50TWFwLmhhcyh1dWlkKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFByb21pc2UgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDUodGhpcywgX1BsYXRmb3JtX2Nvbm5lY3RUb1Byb3ZpZGVyLCBcImZcIikuY2FsbCh0aGlzLCB1dWlkKTtcbiAgICAgICAgICAgICAgICBjbGllbnRNYXAuc2V0KHV1aWQsIGNsaWVudFByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gd2Ugc2V0IGl0IGFib3ZlXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgcmV0dXJuIGNsaWVudE1hcC5nZXQodXVpZCk7XG4gICAgICAgIH07XG4gICAgICAgIF9QbGF0Zm9ybV9jb25uZWN0VG9Qcm92aWRlci5zZXQodGhpcywgYXN5bmMgKHV1aWQpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSBgY3VzdG9tLWZyYW1lLSR7dXVpZH1gO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuX2NoYW5uZWwuY29ubmVjdChjaGFubmVsTmFtZSwgeyB3YWl0OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICBjbGllbnQub25EaXNjb25uZWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50TWFwLmRlbGV0ZSh1dWlkKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjbGllbnRNYXAuZGVsZXRlKHV1aWQpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHRhcmdldGVkIFBsYXRmb3JtIGlzIG5vdCBjdXJyZW50bHkgcnVubmluZy4gTGlzdGVuIGZvciBhcHBsaWNhdGlvbi1zdGFydGVkIGV2ZW50IGZvciB0aGUgZ2l2ZW4gVXVpZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVwcmVjYXRlZCAocmVuYW1lZClcbiAgICAgICAgICogQGlnbm9yZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYXVuY2hMZWdhY3lNYW5pZmVzdCA9IHRoaXMubGF1bmNoQ29udGVudE1hbmlmZXN0O1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xJDEudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuICAgICAgICBpZiAoZXJyb3JNc2cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2hhbm5lbCA9IGNoYW5uZWw7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSB7IHV1aWQ6IGlkZW50aXR5LnV1aWQgfTtcbiAgICAgICAgdGhpcy5MYXlvdXQgPSB0aGlzLmZpbi5QbGF0Zm9ybS5MYXlvdXQ7XG4gICAgICAgIHRoaXMuQXBwbGljYXRpb24gPSB0aGlzLmZpbi5BcHBsaWNhdGlvbi53cmFwU3luYyh0aGlzLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyB2aWV3IGFuZCBhdHRhY2hlcyBpdCB0byBhIHNwZWNpZmllZCB0YXJnZXQgd2luZG93LlxuICAgICAqIEBwYXJhbSB2aWV3T3B0aW9ucyBWaWV3IGNyZWF0aW9uIG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB3aW5kb3cgdG8gd2hpY2ggdGhlIG5ldyB2aWV3IGlzIHRvIGJlIGF0dGFjaGVkLiBJZiBubyB0YXJnZXQsIGNyZWF0ZSBhIHZpZXcgaW4gYSBuZXcgd2luZG93LlxuICAgICAqIEBwYXJhbSB0YXJnZXRWaWV3IElmIHByb3ZpZGVkLCB0aGUgbmV3IHZpZXcgd2lsbCBiZSBhZGRlZCB0byB0aGUgc2FtZSB0YWJzdHJpcCBhcyB0YXJnZXRWaWV3LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgdGhlIHZpZXcgYWxyZWFkeSBleGlzdHMsIHdpbGwgcmVwYXJlbnQgdGhlIHZpZXcgdG8gdGhlIG5ldyB0YXJnZXQuIFlvdSBkbyBub3QgbmVlZCB0byBzZXQgYSBuYW1lIGZvciBhIFZpZXcuXG4gICAgICogVmlld3MgdGhhdCBhcmUgbm90IHBhc3NlZCBhIG5hbWUgZ2V0IGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG9uZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBsZXQgd2luZG93SWRlbnRpdHk7XG4gICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKlxuICAgICAqIHBsYXRmb3JtLmNyZWF0ZVZpZXcoe1xuICAgICAqICAgICBuYW1lOiAndGVzdF92aWV3JyxcbiAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9wbGF0Zm9ybS1hcGknXG4gICAgICogfSwgd2luZG93SWRlbnRpdHkpLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUmVwYXJlbnRpbmcgYSB2aWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogbGV0IHdpbmRvd0lkZW50aXR5O1xuICAgICAqIGlmIChmaW4ubWUuaXNXaW5kb3cpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSBmaW4ubWUuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICogICAgIHdpbmRvd0lkZW50aXR5ID0gKGF3YWl0IGZpbi5tZS5nZXRDdXJyZW50V2luZG93KCkpLmlkZW50aXR5O1xuICAgICAqIH0gZWxzZSB7XG4gICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGxldCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGxldCB2aWV3T3B0aW9ucyA9IHtcbiAgICAgKiAgICAgbmFtZTogJ2V4YW1wbGVfdmlldycsXG4gICAgICogICAgIHVybDogJ2h0dHBzOi8vZXhhbXBsZS5jb20nXG4gICAgICogfTtcbiAgICAgKiAvLyBhIG5ldyB2aWV3IHdpbGwgbm93IHNob3cgaW4gdGhlIGN1cnJlbnQgd2luZG93XG4gICAgICogYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgd2luZG93SWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogd2luZG93SWRlbnRpdHkudXVpZCwgbmFtZTogJ3lhaG9vX3ZpZXcnIH0pO1xuICAgICAqIC8vIHJlcGFyZW50IGBleGFtcGxlX3ZpZXdgIHdoZW4gYSB2aWV3IGluIHRoZSBuZXcgd2luZG93IGlzIHNob3duXG4gICAgICogdmlldy5vbignc2hvd24nLCBhc3luYyAoKSA9PiB7XG4gICAgICogICAgIGxldCB2aWV3SWRlbnRpdHkgPSB7IHV1aWQ6IHdpbmRvd0lkZW50aXR5LnV1aWQsIG5hbWU6ICdleGFtcGxlX3ZpZXcnfTtcbiAgICAgKiAgICAgbGV0IHRhcmdldCA9IHt1dWlkOiB3aW5kb3dJZGVudGl0eS51dWlkLCBuYW1lOiAndGVzdF93aW4nfTtcbiAgICAgKiAgICAgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgdGFyZ2V0KTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIGNyZWF0ZSBhIG5ldyB3aW5kb3dcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5jcmVhdGVXaW5kb3coe1xuICAgICAqICAgICBuYW1lOiBcInRlc3Rfd2luXCIsXG4gICAgICogICAgIGxheW91dDoge1xuICAgICAqICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgKiAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAneWFob29fdmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8veWFob28uY29tJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIF1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVZpZXcodmlld09wdGlvbnMsIHRhcmdldCwgdGFyZ2V0Vmlldykge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tY3JlYXRlLXZpZXcnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnY3JlYXRlLXZpZXcnLCB7XG4gICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICBvcHRzOiB2aWV3T3B0aW9ucyxcbiAgICAgICAgICAgIHRhcmdldFZpZXdcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghcmVzcG9uc2UgfHwgKDAsIHZhbGlkYXRlXzEkMS52YWxpZGF0ZUlkZW50aXR5KShyZXNwb25zZS5pZGVudGl0eSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgV2hlbiBvdmVyd3JpdGluZyB0aGUgY3JlYXRlVmlldyBjYWxsLCBwbGVhc2UgcmV0dXJuIGFuIG9iamVjdCB0aGF0IGhhcyBhIHZhbGlkICdpZGVudGl0eScgcHJvcGVydHk6ICR7SlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmZpbi5WaWV3LndyYXBTeW5jKHJlc3BvbnNlLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBXaW5kb3cuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgV2luZG93IGNyZWF0aW9uIG9wdGlvbnNcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoZXJlIGFyZSB0d28gV2luZG93IHR5cGVzIGF0IHlvdXIgZGlzcG9zYWwgd2hpbGUgdXNpbmcgT3BlbkZpbiBQbGF0Zm9ybXMgLSBEZWZhdWx0IFdpbmRvdyBhbmQgQ3VzdG9tIFdpbmRvdy5cbiAgICAgKlxuICAgICAqIFRoZSBEZWZhdWx0IFdpbmRvdyB1c2VzIHRoZSBzdGFuZGFyZCBPcGVuRmluIFdpbmRvdyBVSS4gSXQgY29udGFpbnMgdGhlIHN0YW5kYXJkIGNsb3NlLCBtYXhpbWl6ZSBhbmQgbWluaW1pemUgYnV0dG9ucyxcbiAgICAgKiBhbmQgd2lsbCBhdXRvbWF0aWNhbGx5IHJlbmRlciB0aGUgV2luZG93J3MgbGF5b3V0IGlmIG9uZSBpcyBzcGVjaWZpZWQuXG4gICAgICpcbiAgICAgKiBGb3IgZGVlcGVyIGN1c3RvbWl6YXRpb24sIHlvdSBjYW4gYnJpbmcgeW91ciBvd24gV2luZG93IGNvZGUgaW50byBhIFBsYXRmb3JtLiBUaGlzIGlzIGNhbGxlZCBhIEN1c3RvbSBXaW5kb3cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICpcbiAgICAgKiBUaGUgZXhhbXBsZSBiZWxvdyB3aWxsIGNyZWF0ZSBhIERlZmF1bHQgV2luZG93IHdoaWNoIHVzZXMgT3BlbkZpbiBkZWZhdWx0IFdpbmRvdyBVSS48YnI+XG4gICAgICogVGhlIFdpbmRvdyBjb250YWlucyB0d28gVmlld3MgaW4gYSBzdGFjayBMYXlvdXQ6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogcGxhdGZvcm0uY3JlYXRlV2luZG93KHtcbiAgICAgKiAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICBjb250ZW50OiBbXG4gICAgICogICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ3ZpZXcnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ3ZpZXcnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMicsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIF1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqIFRoZSBEZWZhdWx0IFdpbmRvdydzIGRlc2lnbiBjYW4gYmUgY3VzdG9taXplZCBieSBzcGVjaWZ5aW5nIHRoZSBgc3R5bGVzaGVldFVybGAgcHJvcGVydHkgaW4gdGhlIG1hbmlmZXN0OlxuICAgICAqXG4gICAgICogYGBganNvblxuICAgICAqIHtcbiAgICAgKiAgICAgcGxhdGZvcm06IHtcbiAgICAgKiAgICAgICAgIGRlZmF1bHRXaW5kb3dPcHRpb25zOiB7XG4gICAgICogICAgICAgICAgICAgc3R5bGVzaGVldFVybDogJ3NvbWUtdXJsLmNzcycsXG4gICAgICogICAgICAgICAgICAgLi4uXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogRm9yIGEgbGlzdCBvZiBjb21tb24gTGF5b3V0IENTUyBjbGFzc2VzIHlvdSBjYW4gb3ZlcnJpZGUgaW4geW91ciBjdXN0b20gc3R5bGVzaGVldCwgc2VlIDxhIGhyZWY9XCJ0dXRvcmlhbC1sYXlvdXRTdHlsZXMuaHRtbFwiPlVzZWZ1bCBMYXlvdXQgQ1NTIENsYXNzZXM8L2E+XG4gICAgICoqXG4gICAgICogVG8gc3BlY2lmeSBhIFBsYXRmb3JtIEN1c3RvbSBXaW5kb3csIHByb3ZpZGUgYSBgdXJsYCBwcm9wZXJ0eSB3aGVuIGNyZWF0aW5nIGEgV2luZG93LlxuICAgICAqIElmIHlvdSBpbnRlbmQgdG8gcmVuZGVyIGEgTGF5b3V0IGluIHlvdXIgQ3VzdG9tIFdpbmRvdywgeW91IG11c3QgYWxzbyBzcGVjaWZ5IGFuIGBIVE1MRWxlbWVudGAgdGhhdCB0aGUgTGF5b3V0IHdpbGwgaW5qZWN0IGludG8gYW5kIHNldCBpdHMgYGlkYCBwcm9wZXJ0eSB0byBgXCJsYXlvdXQtY29udGFpbmVyXCJgLlxuICAgICAqXG4gICAgICogVGhlIGV4YW1wbGUgYmVsb3cgd2lsbCBjcmVhdGUgYSBQbGF0Zm9ybSBDdXN0b20gV2luZG93OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAgICAgLy8gaW4gYW4gT3BlbkZpbiBhcHA6XG4gICAgICogICAgIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogICAgIGNvbnN0IHdpbmRvd0NvbmZpZyA9XG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vd3d3Lm15LWRvbWFpbi5jb20vbXktY3VzdG9tLXdpbmRvdy5odG1sXCIsIC8vIGhlcmUgd2UgcG9pbnQgdG8gd2hlcmUgdGhlIEN1c3RvbSBGcmFtZSBpcyBob3N0ZWQuXG4gICAgICogICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0YWNrXCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImNvbXBvbmVudFwiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogXCJ2aWV3XCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiYXBwICMxXCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJjb21wb25lbnRcIixcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6IFwidmlld1wiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U3RhdGU6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImFwcCAjMlwiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogXCJodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9jYW5hcnkvUGxhdGZvcm0uaHRtbFwiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICBwbGF0Zm9ybS5jcmVhdGVXaW5kb3cod2luZG93Q29uZmlnKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEhlcmUncyBhbiBleGFtcGxlIG9mIGEgbWluaW1hbGlzdCBDdXN0b20gUGxhdGZvcm0gV2luZG93IGltcGxlbWVudGF0aW9uOlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aHRtbD5cbiAgICAgKiAgICAgPGhlYWQ+XG4gICAgICogICAgICAgICA8bWV0YSBjaGFyc2V0PVwidXRmLThcIj5cbiAgICAgKiAgICAgICAgIDxtZXRhIG5hbWU9XCJ2aWV3cG9ydFwiIGNvbnRlbnQ9XCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MVwiPlxuICAgICAqICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIHR5cGU9XCJ0ZXh0L2Nzc1wiIGhyZWY9XCIuL3N0eWxlcy5jc3NcIj5cbiAgICAgKiAgICAgPC9oZWFkPlxuICAgICAqICAgICA8Ym9keT5cbiAgICAgKiAgICAgICAgIDxkaXYgaWQ9XCJvZi1mcmFtZS1tYWluXCI+XG4gICAgICogICAgICAgICAgICAgPGRpdiBpZD1cInRpdGxlLWJhclwiPlxuICAgICAqICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGUtYmFyLWRyYWdnYWJsZVwiPlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInRpdGxlXCI+IFRoaXMgaXMgYSBjdXN0b20gZnJhbWUhIDwvZGl2PlxuICAgICAqICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgKiAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImJ1dHRvbnMtd3JhcHBlclwiPlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvblwiIGlkPVwibWluaW1pemUtYnV0dG9uXCI+PC9kaXY+XG4gICAgICogICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uXCIgaWQ9XCJleHBhbmQtYnV0dG9uXCI+PC9kaXY+XG4gICAgICogICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uXCIgaWQ9XCJjbG9zZS1idXR0b25cIj48L2Rpdj5cbiAgICAgKiAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICAgICAgICAgPGRpdiBpZD1cImxheW91dC1jb250YWluZXJcIj48L2Rpdj4gPCEtLSBPcGVuRmluIGxheW91dCB3b3VsZCBiZSBpbmplY3RlZCBoZXJlIC0tPlxuICAgICAqICAgICAgICAgICAgIDxzY3JpcHQgc3JjPVwiLi9jdXN0b20tZnJhbWUuanNcIj48L3NjcmlwdD5cbiAgICAgKiAgICAgICAgIDwvZGl2PlxuICAgICAqICAgICA8L2JvZHk+XG4gICAgICogPC9odG1sPlxuICAgICAqIGBgYFxuICAgICAqIFlvdXIgQ3VzdG9tIFdpbmRvdyBjYW4gdXNlIGluLWRvbWFpbiByZXNvdXJjZXMgZm9yIGZ1cnRoZXIgY3VzdG9taXphdGlvbiAoc3VjaCBhcyBDU1MsIHNjcmlwdHMsIGV0Yy4pLjxicj5cbiAgICAgKiBGb3IgYSBsaXN0IG9mIGNvbW1vbiBMYXlvdXQgQ1NTIGNsYXNzZXMgeW91IGNhbiBvdmVycmlkZSBpbiB5b3VyIHN0eWxlc2hlZXQsIHNlZSA8YSBocmVmPVwidHV0b3JpYWwtbGF5b3V0U3R5bGVzLmh0bWxcIj5Vc2VmdWwgTGF5b3V0IENTUyBDbGFzc2VzPC9hPlxuICAgICAqXG4gICAgICogVGhlIGV4YW1wbGUgYWJvdmUgd2lsbCByZXF1aXJlIHRoZSBgYm9keWAgZWxlbWVudCB0byBoYXZlIGBoZWlnaHQ6IDEwMCU7YCBzZXQgaW4gb3JkZXIgdG8gcmVuZGVyIHRoZSBsYXlvdXQgY29ycmVjdGx5LlxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVdpbmRvdyhvcHRpb25zKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1jcmVhdGUtd2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgaWYgKCFvcHRpb25zLnJlYXNvbikge1xuICAgICAgICAgICAgb3B0aW9ucy5yZWFzb24gPSAnYXBpLWNhbGwnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdjcmVhdGUtdmlldy1jb250YWluZXInLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSB8fCAoMCwgdmFsaWRhdGVfMSQxLnZhbGlkYXRlSWRlbnRpdHkpKHJlc3BvbnNlLmlkZW50aXR5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXaGVuIG92ZXJ3cml0aW5nIHRoZSBjcmVhdGVXaW5kb3cgY2FsbCwgcGxlYXNlIHJldHVybiBhbiBvYmplY3QgdGhhdCBoYXMgYSB2YWxpZCAnaWRlbnRpdHknIHByb3BlcnR5OiAke0pTT04uc3RyaW5naWZ5KHJlc3BvbnNlKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGlkZW50aXR5IH0gPSByZXNwb25zZTtcbiAgICAgICAgY29uc3QgcmVzID0gdGhpcy5maW4uV2luZG93LndyYXBTeW5jKGlkZW50aXR5KTtcbiAgICAgICAgLy8gd2UgYWRkIHRoZSBpZGVudGl0eSBhdCB0aGUgdG9wIGxldmVsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgICAgICAgcmVzLm5hbWUgPSBpZGVudGl0eS5uYW1lO1xuICAgICAgICByZXMudXVpZCA9IGlkZW50aXR5LnV1aWQ7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBjdXJyZW50IHBsYXRmb3JtLCBhbGwgaXRzIHdpbmRvd3MsIGFuZCB0aGVpciB2aWV3cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogcGxhdGZvcm0ucXVpdCgpO1xuICAgICAqIC8vIEFsbCB3aW5kb3dzL3ZpZXdzIGluIGN1cnJlbnQgbGF5b3V0IHBsYXRmb3JtIHdpbGwgY2xvc2UgYW5kIHBsYXRmb3JtIHdpbGwgc2h1dCBkb3duXG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcXVpdCgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLXF1aXQnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdxdWl0Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBhIHNwZWNpZmllZCB2aWV3IGluIGEgdGFyZ2V0IHdpbmRvdy5cbiAgICAgKiBAcGFyYW0gdmlld0lkZW50aXR5IFZpZXcgaWRlbnRpdHlcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBsZXQgd2luZG93SWRlbnRpdHk7XG4gICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3Qgdmlld09wdGlvbnMgPSB7XG4gICAgICogICAgIG5hbWU6ICd0ZXN0X3ZpZXcnLFxuICAgICAqICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tJ1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzbGVlcChtcykge1xuICAgICAqICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgd2luZG93SWRlbnRpdHkpO1xuICAgICAqIC8vIGEgbmV3IHZpZXcgd2lsbCBub3cgc2hvdyBpbiB0aGUgY3VycmVudCB3aW5kb3dcbiAgICAgKlxuICAgICAqIGF3YWl0IHNsZWVwKDUwMDApO1xuICAgICAqXG4gICAgICogY29uc3Qgdmlld0lkZW50aXR5ID0geyB1dWlkOiB3aW5kb3dJZGVudGl0eS51dWlkLCBuYW1lOiAndGVzdF92aWV3J307XG4gICAgICogcGxhdGZvcm0uY2xvc2VWaWV3KHZpZXdJZGVudGl0eSk7XG4gICAgICogLy8gdGhlIHZpZXcgd2lsbCBub3cgY2xvc2VcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZVZpZXcodmlld0lkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1jbG9zZS12aWV3JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdjbG9zZS12aWV3Jywge1xuICAgICAgICAgICAgdmlldzogdmlld0lkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqKipERVBSRUNBVEVEIC0gcGxlYXNlIHVzZSB7QGxpbmsgUGxhdGZvcm0uY3JlYXRlVmlldyBQbGF0Zm9ybS5jcmVhdGVWaWV3fS4qKipcbiAgICAgKiBSZXBhcmVudHMgYSBzcGVjaWZpZWQgdmlldyBpbiBhIG5ldyB0YXJnZXQgd2luZG93LlxuICAgICAqIEBwYXJhbSB2aWV3SWRlbnRpdHkgVmlldyBpZGVudGl0eVxuICAgICAqIEBwYXJhbSB0YXJnZXQgbmV3IG93bmVyIHdpbmRvdyBpZGVudGl0eVxuICAgICAqXG4gICAgICovXG4gICAgYXN5bmMgcmVwYXJlbnRWaWV3KHZpZXdJZGVudGl0eSwgdGFyZ2V0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUud2FybignUGxhdGZvcm0ucmVwYXJlbnRWaWV3IGhhcyBiZWVuIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgUGxhdGZvcm0uY3JlYXRlVmlldycpO1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tcmVwYXJlbnQtdmlldycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWaWV3SWRlbnRpdHkgPSB7XG4gICAgICAgICAgICAuLi52aWV3SWRlbnRpdHksXG4gICAgICAgICAgICB1dWlkOiB2aWV3SWRlbnRpdHkudXVpZCA/PyB0aGlzLmlkZW50aXR5LnV1aWRcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdmlldyA9IGF3YWl0IHRoaXMuZmluLlZpZXcud3JhcChub3JtYWxpemVkVmlld0lkZW50aXR5KTtcbiAgICAgICAgY29uc3Qgdmlld09wdGlvbnMgPSBhd2FpdCB2aWV3LmdldE9wdGlvbnMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgdGFyZ2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIHRoZSBwbGF0Zm9ybSBpbiBpdHMgY3VycmVudCBzdGF0ZS4gWW91IGNhbiBwYXNzIHRoZSByZXR1cm5pbmcgb2JqZWN0IHRvXG4gICAgICogW1BsYXRmb3JtLmFwcGx5U25hcHNob3Rde0BsaW5rIFBsYXRmb3JtI2FwcGx5U25hcHNob3R9IHRvIGxhdW5jaCBpdC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoZSBzbmFwc2hvdCB3aWxsIGluY2x1ZGUgZGV0YWlscyBzdWNoIGFzIGFuIFtJU08gZm9ybWF0XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiB0aW1lc3RhbXAgb2Ygd2hlbiB0aGUgc25hcHNob3Qgd2FzIHRha2VuLCBPcGVuRmluIHJ1bnRpbWUgdmVyc2lvbiB0aGUgcGxhdGZvcm0gaXMgcnVubmluZyBvbiwgbW9uaXRvciBpbmZvcm1hdGlvblxuICAgICAqIGFuZCB0aGUgbGlzdCBvZiBjdXJyZW50bHkgcnVubmluZyB3aW5kb3dzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHBsYXRmb3JtLmdldFNuYXBzaG90KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1nZXQtc25hcHNob3QnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXQtc25hcHNob3QnKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKipOT1RFKio6IEludGVybmFsIHVzZSBvbmx5LiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdG8gbWFuYWdlIHRoZSBzdGF0ZSBvZiBpbmRpdmlkdWFsIHZpZXdzLlxuICAgICAqXG4gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIGEgc2luZ2xlIHZpZXcncyBvcHRpb25zIGluIGl0cyBjdXJyZW50IHN0YXRlLlxuICAgICAqXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gcmVzdG9yZSBhIHZpZXcgdG8gYSBwcmV2aW91cyBzdGF0ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2aWV3SWRlbnRpdHkgVmlldyBpZGVudGl0eVxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAqIEByZW1hcmtzIFRoaXMgc2xpY2Ugb2Ygc25hcHNob3Qgc3RhdGUgaXMgZXF1aXZhbGVudCB0byB3aGF0IGlzIHN0b3JlZCBhcyBgY29tcG9uZW50U3RhdGVgIGZvciB2aWV3c1xuICAgICAqIHdoZW4gY2FwdHVyaW5nIHBsYXRmb3JtIHN0YXRlIHVzaW5nIFtQbGF0Zm9ybS5nZXRTbmFwc2hvdF17QGxpbmsgUGxhdGZvcm0jZ2V0U25hcHNob3R9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCB1cmwgPSAnaHR0cHM6Ly9nb29nbGUuY29tJztcbiAgICAgKiBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHsgbmFtZTogJ215LXZpZXcnLCB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSwgdXJsIH0pO1xuICAgICAqXG4gICAgICogYXdhaXQgdmlldy5uYXZpZ2F0ZSh1cmwpO1xuICAgICAqXG4gICAgICogY29uc3Qgdmlld1N0YXRlID0gYXdhaXQgcGxhdGZvcm0uZ2V0Vmlld1NuYXBzaG90KHZpZXcuaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2codmlld1N0YXRlKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRWaWV3U25hcHNob3Qodmlld0lkZW50aXR5KSB7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2dldC12aWV3LXNuYXBzaG90JywgeyB2aWV3SWRlbnRpdHkgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBzbmFwc2hvdCB0byBhIHJ1bm5pbmcgUGxhdGZvcm0uXG4gICAgICogUmVxdWVzdGVkIHNuYXBzaG90IG11c3QgYmUgYSB2YWxpZCBTbmFwc2hvdCBvYmplY3QsIG9yIGEgdXJsIG9yIGZpbGVwYXRoIHRvIHN1Y2ggYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQ2FuIG9wdGlvbmFsbHkgY2xvc2UgZXhpc3Rpbmcgd2luZG93cyBhbmQgb3ZlcndyaXRlIGN1cnJlbnQgcGxhdGZvcm0gc3RhdGUgd2l0aCB0aGF0IG9mIGEgc25hcHNob3QuXG4gICAgICpcbiAgICAgKiBUaGUgZnVuY3Rpb24gYWNjZXB0cyBlaXRoZXIgYSBzbmFwc2hvdCB0YWtlbiB1c2luZyB7QGxpbmsgUGxhdGZvcm0jZ2V0U25hcHNob3QgZ2V0U25hcHNob3R9LFxuICAgICAqIG9yIGEgdXJsIG9yIGZpbGVwYXRoIHRvIGEgc25hcHNob3QgSlNPTiBvYmplY3QuXG4gICAgICogQHBhcmFtIHJlcXVlc3RlZFNuYXBzaG90IFNuYXBzaG90IHRvIGFwcGx5LCBvciBhIHVybCBvciBmaWxlcGF0aC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBwYXJhbWV0ZXJzIHRvIHNwZWNpZnkgd2hldGhlciBleGlzdGluZyB3aW5kb3dzIHNob3VsZCBiZSBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXaWxsIGNyZWF0ZSBhbnkgd2luZG93cyBhbmQgdmlld3MgdGhhdCBhcmUgbm90IHJ1bm5pbmcgYnV0IGFyZSBwYXNzZWQgaW4gdGhlIHNuYXBzaG90IG9iamVjdC4gQW55IFZpZXdcbiAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIHNuYXBzaG90IGlzIGFzc2lnbmVkIGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG5hbWUgdG8gYXZvaWQgY29sbGlzaW9ucy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiAvLyBHZXQgYSB3cmFwcGVkIGxheW91dCBwbGF0Zm9ybSBpbnN0YW5jZVxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0ge1xuICAgICAqICAgICB3aW5kb3dzOiBbXG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb21wb25lbnRfWCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly93d3cub3BlbmZpbi5jbydcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb21wb25lbnRfWScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9lbWJlZC13ZWIvY2hhcnQuaHRtbCdcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgXVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHBsYXRmb3JtLmFwcGx5U25hcHNob3Qoc25hcHNob3QpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSW4gcGxhY2Ugb2YgYSBzbmFwc2hvdCBvYmplY3QsIGBhcHBseVNuYXBzaG90YCBjYW4gdGFrZSBhIHVybCBvciBmaWxlcGF0aCBhbmQgdG8gcmV0cmlldmUgYSBKU09OIHNuYXBzaG90LlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogcGxhdGZvcm0uYXBwbHlTbmFwc2hvdCgnaHR0cHM6Ly9hcGkuanNvbmJpbi5pby9iLzVlNmY5MDNlZjQzMzFlNjgxZmMxMjMxZC8xJyk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBPcHRpb25hbGx5LCBgYXBwbHlTbmFwc2hvdGAgY2FuIGNsb3NlIGV4aXN0aW5nIHdpbmRvd3MgYW5kIHJlc3RvcmUgYSBQbGF0Zm9ybSB0byBhIHByZXZpb3VzbHkgc2F2ZWQgc3RhdGUuXG4gICAgICogVGhpcyBpcyBhY2NvbXBsaXNoZWQgYnkgcHJvdmlkaW5nIGB7IGNsb3NlRXhpc3RpbmdXaW5kb3dzOiB0cnVlIH1gIGFzIGFuIG9wdGlvbi5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogLy8gR2V0IGEgd3JhcHBlZCBsYXlvdXQgcGxhdGZvcm0gaW5zdGFuY2VcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICpcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBhZGRWaWV3VG9XaW5kb3cod2luSWQpIHtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHBsYXRmb3JtLmNyZWF0ZVZpZXcoe1xuICAgICAqICAgICAgICAgbmFtZTogJ3Rlc3Rfdmlld18zJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vb3BlbmZpbi5jbydcbiAgICAgKiAgICAgfSwgd2luSWQpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbmRvd1dpdGhUd29WaWV3cygpIHtcbiAgICAgKiAgICAgY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogICAgIHJldHVybiBwbGF0Zm9ybS5jcmVhdGVXaW5kb3coe1xuICAgICAqICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U3RhdGU6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGVzdF92aWV3XzInLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly95YWhvby5jb20nXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbmRvd1dpdGhUd29WaWV3cygpO1xuICAgICAqIC8vIC4uLiB5b3Ugd2lsbCBub3cgc2VlIGEgbmV3IHdpbmRvdyB3aXRoIHR3byB2aWV3cyBpbiBpdFxuICAgICAqXG4gICAgICogLy8gd2UgdGFrZSBhIHNuYXBzaG90IG9mIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBhcHAsIGJlZm9yZSBjaGFuZ2luZyBpdFxuICAgICAqIGNvbnN0IHNuYXBzaG90T2ZJbml0aWFsQXBwU3RhdGUgPSBhd2FpdCBwbGF0Zm9ybS5nZXRTbmFwc2hvdCgpO1xuICAgICAqXG4gICAgICogLy8gbm93IGxldCdzIGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIGFwcDpcbiAgICAgKiBhd2FpdCBhZGRWaWV3VG9XaW5kb3cod2luLmlkZW50aXR5KTtcbiAgICAgKiAvLyAuLi4gdGhlIHdpbmRvdyBub3cgaGFzIHRocmVlIHZpZXdzIGluIGl0XG4gICAgICpcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5hcHBseVNuYXBzaG90KHNuYXBzaG90T2ZJbml0aWFsQXBwU3RhdGUsIHsgY2xvc2VFeGlzdGluZ1dpbmRvd3M6IHRydWUgfSk7XG4gICAgICogLy8gLi4uIHRoZSB3aW5kb3cgd2lsbCByZXZlcnQgdG8gcHJldmlvdXMgc3RhdGUsIHdpdGgganVzdCB0d28gdmlld3NcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGFwcGx5U25hcHNob3QocmVxdWVzdGVkU25hcHNob3QsIG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWFwcGx5LXNuYXBzaG90JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZXJyTXNnID0gJ1JlcXVlc3RlZCBzbmFwc2hvdCBtdXN0IGJlIGEgdmFsaWQgU25hcHNob3Qgb2JqZWN0LCBvciBhIHVybCBvciBmaWxlcGF0aCB0byBzdWNoIGFuIG9iamVjdC4nO1xuICAgICAgICBsZXQgc25hcHNob3Q7XG4gICAgICAgIGlmICh0eXBlb2YgcmVxdWVzdGVkU25hcHNob3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBGZXRjaCBhbmQgcGFyc2Ugc25hcHNob3RcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9jaGFubmVsLndpcmUuc2VuZEFjdGlvbignZ2V0LWFwcGxpY2F0aW9uLW1hbmlmZXN0Jywge1xuICAgICAgICAgICAgICAgICAgICBtYW5pZmVzdFVybDogcmVxdWVzdGVkU25hcHNob3RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzbmFwc2hvdCA9IHJlc3BvbnNlLnBheWxvYWQuZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyTXNnfTogJHtlcnJ9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzbmFwc2hvdCA9IHJlcXVlc3RlZFNuYXBzaG90O1xuICAgICAgICB9XG4gICAgICAgIGlmICghc25hcHNob3Qud2luZG93cykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdhcHBseS1zbmFwc2hvdCcsIHtcbiAgICAgICAgICAgIHNuYXBzaG90LFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgYSBKU09OIG1hbmlmZXN0IHVzaW5nIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIHJldHVybnMgYSBKYXZhc2NyaXB0IG9iamVjdC5cbiAgICAgKiBDYW4gYmUgb3ZlcndyaXR0ZW4gdXNpbmcge0BsaW5rIFBsYXRmb3JtLlBsYXRmb3JtTW9kdWxlLmluaXQgUGxhdGZvcm0uaW5pdH0uXG4gICAgICogQHBhcmFtIG1hbmlmZXN0VXJsIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRvIGZldGNoLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2FuIGJlIG92ZXJ3cml0dGVuIHVzaW5nIHtAbGluayBQbGF0Zm9ybSNpbml0IFBsYXRmb3JtLmluaXR9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKiBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHBsYXRmb3JtLmZldGNoTWFuaWZlc3QoJ2h0dHBzOi8vd3d3LnBhdGgtdG8tbWFuaWZlc3QuY29tL2FwcC5qc29uJyk7XG4gICAgICogY29uc29sZS5sb2cobWFuaWZlc3QpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGZldGNoTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgncGxhdGZvcm0tZmV0Y2gtbWFuaWZlc3QnLCB7IG1hbmlmZXN0VXJsIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYSBtYW5pZmVzdCBieSB1cmwgYW5kIGxhdW5jaGVzIGEgbGVnYWN5IGFwcGxpY2F0aW9uIG1hbmlmZXN0IG9yIHNuYXBzaG90IGludG8gdGhlIHBsYXRmb3JtLiAgUmV0dXJucyBhIHByb21pc2UgdGhhdFxuICAgICAqIHJlc29sdmVzIHRvIHRoZSB3cmFwcGVkIFBsYXRmb3JtLlxuICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRoYXQgd2lsbCBiZSBsYXVuY2hlZCBpbnRvIHRoZSBwbGF0Zm9ybS4gIElmIHRoaXMgYXBwIG1hbmlmZXN0XG4gICAgICogY29udGFpbnMgYSBzbmFwc2hvdCwgdGhhdCB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiAgSWYgbm90LCB0aGUgYXBwbGljYXRpb24gZGVzY3JpYmVkIGluIHN0YXJ0dXBfYXBwIG9wdGlvbnNcbiAgICAgKiB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiBUaGUgYXBwbGljYWJsZSBzdGFydHVwX2FwcCBvcHRpb25zIHdpbGwgYmVjb21lIHtAbGluayBPcGVuRmluLlZpZXdDcmVhdGlvbk9wdGlvbnMgVmlldyBPcHRpb25zfS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIElmIHRoZSBhcHAgbWFuaWZlc3QgY29udGFpbnMgYSBzbmFwc2hvdCwgdGhhdCB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiAgSWYgbm90LCB0aGVcbiAgICAgKiBhcHBsaWNhdGlvbiBkZXNjcmliZWQgaW4gc3RhcnR1cF9hcHAgb3B0aW9ucyB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtIGFzIGEgd2luZG93IHdpdGggYSBzaW5nbGUgdmlldy5cbiAgICAgKiBUaGUgYXBwbGljYWJsZSBzdGFydHVwX2FwcCBvcHRpb25zIHdpbGwgYmVjb21lIFZpZXcgT3B0aW9ucy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqICAgICBhd2FpdCBwbGF0Zm9ybS5sYXVuY2hDb250ZW50TWFuaWZlc3QoJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAuanNvbicpO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgY29udGVudCBsYXVuY2hlZCBzdWNjZXNzZnVsbHkgaW50byBwbGF0Zm9ybWApO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAqIH1cbiAgICAgKiAvLyBGb3IgYSBsb2NhbCBtYW5pZmVzdCBmaWxlOlxuICAgICAqIHRyeSB7XG4gICAgICogICAgIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogICAgIHBsYXRmb3JtLmxhdW5jaENvbnRlbnRNYW5pZmVzdCgnZmlsZTovLy9DOi9zb21lZm9sZGVyL2FwcC5qc29uJyk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBjb250ZW50IGxhdW5jaGVkIHN1Y2Nlc3NmdWxseSBpbnRvIHBsYXRmb3JtYCk7XG4gICAgICogfSBjYXRjaChlKSB7XG4gICAgICogICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgKi9cbiAgICBhc3luYyBsYXVuY2hDb250ZW50TWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWxhdW5jaC1jb250ZW50LW1hbmlmZXN0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHRoaXMuZmV0Y2hNYW5pZmVzdChtYW5pZmVzdFVybCk7XG4gICAgICAgIGNsaWVudC5kaXNwYXRjaCgnbGF1bmNoLWludG8tcGxhdGZvcm0nLCB7IG1hbmlmZXN0LCBtYW5pZmVzdFVybCB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY29udGV4dCBvZiBhIGhvc3Qgd2luZG93LiBUaGUgY29udGV4dCB3aWxsIGJlIGF2YWlsYWJsZSB0byB0aGUgd2luZG93IGl0c2VsZiwgYW5kIHRvIGl0cyBjaGlsZCBWaWV3cy4gSXQgd2lsbCBiZSBzYXZlZCBpbiBhbnkgcGxhdGZvcm0gc25hcHNob3RzLlxuICAgICAqIEl0IGNhbiBiZSByZXRyaWV2ZWQgdXNpbmcge0BsaW5rIFBsYXRmb3JtI2dldFdpbmRvd0NvbnRleHQgZ2V0V2luZG93Q29udGV4dH0uXG4gICAgICogQHBhcmFtIGNvbnRleHQgLSBBIGZpZWxkIHdoZXJlIHNlcmlhbGl6YWJsZSBjb250ZXh0IGRhdGEgY2FuIGJlIHN0b3JlZCB0byBiZSBzYXZlZCBpbiBwbGF0Zm9ybSBzbmFwc2hvdHMuXG4gICAgICogQHBhcmFtIHRhcmdldCAtIEEgdGFyZ2V0IHdpbmRvdyBvciB2aWV3IG1heSBvcHRpb25hbGx5IGJlIHByb3ZpZGVkLiBJZiBubyB0YXJnZXQgaXMgcHJvdmlkZWQsIHRoZSB1cGRhdGUgd2lsbCBiZSBhcHBsaWVkXG4gICAgICogdG8gdGhlIGN1cnJlbnQgd2luZG93IChpZiBjYWxsZWQgZnJvbSBhIFdpbmRvdykgb3IgdGhlIGN1cnJlbnQgaG9zdCB3aW5kb3cgKGlmIGNhbGxlZCBmcm9tIGEgVmlldykuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgY29udGV4dCBkYXRhIG11c3QgYmUgc2VyaWFsaXphYmxlLiAgVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgZnJvbSBhIHdpbmRvdyBvciB2aWV3IHRoYXQgaGFzIGJlZW4gbGF1bmNoZWQgaW50byBhXG4gICAgICogcGxhdGZvcm0uXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBmcm9tIHRoZSB3aW5kb3cgaXRzZWxmLCBvciBmcm9tIGFueSBjaGlsZCB2aWV3LiBDb250ZXh0IGRhdGEgaXMgc2hhcmVkIGJ5IGFsbFxuICAgICAqIGVudGl0aWVzIHdpdGhpbiBhIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogU2V0dGluZyBvd24gY29udGV4dDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGF3YWl0IHBsYXRmb3JtLnNldFdpbmRvd0NvbnRleHQoY29udGV4dERhdGEpO1xuICAgICAqIC8vIENvbnRleHQgb2YgY3VycmVudCB3aW5kb3cgaXMgbm93IHNldCB0byBgY29udGV4dERhdGFgXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoZSBjb250ZXh0IG9mIGFub3RoZXIgd2luZG93IG9yIHZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGNvbnN0IGNvbnRleHREYXRhID0ge1xuICAgICAqICAgICBzZWN1cml0eTogJ1NUT0NLJyxcbiAgICAgKiAgICAgY3VycmVudFZpZXc6ICdkZXRhaWxlZCdcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBjb25zdCB3aW5kb3dPclZpZXdJZGVudGl0eSA9IHsgdXVpZDogZmluLm1lLnV1aWQsIG5hbWU6ICduYW1lT2ZXaW5kb3dPclZpZXcnIH07XG4gICAgICogYXdhaXQgcGxhdGZvcm0uc2V0V2luZG93Q29udGV4dChjb250ZXh0RGF0YSwgd2luZG93T3JWaWV3SWRlbnRpdHkpO1xuICAgICAqIC8vIENvbnRleHQgb2YgdGhlIHRhcmdldCB3aW5kb3cgb3IgdmlldyBpcyBub3cgc2V0IHRvIGBjb250ZXh0RGF0YWBcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEEgdmlldyBjYW4gbGlzdGVuIHRvIGNoYW5nZXMgdG8gaXRzIGhvc3Qgd2luZG93J3MgY29udGV4dCBieSBsaXN0ZW5pbmcgdG8gdGhlIGBob3N0LWNvbnRleHQtY2hhbmdlZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGZpcmUgd2hlbiBhIGhvc3Qgd2luZG93J3MgY29udGV4dCBpcyB1cGRhdGVkIG9yIHdoZW4gdGhlIHZpZXcgaXMgcmVwYXJlbnRlZCB0byBhIG5ldyB3aW5kb3c6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gYSB2aWV3XG4gICAgICogY29uc3QgY29udGV4dENoYW5nZUhhbmRsZXIgPSAoeyBjb250ZXh0IH0pID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0hvc3Qgd2luZG93XFwncyBjb250ZXh0IGhhcyBjaGFuZ2VkLiBOZXcgY29udGV4dCBkYXRhOicsIGNvbnRleHQpO1xuICAgICAqICAgICAvLyByZWFjdCB0byBuZXcgY29udGV4dCBkYXRhIGhlcmVcbiAgICAgKiB9XG4gICAgICogYXdhaXQgZmluLm1lLm9uKCdob3N0LWNvbnRleHQtY2hhbmdlZCcsIGNvbnRleHRDaGFuZ2VIYW5kbGVyKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKiBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGNvbnRleHREYXRhKSAvLyBjb250ZXh0Q2hhbmdlSGFuZGxlciB3aWxsIGxvZyB0aGUgbmV3IGNvbnRleHRcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRvIGxpc3RlbiB0byBhIHdpbmRvdydzIGNvbnRleHQgdXBkYXRlcywgdXNlIHRoZSBgY29udGV4dC1jaGFuZ2VkYCBldmVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gYSB3aW5kb3dcbiAgICAgKiBjb25zdCBjb250ZXh0Q2hhbmdlSGFuZGxlciA9ICh7IGNvbnRleHQgfSkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnVGhpcyB3aW5kb3dcXCdzIGNvbnRleHQgaGFzIGNoYW5nZWQuIE5ldyBjb250ZXh0IGRhdGE6JywgY29udGV4dCk7XG4gICAgICogICAgIC8vIHJlYWN0IHRvIG5ldyBjb250ZXh0IGRhdGEgaGVyZVxuICAgICAqIH1cbiAgICAgKiBhd2FpdCBmaW4ubWUub24oJ2NvbnRleHQtY2hhbmdlZCcsIGNvbnRleHRDaGFuZ2VIYW5kbGVyKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKiBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGNvbnRleHREYXRhKSAvLyBjb250ZXh0Q2hhbmdlSGFuZGxlciB3aWxsIGxvZyB0aGUgbmV3IGNvbnRleHRcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgc2V0V2luZG93Q29udGV4dChjb250ZXh0ID0ge30sIHRhcmdldCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tc2V0LXdpbmRvdy1jb250ZXh0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgc2VyaWFsaXphYmxlIG9iamVjdCBvciBzdHJpbmcgdG8gc2V0IHRoZSBjb250ZXh0LicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5VHlwZSB9ID0gdGFyZ2V0ID8gYXdhaXQgdGhpcy5maW4uU3lzdGVtLmdldEVudGl0eUluZm8odGFyZ2V0LnV1aWQsIHRhcmdldC5uYW1lKSA6IHRoaXMuZmluLm1lO1xuICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3NldC13aW5kb3ctY29udGV4dCcsIHtcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBlbnRpdHlUeXBlLFxuICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQgfHwgeyB1dWlkOiB0aGlzLmZpbi5tZS51dWlkLCBuYW1lOiB0aGlzLmZpbi5tZS5uYW1lIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY29udGV4dCBjb250ZXh0IG9mIGEgaG9zdCB3aW5kb3cgdGhhdCB3YXMgcHJldmlvdXNseSBzZXQgdXNpbmcge0BsaW5rIFBsYXRmb3JtI3NldFdpbmRvd0NvbnRleHQgc2V0V2luZG93Q29udGV4dH0uXG4gICAgICogVGhlIGNvbnRleHQgd2lsbCBiZSBzYXZlZCBpbiBhbnkgcGxhdGZvcm0gc25hcHNob3RzLiAgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gQSB0YXJnZXQgd2luZG93IG9yIHZpZXcgbWF5IG9wdGlvbmFsbHkgYmUgcHJvdmlkZWQuIElmIG5vIHRhcmdldCBpcyBwcm92aWRlZCwgdGFyZ2V0IHdpbGwgYmVcbiAgICAgKiB0aGUgY3VycmVudCB3aW5kb3cgKGlmIGNhbGxlZCBmcm9tIGEgV2luZG93KSBvciB0aGUgY3VycmVudCBob3N0IHdpbmRvdyAoaWYgY2FsbGVkIGZyb20gYSBWaWV3KS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgd2luZG93IGl0c2VsZiwgb3IgZnJvbSBhbnkgY2hpbGQgdmlldy4gQ29udGV4dCBkYXRhIGlzIHNoYXJlZFxuICAgICAqIGJ5IGFsbCBlbnRpdGllcyB3aXRoaW4gYSB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogUmV0cmlldmluZyBjb250ZXh0IGZyb20gY3VycmVudCB3aW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGNvbnN0IGN1c3RvbUNvbnRleHQgPSB7IGFuc3dlcjogNDIgfTtcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGN1c3RvbUNvbnRleHQpO1xuICAgICAqXG4gICAgICogY29uc3QgbXlDb250ZXh0ID0gYXdhaXQgcGxhdGZvcm0uZ2V0V2luZG93Q29udGV4dCgpO1xuICAgICAqIGNvbnNvbGUubG9nKG15Q29udGV4dCk7IC8vIHsgYW5zd2VyOiA0MiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBSZXRyaWV2aW5nIHRoZSBjb250ZXh0IG9mIGFub3RoZXIgd2luZG93IG9yIHZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogY29uc3Qgd2luZG93T3JWaWV3SWRlbnRpdHkgPSB7IHV1aWQ6IGZpbi5tZS51dWlkLCBuYW1lOiAnbmFtZU9mV2luZG93T3JWaWV3JyB9O1xuICAgICAqXG4gICAgICogY29uc3QgdGFyZ2V0V2luZG93Q29udGV4dCA9IGF3YWl0IHBsYXRmb3JtLmdldFdpbmRvd0NvbnRleHQod2luZG93T3JWaWV3SWRlbnRpdHkpO1xuICAgICAqIGNvbnNvbGUubG9nKHRhcmdldFdpbmRvd0NvbnRleHQpOyAvLyBjb250ZXh0IG9mIHRhcmdldCB3aW5kb3dcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0V2luZG93Q29udGV4dCh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWdldC13aW5kb3ctY29udGV4dCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5VHlwZSB9ID0gdGFyZ2V0ID8gYXdhaXQgdGhpcy5maW4uU3lzdGVtLmdldEVudGl0eUluZm8odGFyZ2V0LnV1aWQsIHRhcmdldC5uYW1lKSA6IHRoaXMuZmluLm1lO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXQtd2luZG93LWNvbnRleHQnLCB7XG4gICAgICAgICAgICB0YXJnZXQ6IHRhcmdldCB8fCB7IHV1aWQ6IHRoaXMuZmluLm1lLnV1aWQsIG5hbWU6IHRoaXMuZmluLm1lLm5hbWUgfSxcbiAgICAgICAgICAgIGVudGl0eVR5cGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBhIHdpbmRvdy4gSWYgZW5hYmxlQmVmb3JlVW5sb2FkIGlzIGVuYWJsZWQgaW4gdGhlIFBsYXRmb3JtIG9wdGlvbnMsIGFueSBiZWZvcmV1bmxvYWQgaGFuZGxlciBzZXQgb24gVmlld3Mgd2lsbCBmaXJlXG4gICAgICogVGhpcyBiZWhhdmlvciBjYW4gYmUgZGlzYWJsZWQgYnkgc2V0dGluZyBza2lwQmVmb3JlVW5sb2FkIHRvIGZhbHNlIGluIHRoZSBvcHRpb25zIHBhcmFtZXRlci5cbiAgICAgKiBAcGFyYW0gd2luSWRcbiAgICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhpcyBtZXRob2Qgd29ya3MgYnkgc2V0dGluZyBhIGBjbG9zZS1yZXF1ZXN0ZWRgIGhhbmRsZXIgb24gdGhlIFBsYXRmb3JtIFdpbmRvdy4gSWYgeW91IGhhdmUgeW91ciBvd24gYGNsb3NlLXJlcXVlc3RlZGAgaGFuZGxlciBzZXQgb24gdGhlIFBsYXRmb3JtIFdpbmRvdyBhcyB3ZWxsLFxuICAgICAqIGl0IGlzIHJlY29tbWVuZGVkIHRvIG1vdmUgdGhhdCBsb2dpYyBvdmVyIHRvIHRoZSBbUGxhdGZvcm1Qcm92aWRlci5jbG9zZVdpbmRvd117QGxpbmsgUGxhdGZvcm1Qcm92aWRlciNjbG9zZVdpbmRvd30gb3ZlcnJpZGUgdG8gZW5zdXJlIGl0IHJ1bnMgd2hlbiB0aGUgV2luZG93IGNsb3Nlcy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIENsb3NlIHRoZSBjdXJyZW50IFdpbmRvdyBpbnNpZGUgYSBXaW5kb3cgY29udGV4dFxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBwbGF0Zm9ybS5jbG9zZVdpbmRvdyhmaW4ubWUuaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogLy8gQ2xvc2UgdGhlIFdpbmRvdyBmcm9tIGluc2lkZSBhIFZpZXcgY29udGV4dFxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCBwYXJlbnRXaW5kb3cgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFdpbmRvdygpO1xuICAgICAqIHBsYXRmb3JtLmNsb3NlV2luZG93KHBhcmVudFdpbmRvdy5pZGVudGl0eSk7XG4gICAgICpcbiAgICAgKiAvLyBDbG9zZSB0aGUgV2luZG93IGFuZCBkbyBub3QgZmlyZSB0aGUgYmVmb3JlIHVubG9hZCBoYW5kbGVyIG9uIFZpZXdzXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqIHBsYXRmb3JtLmNsb3NlV2luZG93KGZpbi5tZS5pZGVudGl0eSwgeyBza2lwQmVmb3JlVW5sb2FkOiB0cnVlIH0pO1xuICAgICAqIGBgYFxuICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZVdpbmRvdyh3aW5kb3dJZCwgb3B0aW9ucyA9IHsgc2tpcEJlZm9yZVVubG9hZDogZmFsc2UgfSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tY2xvc2Utd2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnY2xvc2Utd2luZG93JywgeyB3aW5kb3dJZCwgb3B0aW9ucyB9KTtcbiAgICB9XG59XG5JbnN0YW5jZSQyLlBsYXRmb3JtID0gUGxhdGZvcm07XG5fUGxhdGZvcm1fY29ubmVjdFRvUHJvdmlkZXIgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgbGF5b3V0ID0ge307XG5cbnZhciBGYWN0b3J5JDIgPSB7fTtcblxudmFyIEluc3RhbmNlJDEgPSB7fTtcblxudmFyIGNvbW1vblV0aWxzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb21tb25VdGlscywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb21tb25VdGlscy5vdmVycmlkZUZyb21Db21wb3NhYmxlcyA9IGNvbW1vblV0aWxzLmlzVmFsaWRQcmVzZXRUeXBlID0gdm9pZCAwO1xuZnVuY3Rpb24gaXNWYWxpZFByZXNldFR5cGUodHlwZSkge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdjb2x1bW5zJzpcbiAgICAgICAgY2FzZSAnZ3JpZCc6XG4gICAgICAgIGNhc2UgJ3Jvd3MnOlxuICAgICAgICBjYXNlICd0YWJzJzpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmNvbW1vblV0aWxzLmlzVmFsaWRQcmVzZXRUeXBlID0gaXNWYWxpZFByZXNldFR5cGU7XG5mdW5jdGlvbiBvdmVycmlkZUZyb21Db21wb3NhYmxlcyguLi5vdmVycmlkZXMpIHtcbiAgICByZXR1cm4gKGJhc2UpID0+IG92ZXJyaWRlcy5yZWR1Y2VSaWdodCgocCwgYykgPT4gKGIpID0+IGMocChiKSksICh4KSA9PiB4KShiYXNlKTtcbn1cbmNvbW1vblV0aWxzLm92ZXJyaWRlRnJvbUNvbXBvc2FibGVzID0gb3ZlcnJpZGVGcm9tQ29tcG9zYWJsZXM7XG5jb21tb25VdGlscy5kZWZhdWx0ID0geyBpc1ZhbGlkUHJlc2V0VHlwZSB9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX0xheW91dF9sYXlvdXRDbGllbnQ7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW5zdGFuY2UkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZSQxLkxheW91dCA9IHZvaWQgMDtcbmNvbnN0IGxhenlfMSA9IGxhenk7XG5jb25zdCB2YWxpZGF0ZV8xID0gdmFsaWRhdGU7XG5jb25zdCBiYXNlXzEkNSA9IGJhc2U7XG5jb25zdCBjb21tb25fdXRpbHNfMSA9IGNvbW1vblV0aWxzO1xuY29uc3QgbGF5b3V0X2VudGl0aWVzXzEgPSBsYXlvdXRFbnRpdGllcztcbmNvbnN0IGxheW91dF9jb25zdGFudHNfMSQxID0gbGF5b3V0X2NvbnN0YW50cztcbi8qKlxuICpcbiAqIExheW91dHMgZ2l2ZSBhcHAgcHJvdmlkZXJzIHRoZSBhYmlsaXR5IHRvIGVtYmVkIG11bHRpcGxlIHZpZXdzIGluIGEgc2luZ2xlIHdpbmRvdy4gVGhlIExheW91dCBuYW1lc3BhY2VcbiAqIGVuYWJsZXMgdGhlIGluaXRpYWxpemF0aW9uIGFuZCBtYW5pcHVsYXRpb24gb2YgYSB3aW5kb3cncyBMYXlvdXQuIEEgTGF5b3V0IHdpbGxcbiAqIGVtaXQgZXZlbnRzIGxvY2FsbHkgb24gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgbGF5b3V0LWNvbnRhaW5lci5cbiAqXG4gKlxuICogIyMjIExheW91dC5ET01FdmVudHNcbiAqXG4gKiBXaGVuIGEgTGF5b3V0IGlzIGNyZWF0ZWQsIGl0IGVtaXRzIGV2ZW50cyBvbnRvIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRpbmcgdGhlIExheW91dCBjb250YWluZXIuXG4gKiBUaGlzIExheW91dCBjb250YWluZXIgaXMgdGhlIERPTSBlbGVtZW50IHJlZmVyZW5jZWQgYnkgY29udGFpbmVySWQgaW4ge0BsaW5rIExheW91dC5MYXlvdXRNb2R1bGUjaW5pdCBMYXlvdXQuaW5pdH0uXG4gKiBZb3UgY2FuIHVzZSB0aGUgYnVpbHQtaW4gZXZlbnQgZW1pdHRlciB0byBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIHVzaW5nIFthZGRFdmVudExpc3RlbmVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lcikuXG4gKiBUaGUgZXZlbnRzIGFyZSBlbWl0dGVkIHN5bmNocm9ub3VzbHkgYW5kIG9ubHkgaW4gdGhlIHByb2Nlc3Mgd2hlcmUgdGhlIExheW91dCBleGlzdHMuXG4gKiBBbnkgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsZWQgbGlzdGVuZXJzIGFyZSBpZ25vcmVkIGFuZCB3aWxsIGJlIGRpc2NhcmRlZC5cbiAqIElmIHRoZSB0YXJnZXQgRE9NIGVsZW1lbnQgaXMgZGVzdHJveWVkLCBhbnkgZXZlbnRzIHRoYXQgaGF2ZSBiZWVuIHNldCB1cCBvbiB0aGF0IGVsZW1lbnQgd2lsbCBiZSBkZXN0cm95ZWQuXG4gKlxuICogQHJlbWFya3MgVGhlIGJ1aWx0LWluIGV2ZW50IGVtaXR0ZXIgaXMgbm90IGFuIE9wZW5GaW4gZXZlbnQgZW1pdHRlciBzbyBpdCBkb2Vzbid0IHNoYXJlIHByb3BhZ2F0aW9uIHNlbWFudGljcy5cbiAqXG4gKiAjIyMjIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyIFssIG9wdGlvbnNdKTt9XG4gKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBjb25zdCBteUxheW91dENvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsYXlvdXQtY29udGFpbmVyJyk7XG4gKlxuICogbXlMYXlvdXRDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcigndGFiLWNyZWF0ZWQnLCBmdW5jdGlvbihldmVudCkge1xuICogICAgICBjb25zdCB7IHRhYlNlbGVjdG9yIH0gPSBldmVudC5kZXRhaWw7XG4gKiAgICAgIGNvbnN0IHRhYkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJTZWxlY3Rvcik7XG4gKiAgICAgIGNvbnN0IGV4aXN0aW5nQ29sb3IgPSB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvcjtcbiAqICAgICAgdGFiRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcInJlZFwiO1xuICogICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAqICAgICAgICAgIHRhYkVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gZXhpc3RpbmdDb2xvcjtcbiAqICAgICAgfSwgMjAwMCk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqICMjIyMge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9yZW1vdmVFdmVudExpc3RlbmVyIHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIgWywgb3B0aW9uc10pO31cbiAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBganNcbiAqIGNvbnN0IG15TGF5b3V0Q29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xheW91dC1jb250YWluZXInKTtcbiAqXG4gKiBjb25zdCBsaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coZXZlbnQuZGV0YWlsKTtcbiAqICAgICBjb25zb2xlLmxvZygnY29udGFpbmVyLWNyZWF0ZWQgZXZlbnQgZmlyZWQgb25jZSwgcmVtb3ZpbmcgbGlzdGVuZXInKTtcbiAqICAgICBteUxheW91dENvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdjb250YWluZXItY3JlYXRlZCcsIGxpc3RlbmVyKTtcbiAqIH07XG4gKlxuICogbXlMYXlvdXRDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY29udGFpbmVyLWNyZWF0ZWQnLCBsaXN0ZW5lcik7XG4gKiBgYGBcbiAqXG4gKiAjIyMgU3VwcG9ydGVkIGV2ZW50IHR5cGVzIGFyZTpcbiAqXG4gKiAqIHRhYi1jcmVhdGVkXG4gKiAqIGNvbnRhaW5lci1jcmVhdGVkXG4gKiAqIGxheW91dC1zdGF0ZS1jaGFuZ2VkXG4gKiAqIHRhYi1jbG9zZWRcbiAqICogdGFiLWRyb3BwZWRcbiAqXG4gKiAjIyMgTGF5b3V0IERPTSBOb2RlIEV2ZW50c1xuICpcbiAqICMjIyMgdGFiLWNyZWF0ZWRcbiAqIEdlbmVyYXRlZCB3aGVuIGEgdGFiIGlzIGNyZWF0ZWQuICBBcyBhIHVzZXIgZHJhZ3MgYW5kIGRyb3BzIHRhYnMgd2l0aGluIHdpbmRvdywgbmV3IHRhYnMgYXJlIGNyZWF0ZWQuICBBIHNpbmdsZSB2aWV3IG1heSBoYXZlIG11bHRpcGxlIHRhYnMgY3JlYXRlZCBhbmQgZGVzdHJveWVkIGR1cmluZyBpdHMgbGlmZXRpbWUgYXR0YWNoZWQgdG8gYSBzaW5nbGUgd2luZG93LlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWw6XG4gKiB7XG4gKiAgICAgY29udGFpbmVyU2VsZWN0b3I6IFwiY29udGFpbmVyLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgbmFtZTogXCJjb21wb25lbnRfQVwiLFxuICogICAgIHRhYlNlbGVjdG9yOiBcInRhYi1jb21wb25lbnRfQVwiLFxuICogICAgIHRvcGljOiBcIm9wZW5maW4tRE9NLWV2ZW50XCIsXG4gKiAgICAgdHlwZTogXCJ0YWItY3JlYXRlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIyBjb250YWluZXItY3JlYXRlZFxuICogR2VuZXJhdGVkIHdoZW4gYSBjb250YWluZXIgaXMgY3JlYXRlZC4gIEEgc2luZ2xlIHZpZXcgd2lsbCBoYXZlIG9ubHkgb25lIGNvbnRhaW5lciBkdXJpbmcgaXRzIGxpZmV0aW1lIGF0dGFjaGVkIHRvIGEgc2luZ2xlIHdpbmRvdyBhbmQgdGhlIGNvbnRhaW5lcidzIGxpZmVjeWNsZSBpcyB0aWVkIHRvIHRoZSB2aWV3LiAgVG8gZGlzY292ZXIgd2hlbiB0aGUgY29udGFpbmVyIGlzIGRlc3Ryb3llZCwgcGxlYXNlIGxpc3RlbiB0byB2aWV3LWRldGFjaGVkIGV2ZW50LlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWw6XG4gKiB7XG4gKiAgICAgY29udGFpbmVyU2VsZWN0b3I6IFwiY29udGFpbmVyLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgbmFtZTogXCJjb21wb25lbnRfQVwiLFxuICogICAgIHRhYlNlbGVjdG9yOiBcInRhYi1jb21wb25lbnRfQVwiLFxuICogICAgIHRvcGljOiBcIm9wZW5maW4tRE9NLWV2ZW50XCIsXG4gKiAgICAgdHlwZTogXCJjb250YWluZXItY3JlYXRlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIGxheW91dC1zdGF0ZS1jaGFuZ2VkXG4gKiBHZW5lcmF0ZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIGxheW91dCBjaGFuZ2VzIGluIGFueSB3YXksIHN1Y2ggYXMgYSB2aWV3IGFkZGVkL3JlbW92ZWQvcmVwbGFjZWQuIE5vdGUgdGhhdCB0aGlzIGV2ZW50IGNhbiBmaXJlIGZyZXF1ZW50bHkgYXMgdGhlIHVuZGVybHlpbmcgbGF5b3V0IGNhbiBjaGFuZ2UgbXVsdGlwbGUgY29tcG9uZW50cyBmcm9tIGFsbCBraW5kcyBvZiBjaGFuZ2VzIChyZXNpemluZyBmb3IgZXhhbXBsZSkuIEdpdmVuIHRoaXMsIGl0IGlzIHJlY29tbWVuZGVkIHRvIGRlYm91bmNlIHRoaXMgZXZlbnQgYW5kIHRoZW4geW91IGNhbiB1c2UgdGhlIHtAbGluayBMYXlvdXQjZ2V0Q29uZmlnIExheW91dC5nZXRDb25maWd9IEFQSSB0byByZXRyaWV2ZSB0aGUgbW9zdCB1cC10by1kYXRlIHN0YXRlLlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWxcbiAqIHtcbiAqICAgICBjb250YWluZXJTZWxlY3RvcjogXCJjb250YWluZXItY29tcG9uZW50X0FcIixcbiAqICAgICBuYW1lOiBcImNvbXBvbmVudF9BXCIsXG4gKiAgICAgdGFiU2VsZWN0b3I6IFwidGFiLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgdG9waWM6IFwib3BlbmZpbi1ET00tZXZlbnRcIixcbiAqICAgICB0eXBlOiBcImxheW91dC1zdGF0ZS1jaGFuZ2VkXCIsXG4gKiAgICAgdXVpZDogXCJPcGVuRmluIFBPQ1wiXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMjIHRhYi1jbG9zZWRcbiAqIEdlbmVyYXRlZCB3aGVuIGEgdGFiIGlzIGNsb3NlZC5cbiAqIGBgYGpzXG4gKiAvLyBUaGUgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGUgaW4gZXZlbnQuZGV0YWlsOlxuICoge1xuICogICAgIGNvbnRhaW5lclNlbGVjdG9yOiBcImNvbnRhaW5lci1jb21wb25lbnRfQVwiLFxuICogICAgIG5hbWU6IFwiY29tcG9uZW50X0FcIixcbiAqICAgICB0YWJTZWxlY3RvcjogXCJ0YWItY29tcG9uZW50X0FcIixcbiAqICAgICB0b3BpYzogXCJvcGVuZmluLURPTS1ldmVudFwiLFxuICogICAgIHR5cGU6IFwidGFiLWNsb3NlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIixcbiAqICAgICB1cmw6IFwiaHR0cDovL29wZW5maW4uY29cIiAgIC8vIFRoZSB1cmwgb2YgdGhlIHZpZXcgdGhhdCB3YXMgY2xvc2VkLlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIyB0YWItZHJvcHBlZFxuICogR2VuZXJhdGVkIHdoZW4gYSB0YWIgaXMgZHJvcHBlZC5cbiAqIGBgYGpzXG4gKiAvLyBUaGUgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGUgaW4gZXZlbnQuZGV0YWlsOlxuICoge1xuICogICAgIGNvbnRhaW5lclNlbGVjdG9yOiBcImNvbnRhaW5lci1jb21wb25lbnRfQVwiLFxuICogICAgIG5hbWU6IFwiY29tcG9uZW50X0FcIixcbiAqICAgICB0YWJTZWxlY3RvcjogXCJ0YWItY29tcG9uZW50X0FcIixcbiAqICAgICB0b3BpYzogXCJvcGVuZmluLURPTS1ldmVudFwiLFxuICogICAgIHR5cGU6IFwidGFiLWRyb3BwZWRcIixcbiAqICAgICB1dWlkOiBcIk9wZW5GaW4gUE9DXCIsXG4gKiAgICAgdXJsOiBcImh0dHA6Ly9vcGVuZmluLmNvXCIgICAgLy8gVGhlIHVybCBvZiB0aGUgdmlldyBsaW5rZWQgdG8gdGhlIGRyb3BwZWQgdGFiLlxuICogfVxuICogYGBgXG4gKi9cbmNsYXNzIExheW91dCBleHRlbmRzIGJhc2VfMSQ1LkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdHJ1Y3RvcihpZGVudGl0eSwgd2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBMYXppbHkgY29uc3RydWN0ZWQge0BsaW5rIExheW91dEVudGl0aWVzQ2xpZW50fSBib3VuZCB0byB0aGlzIHBsYXRmb3JtJ3MgY2xpZW50IGFuZCBpZGVudGl0eVxuICAgICAgICAgKiBUaGUgY2xpZW50IGlzIGZvciB7QGxpbmsgTGF5b3V0RW50aXRpZXNDb250cm9sbGVyfVxuICAgICAgICAgKi9cbiAgICAgICAgX0xheW91dF9sYXlvdXRDbGllbnQuc2V0KHRoaXMsIG5ldyBsYXp5XzEuTGF6eShhc3luYyAoKSA9PiBsYXlvdXRfZW50aXRpZXNfMS5MYXlvdXROb2RlLm5ld0xheW91dEVudGl0aWVzQ2xpZW50KGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCksIGxheW91dF9jb25zdGFudHNfMSQxLkxBWU9VVF9DT05UUk9MTEVSX0lELCB0aGlzLmlkZW50aXR5KSkpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwbGFjZXMgYSBQbGF0Zm9ybSB3aW5kb3cncyBsYXlvdXQgd2l0aCBhIG5ldyBsYXlvdXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZW1hcmtzIEFueSB2aWV3cyB0aGF0IHdlcmUgaW4gdGhlIG9sZCBsYXlvdXQgYnV0IG5vdCB0aGUgbmV3IGxheW91dCB3aWxsIGJlIGRlc3Ryb3llZC4gVmlld3Mgd2lsbCBiZSBhc3NpZ25lZCBhIHJhbmRvbWx5IGdlbmVyYXRlZCBuYW1lIHRvIGF2b2lkIGNvbGxpc2lvbnMuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSBmaW4ubWUuaWRlbnRpdHk7XG4gICAgICAgICAqIH0gZWxzZSBpZiAoZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICAgICAqIH0gZWxzZSB7XG4gICAgICAgICAqICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluIGEgcGxhdGZvcm0gVmlldyBvciBXaW5kb3cnKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKlxuICAgICAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LndyYXBTeW5jKHdpbmRvd0lkZW50aXR5KTtcbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3QgbmV3TGF5b3V0ID0ge1xuICAgICAgICAgKiAgICAgY29udGVudDogW1xuICAgICAgICAgKiAgICAgICAgIHtcbiAgICAgICAgICogICAgICAgICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgICAgICogICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmV3X2NvbXBvbmVudF9BMScsXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBZmZpbml0eTogJ3BzXzEnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL3d3dy5leGFtcGxlLmNvbSdcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAqICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmV3X2NvbXBvbmVudF9BMicsXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZW1iZWQtd2ViL2NoYXJ0Lmh0bWwnXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgKiAgICAgICAgICAgICBdXG4gICAgICAgICAqICAgICAgICAgfVxuICAgICAgICAgKiAgICAgXVxuICAgICAgICAgKiB9O1xuICAgICAgICAgKlxuICAgICAgICAgKiBsYXlvdXQucmVwbGFjZShuZXdMYXlvdXQpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVwbGFjZSA9IGFzeW5jIChsYXlvdXQpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtcmVwbGFjZScpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlcGxhY2UtbGF5b3V0Jywge1xuICAgICAgICAgICAgICAgIHRhcmdldDogdGhpcy5pZGVudGl0eSxcbiAgICAgICAgICAgICAgICBvcHRzOiB7IGxheW91dCB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGxhY2VzIHRoZSBzcGVjaWZpZWQgdmlldyB3aXRoIGEgdmlldyB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmVtYXJrcyBUaGUgb2xkIHZpZXcgaXMgc3RyaXBwZWQgb2YgaXRzIGxpc3RlbmVycyBhbmQgZWl0aGVyIGNsb3NlZCBvciBhdHRhY2hlZCB0byB0aGUgcHJvdmlkZXIgd2luZG93XG4gICAgICAgICAqIGRlcGVuZGluZyBvbiBgZGV0YWNoT25DbG9zZWAgdmlldyBvcHRpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB2aWV3VG9SZXBsYWNlIElkZW50aXR5IG9mIHRoZSB2aWV3IHRvIGJlIHJlcGxhY2VkXG4gICAgICAgICAqIEBwYXJhbSBuZXdWaWV3IENyZWF0aW9uIG9wdGlvbnMgb2YgdGhlIG5ldyB2aWV3LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBsZXQgY3VycmVudFdpbmRvdztcbiAgICAgICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgKiAgICAgY3VycmVudFdpbmRvdyA9IGZpbi5tZTtcbiAgICAgICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICBjdXJyZW50V2luZG93ID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKTtcbiAgICAgICAgICogfSBlbHNlIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcFN5bmMoY3VycmVudFdpbmRvdy5pZGVudGl0eSk7XG4gICAgICAgICAqIGNvbnN0IHZpZXdUb1JlcGxhY2UgPSAoYXdhaXQgY3VycmVudFdpbmRvdy5nZXRDdXJyZW50Vmlld3MoKSlbMF07XG4gICAgICAgICAqIGNvbnN0IG5ld1ZpZXdDb25maWcgPSB7dXJsOiAnaHR0cHM6Ly9leGFtcGxlLmNvbSd9O1xuICAgICAgICAgKiBhd2FpdCBsYXlvdXQucmVwbGFjZVZpZXcodmlld1RvUmVwbGFjZS5pZGVudGl0eSwgbmV3Vmlld0NvbmZpZyk7XG4gICAgICAgICAqIGBgYFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZXBsYWNlVmlldyA9IGFzeW5jICh2aWV3VG9SZXBsYWNlLCBuZXdWaWV3KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LXJlcGxhY2UtdmlldycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlcGxhY2UtdmlldycsIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3B0czogeyB2aWV3VG9SZXBsYWNlLCBuZXdWaWV3IH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwbGFjZXMgYSBQbGF0Zm9ybSB3aW5kb3cncyBsYXlvdXQgd2l0aCBhIHByZXNldCBsYXlvdXQgYXJyYW5nZW1lbnQgdXNpbmcgdGhlIGV4aXN0aW5nIFZpZXdzIGF0dGFjaGVkIHRvIHRoZSB3aW5kb3cuXG4gICAgICAgICAqIFRoZSBwcmVzZXQgb3B0aW9ucyBhcmUgYGNvbHVtbnNgLCBgZ3JpZGAsIGByb3dzYCwgYW5kIGB0YWJzYC5cbiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgTWFuZGF0b3J5IG9iamVjdCB3aXRoIGBwcmVzZXRUeXBlYCBwcm9wZXJ0eSB0aGF0IHNldHMgd2hpY2ggcHJlc2V0IGxheW91dCBhcnJhbmdlbWVudCB0byB1c2UuXG4gICAgICAgICAqIFRoZSBwcmVzZXQgb3B0aW9ucyBhcmUgYGNvbHVtbnNgLCBgZ3JpZGAsIGByb3dzYCwgYW5kIGB0YWJzYC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogbGV0IHdpbmRvd0lkZW50aXR5O1xuICAgICAgICAgKiBpZiAoZmluLm1lLmlzV2luZG93KSB7XG4gICAgICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IChhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFdpbmRvdygpKS5pZGVudGl0eTtcbiAgICAgICAgICogfSBlbHNlIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcFN5bmMod2luZG93SWRlbnRpdHkpO1xuICAgICAgICAgKiBhd2FpdCBsYXlvdXQuYXBwbHlQcmVzZXQoeyBwcmVzZXRUeXBlOiAnZ3JpZCcgfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIHdhaXQgNSBzZWNvbmRzIHVudGlsIHlvdSBjaGFuZ2UgdGhlIGxheW91dCBmcm9tIGdyaWQgdG8gdGFic1xuICAgICAgICAgKiBhd2FpdCBuZXcgUHJvbWlzZSAocmVzID0+IHNldFRpbWVvdXQocmVzLCA1MDAwKSk7XG4gICAgICAgICAqIGF3YWl0IGxheW91dC5hcHBseVByZXNldCh7IHByZXNldFR5cGU6ICd0YWJzJyB9KTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFwcGx5UHJlc2V0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtYXBwbHktcHJlc2V0JykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5wbGF0Zm9ybS5nZXRDbGllbnQoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgcHJlc2V0VHlwZSB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGlmICghcHJlc2V0VHlwZSB8fCAhKDAsIGNvbW1vbl91dGlsc18xLmlzVmFsaWRQcmVzZXRUeXBlKShwcmVzZXRUeXBlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGFwcGx5IHByZXNldCBsYXlvdXQsIHBsZWFzZSBpbmNsdWRlIGFuIGFwcGxpY2FibGUgcHJlc2V0VHlwZSBwcm9wZXJ0eSBpbiB0aGUgUHJlc2V0TGF5b3V0T3B0aW9ucy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnYXBwbHktcHJlc2V0LWxheW91dCcsIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3B0czogeyBwcmVzZXRUeXBlIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICAgICAgdGhpcy5wbGF0Zm9ybSA9IHRoaXMuZmluLlBsYXRmb3JtLndyYXBTeW5jKHsgdXVpZDogaWRlbnRpdHkudXVpZCB9KTtcbiAgICAgICAgaWYgKGlkZW50aXR5LnV1aWQgPT09IHRoaXMuZmluLm1lLnV1aWQgJiYgaWRlbnRpdHkubmFtZSA9PT0gdGhpcy5maW4ubWUubmFtZSkge1xuICAgICAgICAgICAgdGhpcy5pbml0ID0gdGhpcy5maW4uUGxhdGZvcm0uTGF5b3V0LmluaXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgd2luZG93J3MgbGF5b3V0LiAgUmV0dXJucyB0aGUgc2FtZSBpbmZvcm1hdGlvbiB0aGF0IGlzIHJldHVybmVkIGZvciBhbGwgd2luZG93cyBpbiBnZXRTbmFwc2hvdC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIENhbm5vdCBiZSBjYWxsZWQgZnJvbSBhIFZpZXcuXG4gICAgICpcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gZ2V0IHRoZSBsYXlvdXQgY29uZmlndXJhdGlvbiBvZiB0aGUgY3VycmVudCB3aW5kb3cncyBMYXlvdXQ6XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldENvbmZpZygpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2xheW91dC1nZXQtY29uZmlnJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5wbGF0Zm9ybS5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0LWZyYW1lLXNuYXBzaG90Jywge1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGF0dGFjaGVkIHZpZXdzIGluIGN1cnJlbnQgd2luZG93IGxheW91dC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3Qgdmlld3MgPSBhd2FpdCBsYXlvdXQuZ2V0Q3VycmVudFZpZXdzKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0Q3VycmVudFZpZXdzKCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LWdldC12aWV3cycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHZpZXdJZGVudGl0aWVzID0gYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdnZXQtbGF5b3V0LXZpZXdzJywge1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdmlld0lkZW50aXRpZXMubWFwKChpZGVudGl0eSkgPT4gdGhpcy5maW4uVmlldy53cmFwU3luYyhpZGVudGl0eSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIHRvcCBsZXZlbCBjb250ZW50IGl0ZW0gb2YgdGhlIGxheW91dC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIENhbm5vdCBiZSBjYWxsZWQgZnJvbSBhIHZpZXcuXG4gICAgICpcbiAgICAgKlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGlmICghZmluLm1lLmlzV2luZG93KSB7XG4gICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIEZyb20gdGhlIGxheW91dCB3aW5kb3dcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogLy8gUmV0cmlldmVzIHRoZSBDb2x1bW5PclJvdyBpbnN0YW5jZVxuICAgICAqIGNvbnN0IHJvb3RJdGVtID0gYXdhaXQgbGF5b3V0LmdldFJvb3RJdGVtKCk7XG4gICAgICogY29uc3QgY29udGVudCA9IGF3YWl0IHJvb3RJdGVtLmdldENvbnRlbnQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhgVGhlIHJvb3QgQ29sdW1uT3JSb3cgaW5zdGFuY2UgaGFzICR7Y29udGVudC5sZW5ndGh9IGl0ZW0ocylgKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRSb290SXRlbSgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2xheW91dC1nZXQtcm9vdC1pdGVtJykuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDQodGhpcywgX0xheW91dF9sYXlvdXRDbGllbnQsIFwiZlwiKS5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCByb290ID0gYXdhaXQgY2xpZW50LmdldFJvb3QoJ2xheW91dE5hbWUnIGluIHRoaXMuaWRlbnRpdHkgPyB0aGlzLmlkZW50aXR5IDogdW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIGxheW91dF9lbnRpdGllc18xLkxheW91dE5vZGUuZ2V0RW50aXR5KHJvb3QsIGNsaWVudCk7XG4gICAgfVxufVxuSW5zdGFuY2UkMS5MYXlvdXQgPSBMYXlvdXQ7XG5fTGF5b3V0X2xheW91dENsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDMgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDMgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9MYXlvdXRNb2R1bGVfaW5zdGFuY2VzLCBfTGF5b3V0TW9kdWxlX2xheW91dEluaXRpYWxpemF0aW9uQXR0ZW1wdGVkLCBfTGF5b3V0TW9kdWxlX2xheW91dE1hbmFnZXIsIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweSwgX0xheW91dE1vZHVsZV9nZXRTYWZlTGF5b3V0TWFuYWdlcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuRmFjdG9yeSQyLkxheW91dE1vZHVsZSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSQ0ID0gYmFzZTtcbmNvbnN0IEluc3RhbmNlXzEkMiA9IEluc3RhbmNlJDE7XG5jb25zdCBsYXlvdXRfY29uc3RhbnRzXzEgPSBsYXlvdXRfY29uc3RhbnRzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIExheW91dH0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLlBsYXRmb3JtLkxheW91dGAuXG4gKi9cbmNsYXNzIExheW91dE1vZHVsZSBleHRlbmRzIGJhc2VfMSQ0LkJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcy5hZGQodGhpcyk7XG4gICAgICAgIF9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQuc2V0KHRoaXMsIGZhbHNlKTtcbiAgICAgICAgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLnNldCh0aGlzLCBudWxsKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXRpYWxpemUgdGhlIHdpbmRvdydzIExheW91dC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgTXVzdCBiZSBjYWxsZWQgZnJvbSBhIGN1c3RvbSB3aW5kb3cgdGhhdCBoYXMgYSAnbGF5b3V0JyBvcHRpb24gc2V0IHVwb24gY3JlYXRpb24gb2YgdGhhdCB3aW5kb3cuXG4gICAgICAgICAqIElmIGEgY29udGFpbmVySWQgaXMgbm90IHByb3ZpZGVkLCB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBmaW5kIGFuIGVsZW1lbnQgd2l0aCB0aGUgaWQgYGxheW91dC1jb250YWluZXJgLlxuICAgICAgICAgKiBBIExheW91dCB3aWxsIGVtaXQgZXZlbnRzIGxvY2FsbHkgb24gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgbGF5b3V0LWNvbnRhaW5lci5cbiAgICAgICAgICogSW4gb3JkZXIgdG8gY2FwdHVyZSB0aGUgcmVsZXZhbnQgZXZlbnRzIGR1cmluZyBMYXlvdXQgaW5pdGlhdGlvbiwgc2V0IHVwIHRoZSBsaXN0ZW5lcnMgb24gdGhlIERPTSBlbGVtZW50IHByaW9yIHRvIGNhbGxpbmcgYGluaXRgLlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIExheW91dCBpbml0IG9wdGlvbnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogLy8gSWYgbm8gb3B0aW9ucyBhcmUgaW5jbHVkZWQsIHRoZSBsYXlvdXQgaW4gdGhlIHdpbmRvdyBvcHRpb25zIGlzIGluaXRpYWxpemVkIGluIGFuIGVsZW1lbnQgd2l0aCB0aGUgaWQgYGxheW91dC1jb250YWluZXJgXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5MYXlvdXQuaW5pdCgpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogPGJyPlxuICAgICAgICAgKlxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBjb25zdCBjb250YWluZXJJZCA9ICdteS1jdXN0b20tY29udGFpbmVyLWlkJztcbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3QgbXlMYXlvdXRDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjb250YWluZXJJZCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIG15TGF5b3V0Q29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RhYi1jcmVhdGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICogICAgIGNvbnN0IHsgdGFiU2VsZWN0b3IgfSA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICogICAgIGNvbnN0IHRhYkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJTZWxlY3Rvcik7XG4gICAgICAgICAqICAgICBjb25zdCBleGlzdGluZ0NvbG9yID0gdGFiRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAqICAgICB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgICAgICAqICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICogICAgICAgICB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGV4aXN0aW5nQ29sb3I7XG4gICAgICAgICAqICAgICB9LCAyMDAwKTtcbiAgICAgICAgICogfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIGluaXRpYWxpemUgdGhlIGxheW91dCBpbnRvIGFuIGV4aXN0aW5nIEhUTUwgZWxlbWVudCB3aXRoIHRoZSBkaXYgYG15LWN1c3RvbS1jb250YWluZXItaWRgXG4gICAgICAgICAqIC8vIHRoZSB3aW5kb3cgbXVzdCBoYXZlIGJlZW4gY3JlYXRlZCB3aXRoIGEgbGF5b3V0IGluIGl0cyB3aW5kb3cgb3B0aW9uc1xuICAgICAgICAgKiBjb25zdCBsYXlvdXQgPSBhd2FpdCBmaW4uUGxhdGZvcm0uTGF5b3V0LmluaXQoeyBjb250YWluZXJJZCB9KTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmluaXQgPSBhc3luYyAob3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LWluaXQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMud2lyZS5lbnZpcm9ubWVudC5sYXlvdXRBbGxvd2VkSW5Db250ZXh0KHRoaXMuZmluKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTGF5b3V0LmluaXQgY2FuIG9ubHkgYmUgY2FsbGVkIGZyb20gYSBXaW5kb3cgY29udGV4dC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRJbml0aWFsaXphdGlvbkF0dGVtcHRlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMYXlvdXQuaW5pdCB3YXMgYWxyZWFkeSBjYWxsZWQsIHBsZWFzZSB1c2UgTGF5b3V0LmNyZWF0ZSB0byBhZGQgYWRkaXRpb25hbCBsYXlvdXRzLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMud2lyZS5lbnZpcm9ubWVudC50eXBlID09PSAnb3BlbmZpbicpIHtcbiAgICAgICAgICAgICAgICAvLyBwcmVsb2FkIHRoZSBjbGllbnRcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpLmdldENsaWVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQsIHRydWUsIFwiZlwiKTtcbiAgICAgICAgICAgIC8vIFRPRE86IHJlbmFtZSB0byBjcmVhdGVMYXlvdXRNYW5hZ2VyXG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLCBhd2FpdCB0aGlzLndpcmUuZW52aXJvbm1lbnQuaW5pdExheW91dE1hbmFnZXIodGhpcy5maW4sIHRoaXMud2lyZSwgb3B0aW9ucyksIFwiZlwiKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5hcHBseUxheW91dFNuYXBzaG90KHRoaXMuZmluLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLCBcImZcIiksIG9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgbWVJZGVudGl0eSA9IHsgbmFtZTogdGhpcy5maW4ubWUubmFtZSwgdXVpZDogdGhpcy5maW4ubWUudXVpZCB9O1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmxheW91dE1hbmFnZXJPdmVycmlkZSkge1xuICAgICAgICAgICAgICAgIC8vIENPUkUtMTA4MSB0byBiZSByZW1vdmVkIHdoZW4gd2UgYWN0dWFsbHkgZGVsZXRlIHRoZSBgbGF5b3V0TWFuYWdlcmAgcHJvcFxuICAgICAgICAgICAgICAgIC8vIGluIHNpbmdsZS1sYXlvdXQgY2FzZSwgd2UgcmV0dXJuIHRoZSB1bmRvY3VtZW50ZWQgbGF5b3V0TWFuYWdlciB0eXBlXG4gICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0SWRlbnRpdHkgPSB7IGxheW91dE5hbWU6IGxheW91dF9jb25zdGFudHNfMS5ERUZBVUxUX0xBWU9VVF9LRVksIC4uLm1lSWRlbnRpdHkgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweSwgXCJmXCIpLmNhbGwodGhpcywgbGF5b3V0SWRlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcFN5bmMobWVJZGVudGl0eSk7XG4gICAgICAgIH07XG4gICAgICAgIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweS5zZXQodGhpcywgKGxheW91dElkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSAnW0xheW91dF0gWW91IGFyZSB1c2luZyBhIGRlcHJlY2F0ZWQgcHJvcGVydHkgYGxheW91dE1hbmFnZXJgIC0gaXQgd2lsbCB0aHJvdyBpZiB5b3UgYWNjZXNzIGl0IHN0YXJ0aW5nIGluIHYzNy4nO1xuICAgICAgICAgICAgY29uc3QgbWFuYWdlclByb3h5ID0gbmV3IFByb3h5KHt9LCB7XG4gICAgICAgICAgICAgICAgZ2V0KHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgW0xheW91dC1tZ3ItcHJveHldIGFjY2Vzc2luZyAke2tleS50b1N0cmluZygpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGxheW91dCA9IE9iamVjdC5hc3NpZ24odGhpcy53cmFwU3luYyhsYXlvdXRJZGVudGl0eSksIHsgbGF5b3V0TWFuYWdlcjogbWFuYWdlclByb3h5IH0pO1xuICAgICAgICAgICAgY29uc3QgbGF5b3V0UHJveHkgPSBuZXcgUHJveHkobGF5b3V0LCB7XG4gICAgICAgICAgICAgICAgZ2V0KHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT09ICdsYXlvdXRNYW5hZ2VyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbTGF5b3V0LXByb3h5XSBhY2Nlc3NpbmcgJHtrZXkudG9TdHJpbmcoKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBsYXlvdXRQcm94eTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBsYXlvdXQgbWFuYWdlciBmb3IgdGhlIGN1cnJlbnQgd2luZG93XG4gICAgICAgICAqIEByZXR1cm5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmdldEN1cnJlbnRMYXlvdXRNYW5hZ2VyU3luYyA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9pbnN0YW5jZXMsIFwibVwiLCBfTGF5b3V0TW9kdWxlX2dldFNhZmVMYXlvdXRNYW5hZ2VyKS5jYWxsKHRoaXMsIGBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRMYXlvdXRNYW5hZ2VyU3luYygpYCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY3JlYXRlID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQuY3JlYXRlTGF5b3V0KF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMyh0aGlzLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcywgXCJtXCIsIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIpLmNhbGwodGhpcywgYGZpbi5QbGF0Zm9ybS5MYXlvdXQuY3JlYXRlKClgKSwgb3B0aW9ucyk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZGVzdHJveSA9IGFzeW5jIChsYXlvdXRJZGVudGl0eSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5lbnZpcm9ubWVudC5kZXN0cm95TGF5b3V0KF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMyh0aGlzLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcywgXCJtXCIsIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIpLmNhbGwodGhpcywgYGZpbi5QbGF0Zm9ybS5MYXlvdXQuZGVzdHJveSgpYCksIGxheW91dElkZW50aXR5KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgKiBpZiAoIWZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgbGF5b3V0ID0gYXdhaXQgZmluLlBsYXRmb3JtLkxheW91dC53cmFwKHdpbmRvd0lkZW50aXR5KTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBsYXlvdXRDb25maWcgPSBhd2FpdCBsYXlvdXQuZ2V0Q29uZmlnKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LXdyYXAnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IEluc3RhbmNlXzEkMi5MYXlvdXQoaWRlbnRpdHksIHRoaXMud2lyZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgKiBpZiAoIWZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgbGF5b3V0ID0gZmluLlBsYXRmb3JtLkxheW91dC53cmFwU3luYyh3aW5kb3dJZGVudGl0eSk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDIuTGF5b3V0KGlkZW50aXR5LCB0aGlzLndpcmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgTGF5b3V0IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBXaW5kb3cncyBsYXlvdXQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbGF5b3V0ID0gYXdhaXQgZmluLlBsYXRmb3JtLkxheW91dC5nZXRDdXJyZW50KCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtZ2V0LWN1cnJlbnQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXRoaXMuZmluLm1lLmlzV2luZG93KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IGluIGEgV2luZG93IGNvbnRleHQuICBPbmx5IFdpbmRvd3MgY2FuIGhhdmUgYSBMYXlvdXQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSB0aGlzLmZpbi5tZTtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQsIG5hbWUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2Fubm90IGJlIGNhbGxlZCBmcm9tIGEgdmlldy5cbiAgICAgKlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQuZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBsYXlvdXRDb25maWcgPSBhd2FpdCBsYXlvdXQuZ2V0Q29uZmlnKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q3VycmVudFN5bmMoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtZ2V0LWN1cnJlbnQtc3luYycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghdGhpcy5maW4ubWUuaXNXaW5kb3cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgaW4gYSBXaW5kb3cgY29udGV4dC4gIE9ubHkgV2luZG93cyBjYW4gaGF2ZSBhIExheW91dC4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMuZmluLm1lO1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG4gICAgfVxufVxuRmFjdG9yeSQyLkxheW91dE1vZHVsZSA9IExheW91dE1vZHVsZTtcbl9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2xheW91dE1hbmFnZXIgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2dldExheW91dE1hbmFnZXJTcHkgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcyA9IG5ldyBXZWFrU2V0KCksIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIgPSBmdW5jdGlvbiBfTGF5b3V0TW9kdWxlX2dldFNhZmVMYXlvdXRNYW5hZ2VyKG1ldGhvZCkge1xuICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0TWFuYWdlciwgXCJmXCIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgWW91IG11c3QgY2FsbCBpbml0IGJlZm9yZSB1c2luZyB0aGUgQVBJICR7bWV0aG9kfWApO1xuICAgIH1cbiAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0TWFuYWdlciwgXCJmXCIpO1xufTtcblxuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdC8qKlxuXHQgKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYExheW91dGAgc3Vic2V0IG9mIHRoZSBgUGxhdGZvcm1gIEFQSSAoYGZpbi5QbGF0Zm9ybS5MYXlvdXRgKS5cblx0ICpcblx0ICogKiB7QGxpbmsgTGF5b3V0TW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYExheW91dGAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5QbGF0Zm9ybS5MYXlvdXRgLlxuXHQgKiAqIHtAbGluayBMYXlvdXR9IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIExheW91dCwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlBsYXRmb3JtLkxheW91dC5nZXRDdXJyZW50YC5cblx0ICpcblx0ICogVGhlc2UgYXJlIHNlcGFyYXRlIGNvZGUgZW50aXRpZXMsIGFuZCBhcmUgZG9jdW1lbnRlZCBzZXBhcmF0ZWx5LiBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKlxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnkkMiwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihJbnN0YW5jZSQxLCBleHBvcnRzKTsgXG59IChsYXlvdXQpKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkMywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDMuUGxhdGZvcm1Nb2R1bGUgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEkMyA9IGJhc2U7XG5jb25zdCBJbnN0YW5jZV8xJDEgPSBJbnN0YW5jZSQyO1xuY29uc3QgaW5kZXhfMSQxID0gbGF5b3V0O1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIFBsYXRmb3JtfSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uUGxhdGZvcm1gLlxuICovXG5jbGFzcyBQbGF0Zm9ybU1vZHVsZSBleHRlbmRzIGJhc2VfMSQzLkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIGNoYW5uZWwpIHtcbiAgICAgICAgc3VwZXIod2lyZSk7XG4gICAgICAgIHRoaXMuX2NoYW5uZWwgPSBjaGFubmVsO1xuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogQGRlc2MgTGF5b3V0cyBnaXZlIGFwcCBwcm92aWRlcnMgdGhlIGFiaWxpdHkgdG8gZW1iZWQgbXVsdGlwbGUgdmlld3MgaW4gYSBzaW5nbGUgd2luZG93LiAgVGhlIExheW91dCBuYW1lc3BhY2VcbiAgICAgICAgICogZW5hYmxlcyB0aGUgaW5pdGlhbGl6YXRpb24gYW5kIG1hbmlwdWxhdGlvbiBvZiBhIHdpbmRvdydzIExheW91dC4gIEEgTGF5b3V0IHdpbGxcbiAgICAgICAgICogPGEgaHJlZj1cInR1dG9yaWFsLUxheW91dC5ET01FdmVudHMuaHRtbFwiPmVtaXQgZXZlbnRzIGxvY2FsbHk8L2E+IG9uIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRpbmcgdGhlIGxheW91dC1jb250YWluZXIuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLkxheW91dCA9IG5ldyBpbmRleF8xJDEuTGF5b3V0TW9kdWxlKHRoaXMud2lyZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGEgUGxhdGZvcm0uIE11c3QgYmUgY2FsbGVkIGZyb20gdGhlIFByb3ZpZGVyIHdoZW4gdXNpbmcgYSBjdXN0b20gcHJvdmlkZXIuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBwbGF0Zm9ybSBvcHRpb25zIGluY2x1ZGluZyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZXh0ZW5kIG9yIHJlcGxhY2VcbiAgICAgKiBkZWZhdWx0IFByb3ZpZGVyIGJlaGF2aW9yLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgTXVzdCBiZSBjYWxsZWQgZnJvbSB0aGUgUHJvdmlkZXIgd2hlbiB1c2luZyBhIGN1c3RvbSBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gUHJvdmlkZXIgY29udGV4dFxuICAgICAqIGF3YWl0IGZpbi5QbGF0Zm9ybS5pbml0KCk7XG4gICAgICogLy8gUGxhdGZvcm0gQVBJIGlzIG5vdyBob29rZWQgdXAgYW5kIHdpbmRvd3MgY29udGFpbmVkIGluIHRoZSBtYW5pZmVzdCBzbmFwc2hvdCBhcmUgb3Blbi5cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBQbGF0Zm9ybS5pbml0YCBhY2NlcHRzIGFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCBjYW4gYmUgdXNlZCB0byBleHRlbmQgb3JcbiAgICAgKiByZXBsYWNlIGRlZmF1bHQgUHJvdmlkZXIgYmVoYXZpb3IuIEFzIGFuIGFyZ3VtZW50LCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0aGUgYFByb3ZpZGVyYCBjbGFzcywgd2hpY2ggaXNcbiAgICAgKiB1c2VkIHRvIGhhbmRsZSBQbGF0Zm9ybSBhY3Rpb25zLiBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdpdGggbWV0aG9kcyB0byBoYW5kbGUgUGxhdGZvcm0gQVBJIGFjdGlvbnMuXG4gICAgICogVGhlIHJlY29tbWVuZGVkIGFwcHJvYWNoIGlzIHRvIGV4dGVuZCB0aGUgYFByb3ZpZGVyYCBjbGFzcywgb3ZlcnJpZGluZyB0aGUgbWV0aG9kcyB5b3Ugd2lzaCB0byBhbHRlciwgYW5kIHJldHVybiBhblxuICAgICAqIGluc3RhbmNlIG9mIHlvdXIgc3ViY2xhc3M6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG92ZXJyaWRlQ2FsbGJhY2sgPSBhc3luYyAoUGxhdGZvcm1Qcm92aWRlcikgPT4ge1xuICAgICAqICAgICAvLyBBY3Rpb25zIGNhbiBiZSBwZXJmb3JtZWQgYmVmb3JlIGluaXRpYWxpemF0aW9uLlxuICAgICAqICAgICAvLyBlLmcuIHdlIG1pZ2h0IGF1dGhlbnRpY2F0ZSBhIHVzZXIsIHNldCB1cCBhIENoYW5uZWwsIGV0YyBiZWZvcmUgaW5pdGlhbGl6aW5nIHRoZSBQbGF0Zm9ybS5cbiAgICAgKiAgICAgY29uc3QgeyBtYW5pZmVzdFVybCB9ID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCkuZ2V0SW5mbygpO1xuICAgICAqXG4gICAgICogICAgIC8vIEV4dGVuZCBvciByZXBsYWNlIGRlZmF1bHQgUGxhdGZvcm1Qcm92aWRlciBiZWhhdmlvciBieSBleHRlbmRpbmcgdGhlIFBsYXRmb3JtUHJvdmlkZXIgY2xhc3MuXG4gICAgICogICAgIGNsYXNzIE15T3ZlcnJpZGUgZXh0ZW5kcyBQbGF0Zm9ybVByb3ZpZGVyIHtcbiAgICAgKiAgICAgICAgIC8vIERlZmF1bHQgYmVoYXZpb3IgY2FuIGJlIGNoYW5nZWQgYnkgaW1wbGVtZW50aW5nIG1ldGhvZHMgd2l0aCB0aGUgc2FtZSBuYW1lcyBhcyB0aG9zZSB1c2VkIGJ5IHRoZSBkZWZhdWx0IFBsYXRmb3JtUHJvdmlkZXIuXG4gICAgICogICAgICAgICBhc3luYyBnZXRTbmFwc2hvdCgpIHtcbiAgICAgKiAgICAgICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgZXh0ZW5kaW5nIHRoZSBjbGFzcywgd2UgY2FuIGNhbGwgYHN1cGVyYCBtZXRob2RzIHRvIGFjY2VzcyBkZWZhdWx0IGJlaGF2aW9yLlxuICAgICAqICAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc3VwZXIuZ2V0U25hcHNob3QoKTtcbiAgICAgKiAgICAgICAgICAgICAvLyBCdXQgd2UgY2FuIG1vZGlmeSByZXR1cm4gdmFsdWVzLlxuICAgICAqICAgICAgICAgICAgIHJldHVybiB7IC4uLnNuYXBzaG90LCBhbnN3ZXI6IDQyLCBtYW5pZmVzdFVybCB9O1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICAgICAgYXN5bmMgcmVwbGFjZUxheW91dCh7IG9wdHMsIHRhcmdldCB9KSB7XG4gICAgICogICAgICAgICAgICAgLy8gVG8gZGlzYWJsZSBhbiBBUEkgbWV0aG9kLCBvdmVyd3JpdGUgd2l0aCBhIG5vb3AgZnVuY3Rpb24uXG4gICAgICogICAgICAgICAgICAgcmV0dXJuO1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogICAgIC8vIFJldHVybiBpbnN0YW5jZSB3aXRoIG1ldGhvZHMgdG8gYmUgY29uc3VtZWQgYnkgUGxhdGZvcm0uXG4gICAgICogICAgIC8vIFRoZSByZXR1cm5lZCBvYmplY3QgbXVzdCBpbXBsZW1lbnQgYWxsIG1ldGhvZHMgb2YgdGhlIFBsYXRmb3JtUHJvdmlkZXIgY2xhc3MuXG4gICAgICogICAgIC8vIEJ5IGV4dGVuZGluZyB0aGUgY2xhc3MsIHdlIGNhbiBzaW1wbHkgaW5oZXJpdCBtZXRob2RzIHdlIGRvIG5vdCB3aXNoIHRvIGFsdGVyLlxuICAgICAqICAgICByZXR1cm4gbmV3IE15T3ZlcnJpZGUoKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZmluLlBsYXRmb3JtLmluaXQoe292ZXJyaWRlQ2FsbGJhY2t9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgaW5pdChvcHRpb25zKSB7XG4gICAgICAgIGlmICghZmluLl9faW50ZXJuYWxfLmlzUGxhdGZvcm0gfHwgZmluLm1lLm5hbWUgIT09IGZpbi5tZS51dWlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Zpbi5QbGF0Zm9ybS5pbml0IHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmcm9tIGEgY3VzdG9tIHBsYXRmb3JtIHByb3ZpZGVyIHJ1bm5pbmcgaW4gdGhlIG1haW4gd2luZG93IG9mIHRoZSBhcHBsaWNhdGlvbi4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LmluaXRQbGF0Zm9ybSh0aGlzLmZpbiwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzeW5jaHJvbm91c2x5IHJldHVybnMgYSBQbGF0Zm9ybSBvYmplY3QgdGhhdCByZXByZXNlbnRzIGFuIGV4aXN0aW5nIHBsYXRmb3JtLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHsgaWRlbnRpdHkgfSA9IGZpbi5tZTtcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS53cmFwKGlkZW50aXR5KTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHBsYXRmb3JtLmdldFNuYXBzaG90KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0td3JhcCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMSQxLlBsYXRmb3JtKHsgdXVpZDogaWRlbnRpdHkudXVpZCB9LCB0aGlzLl9jaGFubmVsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleGlzdGluZyBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB7IGlkZW50aXR5IH0gPSBmaW4ubWU7XG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0ud3JhcFN5bmMoaWRlbnRpdHkpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlIHRvIGNvbnRyb2wgbGF5b3V0LCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcGxhdGZvcm0uZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0td3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDEuUGxhdGZvcm0oeyB1dWlkOiBpZGVudGl0eS51dWlkIH0sIHRoaXMuX2NoYW5uZWwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3Qgc25hcHNob3QgPSBhd2FpdCBwbGF0Zm9ybS5nZXRTbmFwc2hvdCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1nZXQtY3VycmVudCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXAoeyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlIHRvIGNvbnRyb2wgbGF5b3V0LCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcGxhdGZvcm0uZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRDdXJyZW50U3luYygpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWdldC1jdXJyZW50LXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQ6IHRoaXMud2lyZS5tZS51dWlkIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuZCBzdGFydHMgYSBQbGF0Zm9ybSBhbmQgcmV0dXJucyBhIHdyYXBwZWQgYW5kIHJ1bm5pbmcgUGxhdGZvcm0gaW5zdGFuY2UuIFRoZSB3cmFwcGVkIFBsYXRmb3JtIG1ldGhvZHMgY2FuXG4gICAgICogYmUgdXNlZCB0byBsYXVuY2ggY29udGVudCBpbnRvIHRoZSBwbGF0Zm9ybS4gIFByb21pc2Ugd2lsbCByZWplY3QgaWYgdGhlIHBsYXRmb3JtIGlzIGFscmVhZHkgcnVubmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5zdGFydCh7XG4gICAgICogICAgICAgICB1dWlkOiAncGxhdGZvcm0tMScsXG4gICAgICogICAgICAgICBhdXRvU2hvdzogZmFsc2UsXG4gICAgICogICAgICAgICBkZWZhdWx0V2luZG93T3B0aW9uczoge1xuICAgICAqICAgICAgICAgICAgIHN0eWxlc2hlZXRVcmw6ICdjc3Mtc2hlZXQtdXJsJyxcbiAgICAgKiAgICAgICAgICAgICBjb3JuZXJSb3VuZGluZzoge1xuICAgICAqICAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwLFxuICAgICAqICAgICAgICAgICAgICAgICB3aWR0aDogMTBcbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqICAgICBjb25zb2xlLmxvZygnUGxhdGZvcm0gaXMgcnVubmluZycsIHBsYXRmb3JtKTtcbiAgICAgKiB9IGNhdGNoKGUpIHtcbiAgICAgKiAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgc3RhcnQocGxhdGZvcm1PcHRpb25zKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1zdGFydCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgdXVpZCB9ID0gcGxhdGZvcm1PcHRpb25zO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSB2YXJpYWJsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLmZpbi5BcHBsaWNhdGlvbi5fY3JlYXRlKHsgLi4ucGxhdGZvcm1PcHRpb25zLCBpc1BsYXRmb3JtQ29udHJvbGxlcjogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgYXBwLm9uY2UoJ3BsYXRmb3JtLWFwaS1yZWFkeScsICgpID0+IHJlc29sdmUodGhpcy53cmFwU3luYyh7IHV1aWQgfSkpKTtcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHVzaW5nIHByaXZhdGUgdmFyaWFibGUuXG4gICAgICAgICAgICAgICAgYXBwLl9ydW4oeyB1dWlkIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgcGxhdGZvcm1zJ3MgbWFuaWZlc3QgYW5kIHJldHVybnMgYSB3cmFwcGVkIGFuZCBydW5uaW5nIFBsYXRmb3JtLiAgSWYgdGhlcmUgaXMgYSBzbmFwc2hvdCBpbiB0aGUgbWFuaWZlc3QsXG4gICAgICogaXQgd2lsbCBiZSBsYXVuY2hlZCBpbnRvIHRoZSBwbGF0Zm9ybS5cbiAgICAgKiBAcGFyYW0gbWFuaWZlc3RVcmwgLSBUaGUgVVJMIG9mIHBsYXRmb3JtJ3MgbWFuaWZlc3QuXG4gICAgICogQHBhcmFtIG9wdHMgLSBQYXJhbWV0ZXJzIHRoYXQgdGhlIFJWTSB3aWxsIHVzZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5zdGFydEZyb21NYW5pZmVzdCgnaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9nb2xkZW4tcHJvdG90eXBlL3B1YmxpYy5qc29uJyk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdQbGF0Zm9ybSBpcyBydW5uaW5nLCB3cmFwcGVkIHBsYXRmb3JtOiAnLCBwbGF0Zm9ybSk7XG4gICAgICogfSBjYXRjaChlKSB7XG4gICAgICogICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICogfVxuICAgICAqIC8vIEZvciBhIGxvY2FsIG1hbmlmZXN0IGZpbGU6XG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uc3RhcnRGcm9tTWFuaWZlc3QoJ2ZpbGU6Ly8vQzovc29tZWZvbGRlci9hcHAuanNvbicpO1xuICAgICAqICAgICBjb25zb2xlLmxvZygnUGxhdGZvcm0gaXMgcnVubmluZywgd3JhcHBlZCBwbGF0Zm9ybTogJywgcGxhdGZvcm0pO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBzdGFydEZyb21NYW5pZmVzdChtYW5pZmVzdFVybCwgb3B0cykge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tc3RhcnQtZnJvbS1tYW5pZmVzdCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSB2YXJpYWJsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLmZpbi5BcHBsaWNhdGlvbi5fY3JlYXRlRnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgYXBwLm9uY2UoJ3BsYXRmb3JtLWFwaS1yZWFkeScsICgpID0+IHJlc29sdmUodGhpcy53cmFwU3luYyh7IHV1aWQ6IGFwcC5pZGVudGl0eS51dWlkIH0pKSk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB1c2luZyBwcml2YXRlIG1ldGhvZCB3aXRob3V0IHdhcm5pbmcuXG4gICAgICAgICAgICAgICAgYXBwLl9ydW4ob3B0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuRmFjdG9yeSQzLlBsYXRmb3JtTW9kdWxlID0gUGxhdGZvcm1Nb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgUGxhdGZvcm1gIEFQSSAoYGZpbi5QbGF0Zm9ybWApXG5cdCAqXG5cdCAqICoge0BsaW5rIFBsYXRmb3JtTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYFBsYXRmb3JtYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLlBsYXRmb3JtYC5cblx0ICogKiB7QGxpbmsgUGxhdGZvcm19IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIFBsYXRmb3JtLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudGAuXG5cdCAqXG5cdCAqIFRoZXNlIGFyZSBzZXBhcmF0ZSBjb2RlIGVudGl0aWVzLCBhbmQgYXJlIGRvY3VtZW50ZWQgc2VwYXJhdGVseS4gIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdCAqL1xuXHRfX2V4cG9ydFN0YXIoRmFjdG9yeSQzLCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKEluc3RhbmNlJDIsIGV4cG9ydHMpOyBcbn0gKHBsYXRmb3JtKSk7XG5cbnZhciBtZSA9IHt9O1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLmdldE1lID0gZXhwb3J0cy5nZXRCYXNlTWUgPSBleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlID0gdm9pZCAwO1xuXHRjb25zdCB2aWV3XzEgPSByZXF1aXJlVmlldygpO1xuXHRjb25zdCBmcmFtZV8xID0gZnJhbWU7XG5cdGNvbnN0IHdpbmRvd18xID0gcmVxdWlyZVdpbmRvdygpO1xuXHRjb25zdCBleHRlcm5hbF9hcHBsaWNhdGlvbl8xID0gZXh0ZXJuYWxBcHBsaWNhdGlvbjtcblx0ZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSA9ICdZb3UgYXJlIG5vdCBydW5uaW5nIGluIE9wZW5GaW4uJztcblx0ZnVuY3Rpb24gZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpIHtcblx0ICAgIGNvbnN0IGVudGl0eVR5cGVIZWxwZXJzID0ge1xuXHQgICAgICAgIGlzVmlldzogZW50aXR5VHlwZSA9PT0gJ3ZpZXcnLFxuXHQgICAgICAgIGlzV2luZG93OiBlbnRpdHlUeXBlID09PSAnd2luZG93Jyxcblx0ICAgICAgICBpc0ZyYW1lOiBlbnRpdHlUeXBlID09PSAnaWZyYW1lJyxcblx0ICAgICAgICBpc0V4dGVybmFsOiBlbnRpdHlUeXBlID09PSAnZXh0ZXJuYWwgY29ubmVjdGlvbidcblx0ICAgIH07XG5cdCAgICByZXR1cm4geyAuLi5lbnRpdHlUeXBlSGVscGVycywgdXVpZCwgbmFtZSwgZW50aXR5VHlwZSB9O1xuXHR9XG5cdGV4cG9ydHMuZ2V0QmFzZU1lID0gZ2V0QmFzZU1lO1xuXHQvLyBXZSBuZWVkIHRvIGRvIGEgbG90IG9mIGNhc3RpbmcgYXMgdW5rbm93biBoZXJlIGJlY2F1c2UgdGhlIGNvbXBpbGVyIGdldCdzIGNvbmZ1c2VkIGFib3V0IG1hdGNoaW5nIHR5cGVzLiBXaGF0IG1hdHRlcnMgaXMgdGhhdCBpdCB3b3JrcyBvbiB0aGUgb3V0c2lkZVxuXHRmdW5jdGlvbiBnZXRNZSh3aXJlKSB7XG5cdCAgICBjb25zdCB7IHV1aWQsIG5hbWUsIGVudGl0eVR5cGUgfSA9IHdpcmUubWU7XG5cdCAgICBjb25zdCB1bnN1cHBvcnRlZEludGVyb3AgPSB7XG5cdCAgICAgICAgc2V0Q29udGV4dCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgYWRkQ29udGV4dEhhbmRsZXIoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldENvbnRleHRHcm91cHMoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGpvaW5Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHJlbW92ZUZyb21Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBjb25zdCBmYWxsYmFja0Vycm9yTWVzc2FnZSA9ICdJbnRlcm9wIEFQSSBoYXMgbm90IGJlZW4gaW5zdGFudGlhdGVkLiBFaXRoZXIgY29ubmVjdGlvbiBoYXMgZmFpbGVkIG9yIHlvdSBoYXZlIG5vdCBkZWNsYXJlZCBpbnRlcm9wIGluIHlvdXIgY29uZmlnLic7XG5cdCAgICBjb25zdCBmYWxsYmFja0ludGVyb3AgPSB7XG5cdCAgICAgICAgc2V0Q29udGV4dCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGFkZENvbnRleHRIYW5kbGVyKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0Q29udGV4dEdyb3VwcygpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGpvaW5Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihmYWxsYmFja0Vycm9yTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICByZW1vdmVGcm9tQ29udGV4dEdyb3VwKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgY29uc3QgdW5zdXBwb3J0ZWRFdmVudEJhc2UgPSB7XG5cdCAgICAgICAgZXZlbnROYW1lczogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBlbWl0OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGxpc3RlbmVyczogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBsaXN0ZW5lckNvdW50OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGFkZExpc3RlbmVyOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uY2U6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcHJlcGVuZExpc3RlbmVyOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHByZXBlbmRPbmNlTGlzdGVuZXI6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcmVtb3ZlTGlzdGVuZXI6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcmVtb3ZlQWxsTGlzdGVuZXJzOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgc3dpdGNoIChlbnRpdHlUeXBlKSB7XG5cdCAgICAgICAgY2FzZSAndmlldyc6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB2aWV3XzEuVmlldyh3aXJlLCB7IHV1aWQsIG5hbWUgfSksIGdldEJhc2VNZShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKSwge1xuXHQgICAgICAgICAgICAgICAgaW50ZXJvcDogZmFsbGJhY2tJbnRlcm9wLFxuXHQgICAgICAgICAgICAgICAgaXNPcGVuRmluOiB0cnVlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIGNhc2UgJ3dpbmRvdyc6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB3aW5kb3dfMS5fV2luZG93KHdpcmUsIHsgdXVpZCwgbmFtZSB9KSwgZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpLCB7XG5cdCAgICAgICAgICAgICAgICBpbnRlcm9wOiBmYWxsYmFja0ludGVyb3AsXG5cdCAgICAgICAgICAgICAgICBpc09wZW5GaW46IHRydWVcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgY2FzZSAnaWZyYW1lJzpcblx0ICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IGZyYW1lXzEuX0ZyYW1lKHdpcmUsIHsgdXVpZCwgbmFtZSB9KSwgZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpLCB7XG5cdCAgICAgICAgICAgICAgICBpbnRlcm9wOiBmYWxsYmFja0ludGVyb3AsXG5cdCAgICAgICAgICAgICAgICBpc09wZW5GaW46IHRydWVcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgY2FzZSAnZXh0ZXJuYWwgY29ubmVjdGlvbic6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBleHRlcm5hbF9hcHBsaWNhdGlvbl8xLkV4dGVybmFsQXBwbGljYXRpb24od2lyZSwgeyB1dWlkIH0pLCBnZXRCYXNlTWUoZW50aXR5VHlwZSwgdXVpZCwgbmFtZSksIHtcblx0ICAgICAgICAgICAgICAgIGludGVyb3A6IGZhbGxiYWNrSW50ZXJvcCxcblx0ICAgICAgICAgICAgICAgIGlzT3BlbkZpbjogZmFsc2Vcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgZGVmYXVsdDpcblx0ICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgICAgIC4uLmdldEJhc2VNZShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKSxcblx0ICAgICAgICAgICAgICAgIC4uLnVuc3VwcG9ydGVkRXZlbnRCYXNlLFxuXHQgICAgICAgICAgICAgICAgaW50ZXJvcDogdW5zdXBwb3J0ZWRJbnRlcm9wLFxuXHQgICAgICAgICAgICAgICAgaXNPcGVuRmluOiBmYWxzZVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgfVxuXHR9XG5cdGV4cG9ydHMuZ2V0TWUgPSBnZXRNZTsgXG59IChtZSkpO1xuXG52YXIgaW50ZXJvcCA9IHt9O1xuXG52YXIgRmFjdG9yeSQxID0ge307XG5cbnZhciBpbmFjY2Vzc2libGVPYmplY3QgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGluYWNjZXNzaWJsZU9iamVjdCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlV2FybmluZ09iamVjdCA9IGluYWNjZXNzaWJsZU9iamVjdC5jcmVhdGVVbnVzYWJsZU9iamVjdCA9IHZvaWQgMDtcbmZ1bmN0aW9uIGNyZWF0ZVVudXNhYmxlT2JqZWN0KG1lc3NhZ2UpIHtcbiAgICBjb25zdCBoYW5kbGUgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJveHkoe30sIHtcbiAgICAgICAgYXBwbHk6IGhhbmRsZSxcbiAgICAgICAgY29uc3RydWN0OiBoYW5kbGUsXG4gICAgICAgIGRlZmluZVByb3BlcnR5OiBoYW5kbGUsXG4gICAgICAgIGRlbGV0ZVByb3BlcnR5OiBoYW5kbGUsXG4gICAgICAgIGdldDogaGFuZGxlLFxuICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6IGhhbmRsZSxcbiAgICAgICAgZ2V0UHJvdG90eXBlT2Y6IGhhbmRsZSxcbiAgICAgICAgaGFzOiBoYW5kbGUsXG4gICAgICAgIGlzRXh0ZW5zaWJsZTogaGFuZGxlLFxuICAgICAgICBvd25LZXlzOiBoYW5kbGUsXG4gICAgICAgIHByZXZlbnRFeHRlbnNpb25zOiBoYW5kbGUsXG4gICAgICAgIHNldDogaGFuZGxlLFxuICAgICAgICBzZXRQcm90b3R5cGVPZjogaGFuZGxlXG4gICAgfSk7XG59XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlVW51c2FibGVPYmplY3QgPSBjcmVhdGVVbnVzYWJsZU9iamVjdDtcbmZ1bmN0aW9uIGNyZWF0ZVdhcm5pbmdPYmplY3QobWVzc2FnZSwgb2JqKSB7XG4gICAgcmV0dXJuIG5ldyBQcm94eShvYmosIHtcbiAgICAgICAgZ2V0OiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LnNldCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb3duS2V5czogKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4obWVzc2FnZSk7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlV2FybmluZ09iamVjdCA9IGNyZWF0ZVdhcm5pbmdPYmplY3Q7XG5cbnZhciBJbnRlcm9wQnJva2VyID0ge307XG5cbnZhciBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyID0ge307XG5cbnZhciBoYXNSZXF1aXJlZFNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXI7XG5cbmZ1bmN0aW9uIHJlcXVpcmVTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcikgcmV0dXJuIFNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXI7XG5cdGhhc1JlcXVpcmVkU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0Y29uc3QgXzEgPSByZXF1aXJlSW50ZXJvcCgpO1xuXHRsZXQgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciQxID0gY2xhc3MgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciB7XG5cdCAgICBjb25zdHJ1Y3Rvcihwcm92aWRlciwgaWQpIHtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7XG5cdCAgICAgICAgdGhpcy5pZCA9IGlkO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHQgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0R3JvdXBNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5jbGllbnRzID0gbmV3IE1hcCgpO1xuXHQgICAgICAgIHRoaXMucmVnaXN0ZXJMaXN0ZW5lcnMoKTtcblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoYHNlc3Npb25Db250ZXh0R3JvdXA6Z2V0Q29udGV4dC0ke3RoaXMuaWR9YCwgdGhpcy5nZXRDdXJyZW50Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKGBzZXNzaW9uQ29udGV4dEdyb3VwOnNldENvbnRleHQtJHt0aGlzLmlkfWAsIHRoaXMuc2V0Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKGBzZXNzaW9uQ29udGV4dEdyb3VwOmhhbmRsZXJBZGRlZC0ke3RoaXMuaWR9YCwgdGhpcy5oYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcihgc2Vzc2lvbkNvbnRleHRHcm91cDpoYW5kbGVyUmVtb3ZlZC0ke3RoaXMuaWR9YCwgdGhpcy5oYW5kbGVyUmVtb3ZlZC5iaW5kKHRoaXMpKTtcblx0ICAgIH1cblx0ICAgIGdldEN1cnJlbnRDb250ZXh0KHBheWxvYWQpIHtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC50eXBlID8gdGhpcy5jb250ZXh0R3JvdXBNYXAuZ2V0KHBheWxvYWQudHlwZSkgOiB0aGlzLmxhc3RDb250ZXh0O1xuXHQgICAgfVxuXHQgICAgc2V0Q29udGV4dChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgY29udGV4dCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQgPSBfMS5JbnRlcm9wQnJva2VyLmNoZWNrQ29udGV4dEludGVncml0eShjb250ZXh0KTtcblx0ICAgICAgICBpZiAoY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0LmlzVmFsaWQgPT09IGZhbHNlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHNldCBDb250ZXh0IC0gYmFkIENvbnRleHQuIFJlYXNvbjogJHtjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQucmVhc29ufS4gQ29udGV4dDogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkbid0IGdldCBoaXQuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0gJHtjbGllbnRJZGVudGl0eS5uYW1lfSBub3QgaW4gU2Vzc2lvbiBDbGllbnQgU3RhdGUgTWFwYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vIHNldCB0aGUgY29udGV4dFxuXHQgICAgICAgIHRoaXMuY29udGV4dEdyb3VwTWFwLnNldChjb250ZXh0LnR5cGUsIGNvbnRleHQpO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHQgPSBjb250ZXh0O1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlcyA9IEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKTtcblx0ICAgICAgICBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZXMuZm9yRWFjaCgoY2xpZW50KSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0ICAgICAgICAgICAgY2xpZW50LmNvbnRleHRIYW5kbGVycy5nZXQoY29udGV4dC50eXBlKT8uZm9yRWFjaCgoaGFuZGxlcklkKSA9PiB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudC5jbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGlmIChjbGllbnQuZ2xvYmFsSGFuZGxlcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnQuY2xpZW50SWRlbnRpdHksIGNsaWVudC5nbG9iYWxIYW5kbGVyLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChpZC5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIGFzeW5jIGhhbmRsZXJBZGRlZChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGlmICghY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBJZGVudGl0eTogJHtjbGllbnRJZGVudGl0eS51dWlkfSAke2NsaWVudElkZW50aXR5Lm5hbWV9IG5vdCBpbiBDbGllbnQgU3RhdGUgTWFwYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50SGFuZGxlckxpc3QgPSBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZS5jb250ZXh0SGFuZGxlcnMuZ2V0KGNvbnRleHRUeXBlKSB8fCBbXTtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEhhbmRsZXJzLnNldChjb250ZXh0VHlwZSwgWy4uLmN1cnJlbnRIYW5kbGVyTGlzdCwgaGFuZGxlcklkXSk7XG5cdCAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gdGhpcy5jb250ZXh0R3JvdXBNYXAuZ2V0KGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250ZXh0KSB7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGN1cnJlbnRDb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuZ2xvYmFsSGFuZGxlciA9IGhhbmRsZXJJZDtcblx0ICAgICAgICAgICAgY29uc3QgZ2xvYmFsRGlzcGF0Y2hQcm9taXNlcyA9IFsuLi50aGlzLmNvbnRleHRHcm91cE1hcC5rZXlzKCldLm1hcChhc3luYyAoY3VycmVudENvbnRleHRUeXBlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dCA9IHRoaXMuY29udGV4dEdyb3VwTWFwLmdldChjdXJyZW50Q29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250ZXh0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjdXJyZW50Q29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChnbG9iYWxEaXNwYXRjaFByb21pc2VzKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBoYW5kbGVyUmVtb3ZlZChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCk7XG5cdCAgICAgICAgaWYgKGNsaWVudCkge1xuXHQgICAgICAgICAgICBBcnJheS5mcm9tKGNsaWVudC5jb250ZXh0SGFuZGxlcnMpLmZvckVhY2goKFssIGhhbmRsZXJzXSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBoYW5kbGVycy5pbmRleE9mKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBpZiAoY2xpZW50Lmdsb2JhbEhhbmRsZXIgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50Lmdsb2JhbEhhbmRsZXIgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybihgVHJ5aW5nIHRvIHJlbW92ZSBhIGhhbmRsZXIgZnJvbSBhIGNsaWVudCB0aGF0IGlzbid0IG1hcHBlZC4gaGFuZGxlcklkOiAke2hhbmRsZXJJZH0uIGNsaWVudElkZW50aXR5OiAke2NsaWVudElkZW50aXR5fWApO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTmV3Q2xpZW50KGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlID0ge1xuXHQgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzOiBuZXcgTWFwKCksXG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eSxcblx0ICAgICAgICAgICAgICAgIGdsb2JhbEhhbmRsZXI6IHVuZGVmaW5lZFxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB0aGlzLmNsaWVudHMuc2V0KGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQsIGNsaWVudFN1YnNjcmlwdGlvblN0YXRlKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBvbkRpc2Nvbm5lY3Rpb24oY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpO1xuXHQgICAgfVxuXHR9O1xuXHRTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyLmRlZmF1bHQgPSBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyJDE7XG5cdHJldHVybiBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyO1xufVxuXG52YXIgdXRpbHMkMyA9IHt9O1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLndyYXBJbnRlbnRIYW5kbGVyID0gZXhwb3J0cy5CUk9LRVJfRVJST1JTID0gZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZyA9IGV4cG9ydHMuZ2VuZXJhdGVPdmVycmlkZUVycm9yID0gZXhwb3J0cy53cmFwQ29udGV4dEhhbmRsZXIgPSBleHBvcnRzLndyYXBJblRyeUNhdGNoID0gZXhwb3J0cy5nZW5lcmF0ZUlkID0gdm9pZCAwO1xuXHRjb25zdCBnZW5lcmF0ZUlkID0gKCkgPT4gYCR7TWF0aC5yYW5kb20oKX0ke0RhdGUubm93KCl9YDtcblx0ZXhwb3J0cy5nZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZDtcblx0Y29uc3Qgd3JhcEluVHJ5Q2F0Y2ggPSAoZiwgcHJlZml4KSA9PiAoLi4uYXJncykgPT4ge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICByZXR1cm4gZiguLi5hcmdzKTtcblx0ICAgIH1cblx0ICAgIGNhdGNoIChlKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKChwcmVmaXggfHwgJycpICsgZSk7XG5cdCAgICB9XG5cdH07XG5cdGV4cG9ydHMud3JhcEluVHJ5Q2F0Y2ggPSB3cmFwSW5UcnlDYXRjaDtcblx0Y29uc3Qgd3JhcENvbnRleHRIYW5kbGVyID0gKGhhbmRsZXIsIGhhbmRsZXJJZCkgPT4ge1xuXHQgICAgcmV0dXJuIGFzeW5jIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgaGFuZGxlcihjb250ZXh0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHRocm93biBieSBoYW5kbGVyICR7aGFuZGxlcklkfSBmb3IgY29udGV4dCB0eXBlICR7Y29udGV4dC50eXBlfTogJHtlcnJvcn1gKTtcblx0ICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy53cmFwQ29udGV4dEhhbmRsZXIgPSB3cmFwQ29udGV4dEhhbmRsZXI7XG5cdGNvbnN0IGdlbmVyYXRlT3ZlcnJpZGVFcnJvciA9IChjbGllbnRBcGksIGJyb2tlckFwaSkgPT4ge1xuXHQgICAgcmV0dXJuIGBZb3UgaGF2ZSB0cmllZCB0byB0byB1c2UgJHtjbGllbnRBcGl9IGJ1dCAke2Jyb2tlckFwaX0gaGFzIG5vdCBiZWVuIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3AgQnJva2VyLiBQbGVhc2Ugb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbi4gUmVmZXIgdG8gb3VyIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mby5gO1xuXHR9O1xuXHRleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvciA9IGdlbmVyYXRlT3ZlcnJpZGVFcnJvcjtcblx0Y29uc3QgZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcgPSAoZmRjM0NsaWVudEFwaSwgYnJva2VyQXBpLCBpZGVudGl0eSwgaW50ZXJvcENsaWVudEFwaSkgPT4ge1xuXHQgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSBpZGVudGl0eTtcblx0ICAgIGNvbnN0IG1lc3NhZ2UgPSBpbnRlcm9wQ2xpZW50QXBpXG5cdCAgICAgICAgPyBgRW50aXR5IHdpdGggaWRlbnRpdHk6ICR7dXVpZH0vJHtuYW1lfSBoYXMgY2FsbGVkICR7aW50ZXJvcENsaWVudEFwaX0gb3IgJHtmZGMzQ2xpZW50QXBpfSBidXQgJHticm9rZXJBcGl9IGhhcyBub3QgYmVlbiBvdmVycmlkZGVuLmBcblx0ICAgICAgICA6IGBFbnRpdHkgd2l0aCBpZGVudGl0eTogJHt1dWlkfS8ke25hbWV9IGhhcyBjYWxsZWQgJHtmZGMzQ2xpZW50QXBpfSBidXQgJHticm9rZXJBcGl9IGhhcyBub3QgYmVlbiBvdmVycmlkZGVuLmA7XG5cdCAgICByZXR1cm4gbWVzc2FnZTtcblx0fTtcblx0ZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZyA9IGdlbmVyYXRlT3ZlcnJpZGVXYXJuaW5nO1xuXHRleHBvcnRzLkJST0tFUl9FUlJPUlMgPSB7XG5cdCAgICBmaXJlSW50ZW50OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdmaXJlSW50ZW50JywgJ2hhbmRsZUZpcmVkSW50ZW50JyksXG5cdCAgICBmaXJlSW50ZW50Rm9yQ29udGV4dDogKDAsIGV4cG9ydHMuZ2VuZXJhdGVPdmVycmlkZUVycm9yKSgnZmlyZUludGVudEZvckNvbnRleHQnLCAnaGFuZGxlRmlyZWRJbnRlbnRGb3JDb250ZXh0JyksXG5cdCAgICBnZXRJbmZvRm9ySW50ZW50OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdnZXRJbmZvRm9ySW50ZW50JywgJ2hhbmRsZUluZm9Gb3JJbnRlbnQnKSxcblx0ICAgIGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdnZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcsICdoYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcpLFxuXHQgICAgam9pblNlc3Npb25Db250ZXh0R3JvdXBXaXRoSm9pbkNvbnRleHRHcm91cDogJ1RoZSBDb250ZXh0IEdyb3VwIHlvdSBoYXZlIHRyaWVkIHRvIGpvaW4gaXMgYSBTZXNzaW9uIENvbnRleHQgR3JvdXAuIEN1c3RvbSBDb250ZXh0IEdyb3VwcyBjYW4gb25seSBiZSBkZWZpbmVkIGJ5IHRoZSBJbnRlcm9wIEJyb2tlciB0aHJvdWdoIGNvZGUgb3IgbWFuaWZlc3QgY29uZmlndXJhdGlvbi4gUGxlYXNlIHVzZSBqb2luU2Vzc2lvbkNvbnRleHRHcm91cC4nLFxuXHQgICAgZmRjM09wZW46ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMub3BlbicsICdmZGMzSGFuZGxlT3BlbicpLFxuXHQgICAgZmRjM0ZpbmRJbnN0YW5jZXM6ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMuZmluZEluc3RhbmNlcycsICdmZGMzSGFuZGxlRmluZEluc3RhbmNlcycpLFxuXHQgICAgZmRjM0dldEFwcE1ldGFkYXRhOiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdmZGMzLmdldEFwcE1ldGFkYXRhJywgJ2ZkYzNIYW5kbGVHZXRBcHBNZXRhZGF0YScpLFxuXHQgICAgZmRjM0dldEluZm86ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMuZ2V0SW5mbycsICdmZGMzSGFuZGxlR2V0SW5mbycpXG5cdH07XG5cdGNvbnN0IHdyYXBJbnRlbnRIYW5kbGVyID0gKGhhbmRsZXIsIGhhbmRsZXJJZCkgPT4ge1xuXHQgICAgcmV0dXJuIGFzeW5jIChpbnRlbnQpID0+IHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gaGFuZGxlcihpbnRlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgdGhyb3duIGJ5IGhhbmRsZXIgJHtoYW5kbGVySWR9OiAke2Vycm9yfWApO1xuXHQgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHR9O1xuXHRleHBvcnRzLndyYXBJbnRlbnRIYW5kbGVyID0gd3JhcEludGVudEhhbmRsZXI7IFxufSAodXRpbHMkMykpO1xuXG52YXIgUHJpdmF0ZUNoYW5uZWxQcm92aWRlciA9IHt9O1xuXG52YXIgaGFzUmVxdWlyZWRQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xuXG5mdW5jdGlvbiByZXF1aXJlUHJpdmF0ZUNoYW5uZWxQcm92aWRlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFByaXZhdGVDaGFubmVsUHJvdmlkZXIpIHJldHVybiBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xuXHRoYXNSZXF1aXJlZFByaXZhdGVDaGFubmVsUHJvdmlkZXIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoUHJpdmF0ZUNoYW5uZWxQcm92aWRlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFByaXZhdGVDaGFubmVsUHJvdmlkZXIuUHJpdmF0ZUNoYW5uZWxQcm92aWRlciA9IHZvaWQgMDtcblx0Y29uc3QgSW50ZXJvcEJyb2tlcl8xID0gcmVxdWlyZUludGVyb3BCcm9rZXIoKTtcblx0bGV0IFByaXZhdGVDaGFubmVsUHJvdmlkZXIkMSA9IGNsYXNzIFByaXZhdGVDaGFubmVsUHJvdmlkZXIge1xuXHQgICAgY29uc3RydWN0b3IocHJvdmlkZXIsIGlkKSB7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyO1xuXHQgICAgICAgIHRoaXMuaWQgPSBpZDtcblx0ICAgICAgICB0aGlzLmNsaWVudHMgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5yZWdpc3Rlckxpc3RlbmVycygpO1xuXHQgICAgICAgIHRoaXMuY29udGV4dEJ5Q29udGV4dFR5cGUgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5sYXN0Q29udGV4dCA9IHVuZGVmaW5lZDtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLm9uQ29ubmVjdGlvbigoY2xpZW50SWRlbnRpdHkpID0+IHRoaXMucmVnaXN0ZXJOZXdDbGllbnQoY2xpZW50SWRlbnRpdHkpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLm9uRGlzY29ubmVjdGlvbihhc3luYyAoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBlbmRwb2ludElkIH0gPSBjbGllbnRJZGVudGl0eTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuY2xpZW50cy5oYXMoZW5kcG9pbnRJZCkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ2xpZW50RGlzY29ubmVjdGluZyhjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3ZpZGVyLmdldEFsbENsaWVudEluZm8oKSkubGVuZ3RoID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRlc3Ryb3koKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChpZC5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2Jyb2FkY2FzdCcsIHRoaXMuYnJvYWRjYXN0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2dldEN1cnJlbnRDb250ZXh0JywgdGhpcy5nZXRDdXJyZW50Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKCdjb250ZXh0SGFuZGxlckFkZGVkJywgdGhpcy5jb250ZXh0SGFuZGxlckFkZGVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2NvbnRleHRIYW5kbGVyUmVtb3ZlZCcsIHRoaXMuY29udGV4dEhhbmRsZXJSZW1vdmVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ25vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQnLCB0aGlzLm5vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25BZGRDb250ZXh0SGFuZGxlckFkZGVkJywgdGhpcy5vbkFkZENvbnRleHRIYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25EaXNjb25uZWN0SGFuZGxlckFkZGVkJywgdGhpcy5vbkRpc2Nvbm5lY3RIYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZCcsIHRoaXMub25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKCdjbGllbnREaXNjb25uZWN0aW5nJywgKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSA9PiB7XG5cdCAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2xpZW50RGlzY29ubmVjdGluZyhjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBicm9hZGNhc3QocGF5bG9hZCwgYnJvYWRjYXN0ZXJDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgY29udGV4dCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBicm9hZGNhc3RlckNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShicm9hZGNhc3RlckNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWJyb2FkY2FzdGVyQ2xpZW50U3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBJZGVudGl0eTogJHticm9hZGNhc3RlckNsaWVudElkZW50aXR5LnV1aWR9ICR7YnJvYWRjYXN0ZXJDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBicm9hZGNhc3QsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0ID0gSW50ZXJvcEJyb2tlcl8xLkludGVyb3BCcm9rZXIuY2hlY2tDb250ZXh0SW50ZWdyaXR5KGNvbnRleHQpO1xuXHQgICAgICAgIGlmIChjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQuaXNWYWxpZCA9PT0gZmFsc2UpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gYnJvYWRjYXN0IC0gYmFkIENvbnRleHQuIFJlYXNvbjogJHtjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQucmVhc29ufS4gQ29udGV4dDogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5jb250ZXh0QnlDb250ZXh0VHlwZS5zZXQoY29udGV4dC50eXBlLCBjb250ZXh0KTtcblx0ICAgICAgICB0aGlzLmxhc3RDb250ZXh0ID0gY29udGV4dDtcblx0ICAgICAgICBBcnJheS5mcm9tKHRoaXMuY2xpZW50cy52YWx1ZXMoKSkuZm9yRWFjaCgoY3VyckNsaWVudFN0YXRlKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJJZHNGb3JDb250ZXh0VHlwZSA9IGN1cnJDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMuZ2V0KGNvbnRleHQudHlwZSk7XG5cdCAgICAgICAgICAgIGlmIChoYW5kbGVySWRzRm9yQ29udGV4dFR5cGUpIHtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJZHNGb3JDb250ZXh0VHlwZS5mb3JFYWNoKChoYW5kbGVySWQpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGN1cnJDbGllbnRTdGF0ZS5jbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChjdXJyQ2xpZW50U3RhdGUuZ2xvYmFsSGFuZGxlcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjdXJyQ2xpZW50U3RhdGUuY2xpZW50SWRlbnRpdHksIGN1cnJDbGllbnRTdGF0ZS5nbG9iYWxIYW5kbGVyLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q3VycmVudENvbnRleHQocGF5bG9hZCwgc2VuZGVyQ2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB7IGNvbnRleHRUeXBlIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShzZW5kZXJDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKCFjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke3NlbmRlckNsaWVudElkZW50aXR5LnV1aWR9ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkubmFtZX0sIHRyaWVkIHRvIGNhbGwgZ2V0Q3VycmVudENvbnRleHQsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGNvbnRleHRUeXBlICE9PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSB0aGlzLmNvbnRleHRCeUNvbnRleHRUeXBlLmdldChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgIGlmIChjdXJyZW50Q29udGV4dClcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dDtcblx0ICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLmxhc3RDb250ZXh0ID8gdGhpcy5sYXN0Q29udGV4dCA6IG51bGw7XG5cdCAgICB9XG5cdCAgICBjb250ZXh0SGFuZGxlckFkZGVkKHBheWxvYWQsIHNlbmRlckNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IHNlbmRlckNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShzZW5kZXJDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKCFzZW5kZXJDbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke3NlbmRlckNsaWVudElkZW50aXR5LnV1aWR9ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkubmFtZX0sIHRyaWVkIHRvIGNhbGwgYWRkQ29udGV4dExpc3RlbmVyLCBpcyBub3QgY29ubmVjdGVkIHRvIHRoaXMgUHJpdmF0ZSBDaGFubmVsYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50SGFuZGxlcnNMaXN0ID0gc2VuZGVyQ2xpZW50U3RhdGUuaGFuZGxlcklkc0J5Q29udGV4dFR5cGVzLmdldChjb250ZXh0VHlwZSkgfHwgW107XG5cdCAgICAgICAgICAgIHNlbmRlckNsaWVudFN0YXRlLmhhbmRsZXJJZHNCeUNvbnRleHRUeXBlcy5zZXQoY29udGV4dFR5cGUsIFsuLi5jdXJyZW50SGFuZGxlcnNMaXN0LCBoYW5kbGVySWRdKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIHNlbmRlckNsaWVudFN0YXRlLmdsb2JhbEhhbmRsZXIgPSBoYW5kbGVySWQ7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKS5mb3JFYWNoKChjdXJyQ2xpZW50U3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgaWYgKGN1cnJDbGllbnRTdGF0ZS5jbGllbnRJZGVudGl0eS5lbmRwb2ludElkICE9PSBzZW5kZXJDbGllbnRJZGVudGl0eS5lbmRwb2ludElkICYmXG5cdCAgICAgICAgICAgICAgICBjdXJyQ2xpZW50U3RhdGUub25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMucHJvdmlkZXIuZGlzcGF0Y2goY3VyckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LCBjdXJyQ2xpZW50U3RhdGUub25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQsIGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgY29udGV4dEhhbmRsZXJSZW1vdmVkKHBheWxvYWQsIHJlbW92aW5nQ2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICAvLyBNQzogTWFkZSB0aGlzIHJlbW92YWwgYXN5bmMgdG8gZW5zdXJlIHRoYXQgb25VbnN1YnNjcmliZSBoYW5kbGVycyBhcmUgaGl0IGJlZm9yZSBhbnl0aGluZyBlbHNlIGhhcHBlbnMuXG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgY29uc3QgcmVtb3ZpbmdDbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUocmVtb3ZpbmdDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKHJlbW92aW5nQ2xpZW50U3RhdGUpIHtcblx0ICAgICAgICAgICAgbGV0IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICBpZiAocmVtb3ZpbmdDbGllbnRTdGF0ZS5nbG9iYWxIYW5kbGVyID09PSBoYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIHJlbW92aW5nQ2xpZW50U3RhdGUuZ2xvYmFsSGFuZGxlciA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2N1cnJDb250ZXh0VHlwZSwgaGFuZGxlcnNJZHNdIG9mIHJlbW92aW5nQ2xpZW50U3RhdGUuaGFuZGxlcklkc0J5Q29udGV4dFR5cGVzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBoYW5kbGVyc0lkcy5pbmRleE9mKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnNJZHMuc3BsaWNlKGluZGV4LCAxKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dFR5cGUgPSBjdXJyQ29udGV4dFR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIGdldHRpbmcgb25seSB2YWxpZCBjbGllbnQgY29ubmVjdGlvbnMgaGVyZSwgaXQgaXMgcG9zc2libGUgd2UgaGF2ZW4ndCByZW1vdmVkIGEgZGlzY29ubmVjdGVkIGNsaWVudCBmcm9tIHRoZSBtYXAgeWV0XG5cdCAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gZW5zdXJlIHdlIGRvbid0IGRpc3BhdGNoIHRvIGFueSBkaXNjb25uZWN0ZWQgY2xpZW50XG5cdCAgICAgICAgICAgIC8vIFRPRE86IFRha2UgYSBsb29rIGF0IG91ciBjbGllbnQgZGlzY29ubmVjdGlvbiBsb2dpYyBhbmQgc2VlIGlmIHdlIGNhbiBoYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3Rpb24gY2xlYW5seVxuXHQgICAgICAgICAgICBjb25zdCBjbGllbnRzVG9EaXNwYXRjaFRvID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWRDbGllbnRzKCk7XG5cdCAgICAgICAgICAgIGNvbnN0IGRpc3BhdGNoUHJvbWlzZXMgPSBjbGllbnRzVG9EaXNwYXRjaFRvLm1hcChhc3luYyAob3RoZXJDbGllbnRTdGF0ZSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgY2xpZW50SWRlbnRpdHk6IHsgZW5kcG9pbnRJZCB9LCBvblVuc3Vic2NyaWJlSGFuZGxlcklkIH0gPSBvdGhlckNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICAgICAgaWYgKGVuZHBvaW50SWQgIT09IHJlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAmJiBvblVuc3Vic2NyaWJlSGFuZGxlcklkKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgb25VbnN1YnNjcmliZUhhbmRsZXJJZCwgY29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGRpc3BhdGNoUHJvbWlzZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgUHJvYmxlbSB3aGVuIGF0dGVtcHRpbmcgdG8gZGlzcGF0Y2ggdG8gb25VbnN1YnNjcmliZUhhbmRsZXJzLiBFcnJvcjogJHtlcnJvcn0gUmVtb3ZpbmcgQ2xpZW50OiAke2hhbmRsZXJJZH0uIHV1aWQ6ICR7cmVtb3ZpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtyZW1vdmluZ0NsaWVudElkZW50aXR5Lm5hbWV9LiBlbmRwb2ludElkOiAke3JlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH1gKTtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybihgVHJ5aW5nIHRvIHJlbW92ZSBhIGhhbmRsZXIgZnJvbSBhIGNsaWVudCB0aGF0IGlzbid0IG1hcHBlZC4gaGFuZGxlcklkOiAke2hhbmRsZXJJZH0uIHV1aWQ6ICR7cmVtb3ZpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtyZW1vdmluZ0NsaWVudElkZW50aXR5Lm5hbWV9LiBlbmRwb2ludElkOiAke3JlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH0uYCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgbm9uU3RhbmRhcmRIYW5kbGVyUmVtb3ZlZChwYXlsb2FkLCBpZCkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShpZCk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGlmIChjbGllbnRTdGF0ZS5vbkRpc2Nvbm5lY3RIYW5kbGVySWQgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3RhdGUub25EaXNjb25uZWN0SGFuZGxlcklkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2UgaWYgKGNsaWVudFN0YXRlLm9uQWRkQ29udGV4dExpc3RlbmVySGFuZGxlcklkID09PSBoYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIGNsaWVudFN0YXRlLm9uQWRkQ29udGV4dExpc3RlbmVySGFuZGxlcklkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2UgaWYgKGNsaWVudFN0YXRlLm9uVW5zdWJzY3JpYmVIYW5kbGVySWQgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3RhdGUub25VbnN1YnNjcmliZUhhbmRsZXJJZCA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKGBUcnlpbmcgdG8gcmVtb3ZlIGEgaGFuZGxlciBmcm9tIGEgY2xpZW50IHRoYXQgaXNuJ3QgbWFwcGVkLiBoYW5kbGVySWQ6ICR7aGFuZGxlcklkfS4gY2xpZW50SWRlbnRpdHk6ICR7aWR9YCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgb25BZGRDb250ZXh0SGFuZGxlckFkZGVkKHBheWxvYWQsIHNlbmRlckNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKHNlbmRlckNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjb25zdCB7IGhhbmRsZXJJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkudXVpZH0gJHtzZW5kZXJDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBvbkFkZENvbnRleHRMaXN0ZW5lciwgaXMgbm90IGNvbm5lY3RlZCB0byB0aGlzIFByaXZhdGUgQ2hhbm5lbGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjbGllbnRTdGF0ZS5vbkFkZENvbnRleHRMaXN0ZW5lckhhbmRsZXJJZCA9IGhhbmRsZXJJZDtcblx0ICAgICAgICAvLyBGREMzIFNwZWMgc2F5cyB0aGF0IHRoZSBhZGRlZCBsaXN0ZW5lciBzaG91bGQgZmlyZSBmb3IgYWxsIHByZXZpb3VzbHktcmVnaXN0ZXJlZCBhZGRDb250ZXh0TGlzdGVuZXJzIGZyb20gdGhlIG90aGVyIGNsaWVudFxuXHQgICAgICAgIEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKS5mb3JFYWNoKChvdGhlckNsaWVudFN0YXRlKSA9PiB7XG5cdCAgICAgICAgICAgIGlmIChvdGhlckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LmVuZHBvaW50SWQgIT09IHNlbmRlckNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpIHtcblx0ICAgICAgICAgICAgICAgIEFycmF5LmZyb20ob3RoZXJDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMua2V5cygpKS5mb3JFYWNoKChzdWJzY3JpYmVkQ29udGV4dFR5cGUpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKHNlbmRlckNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIHN1YnNjcmliZWRDb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgb25EaXNjb25uZWN0SGFuZGxlckFkZGVkKHBheWxvYWQsIGlkKSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGlkKTtcblx0ICAgICAgICBjb25zdCB7IGhhbmRsZXJJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7aWQudXVpZH0gJHtpZC5uYW1lfSwgdHJpZWQgdG8gY2FsbCBvbkRpc2Nvbm5lY3QsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2xpZW50U3RhdGUub25EaXNjb25uZWN0SGFuZGxlcklkID0gaGFuZGxlcklkO1xuXHQgICAgfVxuXHQgICAgb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZChwYXlsb2FkLCBpZCkge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShpZCk7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgaWYgKCFjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2lkLnV1aWR9ICR7aWQubmFtZX0sIHRyaWVkIHRvIGNhbGwgb25VbnN1YnNjcmliZSwgaXMgbm90IGNvbm5lY3RlZCB0byB0aGlzIFByaXZhdGUgQ2hhbm5lbGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjbGllbnRTdGF0ZS5vblVuc3Vic2NyaWJlSGFuZGxlcklkID0gaGFuZGxlcklkO1xuXHQgICAgfVxuXHQgICAgcmVtb3ZlQ2xpZW50KGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS51dWlkfSAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBkaXNjb25uZWN0LCBpcyBub3QgY29ubmVjdGVkIHRvIHRoaXMgUHJpdmF0ZSBDaGFubmVsYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMuY2xlYXIoKTtcblx0ICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIGFzeW5jIGZpcmVPbkRpc2Nvbm5lY3RGb3JPdGhlckNsaWVudHMoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgLy8gVE9ETzogY2FsbCBvbkRpc2Nvbm5lY3QgSGFuZGxlciBvZiB0aGUgb3RoZXIgY2xpZW50IG9ubHkuXG5cdCAgICAgICAgLy8gQ1VSUkVOVExZLCBqdXN0IGNhbGxpbmcgdGhlIG9uRGlzY29ubmVjdCBoYW5kbGVyIGZvciBhbGwgdGhlIG90aGVyIGNsaWVudHMuIE9uY2Ugd2UgbGltaXQgaXQgdG8ganVzdCBvbmUgb3RoZXIgY2xpZW50LCB3ZSBjYW4gZWxpbWluYXRlIGFsbCB0aGUgaXRlcmF0aW9uIGNvZGUuXG5cdCAgICAgICAgY29uc3QgeyBlbmRwb2ludElkIH0gPSBkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHk7XG5cdCAgICAgICAgLy8gZ2V0dGluZyBvbmx5IHZhbGlkIGNsaWVudCBjb25uZWN0aW9ucyBoZXJlLCBpdCBpcyBwb3NzaWJsZSB3ZSBoYXZlbid0IHJlbW92ZWQgYSBkaXNjb25uZWN0ZWQgY2xpZW50IGZyb20gdGhlIG1hcCB5ZXRcblx0ICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIGVuc3VyZSB3ZSBkb24ndCBkaXNwYXRjaCB0byBhbnkgZGlzY29ubmVjdGVkIGNsaWVudFxuXHQgICAgICAgIC8vIFRPRE86IFRha2UgYSBsb29rIGF0IG91ciBjbGllbnQgZGlzY29ubmVjdGlvbiBsb2dpYyBhbmQgc2VlIGlmIHdlIGNhbiBoYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3Rpb24gY2xlYW5seVxuXHQgICAgICAgIGNvbnN0IGNsaWVudHNUb0Rpc3BhdGNoVG8gPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZENsaWVudHMoKTtcblx0ICAgICAgICBjb25zdCBkaXNwYXRjaFByb21pc2VzID0gY2xpZW50c1RvRGlzcGF0Y2hUby5tYXAoYXN5bmMgKG90aGVyQ2xpZW50U3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eTogeyBlbmRwb2ludElkOiBvdGhlckNsaWVudEVuZHBvaW50SWQgfSwgb25EaXNjb25uZWN0SGFuZGxlcklkIH0gPSBvdGhlckNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICBpZiAob3RoZXJDbGllbnRFbmRwb2ludElkICE9PSBlbmRwb2ludElkICYmIG9uRGlzY29ubmVjdEhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChvdGhlckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LCBvbkRpc2Nvbm5lY3RIYW5kbGVySWQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoZGlzcGF0Y2hQcm9taXNlcyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBQcm9ibGVtIHdoZW4gYXR0ZW1wdGluZyB0byBkaXNwYXRjaCB0byBvbkRpc2Nvbm5lY3RIYW5kbGVycy4gRXJyb3I6ICR7ZXJyb3J9IERpc2Nvbm5lY3RpbmcgQ2xpZW50OiB1dWlkOiAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkubmFtZX0uIGVuZHBvaW50SWQ6ICR7ZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5LmVuZHBvaW50SWR9YCk7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgdW5zdWJzY3JpYmVBbGwoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB7IGVuZHBvaW50SWQgfSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5jbGllbnRzLmdldChlbmRwb2ludElkKTtcblx0ICAgICAgICBpZiAoc3RhdGUpIHtcblx0ICAgICAgICAgICAgY29uc3QgY29udGV4dFR5cGVIYW5kbGVySWRzID0gQXJyYXkuZnJvbShzdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMudmFsdWVzKCkpLmZsYXQoKTtcblx0ICAgICAgICAgICAgY29uc3QgZ2xvYmFsSGFuZGxlcklkID0gc3RhdGUuZ2xvYmFsSGFuZGxlcjtcblx0ICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlSGFuZGxlcklkcy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB1bnN1YlByb21pc2VzID0gY29udGV4dFR5cGVIYW5kbGVySWRzLm1hcChhc3luYyAoaGFuZGxlcklkKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dEhhbmRsZXJSZW1vdmVkKHsgaGFuZGxlcklkIH0sIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh1bnN1YlByb21pc2VzKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGdsb2JhbEhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmNvbnRleHRIYW5kbGVyUmVtb3ZlZCh7IGhhbmRsZXJJZDogZ2xvYmFsSGFuZGxlcklkIH0sIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBhc3luYyBoYW5kbGVDbGllbnREaXNjb25uZWN0aW5nKGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGF3YWl0IHRoaXMudW5zdWJzY3JpYmVBbGwoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KTtcblx0ICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGF3YWl0IHRoaXMuZmlyZU9uRGlzY29ubmVjdEZvck90aGVyQ2xpZW50cyhkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgcmVnaXN0ZXJOZXdDbGllbnQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBpZiAoIXRoaXMuY2xpZW50cy5oYXMoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCkpIHtcblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eSxcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJZHNCeUNvbnRleHRUeXBlczogbmV3IE1hcCgpLFxuXHQgICAgICAgICAgICAgICAgZ2xvYmFsSGFuZGxlcjogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICAgICAgb25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQ6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgICAgIG9uVW5zdWJzY3JpYmVIYW5kbGVySWQ6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgICAgIG9uRGlzY29ubmVjdEhhbmRsZXJJZDogdW5kZWZpbmVkXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIHRoaXMuY2xpZW50cy5zZXQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCwgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIGdldENvbm5lY3RlZENsaWVudHMoKSB7XG5cdCAgICAgICAgY29uc3QgYWxsQ2xpZW50SW5mbyA9IGF3YWl0IHRoaXMucHJvdmlkZXIuZ2V0QWxsQ2xpZW50SW5mbygpO1xuXHQgICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuY2xpZW50cy52YWx1ZXMoKSkuZmlsdGVyKChjbGllbnRTdGF0ZSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5O1xuXHQgICAgICAgICAgICByZXR1cm4gYWxsQ2xpZW50SW5mby5zb21lKChjbGllbnRJbmZvKSA9PiB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gY2xpZW50SW5mby5uYW1lICYmIHV1aWQgPT09IGNsaWVudEluZm8udXVpZDtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBzdGF0aWMgaW5pdChjaGFubmVsUHJvdmlkZXIsIGlkKSB7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyKGNoYW5uZWxQcm92aWRlciwgaWQpO1xuXHQgICAgfVxuXHR9O1xuXHRQcml2YXRlQ2hhbm5lbFByb3ZpZGVyLlByaXZhdGVDaGFubmVsUHJvdmlkZXIgPSBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyJDE7XG5cdHJldHVybiBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xufVxuXG52YXIgaGFzUmVxdWlyZWRJbnRlcm9wQnJva2VyO1xuXG5mdW5jdGlvbiByZXF1aXJlSW50ZXJvcEJyb2tlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEludGVyb3BCcm9rZXIpIHJldHVybiBJbnRlcm9wQnJva2VyO1xuXHRoYXNSZXF1aXJlZEludGVyb3BCcm9rZXIgPSAxO1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xuXHR9O1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG5cdCAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG5cdCAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG5cdH07XG5cdHZhciBfX2ltcG9ydERlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnREZWZhdWx0KSB8fCBmdW5jdGlvbiAobW9kKSB7XG5cdCAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcblx0fTtcblx0dmFyIF9JbnRlcm9wQnJva2VyX2ZkYzNJbmZvLCBfSW50ZXJvcEJyb2tlcl9jb250ZXh0R3JvdXBzLCBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2U7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnRlcm9wQnJva2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW50ZXJvcEJyb2tlci5JbnRlcm9wQnJva2VyID0gdm9pZCAwO1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZVNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXIoKSk7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHRjb25zdCBpc0VxdWFsXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMyk7XG5cdGNvbnN0IFByaXZhdGVDaGFubmVsUHJvdmlkZXJfMSA9IHJlcXVpcmVQcml2YXRlQ2hhbm5lbFByb3ZpZGVyKCk7XG5cdGNvbnN0IGxhenlfMSA9IGxhenk7XG5cdGNvbnN0IGRlZmF1bHRDb250ZXh0R3JvdXBzID0gW1xuXHQgICAge1xuXHQgICAgICAgIGlkOiAnZ3JlZW4nLFxuXHQgICAgICAgIGRpc3BsYXlNZXRhZGF0YToge1xuXHQgICAgICAgICAgICBjb2xvcjogJyMwMENDODgnLFxuXHQgICAgICAgICAgICBuYW1lOiAnZ3JlZW4nXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3B1cnBsZScsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnIzhDNjFGRicsXG5cdCAgICAgICAgICAgIG5hbWU6ICdwdXJwbGUnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ29yYW5nZScsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnI0ZGOEM0QycsXG5cdCAgICAgICAgICAgIG5hbWU6ICdvcmFuZ2UnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3JlZCcsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnI0ZGNUU2MCcsXG5cdCAgICAgICAgICAgIG5hbWU6ICdyZWQnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3BpbmsnLFxuXHQgICAgICAgIGRpc3BsYXlNZXRhZGF0YToge1xuXHQgICAgICAgICAgICBjb2xvcjogJyNGRjhGQjgnLFxuXHQgICAgICAgICAgICBuYW1lOiAncGluaydcblx0ICAgICAgICB9XG5cdCAgICB9LFxuXHQgICAge1xuXHQgICAgICAgIGlkOiAneWVsbG93Jyxcblx0ICAgICAgICBkaXNwbGF5TWV0YWRhdGE6IHtcblx0ICAgICAgICAgICAgY29sb3I6ICcjRTlGRjhGJyxcblx0ICAgICAgICAgICAgbmFtZTogJ3llbGxvdydcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdF07XG5cdC8qKlxuXHQgKiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2VuYWJsZS1jb2xvci1saW5raW5nfVxuXHQgKlxuXHQgKiBUaGUgSW50ZXJvcCBCcm9rZXIgaXMgcmVzcG9uc2libGUgZm9yIGtlZXBpbmcgdHJhY2sgb2YgdGhlIEludGVyb3Agc3RhdGUgb2YgdGhlIFBsYXRmb3JtLCBhbmQgZm9yIGRpcmVjdGluZyBtZXNzYWdlcyB0byB0aGUgcHJvcGVyIGxvY2F0aW9ucy5cblx0ICpcblx0ICogQHJlbWFya3MgVGhpcyBjbGFzcyBjb250YWlucyBzb21lIHR5cGVzIHJlbGF0ZWQgdG8gRkRDMyB0aGF0IGFyZSBzcGVjaWZpYyB0byBPcGVuRmluLiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2ZkYzMtc3VwcG9ydC1pbi1vcGVuZmluIE9wZW5GaW4ncyBGREMzIHN1cHBvcnR9IGlzIGZvcndhcmQtIGFuZCBiYWNrd2FyZC1jb21wYXRpYmxlLlxuXHQgKiBTdGFuZGFyZCB0eXBlcyBmb3Ige0BsaW5rIGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvIEZEQzN9IGRvIG5vdCBhcHBlYXIgaW4gT3BlbkZpbuKAmXMgQVBJIGRvY3VtZW50YXRpb24sIHRvIGF2b2lkIGR1cGxpY2F0aW9uLlxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogVGhlcmUgYXJlIDIgd2F5cyB0byBpbmplY3QgY3VzdG9tIGZ1bmN0aW9uYWxpdHkgaW50byB0aGUgSW50ZXJvcCBCcm9rZXI6XG5cdCAqXG5cdCAqICoqMS4gQ29uZmlndXJhdGlvbioqXG5cdCAqXG5cdCAqIEF0IHRoZSBtb21lbnQsIHlvdSBjYW4gY29uZmlndXJlIHRoZSBkZWZhdWx0IGNvbnRleHQgZ3JvdXBzIGZvciB0aGUgSW50ZXJvcCBCcm9rZXIgd2l0aG91dCBoYXZpbmcgdG8gb3ZlcnJpZGUgaXQuIFRvIGRvIHNvLCBpbmNsdWRlIHRoZSBgaW50ZXJvcEJyb2tlckNvbmZpZ3VyYXRpb25gIGBjb250ZXh0R3JvdXBzYCBvcHRpb24gaW4geW91ciBgcGxhdGZvcm1gIG9wdGlvbnMgaW4geW91ciBtYW5pZmVzdC4gVGhpcyBpcyB0aGUgcHJlZmVycmVkIG1ldGhvZC5cblx0ICogYGBganNcblx0ICoge1xuXHQgKiAgICAgIFwicnVudGltZVwiOiB7XG5cdCAqICAgICAgICAgIFwiYXJndW1lbnRzXCI6IFwiLS12PTEgLS1pbnNwZWN0XCIsXG5cdCAqICAgICAgICAgIFwidmVyc2lvblwiOiBcImFscGhhLXYxOVwiXG5cdCAqICAgICAgfSxcblx0ICogICAgICBcInBsYXRmb3JtXCI6IHtcblx0ICogICAgICAgICAgXCJ1dWlkXCI6IFwicGxhdGZvcm1fY3VzdG9taXphdGlvbl9sb2NhbFwiLFxuXHQgKiAgICAgICAgICBcImFwcGxpY2F0aW9uSWNvblwiOiBcImh0dHBzOi8vb3BlbmZpbi5naXRodWIuaW8vZ29sZGVuLXByb3RvdHlwZS9mYXZpY29uLmljb1wiLFxuXHQgKiAgICAgICAgICBcImF1dG9TaG93XCI6IGZhbHNlLFxuXHQgKiAgICAgICAgICBcInByb3ZpZGVyVXJsXCI6IFwiaHR0cDovL2xvY2FsaG9zdDo1NTU1L3Byb3ZpZGVyLmh0bWxcIixcblx0ICogICAgICAgICAgXCJpbnRlcm9wQnJva2VyQ29uZmlndXJhdGlvblwiOiB7XG5cdCAqICAgICAgICAgICAgICBcImNvbnRleHRHcm91cHNcIjogW1xuXHQgKiAgICAgICAgICAgICAgICAgIHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiBcImdyZWVuXCIsXG5cdCAqICAgICAgICAgICAgICAgICAgICAgIFwiZGlzcGxheU1ldGFkYXRhXCI6IHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29sb3JcIjogXCIjMDBDQzg4XCIsXG5cdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJncmVlblwiXG5cdCAqICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICogICAgICAgICAgICAgICAgICB9LFxuXHQgKiAgICAgICAgICAgICAgICAgIHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiBcInB1cnBsZVwiLFxuXHQgKiAgICAgICAgICAgICAgICAgICAgICBcImRpc3BsYXlNZXRhZGF0YVwiOiB7XG5cdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiIzhDNjFGRlwiLFxuXHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwicHVycGxlXCJcblx0ICogICAgICAgICAgICAgICAgICAgICAgfVxuXHQgKiAgICAgICAgICAgICAgICAgIH0sXG5cdCAqICAgICAgICAgICAgICBdXG5cdCAqICAgICAgICAgIH1cblx0ICogICAgICB9XG5cdCAqIH1cblx0ICogYGBgXG5cdCAqXG5cdCAqIEJ5IGRlZmF1bHQgdGhlIEludGVyb3AgQnJva2VyIGxvZ3MgYWxsIGFjdGlvbnMgdG8gdGhlIGNvbnNvbGUuIFlvdSBjYW4gZGlzYWJsZSB0aGlzIGJ5IHVzaW5nIHRoZSBsb2dnaW5nIG9wdGlvbiBpbiBgaW50ZXJvcEJyb2tlckNvbmZpZ3VyYXRpb25gOlxuXHQgKiBgYGBqc1xuXHQgKiB7XG5cdCAqICAgICAgXCJydW50aW1lXCI6IHtcblx0ICogICAgICAgICAgXCJhcmd1bWVudHNcIjogXCItLXY9MSAtLWluc3BlY3RcIixcblx0ICogICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiYWxwaGEtdjE5XCJcblx0ICogICAgICB9LFxuXHQgKiAgICAgIFwicGxhdGZvcm1cIjoge1xuXHQgKiAgICAgICAgICBcInV1aWRcIjogXCJwbGF0Zm9ybV9jdXN0b21pemF0aW9uX2xvY2FsXCIsXG5cdCAqICAgICAgICAgIFwiYXBwbGljYXRpb25JY29uXCI6IFwiaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9nb2xkZW4tcHJvdG90eXBlL2Zhdmljb24uaWNvXCIsXG5cdCAqICAgICAgICAgIFwiYXV0b1Nob3dcIjogZmFsc2UsXG5cdCAqICAgICAgICAgIFwicHJvdmlkZXJVcmxcIjogXCJodHRwOi8vbG9jYWxob3N0OjU1NTUvcHJvdmlkZXIuaHRtbFwiLFxuXHQgKlx0XHQgICAgXCJpbnRlcm9wQnJva2VyQ29uZmlndXJhdGlvblwiOiB7XG5cdCAqICAgICAgIFx0XHRcImxvZ2dpbmdcIjoge1xuXHQgKiAgIFx0XHRcdFx0XCJiZWZvcmVBY3Rpb25cIjoge1xuXHQgKiAgIFx0XHRcdFx0XHRcImVuYWJsZWRcIjogZmFsc2Vcblx0ICogICBcdFx0XHRcdH0sXG5cdCAqICAgXHRcdFx0XHRcImFmdGVyQWN0aW9uXCI6IHtcblx0ICogICBcdFx0XHRcdFx0XCJlbmFibGVkXCI6IGZhbHNlXG5cdCAqICAgXHRcdFx0XHR9XG5cdCAqICAgXHRcdFx0fVxuXHQgKlx0XHQgICAgfVxuXHQgKiAgICAgIH1cblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogLS0tXG5cdCAqICoqMi4gT3ZlcnJpZGluZyoqXG5cdCAqXG5cdCAqIFNpbWlsYXJseSB0byBob3cge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvcGxhdGZvcm0tY3VzdG9taXphdGlvbiNzZWN0aW9uLWN1c3RvbWl6aW5nLXBsYXRmb3JtLWJlaGF2aW9yIFBsYXRmb3JtIE92ZXJyaWRpbmd9IHdvcmtzLCB5b3UgY2FuIG92ZXJyaWRlIGZ1bmN0aW9ucyBpbiB0aGUgSW50ZXJvcCBCcm9rZXIgaW4gYGZpbi5QbGF0Zm9ybS5pbml0YC4gQW4gZXhhbXBsZSBvZiB0aGF0IGlzIHNob3duIGJlbG93LiBPdmVycmlkaW5nIGBpc0Nvbm5lY3Rpb25BdXRob3JpemVkYCBhbmQgYGlzQWN0aW9uQXV0aG9yaXplZGAgd2lsbCBhbGxvdyB5b3UgdG8gY29udHJvbCBhbGxvd2VkIGNvbm5lY3Rpb25zIGFuZCBhbGxvd2VkIGFjdGlvbnMuXG5cdCAqXG5cdCAqIEhvd2V2ZXIsIGlmIHRoZXJlIGlzIGN1c3RvbSBmdW5jdGlvbmFsaXR5IHlvdSB3aXNoIHRvIGluY2x1ZGUgaW4gdGhlIEludGVyb3AgQnJva2VyLCBwbGVhc2UgbGV0IHVzIGtub3cuIFdlIHdvdWxkIGxpa2UgdG8gcHJvdmlkZSBiZXR0ZXIgY29uZmlndXJhdGlvbiBvcHRpb25zIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gY29udGludWFsbHkgbWFpbnRhaW4geW91ciBvd24gb3ZlcnJpZGUgY29kZS5cblx0ICpcblx0ICogYGBganNcblx0ICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgKiAgICAgb3ZlcnJpZGVDYWxsYmFjazogYXN5bmMgKFByb3ZpZGVyKSA9PiB7XG5cdCAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBQcm92aWRlciB7XG5cdCAqICAgICAgICAgICAgIGFzeW5jIGdldFNuYXBzaG90KCkge1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2JlZm9yZSBnZXRTbmFwc2hvdCcpXG5cdCAqICAgICAgICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHN1cGVyLmdldFNuYXBzaG90KCk7XG5cdCAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYWZ0ZXIgZ2V0U25hcHNob3QnKVxuXHQgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHNuYXBzaG90O1xuXHQgKiAgICAgICAgICAgICB9XG5cdCAqXG5cdCAqICAgICAgICAgICAgIGFzeW5jIGFwcGx5U25hcHNob3QoeyBzbmFwc2hvdCwgb3B0aW9ucyB9KSB7XG5cdCAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYmVmb3JlIGFwcGx5U25hcHNob3QnKVxuXHQgKiAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxQcm9taXNlID0gc3VwZXIuYXBwbHlTbmFwc2hvdCh7IHNuYXBzaG90LCBvcHRpb25zIH0pO1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2FmdGVyIGFwcGx5U25hcHNob3QnKVxuXHQgKlxuXHQgKiAgICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZTtcblx0ICogICAgICAgICAgICAgfVxuXHQgKiAgICAgICAgIH07XG5cdCAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgKiAgICAgfSxcblx0ICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgKiAgICAgICAgICAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKGNoYW5uZWxOYW1lID0gJ2RlZmF1bHQnLCB0YXJnZXQpIHtcblx0ICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdiZWZvcmUgc3VwZXIgam9pbkNvbnRleHRHcm91cCcpXG5cdCAqICAgICAgICAgICAgICAgICBzdXBlci5qb2luQ29udGV4dEdyb3VwKGNoYW5uZWxOYW1lLCB0YXJnZXQpO1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2FmdGVyIHN1cGVyIGpvaW5Db250ZXh0R3JvdXAnKVxuXHQgKiAgICAgICAgICAgICB9XG5cdCAqICAgICAgICAgfVxuXHQgKlxuXHQgKiAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKCk7XG5cdCAqICAgfVxuXHQgKiB9KTtcblx0ICogYGBgXG5cdCAqXG5cdCAqIC0tLVxuXHQgKlxuXHQgKi9cblx0bGV0IEludGVyb3BCcm9rZXIkMSA9IGNsYXNzIEludGVyb3BCcm9rZXIgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICovXG5cdCAgICBjb25zdHJ1Y3Rvcih3aXJlLCBjcmVhdGVQcm92aWRlciwgb3B0aW9ucykge1xuXHQgICAgICAgIC8vIFRpcCBmcm9tIFBpZXJyZSBhbmQgTWljaGFlbCBmcm9tIHRoZSBvdmVycmlkZUNoZWNrIHdvcms6IERvbid0IHVzZSBib3VuZCBtZXRob2RzIGZvciBvdmVycmlkZWFibGUgSW50ZXJvcEJyb2tlciBmdW5jdGlvbnMuXG5cdCAgICAgICAgc3VwZXIod2lyZSk7XG5cdCAgICAgICAgX0ludGVyb3BCcm9rZXJfZmRjM0luZm8uc2V0KHRoaXMsIHZvaWQgMCk7XG5cdCAgICAgICAgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3Vwcy5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2Uuc2V0KHRoaXMsIHZvaWQgMCk7XG5cdCAgICAgICAgdGhpcy5nZXRQcm92aWRlciA9ICgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfcHJvdmlkZXJQcm9taXNlLCBcImZcIikuZ2V0VmFsdWUoKTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMuaW50ZXJvcENsaWVudHMgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0R3JvdXBzQnlJZCA9IG5ldyBNYXAoKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQnJva2VyX2NvbnRleHRHcm91cHMsIG9wdGlvbnMuY29udGV4dEdyb3VwcyA/PyBbLi4uZGVmYXVsdENvbnRleHRHcm91cHNdLCBcImZcIik7XG5cdCAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfSW50ZXJvcEJyb2tlcl9mZGMzSW5mbywgb3B0aW9ucy5mZGMzSW5mbywgXCJmXCIpO1xuXHQgICAgICAgIGlmIChvcHRpb25zPy5sb2dnaW5nKSB7XG5cdCAgICAgICAgICAgIHRoaXMubG9nZ2luZyA9IG9wdGlvbnMubG9nZ2luZztcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5pbnRlbnRDbGllbnRNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5sYXN0Q29udGV4dE1hcCA9IG5ldyBNYXAoKTtcblx0ICAgICAgICB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2UsIG5ldyBsYXp5XzEuTGF6eShjcmVhdGVQcm92aWRlciksIFwiZlwiKTtcblx0ICAgICAgICB0aGlzLnNldENvbnRleHRHcm91cE1hcCgpO1xuXHQgICAgICAgIHRoaXMuc2V0dXBDaGFubmVsUHJvdmlkZXIoKTtcblx0ICAgIH1cblx0ICAgIHN0YXRpYyBjcmVhdGVDbG9zZWRDb25zdHJ1Y3RvciguLi5hcmdzKSB7XG5cdCAgICAgICAgcmV0dXJuIGNsYXNzIE92ZXJyaWRlYWJsZUJyb2tlciBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICAgICAgICBjb25zdHJ1Y3RvciguLi51bnVzZWQpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh1bnVzZWQubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgW19pZ25vcmUxLCBpZ25vcmUyLCBvcHRzXSA9IHVudXNlZDtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAob3B0cyAmJiB0eXBlb2Ygb3B0cyA9PT0gJ29iamVjdCcgJiYgISgwLCBpc0VxdWFsXzEuZGVmYXVsdCkob3B0cywgYXJnc1syXSkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdZb3UgaGF2ZSBtb2RpZmllZCB0aGUgcGFyYW1ldGVycyBvZiB0aGUgSW50ZXJvcE92ZXJyaWRlIGNvbnN0cnVjdG9yLiBUaGlzIGJlaGF2aW9yIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLiBZb3UgY2FuIG1vZGlmeSB0aGVzZSBvcHRpb25zIGluIHlvdXIgbWFuaWZlc3QuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIoYXJnc1swXSwgYXJnc1sxXSwgb3B0cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSBhcmUgYXR0ZW1wdGluZyB0byBwYXNzIGFyZ3VtZW50cyB0byB0aGUgSW50ZXJvcE92ZXJyaWRlIGNvbnN0cnVjdG9yLiBUaGlzIGlzIG5vdCBuZWNlc3NhcnksIGFuZCB0aGVzZSBwYXNzZWQgYXJndW1lbnRzIHdpbGwgYmUgaWdub3JlZC4gWW91IGFyZSBsaWtlbHkgdXNpbmcgYW4gb2xkZXIgSW50ZXJvcEJyb2tlciBvdmVycmlkZSBzY2hlbWUuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHN1cGVyKC4uLmFyZ3MpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBDbGllbnQgQVBJXG5cdCAgICAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIGEgY29udGV4dCBmb3IgdGhlIGNvbnRleHQgZ3JvdXAgb2YgdGhlIGluY29taW5nIGN1cnJlbnQgZW50aXR5LlxuXHQgICAgICogQHBhcmFtIHNldENvbnRleHRPcHRpb25zIC0gTmV3IGNvbnRleHQgdG8gc2V0LlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBzZXRDb250ZXh0KHsgY29udGV4dCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1zZXQtY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlICYmIGNsaWVudFN0YXRlLmNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgY29udGV4dEdyb3VwSWQgfSA9IGNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICB0aGlzLnNldENvbnRleHRGb3JHcm91cCh7IGNvbnRleHQgfSwgY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIGlmIChjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBDbGllbnQgaGFzIG5vdCBqb2luZWQgYW55IGNvbnRleHQgZ3JvdXAgYmVoYXZpb3IuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3Qgam9pbiBhIGNvbnRleHQgZ3JvdXAgYmVmb3JlIHlvdSBjYW4gc2V0IGNvbnRleHQuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICAvLyBUaGlzIHNob3VsZG4ndCBnZXQgaGl0LlxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2NsaWVudElkZW50aXR5LnV1aWR9ICR7Y2xpZW50SWRlbnRpdHkubmFtZX0gbm90IGluIENsaWVudCBTdGF0ZSBNYXBgKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNldHMgYSBjb250ZXh0IGZvciB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqIEBwYXJhbSBzZXRDb250ZXh0T3B0aW9ucyAtIE5ldyBjb250ZXh0IHRvIHNldC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0R3JvdXBJZCAtIENvbnRleHQgZ3JvdXAgaWQuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBzZXRDb250ZXh0Rm9yR3JvdXAoeyBjb250ZXh0IH0sIGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtYnJva2VyLXNldC1jb250ZXh0LWZvci1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cFN0YXRlID0gdGhpcy5jb250ZXh0R3JvdXBzQnlJZC5nZXQoY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIGlmICghY29udGV4dEdyb3VwU3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gc2V0IGNvbnRleHQgZm9yIGNvbnRleHQgZ3JvdXAgdGhhdCBpc24ndCBpbiB0aGUgY29udGV4dCBncm91cCBtYXBwaW5nOiAke2NvbnRleHRHcm91cElkfS5gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0ID0gSW50ZXJvcEJyb2tlci5jaGVja0NvbnRleHRJbnRlZ3JpdHkoY29udGV4dCk7XG5cdCAgICAgICAgaWYgKGNvbnRleHRJbnRlZ3JpdHlDaGVja1Jlc3VsdC5pc1ZhbGlkID09PSBmYWxzZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBzZXQgQ29udGV4dCAtIGJhZCBDb250ZXh0LiBSZWFzb246ICR7Y29udGV4dEludGVncml0eUNoZWNrUmVzdWx0LnJlYXNvbn0uIENvbnRleHQ6ICR7SlNPTi5zdHJpbmdpZnkoY29udGV4dCl9YCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IGJyb2FkY2FzdGVkQ29udGV4dFR5cGUgPSBjb250ZXh0LnR5cGU7XG5cdCAgICAgICAgY29udGV4dEdyb3VwU3RhdGUuc2V0KGJyb2FkY2FzdGVkQ29udGV4dFR5cGUsIGNvbnRleHQpO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHRNYXAuc2V0KGNvbnRleHRHcm91cElkLCBicm9hZGNhc3RlZENvbnRleHRUeXBlKTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5TYW1lQ29udGV4dEdyb3VwID0gQXJyYXkuZnJvbSh0aGlzLmludGVyb3BDbGllbnRzLnZhbHVlcygpKS5maWx0ZXIoKGNvbm5lY3RlZENsaWVudCkgPT4gY29ubmVjdGVkQ2xpZW50LmNvbnRleHRHcm91cElkID09PSBjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgY2xpZW50c0luU2FtZUNvbnRleHRHcm91cC5mb3JFYWNoKChjbGllbnQpID0+IHtcblx0ICAgICAgICAgICAgZm9yIChjb25zdCBbLCBoYW5kbGVySW5mb10gb2YgY2xpZW50LmNvbnRleHRIYW5kbGVycykge1xuXHQgICAgICAgICAgICAgICAgaWYgKEludGVyb3BCcm9rZXIuaXNDb250ZXh0VHlwZUNvbXBhdGlibGUoYnJvYWRjYXN0ZWRDb250ZXh0VHlwZSwgaGFuZGxlckluZm8uY29udGV4dFR5cGUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnZva2VDb250ZXh0SGFuZGxlcihjbGllbnQuY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJbmZvLmhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0IGN1cnJlbnQgY29udGV4dCBmb3IgYSBjbGllbnQgc3Vic2NyaWJlZCB0byBhIENvbnRleHQgR3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSXQgdGFrZXMgYW4gb3B0aW9uYWwgQ29udGV4dCBUeXBlIGFyZ3VtZW50IGFuZCByZXR1cm5zIHRoZSBsYXN0IGNvbnRleHQgb2YgdGhhdCB0eXBlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBnZXRDb250ZXh0T3B0aW9ucyAtIE9wdGlvbnMgZm9yIGdldHRpbmcgY29udGV4dFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBnZXRDdXJyZW50Q29udGV4dChnZXRDdXJyZW50Q29udGV4dE9wdGlvbnMsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtYnJva2VyLWdldC1jdXJyZW50LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGlmICghY2xpZW50U3RhdGU/LmNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3QgYmUgYSBtZW1iZXIgb2YgYSBjb250ZXh0IGdyb3VwIHRvIGNhbGwgZ2V0Q3VycmVudENvbnRleHQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgeyBjb250ZXh0R3JvdXBJZCB9ID0gY2xpZW50U3RhdGU7XG5cdCAgICAgICAgY29uc3QgY29udGV4dEdyb3VwU3RhdGUgPSB0aGlzLmNvbnRleHRHcm91cHNCeUlkLmdldChjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgY29uc3QgbGFzdENvbnRleHRUeXBlID0gdGhpcy5sYXN0Q29udGV4dE1hcC5nZXQoY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRUeXBlID0gZ2V0Q3VycmVudENvbnRleHRPcHRpb25zPy5jb250ZXh0VHlwZSA/PyBsYXN0Q29udGV4dFR5cGU7XG5cdCAgICAgICAgcmV0dXJuIGNvbnRleHRHcm91cFN0YXRlICYmIGNvbnRleHRUeXBlID8gY29udGV4dEdyb3VwU3RhdGUuZ2V0KGNvbnRleHRUeXBlKSA6IHVuZGVmaW5lZDtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBQbGF0Zm9ybSBXaW5kb3cgQVBJc1xuXHQgICAgKi9cblx0ICAgIC8vIGpvaW5Db250ZXh0R3JvdXAgYW5kIGFkZENsaWVudFRvQ29udGV4dEdyb3VwIGFyZSBzZXBhcmF0ZSBmdW5jdGlvbnMgaGVyZSwgZm9yIGVhc2llciBvdmVycmlkZXMgYW5kIHNlcGFyYXRpb24gb2YgY29uY2VybnMuXG5cdCAgICAvLyBqb2luQ29udGV4dEdyb3VwIGNoZWNrcyBhbGwgY29ubmVjdGlvbnMgZm9yIG1hdGNoaW5nIGlkZW50aXRpZXMsIGluIGNhc2Ugd2UgaGF2ZSBtdWx0aXBsZSBjb25uZWN0aW9uIGZyb20gYW4gZW50aXR5LlxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFsbCBjb25uZWN0aW9ucyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgKG9yIGp1c3Qgb25lIGlmIGVuZHBvaW50SWQgcHJvdmlkZWQpIHRvIGNvbnRleHQgZ3JvdXAgYGNvbnRleHRHcm91cElkYC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IGFkZHMgdGhlIHNlbmRlciB0byB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqIGpvaW5Db250ZXh0R3JvdXAgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIGNvbm5lY3Rpb25zIGF0IHRoZSBpbmNvbWluZyBpZGVudGl0eS4gSXQgY2FsbHMge0BsaW5rIEludGVyb3BCcm9rZXIjYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAgSW50ZXJvcEJyb2tlci5hZGRDbGllbnRUb0NvbnRleHRHcm91cH0gdG8gYWN0dWFsbHkgZ3JvdXAgdGhlIGNsaWVudC5cblx0ICAgICAqIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gam9pbkNvbnRleHRHcm91cE9wdGlvbnMgLSBJZCBvZiB0aGUgQ29udGV4dCBHcm91cCBhbmQgaWRlbnRpdHkgb2YgdGhlIGVudGl0eSB0byBqb2luIHRvIHRoZSBncm91cC5cblx0ICAgICAqIEBwYXJhbSBzZW5kZXJJZGVudGl0eSAtIElkZW50aXR5IG9mIHRoZSBjbGllbnQgc2VuZGVyLlxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKHsgY29udGV4dEdyb3VwSWQsIHRhcmdldCB9LCBzZW5kZXJJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1qb2luLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAodGhpcy5zZXNzaW9uQ29udGV4dEdyb3VwTWFwLmhhcyhjb250ZXh0R3JvdXBJZCkpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5qb2luU2Vzc2lvbkNvbnRleHRHcm91cFdpdGhKb2luQ29udGV4dEdyb3VwKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKHRhcmdldCkge1xuXHQgICAgICAgICAgICAvLyBJZiBhbiBlbmRwb2ludElkIGlzIHByb3ZpZGVkLCB1c2UgdGhhdC4gVGhpcyB3aWxsIGxpa2VseSBiZSB1c2VkIGJ5IGV4dGVybmFsIGFkYXB0ZXJzLlxuXHQgICAgICAgICAgICBpZiAoSW50ZXJvcEJyb2tlci5oYXNFbmRwb2ludElkKHRhcmdldCkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAoeyBjb250ZXh0R3JvdXBJZCB9LCB0YXJnZXQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIFNhbml0eSBjaGVjayBoZXJlIGluIGNhc2UgYSBzaW5nbGUgYXBwIGhhcyBtdWx0aXBsZSBjb25uZWN0aW9uc1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgYWxsQ29ubmVjdGlvbnMgPSB0aGlzLmNoYW5uZWwuY29ubmVjdGlvbnMuZmlsdGVyKCh4KSA9PiB4LnV1aWQgPT09IHRhcmdldC51dWlkICYmIHgubmFtZSA9PT0gdGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgICAgICAgICAgaWYgKCFhbGxDb25uZWN0aW9ucy5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdpdmVuIElkZW50aXR5ICR7dGFyZ2V0LnV1aWR9ICR7dGFyZ2V0Lm5hbWV9IGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhlIEludGVyb3AgQnJva2VyLmApO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgaWYgKGFsbENvbm5lY3Rpb25zLmxlbmd0aCA+IDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTaG91bGQgZmlndXJlIG91dCBob3cgd2Ugd2FudCB0byBoYW5kbGUgdGhpcyBzaXR1YXRpb24uIEluIHRoZSBtZWFudGltZSwganVzdCBjaGFuZ2UgY29udGV4dCBncm91cCBmb3IgYWxsIGNvbm5lY3Rpb25zLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgTW9yZSB0aGFuIG9uZSBjb25uZWN0aW9uIGZvdW5kIGZvciBpZGVudGl0eSAke3RhcmdldC51dWlkfSAke3RhcmdldC5uYW1lfWApO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblx0ICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBhbGxDb25uZWN0aW9ucykge1xuXHQgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5hZGRDbGllbnRUb0NvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0sIGNvbm5lY3Rpb24pKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIC8vIE5vIHRhcmdldCBwcm92aWRlZCwgYWRkIHRoZSBzZW5kZXIgdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAoeyBjb250ZXh0R3JvdXBJZCB9LCBzZW5kZXJJZGVudGl0eSk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAgZG9lcyB0aGUgYWN0dWFsIGFkZGl0aW9uIG9mIHRoZSBjbGllbnQgdG8gdGhlIENvbnRleHQgR3JvdXBcblx0ICAgIC8qKlxuXHQgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciB7QGxpbmsgSW50ZXJvcEJyb2tlciNqb2luQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIuam9pbkNvbnRleHRHcm91cH0uIERvZXMgdGhlIHdvcmsgb2YgYWN0dWFsbHkgYWRkaW5nIHRoZSBjbGllbnQgdG8gdGhlIENvbnRleHQgR3JvdXAuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGFkZENsaWVudFRvQ29udGV4dEdyb3VwT3B0aW9ucyAtIENvbnRhaW5zIHRoZSBjb250ZXh0R3JvdXBJZFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGFkZENsaWVudFRvQ29udGV4dEdyb3VwKHsgY29udGV4dEdyb3VwSWQgfSwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItYWRkLWNsaWVudC10by1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWNsaWVudFN1YnNjcmlwdGlvblN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0gJHtjbGllbnRJZGVudGl0eS5uYW1lfSBub3QgaW4gQ2xpZW50IFN0YXRlIE1hcGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoIXRoaXMuZ2V0Q29udGV4dEdyb3VwcygpLmZpbmQoKGNvbnRleHRHcm91cEluZm8pID0+IGNvbnRleHRHcm91cEluZm8uaWQgPT09IGNvbnRleHRHcm91cElkKSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEF0dGVtcHRpbmcgdG8gam9pbiBhIGNvbnRleHQgZ3JvdXAgdGhhdCBkb2VzIG5vdCBleGlzdDogJHtjb250ZXh0R3JvdXBJZH0uIFlvdSBtYXkgb25seSBqb2luIGV4aXN0aW5nIGNvbnRleHQgZ3JvdXBzLmApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCBvbGRDb250ZXh0R3JvdXBJZCA9IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlLmNvbnRleHRHcm91cElkO1xuXHQgICAgICAgIGlmIChvbGRDb250ZXh0R3JvdXBJZCAhPT0gY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEdyb3VwSWQgPSBjb250ZXh0R3JvdXBJZDtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRDdXJyZW50Q29udGV4dEdyb3VwSW5DbGllbnRPcHRpb25zKGNsaWVudElkZW50aXR5LCBjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cE1hcCA9IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuZ2V0KGNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgZm9yIChjb25zdCBbLCBoYW5kbGVySW5mb10gb2YgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEhhbmRsZXJzKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRUeXBlLCBoYW5kbGVySWQgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTZW5kIHRoaXMgc2luZ2xlIGhhbmRsZXIgYWxsIG9mIHRoZSBjb250ZXh0LCBiZWNhdXNlIGl0IGFjY2VwdHMgYWxsLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnRleHRHcm91cE1hcC5mb3JFYWNoKChjb250ZXh0LCBfKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZXh0R3JvdXBNYXAuaGFzKGNvbnRleHRUeXBlKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRleHRGb3JUeXBlID0gY29udGV4dEdyb3VwTWFwLmdldChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRGb3JUeXBlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dEZvclR5cGUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIFJlbW92ZXMgdGhlIHRhcmdldCBmcm9tIGl0cyBjb250ZXh0IGdyb3VwLiBTaW1pbGFyIHN0cnVjdHVyZSB0byBqb2luQ29udGV4dEdyb3VwLlxuXHQgICAgLyoqXG5cdCAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGZyb20gYSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogSWYgbm8gdGFyZ2V0IGlzIHNwZWNpZmllZCwgaXQgcmVtb3ZlcyB0aGUgc2VuZGVyIGZyb20gdGhlaXIgY29udGV4dCBncm91cC5cblx0ICAgICAqIHJlbW92ZUZyb21Db250ZXh0R3JvdXAgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIGNvbm5lY3Rpb25zIGF0IHRoZSBpbmNvbWluZyBpZGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBJdCBjYWxscyB7QGxpbmsgSW50ZXJvcEJyb2tlciNyZW1vdmVDbGllbnRGcm9tQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIucmVtb3ZlQ2xpZW50RnJvbUNvbnRleHRHcm91cH0gdG8gYWN0dWFsbHkgdW5ncm91cFxuXHQgICAgICogdGhlIGNsaWVudC4gVXNlZCBieSBQbGF0Zm9ybSBXaW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSByZW1vdmVGcm9tQ29udGV4dEdyb3VwT3B0aW9ucyAtIENvbnRhaW5zIHRoZSB0YXJnZXQgaWRlbnRpdHkgdG8gcmVtb3ZlLlxuXHQgICAgICogQHBhcmFtIHNlbmRlcklkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHJlbW92ZUZyb21Db250ZXh0R3JvdXAoeyB0YXJnZXQgfSwgc2VuZGVySWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItcmVtb3ZlLWZyb20tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICh0YXJnZXQpIHtcblx0ICAgICAgICAgICAgLy8gSWYgYW4gZW5kcG9pbnRJZCBpcyBwcm92aWRlZCwgdXNlIHRoYXQuIFRoaXMgd2lsbCBsaWtlbHkgYmUgdXNlZCBieSBleHRlcm5hbCBhZGFwdGVycy5cblx0ICAgICAgICAgICAgaWYgKEludGVyb3BCcm9rZXIuaGFzRW5kcG9pbnRJZCh0YXJnZXQpKSB7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAodGFyZ2V0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2FuaXR5IGNoZWNrIGhlcmUgaW4gY2FzZSBhIHNpbmdsZSBhcHAgaGFzIG11bHRpcGxlIGNvbm5lY3Rpb25zXG5cdCAgICAgICAgICAgICAgICBjb25zdCBhbGxDb25uZWN0aW9ucyA9IHRoaXMuY2hhbm5lbC5jb25uZWN0aW9ucy5maWx0ZXIoKHgpID0+IHgudXVpZCA9PT0gdGFyZ2V0LnV1aWQgJiYgeC5uYW1lID09PSB0YXJnZXQubmFtZSk7XG5cdCAgICAgICAgICAgICAgICBpZiAoIWFsbENvbm5lY3Rpb25zLmxlbmd0aCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gY29ubmVjdGlvbiBmb3VuZCBmb3IgZ2l2ZW4gSWRlbnRpdHkgJHt0YXJnZXQudXVpZH0gJHt0YXJnZXQubmFtZX1gKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChhbGxDb25uZWN0aW9ucy5sZW5ndGggPiAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBNb3JlIHRoYW4gb25lIGNvbm5lY3Rpb24gZm91bmQgZm9yIGlkZW50aXR5ICR7dGFyZ2V0LnV1aWR9ICR7dGFyZ2V0Lm5hbWV9YCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuXHQgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGFsbENvbm5lY3Rpb25zKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAoY29ubmVjdGlvbikpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgLy8gTm8gdGFyZ2V0IHByb3ZpZGVkLCByZW1vdmUgdGhlIHNlbmRlciBmcm9tIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAoc2VuZGVySWRlbnRpdHkpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIHJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAgZG9lcyB0aGUgYWN0dWFsIHJlbW92ZSBvZiB0aGUgY2xpZW50IGZyb20gdGhlIENvbnRleHQgR3JvdXBcblx0ICAgIC8qKlxuXHQgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciB7QGxpbmsgSW50ZXJvcEJyb2tlciNyZW1vdmVGcm9tQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIucmVtb3ZlRnJvbUNvbnRleHRHcm91cH0uIERvZXMgdGhlIHdvcmsgb2YgYWN0dWFsbHkgcmVtb3ZpbmcgdGhlIGNsaWVudCBmcm9tIHRoZSBDb250ZXh0IEdyb3VwLlxuXHQgICAgICogVXNlZCBieSBQbGF0Zm9ybSBXaW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7IENsaWVudElkZW50aXR5IH0gY2xpZW50SWRlbnRpdHkgLSBJZGVudGl0eSBvZiB0aGUgY2xpZW50IHNlbmRlci5cblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmVtb3ZlQ2xpZW50RnJvbUNvbnRleHRHcm91cChjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1yZW1vdmUtY2xpZW50LWZyb20tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGNsaWVudFN0YXRlLmNvbnRleHRHcm91cElkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhd2FpdCB0aGlzLnNldEN1cnJlbnRDb250ZXh0R3JvdXBJbkNsaWVudE9wdGlvbnMoY2xpZW50SWRlbnRpdHksIG51bGwpO1xuXHQgICAgfVxuXHQgICAgLy8gVXNlZCBieSBwbGF0Zm9ybSB3aW5kb3dzIHRvIGtub3cgd2hhdCBjbGllbnQgZ3JvdXBzIHRoZSBwcm92aWRlciBoYXMgZGVjbGFyZWQuIEFsc28gdXNlZCBpbnRlcm5hbGx5IHRvIGFjY2VzcyBjb250ZXh0IGdyb3Vwcy4gT3ZlcnJpZGVhYmxlIHNvIHRoYXQgdGhlIHBsYXRmb3JtIGRldmVsb3BlciBjYW4gbW9kaWZ5IGl0LlxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBJbnRlcm9wLUJyb2tlci1kZWZpbmVkIGNvbnRleHQgZ3JvdXBzIGF2YWlsYWJsZSBmb3IgYW4gZW50aXR5IHRvIGpvaW4uIEJlY2F1c2UgdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIHRoZSByZXN0IG9mIHRoZSBJbnRlcm9wIEJyb2tlciB0byBmZXRjaCB0aGUgQ29udGV4dCBHcm91cHMsIG92ZXJyaWRpbmcgdGhpcyBhbGxvd3MgeW91IHRvIGN1c3RvbWl6ZSB0aGUgQ29udGV4dCBHcm91cHMgZm9yIHRoZSBJbnRlcm9wIEJyb2tlci4gSG93ZXZlciwgd2UgcmVjb21tZW5kIGN1c3RvbWl6aW5nIHRoZSBjb250ZXh0IGdyb3VwcyB0aHJvdWdoIGNvbmZpZ3VyYXRpb24gaW5zdGVhZC5cblx0ICAgICAqIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBnZXRDb250ZXh0R3JvdXBzKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1nZXQtY29udGV4dC1ncm91cHMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvLyBDcmVhdGUgY29weSBmb3IgaW1tdXRhYmlsaXR5XG5cdCAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3VwcywgXCJmXCIpLm1hcCgoY29udGV4dEdyb3VwKSA9PiB7XG5cdCAgICAgICAgICAgIHJldHVybiB7IC4uLmNvbnRleHRHcm91cCB9O1xuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgLy8gVXNlZCB0byBieSBwbGF0Zm9ybSB3aW5kb3dzIHRvIGdldCBkaXNwbGF5IG1ldGFkYXRhIGZvciBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAvKipcblx0ICAgICAqIEdldHMgZGlzcGxheSBpbmZvIGZvciBhIGNvbnRleHQgZ3JvdXBcblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGdldEluZm9Gb3JDb250ZXh0R3JvdXBPcHRpb25zIC0gQ29udGFpbnMgY29udGV4dEdyb3VwSWQsIHRoZSBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBkaXNwbGF5IGluZm8gZm9yLlxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0pIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItZ2V0LWluZm8tZm9yLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5nZXRDb250ZXh0R3JvdXBzKCkuZmluZCgoY29udGV4dEdyb3VwKSA9PiBjb250ZXh0R3JvdXAuaWQgPT09IGNvbnRleHRHcm91cElkKTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgYnkgcGxhdGZvcm0gd2luZG93cyB0byBnZXQgYWxsIGNsaWVudHMgZm9yIGEgY29udGV4dCBncm91cC5cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBhbGwgY2xpZW50cyBmb3IgYSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzICoqVGhpcyBpcyBwcmltYXJpbHkgdXNlZCBmb3IgcGxhdGZvcm0gd2luZG93cy4gVmlld3Mgd2l0aGluIGEgcGxhdGZvcm0gc2hvdWxkIG5vdCBoYXZlIHRvIHVzZSB0aGlzIEFQSS4qKlxuXHQgICAgICogUmV0dXJucyB0aGUgSW50ZXJvcC1Ccm9rZXItZGVmaW5lZCBjb250ZXh0IGdyb3VwcyBhdmFpbGFibGUgZm9yIGFuIGVudGl0eSB0byBqb2luLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBnZXRBbGxDbGllbnRzSW5Db250ZXh0R3JvdXBPcHRpb25zIC0gQ29udGFpbnMgY29udGV4dEdyb3VwSWQsIHRoZSBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBjbGllbnRzIGZvci5cblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0pIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItZ2V0LWFsbC1jbGllbnRzLWluLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5Db250ZXh0R3JvdXAgPSBBcnJheS5mcm9tKHRoaXMuaW50ZXJvcENsaWVudHMudmFsdWVzKCkpXG5cdCAgICAgICAgICAgIC5maWx0ZXIoKGNvbm5lY3RlZENsaWVudCkgPT4gY29ubmVjdGVkQ2xpZW50LmNvbnRleHRHcm91cElkID09PSBjb250ZXh0R3JvdXBJZClcblx0ICAgICAgICAgICAgLm1hcCgoc3Vic2NyaXB0aW9uU3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvblN0YXRlLmNsaWVudElkZW50aXR5O1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBjbGllbnRzSW5Db250ZXh0R3JvdXA7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciBsYXVuY2hpbmcgb2YgYXBwbGljYXRpb25zIHRoYXQgY2FuIGhhbmRsZSBhIGdpdmVuIGludGVudCwgYW5kIGRlbGVnYXRpb24gb2YgaW50ZW50cyB0byB0aG9zZSBhcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gbWFrZSB0aGlzIGNhbGwgRkRDMy1Db21wbGlhbnQgaXQgd291bGQgbmVlZCB0byByZXR1cm4gYW4gSW50ZW50UmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogaW50ZXJmYWNlIEludGVudFJlc29sdXRpb24ge1xuXHQgICAgICogICBzb3VyY2U6IFRhcmdldEFwcDtcblx0ICAgICAqICAgLy8gZGVwcmVjYXRlZCwgbm90IGFzc2lnbmFibGUgZnJvbSBpbnRlbnQgbGlzdGVuZXJzXG5cdCAgICAgKiAgIGRhdGE/OiBvYmplY3Q7XG5cdCAgICAgKiAgIHZlcnNpb246IHN0cmluZztcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIE1vcmUgaW5mb3JtYXRpb24gb24gdGhlIEludGVudFJlc29sdXRpb24gdHlwZSBjYW4gYmUgZm91bmQgaW4gdGhlIFtGREMzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL0ludGVudFJlc29sdXRpb24pLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgVGhlIGNvbWJpbmF0aW9uIG9mIGFuIGFjdGlvbiBhbmQgYSBjb250ZXh0IHRoYXQgaXMgcGFzc2VkIHRvIGFuIGFwcGxpY2F0aW9uIGZvciByZXNvbHV0aW9uLlxuXHQgICAgICogQHBhcmFtICBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIC8vIG92ZXJyaWRlIGNhbGwgc28gd2Ugc2V0IGludGVudCB0YXJnZXQgYW5kIGNyZWF0ZSB2aWV3IHRoYXQgd2lsbCBoYW5kbGUgaXRcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudChpbnRlbnQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBzdXBlci5zZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB7IHV1aWQ6ICdwbGF0Zm9ybS11dWlkJywgbmFtZTogJ2ludGVudC12aWV3JyB9KTtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyBuYW1lOiAnZm9vJywgdXVpZDogJ3BsYXRmb3JtLXV1aWQnIH0pO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRWaWV3ID0gYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh7IHVybDogJ2h0dHA6Ly9vcGVuZmluLmNvJywgbmFtZTogJ2ludGVudC12aWV3JyB9LCB3aW4uaWRlbnRpdHkpO1xuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIHJldHVybiBuZXcgT3ZlcnJpZGUoKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuXHQgICAgYXN5bmMgaGFuZGxlRmlyZWRJbnRlbnQoaW50ZW50LCBjbGllbnRJZGVudGl0eSAvLyBUT0RPKENPUkUtODExKTogcmVtb3ZlIGlubGluZSBpbnRlcnNlY3RlZCB0eXBlXG5cdCAgICApIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLnJhaXNlSW50ZW50JywgJ0ludGVyb3BCcm9rZXIuaGFuZGxlRmlyZWRJbnRlbnQnLCBjbGllbnRJZGVudGl0eSwgJ2ludGVyb3BDbGllbnQuZmlyZUludGVudCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG91bGQgYmUgY2FsbGVkIGluIHtAbGluayBJbnRlcm9wQnJva2VyI2hhbmRsZUZpcmVkSW50ZW50IEludGVyb3BCcm9rZXIuaGFuZGxlRmlyZWRJbnRlbnR9LlxuXHQgICAgICogV2hpbGUgaGFuZGxlRmlyZWRJbnRlbnQgaXMgcmVzcG9uc2libGUgZm9yIGxhdW5jaGluZyBhcHBsaWNhdGlvbnMsIHNldEludGVudFRhcmdldCBpcyB1c2VkIHRvIHRlbGwgdGhlIEludGVyb3BCcm9rZXIgd2hpY2ggYXBwbGljYXRpb24gc2hvdWxkIHJlY2VpdmUgdGhlIGludGVudCB3aGVuIGl0IGlzIHJlYWR5LlxuXHQgICAgICogQHBhcmFtIGludGVudCBUaGUgY29tYmluYXRpb24gb2YgYW4gYWN0aW9uIGFuZCBhIGNvbnRleHQgdGhhdCBpcyBwYXNzZWQgdG8gYW4gYXBwbGljYXRpb24gZm9yIHJlc29sdXRpb24uXG5cdCAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gSWRlbnRpdHkgb2YgdGhlIHRhcmdldCB0aGF0IHdpbGwgaGFuZGxlIHRoZSBpbnRlbnQuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB0YXJnZXQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItc2V0LWludGVudC10YXJnZXQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIHRoaXMgaXMgb25seSBmb3IgYXBpIGFuYWx5dGljcyBwdXJwb3Nlc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQodGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgIGNvbnN0IGhhbmRsZXJJZCA9IGBpbnRlbnQtaGFuZGxlci0ke2ludGVudC5uYW1lfWA7XG5cdCAgICAgICAgaWYgKCF0YXJnZXRJbmZvKSB7XG5cdCAgICAgICAgICAgIHRoaXMuaW50ZW50Q2xpZW50TWFwLnNldCh0YXJnZXQubmFtZSwgbmV3IE1hcCgpKTtcblx0ICAgICAgICAgICAgY29uc3QgbmV3SGFuZGxlckluZm9NYXAgPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQodGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgICAgICBpZiAobmV3SGFuZGxlckluZm9NYXApIHtcblx0ICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJJbmZvTWFwLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogZmFsc2UsIHBlbmRpbmdJbnRlbnRzOiBbaW50ZW50XSB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY29uc3QgaGFuZGxlckluZm8gPSB0YXJnZXRJbmZvLmdldChoYW5kbGVySWQpO1xuXHQgICAgICAgICAgICBpZiAoIWhhbmRsZXJJbmZvKSB7XG5cdCAgICAgICAgICAgICAgICB0YXJnZXRJbmZvLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogZmFsc2UsIHBlbmRpbmdJbnRlbnRzOiBbaW50ZW50XSB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJbmZvLnBlbmRpbmdJbnRlbnRzLnB1c2goaW50ZW50KTtcblx0ICAgICAgICAgICAgICAgIGlmIChoYW5kbGVySW5mby5jbGllbnRJZGVudGl0eSAmJiBoYW5kbGVySW5mby5pc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgcGVuZGluZ0ludGVudHMgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVudFRvU2VuZCA9IHBlbmRpbmdJbnRlbnRzW3BlbmRpbmdJbnRlbnRzLmxlbmd0aCAtIDFdO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmludm9rZUludGVudEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgaW50ZW50VG9TZW5kKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8ucGVuZGluZ0ludGVudHMgPSBbXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGludGVudCBoYW5kbGVyIGZvciBjbGllbnQgJHtjbGllbnRJZGVudGl0eS51dWlkfS8ke2NsaWVudElkZW50aXR5Lm5hbWV9LyR7Y2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH1gKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8uaXNSZWFkeSA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJldHVybmluZyBpbmZvcm1hdGlvbiBvbiBhIHBhcnRpY3VsYXIgSW50ZW50LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdoZW5ldmVyIEludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCBpcyBjYWxsZWQgdGhpcyBmdW5jdGlvbiB3aWxsIGZpcmUuIFRoZSBvcHRpb25zIGFyZ3VtZW50IGdpdmVzIHlvdVxuXHQgICAgICogYWNjZXNzIHRvIHRoZSBpbnRlbnQgbmFtZSBhbmQgYW55IG9wdGlvbmFsIGNvbnRleHQgdGhhdCB3YXMgcGFzc2VkIGFuZCBjbGllbnRJZGVudGl0eSBpcyB0aGUgaWRlbnRpdHkgb2YgdGhlIGNsaWVudFxuXHQgICAgICogdGhhdCBtYWRlIHRoZSBjYWxsLiBJZGVhbGx5IGhlcmUgeW91IHdvdWxkIGZldGNoIHRoZSBpbmZvIGZvciB0aGUgaW50ZW50IGFuZCByZXR1cm4gaXQgd2l0aCB0aGUgc2hhcGUgdGhhdCB0aGVcblx0ICAgICAqIEludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCBjYWxsIGlzIGV4cGVjdGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBBcHAgSW50ZW50OlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogTW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgQXBwSW50ZW50IHR5cGUgY2FuIGJlIGZvdW5kIGluIHRoZSBbRkRDMyBkb2N1bWVudGF0aW9uXShodHRwczovL2ZkYzMuZmlub3Mub3JnL2RvY3MvYXBpL3JlZi9BcHBJbnRlbnQpLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHkgSWRlbnRpdHkgb2YgdGhlIENsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdCAgICAgKiAgICAgaW50ZXJvcE92ZXJyaWRlOiBhc3luYyAoSW50ZXJvcEJyb2tlcikgPT4ge1xuXHQgICAgICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICogICAgICAgICAgICAgYXN5bmMgaGFuZGxlSW5mb0ZvckludGVudChvcHRpb25zLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIFlvdXIgY29kZSBnb2VzIGhlcmUuXG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBoYW5kbGVJbmZvRm9ySW50ZW50KG9wdGlvbnMsIGNsaWVudElkZW50aXR5IC8vIFRPRE8oQ09SRS04MTEpOiByZW1vdmUgaW5saW5lIGludGVyc2VjdGVkIHR5cGVcblx0ICAgICkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZmluZEludGVudCcsICdJbnRlcm9wQnJva2VyLmhhbmRsZUluZm9Gb3JJbnRlbnQnLCBjbGllbnRJZGVudGl0eSwgJ2ludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXNwb25zaWJsZSBmb3IgcmV0dXJuaW5nIGluZm9ybWF0aW9uIG9uIHdoaWNoIEludGVudHMgYXJlIG1lYW50IHRvIGhhbmRsZSBhIHNwZWNpZmljIENvbnRleHQuXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgUmVzcG9uc2libGUgZm9yIHJldHVybmluZyBpbmZvcm1hdGlvbiBvbiB3aGljaCBJbnRlbnRzIGFyZSBtZWFudCB0byBoYW5kbGUgYSBzcGVjaWZpYyBDb250ZXh0LiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogV2hlbmV2ZXIgSW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBpcyBjYWxsZWQgdGhpcyBmdW5jdGlvbiB3aWxsIGZpcmUuIFRoZSBjb250ZXh0IGFyZ3VtZW50IGdpdmVzIHlvdSBhY2Nlc3MgdG8gdGhlIGNvbnRleHQgdGhhdCB0aGUgY2xpZW50IHdhbnRzIGluZm9ybWF0aW9uIG9uIGFuZCBjbGllbnRJZGVudGl0eSBpcyB0aGUgaWRlbnRpdHkgb2YgdGhlIGNsaWVudCB0aGF0IG1hZGUgdGhlIGNhbGwuIElkZWFsbHkgaGVyZSB5b3Ugd291bGQgZmV0Y2ggdGhlIGluZm8gZm9yIGFueSBpbnRlbnQgdGhhdCBjYW4gaGFuZGxlIGFuZCByZXR1cm4gaXQgd2l0aCB0aGUgc2hhcGUgdGhhdCB0aGUgSW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBjYWxsIGlzIGV4cGVjdGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBhcnJheSBvZiBBcHBJbnRlbnRzOlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyBbe1xuXHQgICAgICogLy8gICAgIGludGVudDogeyBuYW1lOiBcIlN0YXJ0Q2FsbFwiLCBkaXNwbGF5TmFtZTogXCJDYWxsXCIgfSxcblx0ICAgICAqIC8vICAgICBhcHBzOiBbeyBuYW1lOiBcIlNreXBlXCIgfV1cblx0ICAgICAqIC8vIH0sXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfV07XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBNb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBBcHBJbnRlbnQgdHlwZSBjYW4gYmUgZm91bmQgaW4gdGhlIFtGREMzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL0FwcEludGVudCkuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgRGF0YSBwYXNzZWQgYmV0d2VlbiBlbnRpdGllcyBhbmQgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IElkZW50aXR5IG9mIHRoZSBDbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgLy8gWW91ciBjb2RlIGdvZXMgaGVyZS5cblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKCk7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIGNsaWVudElkZW50aXR5IC8vIFRPRE8oQ09SRS04MTEpOiByZW1vdmUgaW5saW5lIGludGVyc2VjdGVkIHR5cGVcblx0ICAgICkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZmluZEludGVudHNCeUNvbnRleHQnLCAnSW50ZXJvcEJyb2tlci5oYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcsIGNsaWVudElkZW50aXR5LCAnaW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBhbiBJbnRlbnQgYmFzZWQgb24gYSBzcGVjaWZpYyBDb250ZXh0LlxuXHQgICAgICogTXVzdCBiZSBvdmVycmlkZGVuLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdoZW5ldmVyIEludGVyb3BDbGllbnQuZmlyZUludGVudEZvckNvbnRleHQgaXMgY2FsbGVkIHRoaXMgZnVuY3Rpb24gd2lsbCBmaXJlLiBUaGUgY29udGV4dEZvckludGVudCBhcmd1bWVudFxuXHQgICAgICogZ2l2ZXMgeW91IGFjY2VzcyB0byB0aGUgY29udGV4dCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgdG8gYW4gaW50ZW50LiBJdCBhbHNvIGNhbiBvcHRpb25hbGx5IGNvbnRhaW4gYW55IG1ldGFkYXRhIHJlbGV2YW50XG5cdCAgICAgKiB0byByZXNvbHZpbmcgaXQsIGxpa2UgYSBzcGVjaWZpYyBhcHAgdGhlIGNsaWVudCB3YW50cyB0aGUgY29udGV4dCB0byBiZSBoYW5kbGVkIGJ5LiBUaGUgY2xpZW50SWRlbnRpdHkgaXMgdGhlIGlkZW50aXR5XG5cdCAgICAgKiBvZiB0aGUgY2xpZW50IHRoYXQgbWFkZSB0aGUgY2FsbC5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBJbnRlbnRSZXNvbHV0aW9uOlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogTW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgSW50ZW50UmVzb2x1dGlvbiB0eXBlIGNhbiBiZSBmb3VuZCBpbiB0aGUgW0ZEQzMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9mZGMzLmZpbm9zLm9yZy9kb2NzL2FwaS9yZWYvTWV0YWRhdGEjaW50ZW50cmVzb2x1dGlvbikuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRGb3JJbnRlbnQgRGF0YSBwYXNzZWQgYmV0d2VlbiBlbnRpdGllcyBhbmQgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IElkZW50aXR5IG9mIHRoZSBDbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGhhbmRsZUZpcmVkSW50ZW50Rm9yQ29udGV4dChjb250ZXh0Rm9ySW50ZW50LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIFlvdXIgY29kZSBnb2VzIGhlcmUuXG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQoY29udGV4dEZvckludGVudCwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLnJhaXNlSW50ZW50Rm9yQ29udGV4dCcsICdJbnRlcm9wQnJva2VyLmhhbmRsZUZpcmVkSW50ZW50Rm9yQ29udGV4dCcsIGNsaWVudElkZW50aXR5LCAnaW50ZXJvcENsaWVudC5maXJlSW50ZW50Rm9yQ29udGV4dCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnRGb3JDb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJvdmlkZXMgdGhlIGlkZW50aXR5IG9mIGFueSBJbnRlcm9wIENsaWVudCB0aGF0IGRpc2Nvbm5lY3RzIGZyb20gdGhlIEludGVyb3AgQnJva2VyLiBJdCBpcyBtZWFudCB0byBiZSBvdmVycmlkZW4uXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHlcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBjbGllbnREaXNjb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDbGllbnQgd2l0aCBpZGVudGl0eSAke3V1aWR9LyR7bmFtZX0gaGFzIGJlZW4gZGlzY29ubmVjdGVkYCk7XG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBjbGllbnREaXNjb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiBjaGFubmVsLm9uRGlzY29ubmVjdGlvbi5cblx0ICAgICAgICAvLyBJdCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIHRvIGluZm9ybSB3aGVuIGFuIEludGVyb3AgQ2xpZW50IGhhcyBiZWVuIGRpc2Nvbm5lY3RlZC5cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBhbiBmZGMzLm9wZW4gY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlbi5cblx0ICAgICAqIEBwYXJhbSBmZGMzT3Blbk9wdGlvbnMgZmRjMy5vcGVuIG9wdGlvbnNcblx0ICAgICAqIEBwYXJhbSBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGZkYzNIYW5kbGVPcGVuKHsgYXBwLCBjb250ZXh0IH0sIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3Qgd2FybmluZyA9ICgwLCB1dGlsc18xLmdlbmVyYXRlT3ZlcnJpZGVXYXJuaW5nKSgnZmRjMy5vcGVuJywgJ0ludGVyb3BCcm9rZXIuZmRjM0hhbmRsZU9wZW4nLCBjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcpO1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcih1dGlsc18xLkJST0tFUl9FUlJPUlMuZmRjM09wZW4pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIHRoZSBmZGMzLmZpbmRJbnN0YW5jZXMgY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlblxuXHQgICAgICogQHBhcmFtIGFwcCBBcHBJZGVudGlmaWVyIHRoYXQgd2FzIHBhc3NlZCB0byBmZGMzLmZpbmRJbnN0YW5jZXNcblx0ICAgICAqIEBwYXJhbSBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGZkYzNIYW5kbGVGaW5kSW5zdGFuY2VzKGFwcCwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLm9wZW4nLCAnSW50ZXJvcEJyb2tlci5mZGMzSGFuZGxlRmluZEluc3RhbmNlcycsIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjb25zb2xlLndhcm4od2FybmluZyk7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5mZGMzRmluZEluc3RhbmNlcyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgdGhlIGZkYzMuZ2V0QXBwTWV0YWRhdGEgY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlblxuXHQgICAgICogQHBhcmFtIGFwcCBBcHBJZGVudGlmaWVyIHRoYXQgd2FzIHBhc3NlZCB0byBmZGMzLmdldEFwcE1ldGFkYXRhXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHkgSWRlbnRpdHkgb2YgdGhlIENsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBmZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEoYXBwLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZ2V0QXBwTWV0YWRhdGEnLCAnSW50ZXJvcEJyb2tlci5mZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEnLCBjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcpO1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcih1dGlsc18xLkJST0tFUl9FUlJPUlMuZmRjM0dldEFwcE1ldGFkYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIEludGVyb3AgQnJva2VyIHdoZW5ldmVyIGEgQ29udGV4dCBoYW5kbGVyIHdvdWxkIGZpcmUuXG5cdCAgICAgKiBGb3IgRkRDMyAyLjAgeW91IHdvdWxkIG5lZWQgdG8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBhbmQgYWRkIHRoZSBjb250ZXh0TWV0YWRhdGEgYXNcblx0ICAgICAqIHBhcnQgb2YgdGhlIENvbnRleHQgb2JqZWN0LiBUaGVuIHdvdWxkIHlvdSBuZWVkIHRvIGNhbGxcblx0ICAgICAqIHN1cGVyLmludm9rZUNvbnRleHRIYW5kbGVyIHBhc3NpbmcgaXQgdGhpcyBuZXcgQ29udGV4dCBvYmplY3QgYWxvbmcgd2l0aCB0aGUgY2xpZW50SWRlbnRpdHkgYW5kIGhhbmRsZXJJZFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5XG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlcklkXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAuLi5jb250ZXh0LFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICBjb250ZXh0TWV0YWRhdGE6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZToge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcElkOiAnb3BlbmZpbi1hcHAnLFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6ICczRDU0RDQ1NkQ5SFQwJ1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpIHtcblx0ICAgICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIoKTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBhd2FpdCBwcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGNvbnRleHQgaGFuZGxlciAke2hhbmRsZXJJZH0gZm9yIGNvbnRleHQgdHlwZSAke2NvbnRleHQudHlwZX0gaW4gY2xpZW50ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0vJHtjbGllbnRJZGVudGl0eS5uYW1lfS8ke2NsaWVudElkZW50aXR5LmVuZHBvaW50SWR9YCwgZXJyb3IpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIEludGVyb3AgQnJva2VyIHdoZW5ldmVyIGFuIEludGVudCBoYW5kbGVyIHdvdWxkIGZpcmUuXG5cdCAgICAgKiBGb3IgRkRDMyAyLjAgeW91IHdvdWxkIG5lZWQgdG8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBhbmQgYWRkIHRoZSBjb250ZXh0TWV0YWRhdGEgYXNcblx0ICAgICAqIHBhcnQgb2YgdGhlIENvbnRleHQgb2JqZWN0IGluc2lkZSB0aGUgSW50ZW50IG9iamVjdC4gVGhlbiB3b3VsZCB5b3UgbmVlZCB0byBjYWxsXG5cdCAgICAgKiBzdXBlci5pbnZva2VJbnRlbnRIYW5kbGVyIHBhc3NpbmcgaXQgdGhpcyBuZXcgSW50ZW50IG9iamVjdCBhbG9uZyB3aXRoIHRoZSBjbGllbnRJZGVudGl0eSBhbmQgaGFuZGxlcklkXG5cdCAgICAgKiBAcGFyYW0gQ2xpZW50SWRlbnRpdHlcblx0ICAgICAqIEBwYXJhbSBoYW5kbGVySWRcblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdCAgICAgKiAgICAgaW50ZXJvcE92ZXJyaWRlOiBhc3luYyAoSW50ZXJvcEJyb2tlcikgPT4ge1xuXHQgICAgICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICogICAgICAgICAgICAgYXN5bmMgaW52b2tlSW50ZW50SGFuZGxlcihjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KSB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgY29uc3QgeyBjb250ZXh0IH0gPSBpbnRlbnQ7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmludm9rZUludGVudEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAuLi5pbnRlbnQsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmNvbnRleHQsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0TWV0YWRhdGE6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwSWQ6ICdvcGVuZmluLWFwcCcsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6ICczRDU0RDQ1NkQ5SFQwJ1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIHJldHVybiBuZXcgT3ZlcnJpZGUoKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBpbnZva2VJbnRlbnRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudCkge1xuXHQgICAgICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgdGhpcy5nZXRQcm92aWRlcigpO1xuXHQgICAgICAgIGF3YWl0IHByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgZmRjMy5nZXRJbmZvIGZvciBGREMzIDIuMFxuXHQgICAgICogV291bGQgbmVlZCB0byByZXR1cm4gdGhlIG9wdGlvbmFsRmVhdHVyZXMgYW5kIGFwcE1ldGFkYXRhIGZvciB0aGUge0BsaW5rIGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL01ldGFkYXRhI2ltcGxlbWVudGF0aW9ubWV0YWRhdGEgSW1wbGVtZW50YXRpb25NZXRhZGF0YX0uXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHlcblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBmZGMzSGFuZGxlR2V0SW5mbyhwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgZmRjM1ZlcnNpb24gfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgZmRjM1ZlcnNpb24sXG5cdCAgICAgICAgICAgIC4uLl9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfZmRjM0luZm8sIFwiZlwiKSxcblx0ICAgICAgICAgICAgb3B0aW9uYWxGZWF0dXJlczoge1xuXHQgICAgICAgICAgICAgICAgT3JpZ2luYXRpbmdBcHBNZXRhZGF0YTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBVc2VyQ2hhbm5lbE1lbWJlcnNoaXBBUElzOiB0cnVlXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGFwcE1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgICAgICBhcHBJZDogJycsXG5cdCAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiAnJ1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBpbmZvIGZvciBlYWNoIEludGVyb3AgQ2xpZW50IGNvbm5lY3RlZCB0byB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKlxuXHQgICAgICogRkRDMyAyLjA6IFVzZSB0aGUgZW5kcG9pbnRJZCBpbiB0aGUgQ2xpZW50SW5mbyBhcyB0aGUgaW5zdGFuY2VJZCB3aGVuIGdlbmVyYXRpbmdcblx0ICAgICAqIGFuIEFwcElkZW50aWZpZXIuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgRkRDMyAyLjAgTm90ZTogV2hlbiBuZWVkaW5nIGFuIGluc3RhbmNlSWQgdG8gZ2VuZXJhdGUgYW4gQXBwSWRlbnRpZmllciB1c2UgdGhpcyBjYWxsIHRvXG5cdCAgICAgKiBnZXQgdGhlIGVuZHBvaW50SWQgYW5kIHVzZSBpdCBhcyB0aGUgaW5zdGFuY2VJZC4gSW4gdGhlIEV4YW1wbGUgYmVsb3cgd2Ugb3ZlcnJpZGUgaGFuZGxlRmlyZWRJbnRlbnRcblx0ICAgICAqIGFuZCB0aGVuIGNhbGwgc3VwZXIuZ2V0QWxsQ2xpZW50SW5mbyB0byBnZW5lcmF0ZSB0aGUgQXBwSWRlbnRpZmllciBmb3IgdGhlIEludGVudFJlc29sdXRpb24uXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogLy8gRkRDMyAyLjAgRXhhbXBsZTpcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyLCAuLi5hcmdzKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudChpbnRlbnQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBzdXBlci5zZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB7IHV1aWQ6ICdwbGF0Zm9ybS11dWlkJywgbmFtZTogJ2ludGVudC12aWV3JyB9KTtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyBuYW1lOiAnZm9vJywgdXVpZDogJ3BsYXRmb3JtLXV1aWQnIH0pO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRWaWV3ID0gYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh7IHVybDogJ2h0dHA6Ly9vcGVuZmluLmNvJywgbmFtZTogJ2ludGVudC12aWV3JyB9LCB3aW4uaWRlbnRpdHkpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBhbGxDbGllbnRJbmZvID0gYXdhaXQgc3VwZXIuZ2V0QWxsQ2xpZW50SW5mbygpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBpbmZvRm9yVGFyZ2V0ID0gYWxsQ2xpZW50SW5mby5maW5kKChjbGllbnRJbmZvKSA9PiB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRJbmZvLnV1aWQgPT09ICdwbGF0Zm9ybS11dWlkJyAmJiBjbGllbnRJbmZvLm5hbWUgPT09ICdpbnRlbnQtdmlldyc7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgKlxuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgYXBwSWQ6ICdpbnRlbnQtdmlldycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6IGluZm9Gb3JUYXJnZXQuZW5kcG9pbnRJZFxuXHQgICAgICogICAgICAgICAgICAgICAgIH1cblx0ICAgICAqXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgc291cmNlLFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICBpbnRlbnQ6IGludGVudC5uYW1lXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKC4uLmFyZ3MpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEFsbENsaWVudEluZm8oKSB7XG5cdCAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCB0aGlzLmdldFByb3ZpZGVyKCk7XG5cdCAgICAgICAgcmV0dXJuIHByb3ZpZGVyLmdldEFsbENsaWVudEluZm8oKTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBTbmFwc2hvdCBBUElzXG5cdCAgICAqL1xuXHQgICAgLy8gVXNlZCB0byBzYXZlIGludGVyb3AgYnJva2VyIHN0YXRlIGluIHNuYXBzaG90c1xuXHQgICAgZGVjb3JhdGVTbmFwc2hvdChzbmFwc2hvdCkge1xuXHQgICAgICAgIHJldHVybiB7IC4uLnNuYXBzaG90LCBpbnRlcm9wU25hcHNob3REZXRhaWxzOiB7IGNvbnRleHRHcm91cFN0YXRlczogdGhpcy5nZXRDb250ZXh0R3JvdXBTdGF0ZXMoKSB9IH07XG5cdCAgICB9XG5cdCAgICAvLyBVc2VkIHRvIHJlc3RvcmUgaW50ZXJvcCBicm9rZXIgc3RhdGUgaW4gc25hcHNob3RzLlxuXHQgICAgYXBwbHlTbmFwc2hvdChzbmFwc2hvdCwgb3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cFN0YXRlcyA9IHNuYXBzaG90Py5pbnRlcm9wU25hcHNob3REZXRhaWxzPy5jb250ZXh0R3JvdXBTdGF0ZXM7XG5cdCAgICAgICAgaWYgKGNvbnRleHRHcm91cFN0YXRlcykge1xuXHQgICAgICAgICAgICBpZiAoIW9wdGlvbnM/LmNsb3NlRXhpc3RpbmdXaW5kb3dzKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUV4aXN0aW5nQ2xpZW50cyhjb250ZXh0R3JvdXBTdGF0ZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMucmVoeWRyYXRlQ29udGV4dEdyb3VwU3RhdGVzKGNvbnRleHRHcm91cFN0YXRlcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgdXBkYXRlRXhpc3RpbmdDbGllbnRzKGNvbnRleHRHcm91cFN0YXRlcykge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmludGVyb3BDbGllbnRzO1xuXHQgICAgICAgIGNsaWVudHMuZm9yRWFjaCgoc3ViU3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgY29udGV4dEdyb3VwSWQsIGNvbnRleHRIYW5kbGVycyB9ID0gc3ViU3RhdGU7XG5cdCAgICAgICAgICAgIGlmIChjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBDb250ZXh0cyA9IGNvbnRleHRHcm91cFN0YXRlc1tjb250ZXh0R3JvdXBJZF07XG5cdCAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFssIGNvbnRleHRdIG9mIE9iamVjdC5lbnRyaWVzKGdyb3VwQ29udGV4dHMpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzLmZvckVhY2goKGNvbnRleHRIYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9ID0gY29udGV4dEhhbmRsZXI7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJbnRlcm9wQnJva2VyLmlzQ29udGV4dFR5cGVDb21wYXRpYmxlKGNvbnRleHQudHlwZSwgY29udGV4dFR5cGUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgdG8gc3RvcmUgY29udGV4dCBncm91cCBzdGF0ZSBpbiBzbmFwc2hvdHNcblx0ICAgIGdldENvbnRleHRHcm91cFN0YXRlcygpIHtcblx0ICAgICAgICByZXR1cm4gSW50ZXJvcEJyb2tlci50b09iamVjdCh0aGlzLmNvbnRleHRHcm91cHNCeUlkKTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgdG8gcmVoeWRyYXRlIHRoZSBjb250ZXh0IHN0YXRlIGZyb20gYSBzbmFwc2hvdFxuXHQgICAgcmVoeWRyYXRlQ29udGV4dEdyb3VwU3RhdGVzKGluY29taW5nQ29udGV4dEdyb3VwU3RhdGVzKSB7XG5cdCAgICAgICAgY29uc3QgY29udGV4dEdyb3VwU3RhdGVzID0gT2JqZWN0LmVudHJpZXMoaW5jb21pbmdDb250ZXh0R3JvdXBTdGF0ZXMpO1xuXHQgICAgICAgIGZvciAoY29uc3QgW2NvbnRleHRHcm91cElkLCBjb250ZXh0c10gb2YgY29udGV4dEdyb3VwU3RhdGVzKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRPYmplY3RzID0gT2JqZWN0LmVudHJpZXMoY29udGV4dHMpO1xuXHQgICAgICAgICAgICBmb3IgKGNvbnN0IFtjb250ZXh0VHlwZSwgY29udGV4dF0gb2YgY29udGV4dE9iamVjdHMpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHRHcm91cHNCeUlkLmhhcyhjb250ZXh0R3JvdXBJZCkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dEdyb3VwU3RhdGUgPSB0aGlzLmNvbnRleHRHcm91cHNCeUlkLmdldChjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbnRleHRHcm91cFN0YXRlLnNldChjb250ZXh0VHlwZSwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGxvZ2ljIHdpbGwgY2hhbmdlIHdoZW4gZHluYW1pYyBjb250ZXh0IGdyb3VwIGNyZWF0aW9uIGNvbWVzIGluLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQXR0ZW1wdGluZyB0byBzZXQgYSBjb250ZXh0IGdyb3VwIHRoYXQgaXNuJ3QgaW4gdGhlIGNvbnRleHQgZ3JvdXAgbWFwcGluZy4gU2tpcHBpbmcgY29udGV4dCBncm91cCByZWh5ZHJhdGlvbiBmb3I6ICR7Y29udGV4dEdyb3VwSWR9YCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKlxuXHQgICAgSW50ZXJuYWwgQ29udGV4dCBIYW5kbGVyIEFQSXNcblx0ICAgICovXG5cdCAgICAvLyBVc2VkIHRvIGdpdmUgY29udGV4dCB0byBhIGNsaWVudCB0aGF0IGhhcyByZWdpc3RlcmVkIHRoZWlyIGNvbnRleHQgaGFuZGxlclxuXHQgICAgY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkKHsgY29udGV4dFR5cGUsIGhhbmRsZXJJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGhhbmRsZXJJbmZvID0geyBjb250ZXh0VHlwZSwgaGFuZGxlcklkIH07XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjbGllbnRTdGF0ZT8uY29udGV4dEhhbmRsZXJzLnNldChoYW5kbGVySWQsIGhhbmRsZXJJbmZvKTtcblx0ICAgICAgICBpZiAoY2xpZW50U3RhdGUgJiYgY2xpZW50U3RhdGUuY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjb250ZXh0R3JvdXBJZCB9ID0gY2xpZW50U3RhdGU7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cE1hcCA9IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuZ2V0KGNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNlbmQgdGhpcyBzaW5nbGUgaGFuZGxlciBhbGwgb2YgdGhlIGNvbnRleHQsIGJlY2F1c2UgaXQgYWNjZXB0cyBhbGwuXG5cdCAgICAgICAgICAgICAgICBjb250ZXh0R3JvdXBNYXAuZm9yRWFjaCgoY29udGV4dCwgXykgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIGlmIChjb250ZXh0R3JvdXBNYXAuaGFzKGNvbnRleHRUeXBlKSkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dEZvclR5cGUgPSBjb250ZXh0R3JvdXBNYXAuZ2V0KGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgICAgIGlmIChjb250ZXh0Rm9yVHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dEZvclR5cGUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGludGVudEhhbmRsZXJSZWdpc3RlcmVkKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgY29uc3QgY2xpZW50SW50ZW50SW5mbyA9IHRoaXMuaW50ZW50Q2xpZW50TWFwLmdldChjbGllbnRJZGVudGl0eS5uYW1lKTtcblx0ICAgICAgICBjb25zdCBoYW5kbGVySW5mbyA9IGNsaWVudEludGVudEluZm8/LmdldChoYW5kbGVySWQpO1xuXHQgICAgICAgIGlmICghY2xpZW50SW50ZW50SW5mbykge1xuXHQgICAgICAgICAgICB0aGlzLmludGVudENsaWVudE1hcC5zZXQoY2xpZW50SWRlbnRpdHkubmFtZSwgbmV3IE1hcCgpKTtcblx0ICAgICAgICAgICAgY29uc3QgbmV3SGFuZGxlckluZm9NYXAgPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQoY2xpZW50SWRlbnRpdHkubmFtZSk7XG5cdCAgICAgICAgICAgIGlmIChuZXdIYW5kbGVySW5mb01hcCkge1xuXHQgICAgICAgICAgICAgICAgbmV3SGFuZGxlckluZm9NYXAuc2V0KGhhbmRsZXJJZCwgeyBpc1JlYWR5OiB0cnVlLCBwZW5kaW5nSW50ZW50czogW10sIGNsaWVudElkZW50aXR5IH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2UgaWYgKCFoYW5kbGVySW5mbykge1xuXHQgICAgICAgICAgICBjbGllbnRJbnRlbnRJbmZvLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogdHJ1ZSwgcGVuZGluZ0ludGVudHM6IFtdLCBjbGllbnRJZGVudGl0eSB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgcGVuZGluZ0ludGVudHMgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICBoYW5kbGVySW5mby5jbGllbnRJZGVudGl0eSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICAgICAgICBoYW5kbGVySW5mby5pc1JlYWR5ID0gdHJ1ZTtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nSW50ZW50cy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZW50VG9TZW5kID0gcGVuZGluZ0ludGVudHNbcGVuZGluZ0ludGVudHMubGVuZ3RoIC0gMV07XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5pbnZva2VJbnRlbnRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudFRvU2VuZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8ucGVuZGluZ0ludGVudHMgPSBbXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGludGVudCBoYW5kbGVyOiAke2hhbmRsZXJJZH0gZm9yIGNsaWVudCAke2NsaWVudElkZW50aXR5LnV1aWR9LyR7Y2xpZW50SWRlbnRpdHkubmFtZX0vJHtjbGllbnRJZGVudGl0eS5lbmRwb2ludElkfWApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gVXNlZCB0byByZW1vdmUgYSBjb250ZXh0IGhhbmRsZXIgZm9yIGEgY2xpZW50XG5cdCAgICByZW1vdmVDb250ZXh0SGFuZGxlcih7IGhhbmRsZXJJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGNsaWVudFN0YXRlLmNvbnRleHRIYW5kbGVycy5kZWxldGUoaGFuZGxlcklkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBoYW5kbGVKb2luU2Vzc2lvbkNvbnRleHRHcm91cCh7IHNlc3Npb25Db250ZXh0R3JvdXBJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGlmICghc2Vzc2lvbkNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBqb2luIHNlc3Npb24gY29udGV4dCBncm91cDogbXVzdCBzcGVjaWZ5IGdyb3VwIGlkLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNvbnN0IHNlc3Npb25Db250ZXh0R3JvdXAgPSB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAuZ2V0KHNlc3Npb25Db250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgIGlmIChzZXNzaW9uQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICBzZXNzaW9uQ29udGV4dEdyb3VwLnJlZ2lzdGVyTmV3Q2xpZW50KGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb25Db250ZXh0R3JvdXBCcm9rZXIgPSBuZXcgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcl8xLmRlZmF1bHQodGhpcy5jaGFubmVsLCBzZXNzaW9uQ29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgICAgICAgICAgbmV3U2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlci5yZWdpc3Rlck5ld0NsaWVudChjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAuc2V0KHNlc3Npb25Db250ZXh0R3JvdXBJZCwgbmV3U2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIHsgaGFzQ29uZmxpY3Q6IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuaGFzKHNlc3Npb25Db250ZXh0R3JvdXBJZCkgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLypcblx0ICAgIEludGVybmFsIFV0aWx0aWVzXG5cdCAgICAqL1xuXHQgICAgLy8gR2V0dGVyIGZvciBpbnRlcm9wIGluZm8gZm9yIGEgY2xpZW50LlxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm9wQ2xpZW50cy5nZXQoaWQuZW5kcG9pbnRJZCk7XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIGZvciBnZXRDb250ZXh0R3JvdXBTdGF0ZXMuIFNlcmlhbGl6ZXMgdGhlIGNvbnRleHRHcm91cFN0YXRlcyBvYmplY3Qgc28gd2UgY2FuIHN0b3JlIGl0LlxuXHQgICAgc3RhdGljIHRvT2JqZWN0KG1hcCkge1xuXHQgICAgICAgIGNvbnN0IG9iamVjdEZyb21NYXAgPSBPYmplY3QuZnJvbUVudHJpZXMobWFwKTtcblx0ICAgICAgICBjb25zdCBuZXdPYmplY3QgPSB7fTtcblx0ICAgICAgICBPYmplY3QuZW50cmllcyhvYmplY3RGcm9tTWFwKS5mb3JFYWNoKChbY29udGV4dEdyb3VwSWQsIGNvbnRleHRNYXBdKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHRPYmplY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoY29udGV4dE1hcCk7XG5cdCAgICAgICAgICAgIG5ld09iamVjdFtjb250ZXh0R3JvdXBJZF0gPSBuZXdDb250ZXh0T2JqZWN0O1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBuZXdPYmplY3Q7XG5cdCAgICB9XG5cdCAgICBzdGF0aWMgY2hlY2tDb250ZXh0SW50ZWdyaXR5KGNvbnRleHQpIHtcblx0ICAgICAgICBpZiAoIWNvbnRleHQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ05vIGNvbnRleHQgc3VwcGxpZWQnIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ0NvbnRleHQgbXVzdCBiZSBhbiBPYmplY3QnIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICghY29udGV4dC50eXBlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCByZWFzb246ICdDb250ZXh0IG11c3QgaGF2ZSBhIHR5cGUgcHJvcGVydHknIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0LmlkICYmIHR5cGVvZiBjb250ZXh0LmlkICE9PSAnb2JqZWN0Jykge1xuXHQgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICByZWFzb246ICdDb250ZXh0IGlkIG11c3QgYmUgYW4gT2JqZWN0IHBvcHVsYXRlZCB3aXRoIGtleS12YWx1ZSBpZGVudGlmaWVycyAoaWYgc2V0KSdcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGNvbnRleHQuaWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBpZCB9ID0gY29udGV4dDtcblx0ICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGlkKTtcblx0ICAgICAgICAgICAgbGV0IGZvdW5kQmFkSWRlbnRpZmllciA9IGZhbHNlO1xuXHQgICAgICAgICAgICBpZiAoIWtleXMubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4geyBpc1ZhbGlkOiBmYWxzZSwgcmVhc29uOiAnQ29udGV4dCBpZCBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGtleS12YWx1ZSBpZGVudGlmaWVyJyB9O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycgfHwgdHlwZW9mIGlkW2tleV0gIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZm91bmRCYWRJZGVudGlmaWVyID0gdHJ1ZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGlmIChmb3VuZEJhZElkZW50aWZpZXIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCByZWFzb246ICdDb250ZXh0IGlkIGtleS12YWx1ZSBpZGVudGlmaWVycyBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nJyB9O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0Lm5hbWUgJiYgdHlwZW9mIGNvbnRleHQubmFtZSAhPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ0NvbnRleHQgbmFtZSBtdXN0IGJlIG9mIHN0cmluZyB0eXBlIChpZiBzZXQpJyB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlIH07XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIHRvIGNoZWNrIGEgY2xpZW50IGlkZW50aXR5LlxuXHQgICAgc3RhdGljIGhhc0VuZHBvaW50SWQodGFyZ2V0KSB7XG5cdCAgICAgICAgcmV0dXJuIHRhcmdldC5lbmRwb2ludElkICE9PSB1bmRlZmluZWQ7XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIHRvIGNoZWNrIGlmIHdlIHNob3VsZCBzZW5kIGEgY29udGV4dCB0byBhIGhhbmRsZXIuXG5cdCAgICBzdGF0aWMgaXNDb250ZXh0VHlwZUNvbXBhdGlibGUoY29udGV4dFR5cGUsIHJlZ2lzdGVyZWRDb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgcmVnaXN0ZXJlZENvbnRleHRUeXBlID09PSAndW5kZWZpbmVkJyB8fCBjb250ZXh0VHlwZSA9PT0gcmVnaXN0ZXJlZENvbnRleHRUeXBlO1xuXHQgICAgfVxuXHQgICAgLy8gU2V0dXAgZnVuY3Rpb24gZm9yIHN0YXRlIG1hcHBpbmdcblx0ICAgIHNldENvbnRleHRHcm91cE1hcCgpIHtcblx0ICAgICAgICAvLyBUaGlzIHdheSwgaWYgYSB1c2VyIG92ZXJyaWRlcyB0aGlzLmdldENvbnRleHRHcm91cHMsIGl0J3MgcmVmbGVjdGVkIGluIHRoZSBjb250ZXh0R3JvdXBNYXBwaW5nLlxuXHQgICAgICAgIGZvciAoY29uc3QgY29udGV4dEdyb3VwSW5mbyBvZiB0aGlzLmdldENvbnRleHRHcm91cHMoKSkge1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHRHcm91cHNCeUlkLnNldChjb250ZXh0R3JvdXBJbmZvLmlkLCBuZXcgTWFwKCkpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIHNldEN1cnJlbnRDb250ZXh0R3JvdXBJbkNsaWVudE9wdGlvbnMoY2xpZW50SWRlbnRpdHksIGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3QgZW50aXR5SW5mbyA9IGF3YWl0IHRoaXMuZmluLlN5c3RlbS5nZXRFbnRpdHlJbmZvKGNsaWVudElkZW50aXR5LnV1aWQsIGNsaWVudElkZW50aXR5Lm5hbWUpO1xuXHQgICAgICAgICAgICBsZXQgZW50aXR5O1xuXHQgICAgICAgICAgICBpZiAoZW50aXR5SW5mby5lbnRpdHlUeXBlID09PSAndmlldycpIHtcblx0ICAgICAgICAgICAgICAgIGVudGl0eSA9IGF3YWl0IHRoaXMuZmluLlZpZXcud3JhcChjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgZWxzZSBpZiAoZW50aXR5SW5mby5lbnRpdHlUeXBlID09PSAnd2luZG93Jykge1xuXHQgICAgICAgICAgICAgICAgZW50aXR5ID0gYXdhaXQgdGhpcy5maW4uV2luZG93LndyYXAoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChlbnRpdHkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IGVudGl0eS51cGRhdGVPcHRpb25zKHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnRlcm9wOiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDb250ZXh0R3JvdXA6IGNvbnRleHRHcm91cElkXG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIC8vICBNYXkgZmlsZSBpbiBpbnRlcm9wXG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgc2V0dXBDaGFubmVsUHJvdmlkZXIoKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIoKTtcblx0ICAgICAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcblx0ICAgICAgICAgICAgdGhpcy53aXJlQ2hhbm5lbChjaGFubmVsKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3Igc2V0dGluZyB1cCBJbnRlcm9wIEJyb2tlciBDaGFubmVsIFByb3ZpZGVyOiAke2Vycm9yfWApO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIFNldHVwIENoYW5uZWwgQ29ubmVjdGlvbiBMb2dpY1xuXHQgICAgd2lyZUNoYW5uZWwoY2hhbm5lbCkge1xuXHQgICAgICAgIGNoYW5uZWwub25Db25uZWN0aW9uKGFzeW5jIChjbGllbnRJZGVudGl0eSwgLy8gVE9ETyhDT1JFLTgxMSk6IHJlbW92ZSBpbmxpbmUgaW50ZXJzZWN0ZWQgdHlwZVxuXHQgICAgICAgIHBheWxvYWQpID0+IHtcblx0ICAgICAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5pc0Nvbm5lY3Rpb25BdXRob3JpemVkKGNsaWVudElkZW50aXR5LCBwYXlsb2FkKSkpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBub3QgYXV0aG9yaXplZCBmb3IgJHtjbGllbnRJZGVudGl0eS51dWlkfSwgJHtjbGllbnRJZGVudGl0eS5uYW1lfWApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmICghY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZXJzaW9uIHRvbyBvbGQgdG8gYmUgY29tcGF0aWJsZSB3aXRoIEludGVyb3AuIFBsZWFzZSB1cGdyYWRlIHlvdXIgcnVudGltZSB0byBhIG1vcmUgcmVjZW50IHZlcnNpb24uJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjb250ZXh0R3JvdXBJZDogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzOiBuZXcgTWFwKCksXG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICAvLyBPbmx5IGFsbG93IHRoZSBjbGllbnQgdG8gam9pbiBhIGNvbnRleHRHcm91cCB0aGF0IGFjdHVhbGx5IGV4aXN0cy5cblx0ICAgICAgICAgICAgaWYgKHBheWxvYWQ/LmN1cnJlbnRDb250ZXh0R3JvdXAgJiYgdGhpcy5jb250ZXh0R3JvdXBzQnlJZC5oYXMocGF5bG9hZC5jdXJyZW50Q29udGV4dEdyb3VwKSkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEdyb3VwSWQgPSBwYXlsb2FkPy5jdXJyZW50Q29udGV4dEdyb3VwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuaW50ZXJvcENsaWVudHMuc2V0KGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQsIGNsaWVudFN1YnNjcmlwdGlvblN0YXRlKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjaGFubmVsLm9uRGlzY29ubmVjdGlvbigoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgdGhpcy5pbnRlcm9wQ2xpZW50cy5kZWxldGUoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCk7XG5cdCAgICAgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQoY2xpZW50SWRlbnRpdHkubmFtZSk7XG5cdCAgICAgICAgICAgIGlmICh0YXJnZXRJbmZvICYmIGNsaWVudElkZW50aXR5LnV1aWQgPT09IHRoaXMuZmluLm1lLnV1aWQpIHtcblx0ICAgICAgICAgICAgICAgIHRhcmdldEluZm8uZm9yRWFjaCgoaGFuZGxlcikgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuaXNSZWFkeSA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5zZXNzaW9uQ29udGV4dEdyb3VwTWFwLmZvckVhY2goKHNlc3Npb25Db250ZXh0R3JvdXApID0+IHtcblx0ICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXAub25EaXNjb25uZWN0aW9uKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIHRoaXMuY2xpZW50RGlzY29ubmVjdGVkKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjaGFubmVsLmJlZm9yZUFjdGlvbihhc3luYyAoYWN0aW9uLCBwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkgPT4ge1xuXHQgICAgICAgICAgICBpZiAoIShhd2FpdCB0aGlzLmlzQWN0aW9uQXV0aG9yaXplZChhY3Rpb24sIHBheWxvYWQsIGNsaWVudElkZW50aXR5KSkpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQWN0aW9uICgke2FjdGlvbn0pIG5vdCBhdXRob3JpemVkIGZvciAke2NsaWVudElkZW50aXR5LnV1aWR9LCAke2NsaWVudElkZW50aXR5Lm5hbWV9YCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9nZ2luZz8uYmVmb3JlQWN0aW9uPy5lbmFibGVkKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhhY3Rpb24sIHBheWxvYWQsIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNoYW5uZWwuYWZ0ZXJBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9nZ2luZz8uYWZ0ZXJBY3Rpb24/LmVuYWJsZWQpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGFjdGlvbiwgcGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy8gQ2xpZW50IGZ1bmN0aW9uc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ3NldENvbnRleHQnLCB0aGlzLnNldENvbnRleHQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZmlyZUludGVudCcsIHRoaXMuaGFuZGxlRmlyZWRJbnRlbnQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZ2V0Q3VycmVudENvbnRleHQnLCB0aGlzLmdldEN1cnJlbnRDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEluZm9Gb3JJbnRlbnQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZ2V0SW5mb0ZvckludGVudHNCeUNvbnRleHQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ZpcmVJbnRlbnRGb3JDb250ZXh0JywgdGhpcy5oYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gUGxhdGZvcm0gd2luZG93IGZ1bmN0aW9uc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldENvbnRleHRHcm91cHMnLCB0aGlzLmdldENvbnRleHRHcm91cHMuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3Rlcignam9pbkNvbnRleHRHcm91cCcsIHRoaXMuam9pbkNvbnRleHRHcm91cC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdyZW1vdmVGcm9tQ29udGV4dEdyb3VwJywgdGhpcy5yZW1vdmVGcm9tQ29udGV4dEdyb3VwLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCcsIHRoaXMuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEluZm9Gb3JDb250ZXh0R3JvdXAnLCB0aGlzLmdldEluZm9Gb3JDb250ZXh0R3JvdXAuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gSW50ZXJuYWwgbWV0aG9kc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2NvbnRleHRIYW5kbGVyUmVnaXN0ZXJlZCcsIHRoaXMuY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ludGVudEhhbmRsZXJSZWdpc3RlcmVkJywgdGhpcy5pbnRlbnRIYW5kbGVyUmVnaXN0ZXJlZC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdyZW1vdmVDb250ZXh0SGFuZGxlcicsIHRoaXMucmVtb3ZlQ29udGV4dEhhbmRsZXIuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3Rlcignc2Vzc2lvbkNvbnRleHRHcm91cDpjcmVhdGVJZk5lZWRlZCcsIHRoaXMuaGFuZGxlSm9pblNlc3Npb25Db250ZXh0R3JvdXAuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gZmRjMyBvbmx5IG1ldGhvZHNcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzT3BlbicsIHRoaXMuZmRjM0hhbmRsZU9wZW4uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZmRjM3YyRmluZEludGVudHNCeUNvbnRleHQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ZkYzNGaW5kSW5zdGFuY2VzJywgdGhpcy5mZGMzSGFuZGxlRmluZEluc3RhbmNlcy5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzR2V0QXBwTWV0YWRhdGEnLCB0aGlzLmZkYzNIYW5kbGVHZXRBcHBNZXRhZGF0YS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzdjJHZXRJbmZvJywgYXN5bmMgKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSA9PiB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmZkYzNIYW5kbGVHZXRJbmZvLmJpbmQodGhpcykocGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2NyZWF0ZVByaXZhdGVDaGFubmVsUHJvdmlkZXInLCBhc3luYyAocGF5bG9hZCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IGNoYW5uZWxJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICAgICAgY29uc3QgY2hhbm5lbFByb3ZpZGVyID0gYXdhaXQgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShjaGFubmVsSWQpO1xuXHQgICAgICAgICAgICBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyXzEuUHJpdmF0ZUNoYW5uZWxQcm92aWRlci5pbml0KGNoYW5uZWxQcm92aWRlciwgY2hhbm5lbElkKTtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2FuIGJlIHVzZWQgdG8gY29tcGxldGVseSBwcmV2ZW50IGEgY29ubmVjdGlvbi4gUmV0dXJuIGZhbHNlIHRvIHByZXZlbnQgY29ubmVjdGlvbnMuIEFsbG93cyBhbGwgY29ubmVjdGlvbnMgYnkgZGVmYXVsdC5cblx0ICAgICAqIEBwYXJhbSBfaWQgdGhlIGlkZW50aXR5IHRyeWluYyB0byBjb25uZWN0XG5cdCAgICAgKiBAcGFyYW0gX2Nvbm5lY3Rpb25QYXlsb2FkIG9wdGlvbmFsIHBheWxvYWQgdG8gdXNlIGluIGN1c3RvbSBpbXBsZW1lbnRhdGlvbnMsIHdpbGwgYmUgdW5kZWZpbmVkIGJ5IGRlZmF1bHRcblx0ICAgICAqL1xuXHQgICAgaXNDb25uZWN0aW9uQXV0aG9yaXplZChfaWQsIF9jb25uZWN0aW9uUGF5bG9hZCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1pcy1jb25uZWN0aW9uLWF1dGhvcml6ZWQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDYWxsZWQgYmVmb3JlIGV2ZXJ5IGFjdGlvbiB0byBjaGVjayBpZiB0aGlzIGVudGl0eSBzaG91bGQgYmUgYWxsb3dlZCB0byB0YWtlIHRoZSBhY3Rpb24uXG5cdCAgICAgKiBSZXR1cm4gZmFsc2UgdG8gcHJldmVudCB0aGUgYWN0aW9uXG5cdCAgICAgKiBAcGFyYW0gX2FjdGlvbiB0aGUgc3RyaW5nIGFjdGlvbiB0byBhdXRob3JpemUgaW4gY2FtZWwgY2FzZVxuXHQgICAgICogQHBhcmFtIF9wYXlsb2FkIHRoZSBkYXRhIGJlaW5nIHNlbnQgZm9yIHRoaXMgYWN0aW9uXG5cdCAgICAgKiBAcGFyYW0gX2lkZW50aXR5IHRoZSBjb25uZWN0aW9uIGF0dGVtcHRpbmcgdG8gZGlzcGF0Y2ggdGhpcyBhY3Rpb25cblx0ICAgICAqL1xuXHQgICAgaXNBY3Rpb25BdXRob3JpemVkKF9hY3Rpb24sIF9wYXlsb2FkLCBfaWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItaXMtYWN0aW9uLWF1dGhvcml6ZWQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXHQgICAgfVxuXHR9O1xuXHRJbnRlcm9wQnJva2VyLkludGVyb3BCcm9rZXIgPSBJbnRlcm9wQnJva2VyJDE7XG5cdF9JbnRlcm9wQnJva2VyX2ZkYzNJbmZvID0gbmV3IFdlYWtNYXAoKSwgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3VwcyA9IG5ldyBXZWFrTWFwKCksIF9JbnRlcm9wQnJva2VyX3Byb3ZpZGVyUHJvbWlzZSA9IG5ldyBXZWFrTWFwKCk7XG5cdHJldHVybiBJbnRlcm9wQnJva2VyO1xufVxuXG52YXIgSW50ZXJvcENsaWVudCA9IHt9O1xuXG52YXIgU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxID0ge307XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMiA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2U7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbnN0IGJhc2VfMSQyID0gYmFzZTtcbmNvbnN0IHV0aWxzXzEkMiA9IHV0aWxzJDM7XG5jbGFzcyBTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50IGV4dGVuZHMgYmFzZV8xJDIuQmFzZSB7XG4gICAgY29uc3RydWN0b3Iod2lyZSwgY2xpZW50LCBpZCkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZS5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDIodGhpcywgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSwgY2xpZW50LCBcImZcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgYSBjb250ZXh0IGZvciB0aGUgc2Vzc2lvbiBjb250ZXh0IGdyb3VwLlxuICAgICAqIEBwYXJhbSBjb250ZXh0IC0gTmV3IGNvbnRleHQgdG8gc2V0LlxuICAgICAqXG4gICAgICogQHR1dG9yaWFsIGludGVyb3Auc2V0Q29udGV4dFxuICAgICAqL1xuICAgIGFzeW5jIHNldENvbnRleHQoY29udGV4dCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1zZXNzaW9uLWNvbnRleHQtZ3JvdXAtc2V0LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDIodGhpcywgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKGBzZXNzaW9uQ29udGV4dEdyb3VwOnNldENvbnRleHQtJHt0aGlzLmlkfWAsIHtcbiAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXBJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0KHR5cGUpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3Atc2Vzc2lvbi1jb250ZXh0LWdyb3VwLWdldC1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQyKHRoaXMsIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaChgc2Vzc2lvbkNvbnRleHRHcm91cDpnZXRDb250ZXh0LSR7dGhpcy5pZH1gLCB7XG4gICAgICAgICAgICBzZXNzaW9uQ29udGV4dEdyb3VwSWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICB0eXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBhZGRDb250ZXh0SGFuZGxlcihjb250ZXh0SGFuZGxlciwgY29udGV4dFR5cGUpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3Atc2Vzc2lvbi1jb250ZXh0LWdyb3VwLWFkZC1oYW5kbGVyJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0SGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm9uLWZ1bmN0aW9uIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZmlyc3QgcGFyYW1ldGVyICdoYW5kbGVyJy4gQmUgYXdhcmUgdGhhdCB0aGUgYXJndW1lbnQgb3JkZXIgZG9lcyBub3QgbWF0Y2ggdGhlIEZEQzMgc3RhbmRhcmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMih0aGlzLCBfU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG4gICAgICAgIGxldCBoYW5kbGVySWQ7XG4gICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYHNlc3Npb25Db250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfS0ke2NvbnRleHRUeXBlfS0keygwLCB1dGlsc18xJDIuZ2VuZXJhdGVJZCkoKX1gO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYHNlc3Npb25Db250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfWA7XG4gICAgICAgIH1cbiAgICAgICAgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgKDAsIHV0aWxzXzEkMi53cmFwQ29udGV4dEhhbmRsZXIpKGNvbnRleHRIYW5kbGVyLCBoYW5kbGVySWQpKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKGBzZXNzaW9uQ29udGV4dEdyb3VwOmhhbmRsZXJBZGRlZC0ke3RoaXMuaWR9YCwgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0pO1xuICAgICAgICByZXR1cm4geyB1bnN1YnNjcmliZTogYXdhaXQgdGhpcy5jcmVhdGVVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlVW5zdWJzY3JpYmVDYihoYW5kbGVySWQpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQyKHRoaXMsIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcbiAgICAgICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaChgc2Vzc2lvbkNvbnRleHRHcm91cDpoYW5kbGVyUmVtb3ZlZC0ke3RoaXMuaWR9YCwgeyBoYW5kbGVySWQgfSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldFVzZXJJbnN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICAgICAgc2V0Q29udGV4dDogKDAsIHV0aWxzXzEkMi53cmFwSW5UcnlDYXRjaCkodGhpcy5zZXRDb250ZXh0LmJpbmQodGhpcyksICdGYWlsZWQgdG8gc2V0IGNvbnRleHQ6ICcpLFxuICAgICAgICAgICAgZ2V0Q3VycmVudENvbnRleHQ6ICgwLCB1dGlsc18xJDIud3JhcEluVHJ5Q2F0Y2gpKHRoaXMuZ2V0Q3VycmVudENvbnRleHQuYmluZCh0aGlzKSwgJ0ZhaWxlZCB0byBnZXQgY29udGV4dDogJyksXG4gICAgICAgICAgICBhZGRDb250ZXh0SGFuZGxlcjogKDAsIHV0aWxzXzEkMi53cmFwSW5UcnlDYXRjaCkodGhpcy5hZGRDb250ZXh0SGFuZGxlci5iaW5kKHRoaXMpLCAnRmFpbGVkIHRvIGFkZCBjb250ZXh0IGhhbmRsZXI6ICcpXG4gICAgICAgIH07XG4gICAgfVxufVxuU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxLmRlZmF1bHQgPSBTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50O1xuX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBmZGMzMV8yID0ge307XG5cbnZhciBmZGMzQ29tbW9uID0ge307XG5cbnZhciB1dGlscyQyID0ge307XG5cbnZhciBQcml2YXRlQ2hhbm5lbENsaWVudCQxID0ge307XG5cbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jcmVhdGVCaW5kaW5nKSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG4gICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIG9bazJdID0gbVtrXTtcbn0pKTtcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xufSkgOiBmdW5jdGlvbihvLCB2KSB7XG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xufSk7XG52YXIgX19pbXBvcnRTdGFyID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0U3RhcikgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFByaXZhdGVDaGFubmVsQ2xpZW50JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuUHJpdmF0ZUNoYW5uZWxDbGllbnQkMS5Qcml2YXRlQ2hhbm5lbENsaWVudCA9IHZvaWQgMDtcbmNvbnN0IHV0aWxzJDEgPSBfX2ltcG9ydFN0YXIodXRpbHMkMyk7XG5jbGFzcyBQcml2YXRlQ2hhbm5lbENsaWVudCB7XG4gICAgY29uc3RydWN0b3IoY2xpZW50LCBpZCkge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgYXN5bmMgYnJvYWRjYXN0KGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmRpc3BhdGNoKCdicm9hZGNhc3QnLCB7IGNvbnRleHQgfSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0KGNvbnRleHRUeXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5kaXNwYXRjaCgnZ2V0Q3VycmVudENvbnRleHQnLCB7IGNvbnRleHRUeXBlIH0pO1xuICAgIH1cbiAgICBhc3luYyBhZGRDb250ZXh0TGlzdGVuZXIoY29udGV4dFR5cGUsIGhhbmRsZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb24tZnVuY3Rpb24gYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBzZWNvbmQgcGFyYW1ldGVyICdoYW5kbGVyJy4gQmUgYXdhcmUgdGhhdCB0aGUgYXJndW1lbnQgb3JkZXIgZG9lcyBub3QgbWF0Y2ggdGhlIEZEQzMgc3RhbmRhcmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBoYW5kbGVySWQ7XG4gICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYGNvbnRleHRIYW5kbGVyOmludm9rZS0ke3RoaXMuaWR9LSR7Y29udGV4dFR5cGV9LSR7dXRpbHMkMS5nZW5lcmF0ZUlkKCl9YDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhhbmRsZXJJZCA9IGBjb250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfS0ke3V0aWxzJDEuZ2VuZXJhdGVJZCgpfWA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGllbnQucmVnaXN0ZXIoaGFuZGxlcklkLCB1dGlscyQxLndyYXBDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBoYW5kbGVySWQpKTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB7IHVuc3Vic2NyaWJlOiBhd2FpdCB0aGlzLmNyZWF0ZUNvbnRleHRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICBhd2FpdCB0aGlzLmNsaWVudC5kaXNwYXRjaChgY29udGV4dEhhbmRsZXJBZGRlZGAsIHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuICAgIH1cbiAgICBjcmVhdGVOb25TdGFuZGFyZFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ25vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQnLCB7IGhhbmRsZXJJZCB9KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY3JlYXRlQ29udGV4dFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ2NvbnRleHRIYW5kbGVyUmVtb3ZlZCcsIHsgaGFuZGxlcklkIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBvbkFkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJJZCA9IGBvbkNvbnRleHRIYW5kbGVyQWRkZWQ6aW52b2tlLSR7dGhpcy5pZH0tJHt1dGlscyQxLmdlbmVyYXRlSWQoKX1gO1xuICAgICAgICB0aGlzLmNsaWVudC5yZWdpc3RlcihoYW5kbGVySWQsIGhhbmRsZXIpO1xuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHsgdW5zdWJzY3JpYmU6IHRoaXMuY3JlYXRlTm9uU3RhbmRhcmRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICB0aGlzLmNsaWVudC5kaXNwYXRjaChgb25BZGRDb250ZXh0SGFuZGxlckFkZGVkYCwgeyBoYW5kbGVySWQgfSk7XG4gICAgICAgIHJldHVybiBsaXN0ZW5lcjtcbiAgICB9XG4gICAgb25EaXNjb25uZWN0KGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYG9uRGlzY29ubmVjdDppbnZva2UtJHt0aGlzLmlkfS0ke3V0aWxzJDEuZ2VuZXJhdGVJZCgpfWA7XG4gICAgICAgIHRoaXMuY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgaGFuZGxlcik7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyID0geyB1bnN1YnNjcmliZTogdGhpcy5jcmVhdGVOb25TdGFuZGFyZFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB9O1xuICAgICAgICB0aGlzLmxpc3RlbmVycy5zZXQoaGFuZGxlcklkLCBsaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuY2xpZW50LmRpc3BhdGNoKGBvbkRpc2Nvbm5lY3RIYW5kbGVyQWRkZWRgLCB7IGhhbmRsZXJJZCB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuICAgIH1cbiAgICBvblVuc3Vic2NyaWJlKGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYG9uVW5zdWJzY3JpYmU6aW52b2tlLSR7dGhpcy5pZH0tJHt1dGlscyQxLmdlbmVyYXRlSWQoKX1gO1xuICAgICAgICB0aGlzLmNsaWVudC5yZWdpc3RlcihoYW5kbGVySWQsIGhhbmRsZXIpO1xuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHsgdW5zdWJzY3JpYmU6IHRoaXMuY3JlYXRlTm9uU3RhbmRhcmRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICB0aGlzLmNsaWVudC5kaXNwYXRjaChgb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZGAsIHsgaGFuZGxlcklkIH0pO1xuICAgICAgICByZXR1cm4gbGlzdGVuZXI7XG4gICAgfVxuICAgIGFzeW5jIGNsZWFuVXBBbGxTdWJzKCkge1xuICAgICAgICBjb25zdCBsaXN0ZW5lclVuc3Vic2NyaWJlcnMgPSBBcnJheS5mcm9tKHRoaXMubGlzdGVuZXJzLmtleXMoKSk7XG4gICAgICAgIGxpc3RlbmVyVW5zdWJzY3JpYmVycy5mb3JFYWNoKChoYW5kbGVySWQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xpZW50LnJlbW92ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMuZGVsZXRlKGhhbmRsZXJJZCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBkaXNjb25uZWN0KCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ2NsaWVudERpc2Nvbm5lY3RpbmcnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xlYW5VcEFsbFN1YnMoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblByaXZhdGVDaGFubmVsQ2xpZW50JDEuUHJpdmF0ZUNoYW5uZWxDbGllbnQgPSBQcml2YXRlQ2hhbm5lbENsaWVudDtcblxuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdHZhciBfX2ltcG9ydERlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnREZWZhdWx0KSB8fCBmdW5jdGlvbiAobW9kKSB7XG5cdCAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLmdldEludGVudFJlc29sdXRpb24gPSBleHBvcnRzLmlzQ2hhbm5lbCA9IGV4cG9ydHMuaXNDb250ZXh0ID0gZXhwb3J0cy5jb25uZWN0UHJpdmF0ZUNoYW5uZWwgPSBleHBvcnRzLmJ1aWxkQXBwQ2hhbm5lbE9iamVjdCA9IGV4cG9ydHMuYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdCA9IGV4cG9ydHMuQ2hhbm5lbEVycm9yID0gZXhwb3J0cy5SZXN1bHRFcnJvciA9IGV4cG9ydHMuVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IgPSBleHBvcnRzLmdldFVuc3VwcG9ydGVkQ2hhbm5lbEFwaXMgPSB2b2lkIDA7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHRjb25zdCBQcml2YXRlQ2hhbm5lbENsaWVudF8xID0gUHJpdmF0ZUNoYW5uZWxDbGllbnQkMTtcblx0Y29uc3QgaXNFcXVhbF8xID0gX19pbXBvcnREZWZhdWx0KHJlcXVpcmUkJDMpO1xuXHRjb25zdCBnZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzID0gKGNoYW5uZWxUeXBlKSA9PiB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICAgIGFkZENvbnRleHRMaXN0ZW5lcjogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IoJ0NoYW5uZWwuYWRkQ29udGV4dExpc3RlbmVyJywgY2hhbm5lbFR5cGUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgYnJvYWRjYXN0OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZENoYW5uZWxBcGlFcnJvcignQ2hhbm5lbC5icm9hZGNhc3QnLCBjaGFubmVsVHlwZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXRDdXJyZW50Q29udGV4dDogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IoJ0NoYW5uZWwuZ2V0Q3VycmVudENvbnRleHQnLCBjaGFubmVsVHlwZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy5nZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzID0gZ2V0VW5zdXBwb3J0ZWRDaGFubmVsQXBpcztcblx0Y2xhc3MgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdCAgICBjb25zdHJ1Y3RvcihhcGlOYW1lLCBjaGFubmVsVHlwZSA9ICdTeXN0ZW0nKSB7XG5cdCAgICAgICAgc3VwZXIoYXBpTmFtZSk7XG5cdCAgICAgICAgdGhpcy5tZXNzYWdlID0gYENhbGxpbmcgJHthcGlOYW1lfSBvbiBhbiBpbnN0YW5jZSBvZiBhICR7Y2hhbm5lbFR5cGV9IENoYW5uZWwgcmV0dXJuZWQgYnkgZmRjMy5nZXQke2NoYW5uZWxUeXBlfUNoYW5uZWxzIGlzIG5vdCBzdXBwb3J0ZWQuIElmIHlvdSB3b3VsZCBsaWtlIHRvIHVzZSBhICR7Y2hhbm5lbFR5cGV9IENoYW5uZWwsIHBsZWFzZSB1c2UgZmRjMy5qb2luQ2hhbm5lbCwgZmRjMy5hZGRDb250ZXh0TGlzdGVuZXIsIGFuZCBmZGMzLmJyb2FkY2FzdCBpbnN0ZWFkLmA7XG5cdCAgICB9XG5cdH1cblx0ZXhwb3J0cy5VbnN1cHBvcnRlZENoYW5uZWxBcGlFcnJvciA9IFVuc3VwcG9ydGVkQ2hhbm5lbEFwaUVycm9yO1xuXHR2YXIgUmVzdWx0RXJyb3I7XG5cdChmdW5jdGlvbiAoUmVzdWx0RXJyb3IpIHtcblx0ICAgIC8qKiBSZXR1cm5lZCBpZiB0aGUgYEludGVudEhhbmRsZXJgIGV4aXRlZCB3aXRob3V0IHJldHVybmluZyBhIFByb21pc2Ugb3IgdGhhdFxuXHQgICAgICogIFByb21pc2Ugd2FzIG5vdCByZXNvbHZlZCB3aXRoIGEgQ29udGV4dCBvciBDaGFubmVsIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgUmVzdWx0RXJyb3JbXCJOb1Jlc3VsdFJldHVybmVkXCJdID0gXCJOb1Jlc3VsdFJldHVybmVkXCI7XG5cdCAgICAvKiogUmV0dXJuZWQgaWYgdGhlIGBJbnRlbnRIYW5kbGVyYCBmdW5jdGlvbiBwcm9jZXNzaW5nIHRoZSByYWlzZWQgaW50ZW50XG5cdCAgICAgKiAgdGhyb3dzIGFuIGVycm9yIG9yIHJlamVjdHMgdGhlIFByb21pc2UgaXQgcmV0dXJuZWQuXG5cdCAgICAgKi9cblx0ICAgIFJlc3VsdEVycm9yW1wiSW50ZW50SGFuZGxlclJlamVjdGVkXCJdID0gXCJJbnRlbnRIYW5kbGVyUmVqZWN0ZWRcIjtcblx0fSkoUmVzdWx0RXJyb3IgPSBleHBvcnRzLlJlc3VsdEVycm9yIHx8IChleHBvcnRzLlJlc3VsdEVycm9yID0ge30pKTtcblx0KGZ1bmN0aW9uIChDaGFubmVsRXJyb3IpIHtcblx0ICAgIC8qKiBSZXR1cm5lZCBpZiB0aGUgc3BlY2lmaWVkIGNoYW5uZWwgaXMgbm90IGZvdW5kIHdoZW4gYXR0ZW1wdGluZyB0byBqb2luIGFcblx0ICAgICAqICBjaGFubmVsIHZpYSB0aGUgYGpvaW5Vc2VyQ2hhbm5lbGAgZnVuY3Rpb24gb2YgdGhlIERlc2t0b3BBZ2VudCAoYGZkYzNgKS5cblx0ICAgICAqL1xuXHQgICAgQ2hhbm5lbEVycm9yW1wiTm9DaGFubmVsRm91bmRcIl0gPSBcIk5vQ2hhbm5lbEZvdW5kXCI7XG5cdCAgICAvKiogU0hPVUxEIGJlIHJldHVybmVkIHdoZW4gYSByZXF1ZXN0IHRvIGpvaW4gYSB1c2VyIGNoYW5uZWwgb3IgdG8gYSByZXRyaWV2ZVxuXHQgICAgICogIGEgQ2hhbm5lbCBvYmplY3QgdmlhIHRoZSBgam9pblVzZXJDaGFubmVsYCBvciBgZ2V0T3JDcmVhdGVDaGFubmVsYCBtZXRob2RzXG5cdCAgICAgKiAgb2YgdGhlIERlc2t0b3BBZ2VudCAoYGZkYzNgKSBvYmplY3QgaXMgZGVuaWVkLlxuXHQgICAgICovXG5cdCAgICBDaGFubmVsRXJyb3JbXCJBY2Nlc3NEZW5pZWRcIl0gPSBcIkFjY2Vzc0RlbmllZFwiO1xuXHQgICAgLyoqIFNIT1VMRCBiZSByZXR1cm5lZCB3aGVuIGEgY2hhbm5lbCBjYW5ub3QgYmUgY3JlYXRlZCBvciByZXRyaWV2ZWQgdmlhIHRoZVxuXHQgICAgICogIGBnZXRPckNyZWF0ZUNoYW5uZWxgIG1ldGhvZCBvZiB0aGUgRGVza3RvcEFnZW50IChgZmRjM2ApLlxuXHQgICAgICovXG5cdCAgICBDaGFubmVsRXJyb3JbXCJDcmVhdGlvbkZhaWxlZFwiXSA9IFwiQ3JlYXRpb25GYWlsZWRcIjtcblx0fSkoZXhwb3J0cy5DaGFubmVsRXJyb3IgfHwgKGV4cG9ydHMuQ2hhbm5lbEVycm9yID0ge30pKTtcblx0Y29uc3QgYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdCA9IChwcml2YXRlQ2hhbm5lbENsaWVudCkgPT4ge1xuXHQgICAgbGV0IGNsaWVudERpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuXHQgICAgY29uc3QgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCA9ICgpID0+IHtcblx0ICAgICAgICBpZiAoY2xpZW50RGlzY29ubmVjdGVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUHJpdmF0ZSBDaGFubmVsIENsaWVudCBoYXMgYmVlbiBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgUHJpdmF0ZSBDaGFubmVsJyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgaWQ6IHByaXZhdGVDaGFubmVsQ2xpZW50LmlkLFxuXHQgICAgICAgIHR5cGU6ICdwcml2YXRlJyxcblx0ICAgICAgICBicm9hZGNhc3Q6IGFzeW5jIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50LmJyb2FkY2FzdChjb250ZXh0KTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldEN1cnJlbnRDb250ZXh0OiBhc3luYyAoY29udGV4dFR5cGUpID0+IHtcblx0ICAgICAgICAgICAgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCgpO1xuXHQgICAgICAgICAgICByZXR1cm4gcHJpdmF0ZUNoYW5uZWxDbGllbnQuZ2V0Q3VycmVudENvbnRleHQoY29udGV4dFR5cGUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUT0RPIFtDT1JFLTE1MjRdXG5cdCAgICAgICAgYWRkQ29udGV4dExpc3RlbmVyOiBhc3luYyAoY29udGV4dFR5cGUsIGhhbmRsZXIpID0+IHtcblx0ICAgICAgICAgICAgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCgpO1xuXHQgICAgICAgICAgICBsZXQgaGFuZGxlckluVXNlID0gaGFuZGxlcjtcblx0ICAgICAgICAgICAgbGV0IGNvbnRleHRUeXBlSW5Vc2UgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJblVzZSA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICAgICAgY29udGV4dFR5cGVJblVzZSA9IG51bGw7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBwcml2YXRlQ2hhbm5lbENsaWVudC5hZGRDb250ZXh0TGlzdGVuZXIoY29udGV4dFR5cGVJblVzZSwgaGFuZGxlckluVXNlKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgb25BZGRDb250ZXh0TGlzdGVuZXI6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uQWRkQ29udGV4dExpc3RlbmVyKGhhbmRsZXIpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZGlzY29ubmVjdDogYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjaGVja0lmQ2xpZW50RGlzY29ubmVjdGVkKCk7XG5cdCAgICAgICAgICAgIGNsaWVudERpc2Nvbm5lY3RlZCA9IHRydWU7XG5cdCAgICAgICAgICAgIHJldHVybiBwcml2YXRlQ2hhbm5lbENsaWVudC5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBvbkRpc2Nvbm5lY3Q6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uRGlzY29ubmVjdChoYW5kbGVyKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uVW5zdWJzY3JpYmU6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uVW5zdWJzY3JpYmUoaGFuZGxlcik7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy5idWlsZFByaXZhdGVDaGFubmVsT2JqZWN0ID0gYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdDtcblx0Y29uc3QgYnVpbGRBcHBDaGFubmVsT2JqZWN0ID0gKHNlc3Npb25Db250ZXh0R3JvdXApID0+IHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgaWQ6IHNlc3Npb25Db250ZXh0R3JvdXAuaWQsXG5cdCAgICAgICAgdHlwZTogJ2FwcCcsXG5cdCAgICAgICAgYnJvYWRjYXN0OiBzZXNzaW9uQ29udGV4dEdyb3VwLnNldENvbnRleHQsXG5cdCAgICAgICAgZ2V0Q3VycmVudENvbnRleHQ6IGFzeW5jIChjb250ZXh0VHlwZSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgc2Vzc2lvbkNvbnRleHRHcm91cC5nZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgIHJldHVybiBjb250ZXh0ID09PSB1bmRlZmluZWQgPyBudWxsIDogY29udGV4dDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETyBbQ09SRS0xNTI0XVxuXHQgICAgICAgIGFkZENvbnRleHRMaXN0ZW5lcjogKGNvbnRleHRUeXBlLCBoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGxldCByZWFsSGFuZGxlcjtcblx0ICAgICAgICAgICAgbGV0IHJlYWxUeXBlO1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2FkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGFkZENvbnRleHRMaXN0ZW5lcihudWxsLCBoYW5kbGVyKScpO1xuXHQgICAgICAgICAgICAgICAgcmVhbEhhbmRsZXIgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJlYWxIYW5kbGVyID0gaGFuZGxlcjtcblx0ICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVhbFR5cGUgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IChhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCBzZXNzaW9uQ29udGV4dEdyb3VwLmdldEN1cnJlbnRDb250ZXh0KHJlYWxUeXBlKTtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRIYW5kbGVyID0gKGNvbnRleHQsIGNvbnRleHRNZXRhZGF0YSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKDAsIGlzRXF1YWxfMS5kZWZhdWx0KShjdXJyZW50Q29udGV4dCwgY29udGV4dCkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhbEhhbmRsZXIoY29udGV4dCwgY29udGV4dE1ldGFkYXRhKTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc2Vzc2lvbkNvbnRleHRHcm91cC5hZGRDb250ZXh0SGFuZGxlcih3cmFwcGVkSGFuZGxlciwgcmVhbFR5cGUpO1xuXHQgICAgICAgICAgICB9KSgpO1xuXHQgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgLi4ubGlzdGVuZXIsXG5cdCAgICAgICAgICAgICAgICB1bnN1YnNjcmliZTogKCkgPT4gbGlzdGVuZXIudGhlbigobCkgPT4gbC51bnN1YnNjcmliZSgpKVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdH07XG5cdGV4cG9ydHMuYnVpbGRBcHBDaGFubmVsT2JqZWN0ID0gYnVpbGRBcHBDaGFubmVsT2JqZWN0O1xuXHRjb25zdCBjb25uZWN0UHJpdmF0ZUNoYW5uZWwgPSBhc3luYyAoY2hhbm5lbElkKSA9PiB7XG5cdCAgICB0cnkge1xuXHQgICAgICAgIGNvbnN0IGNoYW5uZWxDbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbElkKTtcblx0ICAgICAgICBjb25zdCBwcml2YXRlQ2hhbm5lbENsaWVudCA9IG5ldyBQcml2YXRlQ2hhbm5lbENsaWVudF8xLlByaXZhdGVDaGFubmVsQ2xpZW50KGNoYW5uZWxDbGllbnQsIGNoYW5uZWxJZCk7XG5cdCAgICAgICAgcmV0dXJuICgwLCBleHBvcnRzLmJ1aWxkUHJpdmF0ZUNoYW5uZWxPYmplY3QpKHByaXZhdGVDaGFubmVsQ2xpZW50KTtcblx0ICAgIH1cblx0ICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJpdmF0ZSBDaGFubmVsIHdpdGggaWQ6ICR7Y2hhbm5lbElkfSBkb2Vzbid0IGV4aXN0YCk7XG5cdCAgICB9XG5cdH07XG5cdGV4cG9ydHMuY29ubmVjdFByaXZhdGVDaGFubmVsID0gY29ubmVjdFByaXZhdGVDaGFubmVsO1xuXHRjb25zdCBpc0NvbnRleHQgPSAoY29udGV4dCkgPT4ge1xuXHQgICAgaWYgKGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiBjb250ZXh0KSB7XG5cdCAgICAgICAgY29uc3QgeyB0eXBlIH0gPSBjb250ZXh0O1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZyc7XG5cdCAgICB9XG5cdCAgICByZXR1cm4gZmFsc2U7XG5cdH07XG5cdGV4cG9ydHMuaXNDb250ZXh0ID0gaXNDb250ZXh0O1xuXHRjb25zdCBpc0NoYW5uZWwgPSAoY2hhbm5lbCkgPT4ge1xuXHQgICAgaWYgKGNoYW5uZWwgJiYgdHlwZW9mIGNoYW5uZWwgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiBjaGFubmVsICYmICdpZCcgaW4gY2hhbm5lbCkge1xuXHQgICAgICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGNoYW5uZWw7XG5cdCAgICAgICAgcmV0dXJuIHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmICh0eXBlID09PSAnYXBwJyB8fCB0eXBlID09PSAncHJpdmF0ZScpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIGZhbHNlO1xuXHR9O1xuXHRleHBvcnRzLmlzQ2hhbm5lbCA9IGlzQ2hhbm5lbDtcblx0Y29uc3QgZ2V0SW50ZW50UmVzb2x1dGlvbiA9IGFzeW5jIChpbnRlcm9wTW9kdWxlLCBjb250ZXh0LCBhcHAsIGludGVudCkgPT4ge1xuXHQgICAgLy8gR2VuZXJhdGUgYW4gSUQgdG8gbWFrZSBhIHNlc3Npb24gY29udGV4dCBncm91cCB3aXRoLiBXZSB3aWxsIHBhc3MgdGhhdCBJRCB0byB0aGUgQnJva2VyLlxuXHQgICAgLy8gVGhlIGJyb2tlciB3aWxsIHRoZW4gc2V0Q29udGV4dCBvbiB0aGF0IHNlc3Npb24gY29udGV4dCBncm91cCBsYXRlciB3aXRoIG91ciBJbnRlbnQgUmVzdWx0LFxuXHQgICAgY29uc3QgZ3VpZCA9ICgwLCB1dGlsc18xLmdlbmVyYXRlSWQpKCk7IC8vIFRPRE8gbWFrZSB0aGlzIHVuZGVmaW5lZCBpbiB3ZWJcblx0ICAgIC8vIFByb21pc2Ugd2UnbGwgdXNlIGluIGdldFJlc3VsdFxuXHQgICAgY29uc3QgZ2V0UmVzdWx0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0ICAgICAgICBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5zdWJzY3JpYmUoeyB1dWlkOiAnKicgfSwgZ3VpZCwgKGludGVudFJlc3VsdCkgPT4ge1xuXHQgICAgICAgICAgICByZXNvbHZlKGludGVudFJlc3VsdCk7XG5cdCAgICAgICAgfSkuY2F0Y2goKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignZ2V0UmVzdWx0IGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudCcpKSk7XG5cdCAgICB9KTtcblx0ICAgIC8vIEFkZGluZyB0aGUgaW50ZW50UmVzb2x1dGlvblJlc3VsdElkIHRvIHRoZSBpbnRlbnRPYmouIEJlY2F1c2UgZmlyZUludGVudCBvbmx5IGFjY2VwdHMgYSBzaW5nbGUgYXJnLCB3ZSBoYXZlIHRvIHNsYXAgaXQgaW4gaGVyZS5cblx0ICAgIGNvbnN0IG1ldGFkYXRhID0gYXBwID8geyB0YXJnZXQ6IGFwcCwgaW50ZW50UmVzb2x1dGlvblJlc3VsdElkOiBndWlkIH0gOiB7IGludGVudFJlc29sdXRpb25SZXN1bHRJZDogZ3VpZCB9O1xuXHQgICAgY29uc3QgaW50ZW50T2JqID0gaW50ZW50ID8geyBuYW1lOiBpbnRlbnQsIGNvbnRleHQsIG1ldGFkYXRhIH0gOiB7IC4uLmNvbnRleHQsIG1ldGFkYXRhIH07XG5cdCAgICAvLyBTZXQgdXAgdGhlIGdldFJlc3VsdCBjYWxsLlxuXHQgICAgY29uc3QgZ2V0UmVzdWx0ID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgIGxldCBpbnRlbnRSZXN1bHQgPSBhd2FpdCBnZXRSZXN1bHRQcm9taXNlO1xuXHQgICAgICAgIGlmICghaW50ZW50UmVzdWx0IHx8IHR5cGVvZiBpbnRlbnRSZXN1bHQgIT09ICdvYmplY3QnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihSZXN1bHRFcnJvci5Ob1Jlc3VsdFJldHVybmVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgeyBlcnJvciB9ID0gaW50ZW50UmVzdWx0O1xuXHQgICAgICAgIGlmIChlcnJvcikge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoUmVzdWx0RXJyb3IuSW50ZW50SGFuZGxlclJlamVjdGVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCgwLCBleHBvcnRzLmlzQ2hhbm5lbCkoaW50ZW50UmVzdWx0KSkge1xuXHQgICAgICAgICAgICBjb25zdCB7IGlkLCB0eXBlIH0gPSBpbnRlbnRSZXN1bHQ7XG5cdCAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuXHQgICAgICAgICAgICAgICAgY2FzZSAncHJpdmF0ZSc6IHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnRlbnRSZXN1bHQgPSBhd2FpdCAoMCwgZXhwb3J0cy5jb25uZWN0UHJpdmF0ZUNoYW5uZWwpKGlkKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhc2UgJ2FwcCc6IHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uQ29udGV4dEdyb3VwID0gYXdhaXQgaW50ZXJvcE1vZHVsZS5qb2luU2Vzc2lvbkNvbnRleHRHcm91cChpZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gKDAsIGV4cG9ydHMuYnVpbGRBcHBDaGFubmVsT2JqZWN0KShzZXNzaW9uQ29udGV4dEdyb3VwKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIGlmICghKDAsIGV4cG9ydHMuaXNDb250ZXh0KShpbnRlbnRSZXN1bHQpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihSZXN1bHRFcnJvci5Ob1Jlc3VsdFJldHVybmVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGludGVudFJlc3VsdDtcblx0ICAgIH07XG5cdCAgICAvLyBGaW5hbGx5IGZpcmUgdGhlIGludGVudC5cblx0ICAgIGNvbnN0IGludGVudFJlc29sdXRpb25JbmZvRnJvbUJyb2tlciA9IGludGVudFxuXHQgICAgICAgID8gYXdhaXQgaW50ZXJvcE1vZHVsZS5maXJlSW50ZW50KGludGVudE9iailcblx0ICAgICAgICA6IGF3YWl0IGludGVyb3BNb2R1bGUuZmlyZUludGVudEZvckNvbnRleHQoaW50ZW50T2JqKTtcblx0ICAgIGlmICh0eXBlb2YgaW50ZW50UmVzb2x1dGlvbkluZm9Gcm9tQnJva2VyICE9PSAnb2JqZWN0Jykge1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHNvdXJjZToge1xuXHQgICAgICAgICAgICAgICAgYXBwSWQ6ICcnLFxuXHQgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogJydcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgaW50ZW50OiAnJyxcblx0ICAgICAgICAgICAgdmVyc2lvbjogJzIuMCcsXG5cdCAgICAgICAgICAgIGdldFJlc3VsdFxuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICByZXR1cm4geyAuLi5pbnRlbnRSZXNvbHV0aW9uSW5mb0Zyb21Ccm9rZXIsIGdldFJlc3VsdCB9O1xuXHR9O1xuXHRleHBvcnRzLmdldEludGVudFJlc29sdXRpb24gPSBnZXRJbnRlbnRSZXNvbHV0aW9uOyBcbn0gKHV0aWxzJDIpKTtcblxudmFyIGhhc1JlcXVpcmVkRmRjM0NvbW1vbjtcblxuZnVuY3Rpb24gcmVxdWlyZUZkYzNDb21tb24gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGZGMzQ29tbW9uKSByZXR1cm4gZmRjM0NvbW1vbjtcblx0aGFzUmVxdWlyZWRGZGMzQ29tbW9uID0gMTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xuXHR9O1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xuXHR9O1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdHZhciBfRkRDM01vZHVsZUJhc2VfcHJvZHVjZXI7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmZGMzQ29tbW9uLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0ZmRjM0NvbW1vbi5GREMzTW9kdWxlQmFzZSA9IHZvaWQgMDtcblx0Y29uc3QgdXRpbHNfMSA9IHV0aWxzJDI7XG5cdGNvbnN0IHV0aWxzXzIgPSB1dGlscyQzO1xuXHRjb25zdCBJbnRlcm9wQ2xpZW50XzEgPSByZXF1aXJlSW50ZXJvcENsaWVudCgpO1xuXHRjb25zdCBpc0VxdWFsXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMyk7XG5cdGNsYXNzIEZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIGdldCBjbGllbnQoKSB7XG5cdCAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLCBcImZcIikuY2FsbCh0aGlzKTtcblx0ICAgIH1cblx0ICAgIGdldCBmaW4oKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5nZXRGaW4oKTtcblx0ICAgIH1cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNvbnN0cnVjdG9yXG5cdCAgICBjb25zdHJ1Y3Rvcihwcm9kdWNlciwgd2lyZSkge1xuXHQgICAgICAgIHRoaXMud2lyZSA9IHdpcmU7XG5cdCAgICAgICAgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLnNldCh0aGlzLCB2b2lkIDApO1xuXHQgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLCBwcm9kdWNlciwgXCJmXCIpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBCcm9hZGNhc3RzIGEgY29udGV4dCBmb3IgdGhlIGNoYW5uZWwgb2YgdGhlIGN1cnJlbnQgZW50aXR5LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgLSBOZXcgY29udGV4dCB0byBzZXQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYnJvYWRjYXN0XG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGJyb2FkY2FzdChjb250ZXh0KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYnJvYWRjYXN0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LnNldENvbnRleHQoY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIExhdW5jaGVzIGFuIGFwcCB3aXRoIHRhcmdldCBpbmZvcm1hdGlvbiwgd2hpY2ggY2FuIGVpdGhlciBiZSBhIHN0cmluZyBvciBhbiBBcHBNZXRhZGF0YSBvYmplY3QuXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLm9wZW5cblx0ICAgICAqL1xuXHQgICAgYXN5bmMgX29wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtb3BlbicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCBJbnRlcm9wQ2xpZW50XzEuSW50ZXJvcENsaWVudC5mZXJyeUZkYzNDYWxsKHRoaXMuY2xpZW50LCAnZmRjM09wZW4nLCB7IGFwcCwgY29udGV4dCB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGVycm9yVG9UaHJvdyA9IGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzIuQlJPS0VSX0VSUk9SUy5mZGMzT3BlbiA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIF9nZXRDaGFubmVscygpIHtcblx0ICAgICAgICBjb25zdCBjaGFubmVscyA9IGF3YWl0IHRoaXMuY2xpZW50LmdldENvbnRleHRHcm91cHMoKTtcblx0ICAgICAgICAvLyBmZGMzIGltcGxlbWVudGF0aW9uIG9mIGdldFN5c3RlbUNoYW5uZWxzIHJldHVybnMgYW4gYXJyYXkgb2YgY2hhbm5lbHMsIGhhdmUgdG8gZGVjb3JhdGUgb3ZlclxuXHQgICAgICAgIC8vIHRoaXMgc28gcGVvcGxlIGtub3cgdGhhdCB0aGVzZSBBUElzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdCAgICAgICAgcmV0dXJuIGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4geyAuLi5jaGFubmVsLCB0eXBlOiAnc3lzdGVtJywgLi4uKDAsIHV0aWxzXzEuZ2V0VW5zdXBwb3J0ZWRDaGFubmVsQXBpcykoKSB9O1xuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIGEgQ2hhbm5lbCBvYmplY3QgZm9yIHRoZSBzcGVjaWZpZWQgY2hhbm5lbCwgY3JlYXRpbmcgaXQgYXMgYW4gQXBwIENoYW5uZWwgaWYgaXQgZG9lcyBub3QgZXhpc3QuXG5cdCAgICAgKiBAcGFyYW0gY2hhbm5lbElkXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZ2V0T3JDcmVhdGVDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldE9yQ3JlYXRlQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtb3ItY3JlYXRlLWNoYW5uZWwnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBzeXN0ZW1DaGFubmVscyA9IGF3YWl0IHRoaXMuX2dldENoYW5uZWxzKCk7XG5cdCAgICAgICAgY29uc3QgdXNlckNoYW5uZWwgPSBzeXN0ZW1DaGFubmVscy5maW5kKChjaGFubmVsKSA9PiBjaGFubmVsLmlkID09PSBjaGFubmVsSWQpO1xuXHQgICAgICAgIGlmICh1c2VyQ2hhbm5lbCkge1xuXHQgICAgICAgICAgICByZXR1cm4geyAuLi51c2VyQ2hhbm5lbCwgdHlwZTogJ3N5c3RlbScsIC4uLigwLCB1dGlsc18xLmdldFVuc3VwcG9ydGVkQ2hhbm5lbEFwaXMpKCkgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkNvbnRleHRHcm91cCA9IGF3YWl0IHRoaXMuY2xpZW50LmpvaW5TZXNzaW9uQ29udGV4dEdyb3VwKGNoYW5uZWxJZCk7XG5cdCAgICAgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMS5idWlsZEFwcENoYW5uZWxPYmplY3QpKHNlc3Npb25Db250ZXh0R3JvdXApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQ2hhbm5lbEVycm9yLkNyZWF0aW9uRmFpbGVkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIEludGVyb3AtQnJva2VyLWRlZmluZWQgY29udGV4dCBncm91cHMgYXZhaWxhYmxlIGZvciBhbiBlbnRpdHkgdG8gam9pbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRTeXN0ZW1DaGFubmVsc1xuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRTeXN0ZW1DaGFubmVscygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtc3lzdGVtLWNoYW5uZWxzJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxzKCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEpvaW4gYWxsIEludGVyb3AgQ2xpZW50cyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgdG8gY29udGV4dCBncm91cCBgY29udGV4dEdyb3VwSWRgLlxuXHQgICAgICogSWYgbm8gdGFyZ2V0IGlzIHNwZWNpZmllZCwgaXQgYWRkcyB0aGUgc2VuZGVyIHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogQmVjYXVzZSBtdWx0aXBsZSBDaGFubmVsIGNvbm5lY3Rpb25zL0ludGVyb3AgQ2xpZW50cyBjYW4gcG90ZW50aWFsbHkgZXhpc3QgYXQgYSBgdXVpZGAvYG5hbWVgIGNvbWJvLCB3ZSBjdXJyZW50bHkgam9pbiBhbGwgQ2hhbm5lbCBjb25uZWN0aW9ucy9JbnRlcm9wIENsaWVudHMgYXQgdGhlIGdpdmVuIGlkZW50aXR5IHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogSWYgYW4gYGVuZHBvaW50SWRgIGlzIHByb3ZpZGVkICh3aGljaCBpcyB1bmxpa2VseSwgdW5sZXNzIHRoZSBjYWxsIGlzIGNvbWluZyBmcm9tIGFuIGV4dGVybmFsIGFkYXB0ZXIpLCB0aGVuIHdlIG9ubHkgam9pbiB0aGF0IHNpbmdsZSBjb25uZWN0aW9uIHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogRm9yIGFsbCBpbnRlbnRzIGFuZCBwdXJwb3NlcywgdGhlcmUgd2lsbCBvbmx5IGJlIDEgY29ubmVjdGlvbiBwcmVzZW50IGluIFBsYXRmb3JtIGFuZCBCcm93c2VyIGltcGxlbWVudGF0aW9ucywgc28gdGhpcyBwb2ludCBpcyBtb3JlLW9yLWxlc3MgbW9vdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWQgLSBJZCBvZiB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5qb2luQ2hhbm5lbFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1qb2luLWNoYW5uZWwnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuam9pbkNvbnRleHRHcm91cChjaGFubmVsSWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzIuQlJPS0VSX0VSUk9SUy5qb2luU2Vzc2lvbkNvbnRleHRHcm91cFdpdGhKb2luQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgQ2hhbm5lbCB5b3UgaGF2ZSB0cmllZCB0byBqb2luIGlzIGFuIEFwcCBDaGFubmVsLiBDdXN0b20gQ2hhbm5lbHMgY2FuIG9ubHkgYmUgZGVmaW5lZCBieSB0aGUgSW50ZXJvcCBCcm9rZXIgdGhyb3VnaCBjb2RlIG9yIG1hbmlmZXN0IGNvbmZpZ3VyYXRpb24uIFBsZWFzZSB1c2UgZ2V0T3JDcmVhdGVDaGFubmVsLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZS5zdGFydHNXaXRoKCdBdHRlbXB0aW5nIHRvIGpvaW4gYSBjb250ZXh0IGdyb3VwIHRoYXQgZG9lcyBub3QgZXhpc3QnKSkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQ2hhbm5lbEVycm9yLk5vQ2hhbm5lbEZvdW5kKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5DaGFubmVsRXJyb3IuQWNjZXNzRGVuaWVkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIENoYW5uZWwgdGhhdCB0aGUgZW50aXR5IGlzIHN1YnNjcmliZWQgdG8uIFJldHVybnMgbnVsbCBpZiBub3Qgam9pbmVkIHRvIGEgY2hhbm5lbC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRDdXJyZW50Q2hhbm5lbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRDdXJyZW50Q2hhbm5lbCgpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtY3VycmVudC1jaGFubmVsJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY3VycmVudENvbnRleHRHcm91cEluZm8gPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKCk7XG5cdCAgICAgICAgaWYgKCFjdXJyZW50Q29udGV4dEdyb3VwSW5mbykge1xuXHQgICAgICAgICAgICByZXR1cm4gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRDaGFubmVsT2JqZWN0KGN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHRhcmdldCBmcm9tIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IHJlbW92ZXMgdGhlIHNlbmRlciBmcm9tIHRoZWlyIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMubGVhdmVDdXJyZW50Q2hhbm5lbFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBsZWF2ZUN1cnJlbnRDaGFubmVsKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWxlYXZlLWN1cnJlbnQtY2hhbm5lbCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5yZW1vdmVGcm9tQ29udGV4dEdyb3VwKCk7XG5cdCAgICB9XG5cdCAgICAvLyB1dGlsc1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKCkge1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cHMgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRDb250ZXh0R3JvdXBzKCk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50c0luQ3R4R3JvdXBzUHJvbWlzZSA9IGNvbnRleHRHcm91cHMubWFwKGFzeW5jIChjdHhHcm91cCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKGN0eEdyb3VwLmlkKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5DdHhHcm91cHMgPSBhd2FpdCBQcm9taXNlLmFsbChjbGllbnRzSW5DdHhHcm91cHNQcm9taXNlKTtcblx0ICAgICAgICBjb25zdCBjbGllbnRJZHggPSBjbGllbnRzSW5DdHhHcm91cHMuZmluZEluZGV4KChjbGllbnRJZGVudGl0eUFycikgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xpZW50SWRlbnRpdHlBcnIuc29tZSgoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gY2xpZW50SWRlbnRpdHk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLm1lLnV1aWQgPT09IHV1aWQgJiYgdGhpcy53aXJlLm1lLm5hbWUgPT09IG5hbWU7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBjb250ZXh0R3JvdXBzW2NsaWVudElkeF07XG5cdCAgICB9XG5cdCAgICBhc3luYyBidWlsZENoYW5uZWxPYmplY3QoY3VycmVudENvbnRleHRHcm91cEluZm8pIHtcblx0ICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLi4uY3VycmVudENvbnRleHRHcm91cEluZm8sXG5cdCAgICAgICAgICAgIHR5cGU6ICdzeXN0ZW0nLFxuXHQgICAgICAgICAgICBhZGRDb250ZXh0TGlzdGVuZXI6ICguLi5bY29udGV4dFR5cGUsIGhhbmRsZXJdKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBsZXQgcmVhbEhhbmRsZXI7XG5cdCAgICAgICAgICAgICAgICBsZXQgcmVhbFR5cGU7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgICAgICAgICByZWFsSGFuZGxlciA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVhbEhhbmRsZXIgPSBoYW5kbGVyO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxUeXBlID0gY29udGV4dFR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRDdXJyZW50Q29udGV4dChyZWFsVHlwZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZEhhbmRsZXIgPSAoY29udGV4dCwgY29udGV4dE1ldGFkYXRhKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoMCwgaXNFcXVhbF8xLmRlZmF1bHQpKGN1cnJlbnRDb250ZXh0LCBjb250ZXh0KSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWxIYW5kbGVyKGNvbnRleHQsIGNvbnRleHRNZXRhZGF0YSk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIsIHJlYWxUeXBlKTtcblx0ICAgICAgICAgICAgICAgIH0pKCk7XG5cdCAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgICAgICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgICAgICAgICAgLi4ubGlzdGVuZXIsXG5cdCAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IGxpc3RlbmVyLnRoZW4oKGwpID0+IGwudW5zdWJzY3JpYmUoKSlcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGJyb2FkY2FzdDogdGhpcy5icm9hZGNhc3QuYmluZCh0aGlzKSxcblx0ICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUeXBlc2NyaXB0IGZhaWxzIHRvIGluZmVyIHRoZSByZXR1cm50eXBlIGlzIGEgUHJvbWlzZVxuXHQgICAgICAgICAgICBnZXRDdXJyZW50Q29udGV4dDogYXN5bmMgKGNvbnRleHRUeXBlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0Q3VycmVudENvbnRleHQoY29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUeXBlc2NyaXB0IGZhaWxzIHRvIGluZmVyIHRoZSByZXR1cm50eXBlIGlzIGEgUHJvbWlzZVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb250ZXh0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0fVxuXHRmZGMzQ29tbW9uLkZEQzNNb2R1bGVCYXNlID0gRkRDM01vZHVsZUJhc2U7XG5cdF9GREMzTW9kdWxlQmFzZV9wcm9kdWNlciA9IG5ldyBXZWFrTWFwKCk7XG5cdHJldHVybiBmZGMzQ29tbW9uO1xufVxuXG52YXIgaGFzUmVxdWlyZWRGZGMzMV8yO1xuXG5mdW5jdGlvbiByZXF1aXJlRmRjMzFfMiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZkYzMxXzIpIHJldHVybiBmZGMzMV8yO1xuXHRoYXNSZXF1aXJlZEZkYzMxXzIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZmRjMzFfMiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdGZkYzMxXzIuRmRjM01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgdXRpbHNfMSA9IHV0aWxzJDM7XG5cdGNvbnN0IGZkYzNfY29tbW9uXzEgPSByZXF1aXJlRmRjM0NvbW1vbigpO1xuXHQvKipcblx0ICogQHZlcnNpb24gMS4yXG5cdCAqIFRoZSBGREMzIENsaWVudCBMaWJyYXJ5IHByb3ZpZGVzIGEgc2V0IEFQSXMgdG8gYmUgdXNlZCBmb3IgRkRDMyBjb21wbGlhbmNlLFxuXHQgKiB3aGlsZSB1c2luZyBvdXIgSW50ZXJvcCBBUEkgdW5kZXIgdGhlIGhvb2QuIEluIG9yZGVyIHRvIHVzZSB0aGlzIHNldCBvZiBBUElzXG5cdCAqIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHVwIHlvdXIgb3duIHtAbGluayBJbnRlcm9wQnJva2VyIEludGVyb3BCcm9rZXJ9IG9yIHVzZSBhIFBsYXRmb3JtIGFwcGxpY2F0aW9uLCB3aGljaCBkb2VzIHRoZSBzZXR1cCBmb3IgeW91LiBSZWZlciB0byBvdXIgZG9jdW1lbnRhdGlvbiBvblxuXHQgKiBvdXIge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL29mLWRvY3MvZG9jcy9lbmFibGUtY29sb3ItbGlua2luZyBJbnRlcm9wIEFQSX0uXG5cdCAqXG5cdCAqIFRvIGVuYWJsZSB0aGUgRkRDMyBBUElzIGluIGEge0BsaW5rIFdpbmRvdyBXaW5kb3d9IG9yIHtAbGluayBWaWV3IFZpZXd9LCBhZGQgdGhlIGZkYzNJbnRlcm9wQXBpXG5cdCAqIHByb3BlcnR5IHRvIGl0cyBvcHRpb25zOlxuXHQgKlxuXHQgKiBgYGBqc1xuXHQgKiB7XG5cdCAqICAgICBhdXRvU2hvdzogZmFsc2UsXG5cdCAqICAgICBzYXZlV2luZG93U3RhdGU6IHRydWUsXG5cdCAqICAgICB1cmw6ICdodHRwczovL29wZW5maW4uY28nLFxuXHQgKiAgICAgZmRjM0ludGVyb3BBcGk6ICcxLjInXG5cdCAqIH1cblx0ICogYGBgXG5cdCAqXG5cdCAqIElmIHVzaW5nIGEge0BsaW5rIFBsYXRmb3JtIFBsYXRmb3JtIH0gYXBwbGljYXRpb24sIHlvdSBjYW4gc2V0IHRoaXMgcHJvcGVydHkgaW4gZGVmYXVsdFdpbmRvd09wdGlvbnMgYW5kIGRlZmF1bHRWaWV3T3B0aW9ucy5cblx0ICpcblx0ICogSW4gb3JkZXIgdG8gZW5zdXJlIHRoYXQgdGhlIEZEQzMgQXBpIGlzIHJlYWR5IGJlZm9yZSB1c2UsIHlvdSBjYW4gdXNlIHRoZSAnZmRjM1JlYWR5JyBldmVudCBmaXJlZCBvbiB0aGUgRE9NIFdpbmRvdyBvYmplY3Q6XG5cdCAqXG5cdCAqIGBgYGpzXG5cdCAqIGZ1bmN0aW9uIGZkYzNBY3Rpb24oKSB7XG5cdCAqICAgICAvLyBNYWtlIHNvbWUgZmRjMyBBUEkgY2FsbHMgaGVyZVxuXHQgKiB9XG5cdCAqXG5cdCAqIGlmICh3aW5kb3cuZmRjMykge1xuXHQgKiAgICBmZGMzQWN0aW9uKCk7XG5cdCAqIH0gZWxzZSB7XG5cdCAqICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdmZGMzUmVhZHknLCBmZGMzQWN0aW9uKTtcblx0ICogfVxuXHQgKiBgYGBcblx0ICovXG5cdGNsYXNzIEZkYzNNb2R1bGUgZXh0ZW5kcyBmZGMzX2NvbW1vbl8xLkZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIGFzeW5jIG9wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgYXdhaXQgc3VwZXIuX29wZW4oYXBwLCBjb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkIGEgY29udGV4dCBoYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LiBJZiBhbiBlbnRpdHkgaXMgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAsIGFuZCB0aGVuIHNldHMgaXRzIGNvbnRleHQgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuIElmIHlvdSB3aXNoIHRvIGxpc3RlbiBmb3IgYWxsIGluY29taW5nIGNvbnRleHRzLCBwYXNzIGBudWxsYCBmb3IgdGhlIGNvbnRleHRUeXBlIGFyZ3VtZW50LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlIC0gVGhlIHR5cGUgb2YgY29udGV4dCB5b3Ugd2lzaCB0byBoYW5kbGUuXG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlciAtIEhhbmRsZXIgZm9yIGluY29taW5nIGNvbnRleHQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYWRkQ29udGV4dExpc3RlbmVyXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKi9cblx0ICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETyBbQ09SRS0xNTI0XVxuXHQgICAgYWRkQ29udGV4dExpc3RlbmVyKGNvbnRleHRUeXBlLCBoYW5kbGVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYWRkLWNvbnRleHQtbGlzdGVuZXInKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBsZXQgbGlzdGVuZXI7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2FkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGFkZENvbnRleHRMaXN0ZW5lcihudWxsLCBoYW5kbGVyKScpO1xuXHQgICAgICAgICAgICBsaXN0ZW5lciA9IHRoaXMuY2xpZW50LmFkZENvbnRleHRIYW5kbGVyKGNvbnRleHRUeXBlKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGxpc3RlbmVyID0gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlciwgY29udGV4dFR5cGUgPT09IG51bGwgPyB1bmRlZmluZWQgOiBjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIC4uLmxpc3RlbmVyLFxuXHQgICAgICAgICAgICB1bnN1YnNjcmliZTogKCkgPT4gbGlzdGVuZXIudGhlbigobCkgPT4gbC51bnN1YnNjcmliZSgpKVxuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmb3IgaW5jb21pbmcgSW50ZW50cy5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgLSBOYW1lIG9mIHRoZSBJbnRlbnRcblx0ICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gSGFuZGxlciBmb3IgaW5jb21pbmcgSW50ZW50XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYWRkSW50ZW50TGlzdGVuZXJcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqL1xuXHQgICAgYWRkSW50ZW50TGlzdGVuZXIoaW50ZW50LCBoYW5kbGVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYWRkLWludGVudC1saXN0ZW5lcicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRIYW5kbGVyID0gKHJhaXNlZEludGVudCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHQsIG1ldGFkYXRhOiBpbnRlbnRNZXRhZGF0YSB9ID0gcmFpc2VkSW50ZW50O1xuXHQgICAgICAgICAgICBjb25zdCB7IG1ldGFkYXRhIH0gPSBjb250ZXh0O1xuXHQgICAgICAgICAgICBjb25zdCBpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQgPSBpbnRlbnRNZXRhZGF0YT8uaW50ZW50UmVzb2x1dGlvblJlc3VsdElkIHx8IG1ldGFkYXRhPy5pbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQ7XG5cdCAgICAgICAgICAgIGlmIChpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMucHVibGlzaChpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQsIG51bGwpLmNhdGNoKCgpID0+IG51bGwpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGhhbmRsZXIocmFpc2VkSW50ZW50LmNvbnRleHQpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB0aGlzLmNsaWVudC5yZWdpc3RlckludGVudEhhbmRsZXIoY29udGV4dEhhbmRsZXIsIGludGVudCwge1xuXHQgICAgICAgICAgICBmZGMzVmVyc2lvbjogJzEuMidcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAuLi5saXN0ZW5lcixcblx0ICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IGxpc3RlbmVyLnRoZW4oKGwpID0+IGwudW5zdWJzY3JpYmUoKSlcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSYWlzZXMgYSBzcGVjaWZpYyBpbnRlbnQuXG5cdCAgICAgKiBAcGFyYW0gaW50ZW50IE5hbWUgb2YgdGhlIEludGVudC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSBJbnRlbnQuXG5cdCAgICAgKiBAcGFyYW0gIGFwcCBBcHAgdGhhdCB3aWxsIHJlc29sdmUgdGhlIEludGVudC4gVGhpcyBpcyBhZGRlZCBhcyBtZXRhZGF0YSB0byB0aGUgSW50ZW50LiBDYW4gYmUgYWNjZXNzZWQgYnkgdGhlIGFwcCBwcm92aWRlciBpbiB7QGxpbmsgSW50ZXJvcEJyb2tlciNoYW5kbGVGaXJlZEludGVudCBJbnRlcm9wQnJva2VyLmhhbmRsZUZpcmVkSW50ZW50fS5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5yYWlzZUludGVudFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyByYWlzZUludGVudChpbnRlbnQsIGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGludGVudE9iaiA9IGFwcFxuXHQgICAgICAgICAgICA/IHsgbmFtZTogaW50ZW50LCBjb250ZXh0LCBtZXRhZGF0YTogeyB0YXJnZXQ6IGFwcCB9IH1cblx0ICAgICAgICAgICAgOiB7IG5hbWU6IGludGVudCwgY29udGV4dCB9O1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5maXJlSW50ZW50KGludGVudE9iaik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmluZCBvdXQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBhIHBhcnRpY3VsYXIgaW50ZW50IGJ5IHBhc3NpbmcgaXRzIG5hbWUsIGFuZCBvcHRpb25hbGx5IGl0cyBjb250ZXh0LlxuXHQgICAgICogQHBhcmFtIGludGVudCBOYW1lIG9mIHRoZSBJbnRlbnRcblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZmluZEludGVudFxuXHQgICAgICovXG5cdCAgICBhc3luYyBmaW5kSW50ZW50KGludGVudCwgY29udGV4dCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWZpbmQtaW50ZW50JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmdldEluZm9Gb3JJbnRlbnQoeyBuYW1lOiBpbnRlbnQsIGNvbnRleHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZ2V0SW5mb0ZvckludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmluZCBhbGwgdGhlIGF2YWlsYWJsZSBpbnRlbnRzIGZvciBhIHBhcnRpY3VsYXIgY29udGV4dC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZmluZEludGVudHNCeUNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZmluZEludGVudHNCeUNvbnRleHQoY29udGV4dCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWZpbmQtaW50ZW50cy1ieS1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0ID8gJ1Jlc29sdmVyVW5hdmFpbGFibGUnIDogZXJyb3IubWVzc2FnZTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yVG9UaHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBGaW5kcyBhbmQgcmFpc2VzIGFuIGludGVudCBhZ2FpbnN0IGEgdGFyZ2V0IGFwcCBiYXNlZCBwdXJlbHkgb24gY29udGV4dCBkYXRhLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRcblx0ICAgICAqIEBwYXJhbSBhcHBcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5yYWlzZUludGVudEZvckNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmFpc2VJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudC1mb3ItY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5maXJlSW50ZW50Rm9yQ29udGV4dCh7IC4uLmNvbnRleHQsIG1ldGFkYXRhOiB7IHRhcmdldDogYXBwIH0gfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudEZvckNvbnRleHQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBDaGFubmVsIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFubmVsLCBjcmVhdGluZyBpdCBhcyBhbiBBcHAgQ2hhbm5lbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRPckNyZWF0ZUNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0T3JDcmVhdGVDaGFubmVsKGNoYW5uZWxJZCkge1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRPckNyZWF0ZUNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBtZXRhZGF0YSByZWxhdGluZyB0byB0aGUgRkRDMyBvYmplY3QgYW5kIGl0cyBwcm92aWRlciwgaW5jbHVkaW5nIHRoZSBzdXBwb3J0ZWQgdmVyc2lvbiBvZiB0aGUgRkRDMyBzcGVjaWZpY2F0aW9uIGFuZCB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgb2YgdGhlIGltcGxlbWVudGF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldEluZm9cblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mbygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtaW5mbycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0QWRhcHRlclZlcnNpb25TeW5jKCk7XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgcHJvdmlkZXJWZXJzaW9uOiB2ZXJzaW9uLFxuXHQgICAgICAgICAgICBwcm92aWRlcjogYG9wZW5maW4tJHt0aGlzLndpcmUubWUudXVpZH1gLFxuXHQgICAgICAgICAgICBmZGMzVmVyc2lvbjogJzEuMidcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHR9XG5cdGZkYzMxXzIuRmRjM01vZHVsZSA9IEZkYzNNb2R1bGU7XG5cdHJldHVybiBmZGMzMV8yO1xufVxuXG52YXIgZmRjMzJfMCA9IHt9O1xuXG52YXIgaGFzUmVxdWlyZWRGZGMzMl8wO1xuXG5mdW5jdGlvbiByZXF1aXJlRmRjMzJfMCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZkYzMyXzApIHJldHVybiBmZGMzMl8wO1xuXHRoYXNSZXF1aXJlZEZkYzMyXzAgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZmRjMzJfMCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdGZkYzMyXzAuRmRjM01vZHVsZTIgPSB2b2lkIDA7XG5cdGNvbnN0IGZkYzNfY29tbW9uXzEgPSByZXF1aXJlRmRjM0NvbW1vbigpO1xuXHRjb25zdCB1dGlsc18xID0gdXRpbHMkMztcblx0Y29uc3QgSW50ZXJvcENsaWVudF8xID0gcmVxdWlyZUludGVyb3BDbGllbnQoKTtcblx0Y29uc3QgdXRpbHNfMiA9IHV0aWxzJDI7XG5cdGNvbnN0IFByaXZhdGVDaGFubmVsQ2xpZW50XzEgPSBQcml2YXRlQ2hhbm5lbENsaWVudCQxO1xuXHQvKipcblx0ICogQHZlcnNpb24gMi4wXG5cdCAqIFRoZSBGREMzIENsaWVudCBMaWJyYXJ5IHByb3ZpZGVzIGEgc2V0IEFQSXMgdG8gYmUgdXNlZCBmb3IgRkRDMyBjb21wbGlhbmNlLFxuXHQgKiB3aGlsZSB1c2luZyBvdXIgSW50ZXJvcCBBUEkgdW5kZXIgdGhlIGhvb2QuIEluIG9yZGVyIHRvIHVzZSB0aGlzIHNldCBvZiBBUElzXG5cdCAqIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHVwIHlvdXIgb3duIHtAbGluayBJbnRlcm9wQnJva2VyIEludGVyb3BCcm9rZXJ9IG9yIHVzZSBhIFBsYXRmb3JtIGFwcGxpY2F0aW9uLCB3aGljaCBkb2VzIHRoZSBzZXR1cCBmb3IgeW91LiBSZWZlciB0byBvdXIgZG9jdW1lbnRhdGlvbiBvblxuXHQgKiBvdXIge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL29mLWRvY3MvZG9jcy9lbmFibGUtY29udGV4dC1zaGFyaW5nIEludGVyb3AgQVBJfS5cblx0ICpcblx0ICogVG8gZW5hYmxlIHRoZSBGREMzIEFQSXMgaW4gYSB7QGxpbmsgV2luZG93IFdpbmRvd30gb3Ige0BsaW5rIFZpZXcgVmlld30sIGFkZCB0aGUgZmRjM0ludGVyb3BBcGlcblx0ICogcHJvcGVydHkgdG8gaXRzIG9wdGlvbnM6XG5cdCAqXG5cdCAqIGBgYGpzXG5cdCAqIHtcblx0ICogICAgIGF1dG9TaG93OiBmYWxzZSxcblx0ICogICAgIHNhdmVXaW5kb3dTdGF0ZTogdHJ1ZSxcblx0ICogICAgIHVybDogJ2h0dHBzOi8vb3BlbmZpbi5jbycsXG5cdCAqICAgICBmZGMzSW50ZXJvcEFwaTogJzIuMCdcblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogSWYgdXNpbmcgYSB7QGxpbmsgUGxhdGZvcm0gUGxhdGZvcm0gfSBhcHBsaWNhdGlvbiwgeW91IGNhbiBzZXQgdGhpcyBwcm9wZXJ0eSBpbiBkZWZhdWx0V2luZG93T3B0aW9ucyBhbmQgZGVmYXVsdFZpZXdPcHRpb25zLlxuXHQgKlxuXHQgKiBJbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUgRkRDMyBBcGkgaXMgcmVhZHkgYmVmb3JlIHVzZSwgeW91IGNhbiB1c2UgdGhlICdmZGMzUmVhZHknIGV2ZW50IGZpcmVkIG9uIHRoZSBET00gV2luZG93IG9iamVjdDpcblx0ICpcblx0ICogYGBganNcblx0ICogZnVuY3Rpb24gZmRjM0FjdGlvbigpIHtcblx0ICogICAgIC8vIE1ha2Ugc29tZSBmZGMzIEFQSSBjYWxscyBoZXJlXG5cdCAqIH1cblx0ICpcblx0ICogaWYgKHdpbmRvdy5mZGMzKSB7XG5cdCAqICAgIGZkYzNBY3Rpb24oKTtcblx0ICogfSBlbHNlIHtcblx0ICogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2ZkYzNSZWFkeScsIGZkYzNBY3Rpb24pO1xuXHQgKiB9XG5cdCAqIGBgYFxuXHQgKi9cblx0Y2xhc3MgRmRjM01vZHVsZTIgZXh0ZW5kcyBmZGMzX2NvbW1vbl8xLkZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIC8qKlxuXHQgICAgICogTGF1bmNoZXMgYW4gYXBwLCBzcGVjaWZpZWQgdmlhIGFuIEFwcElkZW50aWZpZXIgb2JqZWN0LlxuXHQgICAgICogQHBhcmFtIGFwcFxuXHQgICAgICogQHBhcmFtIGNvbnRleHRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5vcGVuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIG9wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBhcHAgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFzc2luZyBhIHN0cmluZyBhcyB0aGUgYXBwIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGFuIEFwcElkZW50aWZpZXIgKHsgYXBwSWQ6IHN0cmluZzsgaW5zdGFuY2VJZD86IHN0cmluZyB9KS4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgcmV0dXJuIHN1cGVyLl9vcGVuKGFwcCwgY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmQgYWxsIHRoZSBhdmFpbGFibGUgaW5zdGFuY2VzIGZvciBhIHBhcnRpY3VsYXIgYXBwbGljYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5maW5kSW5zdGFuY2VzXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnN0YW5jZXMoYXBwKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtZmluZC1pbnN0YW5jZXMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgSW50ZXJvcENsaWVudF8xLkludGVyb3BDbGllbnQuZmVycnlGZGMzQ2FsbCh0aGlzLmNsaWVudCwgJ2ZkYzNGaW5kSW5zdGFuY2VzJywgYXBwKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGVycm9yVG9UaHJvdyA9IGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5mZGMzRmluZEluc3RhbmNlcyA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIHRoZSBBcHBNZXRhZGF0YSBmb3IgYW4gQXBwSWRlbnRpZmllciwgd2hpY2ggcHJvdmlkZXMgYWRkaXRpb25hbCBtZXRhZGF0YSAoc3VjaCBhcyBpY29ucywgYSB0aXRsZSBhbmQgZGVzY3JpcHRpb24pIGZyb20gdGhlIEFwcCBEaXJlY3RvcnkgcmVjb3JkIGZvciB0aGUgYXBwbGljYXRpb24sIHRoYXQgbWF5IGJlIHVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRBcHBNZXRhZGF0YVxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRBcHBNZXRhZGF0YShhcHApIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtYXBwLW1ldGFkYXRhJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzR2V0QXBwTWV0YWRhdGEnLCBhcHApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmZkYzNHZXRBcHBNZXRhZGF0YSA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkIGEgY29udGV4dCBoYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LiBJZiBhbiBlbnRpdHkgaXMgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAsIGFuZCB0aGVuIHNldHMgaXRzIGNvbnRleHQgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuIElmIHlvdSB3aXNoIHRvIGxpc3RlbiBmb3IgYWxsIGluY29taW5nIGNvbnRleHRzLCBwYXNzIGBudWxsYCBmb3IgdGhlIGNvbnRleHRUeXBlIGFyZ3VtZW50LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlXG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlclxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmFkZENvbnRleHRMaXN0ZW5lclxuXHQgICAgICovXG5cdCAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgIGFzeW5jIGFkZENvbnRleHRMaXN0ZW5lcihjb250ZXh0VHlwZSwgaGFuZGxlcikge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWFkZC1jb250ZXh0LWxpc3RlbmVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy8gVGhlIEZEQzMgQ29udGV4dEhhbmRsZXIgb25seSBleHBlY3RzIHRoZSBjb250ZXh0IGFuZCBvcHRpb25hbCBDb250ZXh0TWV0YWRhdGEsIHNvIHdlIHdyYXAgdGhlIGhhbmRsZXJcblx0ICAgICAgICAvLyBoZXJlIHNvIGl0IG9ubHkgZ2V0cyBwYXNzZWQgdGhlc2UgcGFyYW1ldGVyc1xuXHQgICAgICAgIGNvbnN0IGdldFdyYXBwZWRIYW5kbGVyID0gKGhhbmRsZXJUb1dyYXApID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRNZXRhZGF0YSwgLi4ucmVzdCB9ID0gY29udGV4dDtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBjb250ZXh0TWV0YWRhdGEgPyBbeyAuLi5yZXN0IH0sIGNvbnRleHRNZXRhZGF0YV0gOiBbY29udGV4dCwgbnVsbF07XG5cdCAgICAgICAgICAgICAgICBoYW5kbGVyVG9XcmFwKC4uLmFyZ3MpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgbGV0IGFjdHVhbEhhbmRsZXIgPSBoYW5kbGVyO1xuXHQgICAgICAgIGxldCB3cmFwcGVkSGFuZGxlciA9IGdldFdyYXBwZWRIYW5kbGVyKGFjdHVhbEhhbmRsZXIpO1xuXHQgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgYWN0dWFsSGFuZGxlciA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICB3cmFwcGVkSGFuZGxlciA9IGdldFdyYXBwZWRIYW5kbGVyKGFjdHVhbEhhbmRsZXIpO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIsIGNvbnRleHRUeXBlID09PSBudWxsID8gdW5kZWZpbmVkIDogY29udGV4dFR5cGUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBGaW5kIG91dCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGEgcGFydGljdWxhciBpbnRlbnQgYnkgcGFzc2luZyBpdHMgbmFtZSwgYW5kIG9wdGlvbmFsbHkgaXRzIGNvbnRleHQgYW5kIHJlc3VsdFR5cGUuXG5cdCAgICAgKiBAcGFyYW0gaW50ZW50IE5hbWUgb2YgdGhlIEludGVudFxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgQ29udGV4dFxuXHQgICAgICogQHBhcmFtIHJlc3VsdFR5cGUgVGhlIHR5cGUgb2YgcmVzdWx0IHJldHVybmVkIGZvciBhbnkgaW50ZW50IHNwZWNpZmllZCBkdXJpbmcgcmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5maW5kSW50ZW50XG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnRlbnQoaW50ZW50LCBjb250ZXh0LCByZXN1bHRUeXBlKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtZmluZC1pbnRlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuZ2V0SW5mb0ZvckludGVudCh7IG5hbWU6IGludGVudCwgY29udGV4dCwgbWV0YWRhdGE6IHsgcmVzdWx0VHlwZSB9IH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmQgYWxsIHRoZSBhdmFpbGFibGUgaW50ZW50cyBmb3IgYSBwYXJ0aWN1bGFyIGNvbnRleHQuXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICogQHBhcmFtIHJlc3VsdFR5cGUgVGhlIHR5cGUgb2YgcmVzdWx0IHJldHVybmVkIGZvciBhbnkgaW50ZW50IHNwZWNpZmllZCBkdXJpbmcgcmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjM3YyLmZpbmRJbnRlbnRzQnlDb250ZXh0XG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIHJlc3VsdFR5cGUpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1maW5kLWludGVudHMtYnktY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHBheWxvYWQgPSByZXN1bHRUeXBlID8geyBjb250ZXh0LCBtZXRhZGF0YTogeyByZXN1bHRUeXBlIH0gfSA6IGNvbnRleHQ7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzdjJGaW5kSW50ZW50c0J5Q29udGV4dCcsIHBheWxvYWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0ID8gJ1Jlc29sdmVyVW5hdmFpbGFibGUnIDogZXJyb3IubWVzc2FnZTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yVG9UaHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSYWlzZXMgYSBzcGVjaWZpYyBpbnRlbnQgZm9yIHJlc29sdXRpb24gYWdhaW5zdCBhcHBzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgZGVza3RvcCBhZ2VudC5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgTmFtZSBvZiB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCBDb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5yYWlzZUludGVudFxuXHQgICAgICovXG5cdCAgICBhc3luYyByYWlzZUludGVudChpbnRlbnQsIGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgYXBwID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQYXNzaW5nIGEgc3RyaW5nIGFzIHRoZSBhcHAgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYW4gQXBwSWRlbnRpZmllciAoeyBhcHBJZDogc3RyaW5nOyBpbnN0YW5jZUlkPzogc3RyaW5nIH0pLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMi5nZXRJbnRlbnRSZXNvbHV0aW9uKSh0aGlzLmNsaWVudCwgY29udGV4dCwgYXBwLCBpbnRlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmRzIGFuZCByYWlzZXMgYW4gaW50ZW50IGFnYWluc3QgYXBwcyByZWdpc3RlcmVkIHdpdGggdGhlIGRlc2t0b3AgYWdlbnQgYmFzZWQgcHVyZWx5IG9uIHRoZSB0eXBlIG9mIHRoZSBjb250ZXh0IGRhdGEuXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCBDb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5yYWlzZUludGVudEZvckNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmFpc2VJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIC8vIFRPRE86IFdlIGhhdmUgdG8gZG8gdGhlIHNhbWUgdGhpbmcgd2UgZG8gZm9yIHJhaXNlSW50ZW50IGhlcmUgYXMgd2VsbC5cblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1yYWlzZS1pbnRlbnQtZm9yLWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGFwcCA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFzc2luZyBhIHN0cmluZyBhcyB0aGUgYXBwIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGFuIEFwcElkZW50aWZpZXIgKHsgYXBwSWQ6IHN0cmluZzsgaW5zdGFuY2VJZD86IHN0cmluZyB9KS4nKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICByZXR1cm4gKDAsIHV0aWxzXzIuZ2V0SW50ZW50UmVzb2x1dGlvbikodGhpcy5jbGllbnQsIGNvbnRleHQsIGFwcCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkcyBhIGxpc3RlbmVyIGZvciBpbmNvbWluZyBpbnRlbnRzLlxuXHQgICAgICogQHBhcmFtIGludGVudCAgTmFtZSBvZiB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlciBBIGNhbGxiYWNrIHRoYXQgaGFuZGxlcyBhIGNvbnRleHQgZXZlbnQgYW5kIG1heSByZXR1cm4gYSBwcm9taXNlIG9mIGEgQ29udGV4dCBvciBDaGFubmVsIG9iamVjdCB0byBiZSByZXR1cm5lZCB0byB0aGUgYXBwbGljYXRpb24gdGhhdCByYWlzZWQgdGhlIGludGVudC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5hZGRJbnRlbnRMaXN0ZW5lclxuXHQgICAgICovXG5cdCAgICBhc3luYyBhZGRJbnRlbnRMaXN0ZW5lcihpbnRlbnQsIGhhbmRsZXIpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1hZGQtaW50ZW50LWxpc3RlbmVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBpbnRlbnQgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBJbnRlbnQgbmFtZScpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvLyBUaGUgRkRDMyBJbnRlbnRlciBoYW5kbGVyIG9ubHkgZXhwZWN0cyB0aGUgY29udGV4dCBhbmQgY29udGV4dE1ldGFkYXRhIHRvIGJlIHBhc3NlZCB0byB0aGUgaGFuZGxlcixcblx0ICAgICAgICAvLyBzbyB3ZSB3cmFwIGl0IGhlcmUgYW5kIG9ubHkgcGFzcyB0aG9zZSBwYXJhbWF0ZXJzLlxuXHQgICAgICAgIGNvbnN0IGNvbnRleHRIYW5kbGVyID0gYXN5bmMgKHJhaXNlZEludGVudCkgPT4ge1xuXHQgICAgICAgICAgICBsZXQgaW50ZW50UmVzdWx0O1xuXHQgICAgICAgICAgICBsZXQgaW50ZW50UmVzdWx0VG9TZW5kO1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHQsIG1ldGFkYXRhOiBpbnRlbnRNZXRhZGF0YSB9ID0gcmFpc2VkSW50ZW50O1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRNZXRhZGF0YSwgbWV0YWRhdGEsIC4uLnJlc3QgfSA9IGNvbnRleHQ7XG5cdCAgICAgICAgICAgIGNvbnN0IGludGVudFJlc29sdXRpb25SZXN1bHRJZCA9IGludGVudE1ldGFkYXRhPy5pbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQgfHwgbWV0YWRhdGE/LmludGVudFJlc29sdXRpb25SZXN1bHRJZDtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSBtZXRhZGF0YSA/IHsgbWV0YWRhdGEsIC4uLnJlc3QgfSA6IHsgLi4ucmVzdCB9O1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gYXdhaXQgaGFuZGxlcihuZXdDb250ZXh0LCBjb250ZXh0TWV0YWRhdGEpO1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0VG9TZW5kID0gaW50ZW50UmVzdWx0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gZXJyb3I7XG5cdCAgICAgICAgICAgICAgICBpbnRlbnRSZXN1bHRUb1NlbmQgPSB7IGVycm9yOiB0cnVlIH07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGludGVudFJlc29sdXRpb25SZXN1bHRJZCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5wdWJsaXNoKGludGVudFJlc29sdXRpb25SZXN1bHRJZCwgaW50ZW50UmVzdWx0VG9TZW5kKS5jYXRjaCgoKSA9PiBudWxsKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoaW50ZW50UmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihpbnRlbnRSZXN1bHQubWVzc2FnZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIGludGVudFJlc3VsdDtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5yZWdpc3RlckludGVudEhhbmRsZXIoY29udGV4dEhhbmRsZXIsIGludGVudCwgeyBmZGMzVmVyc2lvbjogJzIuMCcgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBDaGFubmVsIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFubmVsLCBjcmVhdGluZyBpdCBhcyBhbiBBcHAgQ2hhbm5lbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRPckNyZWF0ZUNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0T3JDcmVhdGVDaGFubmVsKGNoYW5uZWxJZCkge1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRPckNyZWF0ZUNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIENoYW5uZWwgd2l0aCBhbiBhdXRvLWdlbmVyYXRlZCBpZGVudGl0eSB0aGF0IGlzIGludGVuZGVkIGZvciBwcml2YXRlIGNvbW11bmljYXRpb24gYmV0d2VlbiBhcHBsaWNhdGlvbnMuIFByaW1hcmlseSB1c2VkIHRvIGNyZWF0ZSBjaGFubmVscyB0aGF0IHdpbGwgYmUgcmV0dXJuZWQgdG8gb3RoZXIgYXBwbGljYXRpb25zIHZpYSBhbiBJbnRlbnRSZXNvbHV0aW9uIGZvciBhIHJhaXNlZCBpbnRlbnQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5jcmVhdGVQcml2YXRlQ2hhbm5lbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjcmVhdGVQcml2YXRlQ2hhbm5lbCgpIHtcblx0ICAgICAgICBjb25zdCBjaGFubmVsSWQgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZUlkKSgpO1xuXHQgICAgICAgIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdjcmVhdGVQcml2YXRlQ2hhbm5lbFByb3ZpZGVyJywgeyBjaGFubmVsSWQgfSk7XG5cdCAgICAgICAgY29uc3QgY2hhbm5lbENsaWVudCA9IGF3YWl0IHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxJZCk7XG5cdCAgICAgICAgY29uc3QgbmV3UHJpdmF0ZUNoYW5uZWxDbGllbnQgPSBuZXcgUHJpdmF0ZUNoYW5uZWxDbGllbnRfMS5Qcml2YXRlQ2hhbm5lbENsaWVudChjaGFubmVsQ2xpZW50LCBjaGFubmVsSWQpO1xuXHQgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMi5idWlsZFByaXZhdGVDaGFubmVsT2JqZWN0KShuZXdQcml2YXRlQ2hhbm5lbENsaWVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdGhlIFVzZXIgQ2hhbm5lbHMgYXZhaWxhYmxlIGZvciB0aGUgYXBwIHRvIGpvaW4uXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRVc2VyQ2hhbm5lbHNcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0VXNlckNoYW5uZWxzKCkge1xuXHQgICAgICAgIGNvbnN0IGNoYW5uZWxzID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0Q29udGV4dEdyb3VwcygpO1xuXHQgICAgICAgIC8vIGZkYzMgaW1wbGVtZW50YXRpb24gb2YgZ2V0VXNlckNoYW5uZWxzIHJldHVybnMgb24gYXJyYXkgb2YgY2hhbm5lbHMsIGhhdmUgdG8gZGVjb3JhdGUgb3ZlclxuXHQgICAgICAgIC8vIHRoaXMgc28gcGVvcGxlIGtub3cgdGhhdCB0aGVzZSBBUElzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdCAgICAgICAgcmV0dXJuIGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuXHQgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgICAgICAgICAgcmV0dXJuIHsgLi4uY2hhbm5lbCwgdHlwZTogJ3VzZXInLCAuLi4oMCwgdXRpbHNfMi5nZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzKSgnVXNlcicpIH07XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdGhlIFVzZXIgQ2hhbm5lbHMgYXZhaWxhYmxlIGZvciB0aGUgYXBwIHRvIGpvaW4uXG5cdCAgICAgKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgUGxlYXNlIHVzZSB7QGxpbmsgZmRjMy5nZXRVc2VyQ2hhbm5lbHMgZmRjMy5nZXRVc2VyQ2hhbm5lbHN9IGluc3RlYWRcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldFN5c3RlbUNoYW5uZWxzXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldFN5c3RlbUNoYW5uZWxzKCkge1xuXHQgICAgICAgIGNvbnNvbGUud2FybignVGhpcyBBUEkgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBmZGMzLmdldFVzZXJDaGFubmVscyBpbnN0ZWFkLicpO1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRTeXN0ZW1DaGFubmVscygpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFuIGFwcCB0byBhIHNwZWNpZmllZCBVc2VyIGNoYW5uZWwuXG5cdCAgICAgKiBAcGFyYW0gY2hhbm5lbElkIENoYW5uZWwgbmFtZVxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzdjIuam9pblVzZXJDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGpvaW5Vc2VyQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICByZXR1cm4gc3VwZXIuam9pbkNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSm9pbiBhbiBhcHAgdG8gYSBzcGVjaWZpZWQgVXNlciBjaGFubmVsLlxuXHQgICAgICogQHBhcmFtIGNoYW5uZWxJZCBDaGFubmVsIG5hbWVcblx0ICAgICAqIEBkZXByZWNhdGVkIFBsZWFzZSB1c2Uge0BsaW5rIGZkYzMuam9pblVzZXJDaGFubmVsIGZkYzMuam9pblVzZXJDaGFubmVsfSBpbnN0ZWFkXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuam9pbkNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgam9pbkNoYW5uZWwoY2hhbm5lbElkKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdUaGlzIEFQSSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGZkYzMuam9pblVzZXJDaGFubmVsIGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHN1cGVyLmpvaW5DaGFubmVsKGNoYW5uZWxJZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIENoYW5uZWwgb2JqZWN0IGZvciB0aGUgY3VycmVudCBVc2VyIGNoYW5uZWwgbWVtYmVyc2hpcFxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldEN1cnJlbnRDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEN1cnJlbnRDaGFubmVsKCkge1xuXHQgICAgICAgIGNvbnN0IGN1cnJlbnRDaGFubmVsID0gYXdhaXQgc3VwZXIuZ2V0Q3VycmVudENoYW5uZWwoKTtcblx0ICAgICAgICBpZiAoIWN1cnJlbnRDaGFubmVsKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAuLi5jdXJyZW50Q2hhbm5lbCxcblx0ICAgICAgICAgICAgdHlwZTogJ3VzZXInLFxuXHQgICAgICAgICAgICBicm9hZGNhc3Q6IHRoaXMuYnJvYWRjYXN0LmJpbmQodGhpcylcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIEZEQzMgaW1wbGVtZW50YXRpb24sIGluY2x1ZGluZyB0aGUgc3VwcG9ydGVkIHZlcnNpb24gb2YgdGhlIEZEQzMgc3BlY2lmaWNhdGlvbiwgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIG9mIHRoZSBpbXBsZW1lbnRhdGlvbiwgaXRzIG93biB2ZXJzaW9uIG51bWJlciwgZGV0YWlscyBvZiB3aGV0aGVyIG9wdGlvbmFsIEFQSSBmZWF0dXJlcyBhcmUgaW1wbGVtZW50ZWQgYW5kIHRoZSBtZXRhZGF0YSBvZiB0aGUgY2FsbGluZyBhcHBsaWNhdGlvbiBhY2NvcmRpbmcgdG8gdGhlIGRlc2t0b3AgYWdlbnQuXG5cdCAgICAgKiBmZGMzSGFuZGxlR2V0SW5mbyBtdXN0IGJlIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3BCcm9rZXIgc28gdGhhdCB0aGUgSW1wbGVtZW50YXRpb25NZXRhZGF0YSB3aWxsIGhhdmUgdGhlIGFwcE1ldGFkYXRhIGluZm8uXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRJbmZvXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEluZm8oKSB7XG5cdCAgICAgICAgcmV0dXJuIEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzdjJHZXRJbmZvJywgeyBmZGMzVmVyc2lvbjogJzIuMCcgfSk7XG5cdCAgICB9XG5cdH1cblx0ZmRjMzJfMC5GZGMzTW9kdWxlMiA9IEZkYzNNb2R1bGUyO1xuXHRyZXR1cm4gZmRjMzJfMDtcbn1cblxudmFyIGhhc1JlcXVpcmVkSW50ZXJvcENsaWVudDtcblxuZnVuY3Rpb24gcmVxdWlyZUludGVyb3BDbGllbnQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRJbnRlcm9wQ2xpZW50KSByZXR1cm4gSW50ZXJvcENsaWVudDtcblx0aGFzUmVxdWlyZWRJbnRlcm9wQ2xpZW50ID0gMTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcblx0ICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcblx0ICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcblx0ICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcblx0fTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xuXHR9O1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdHZhciBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3Vwcztcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEludGVyb3BDbGllbnQsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRJbnRlcm9wQ2xpZW50LkludGVyb3BDbGllbnQgPSB2b2lkIDA7XG5cdGNvbnN0IGJhc2VfMSA9IGJhc2U7XG5cdGNvbnN0IFNlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfMSA9IF9faW1wb3J0RGVmYXVsdChTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50JDEpO1xuXHRjb25zdCBmZGMzXzFfMl8xID0gcmVxdWlyZUZkYzMxXzIoKTtcblx0Y29uc3QgZmRjM18yXzBfMSA9IHJlcXVpcmVGZGMzMl8wKCk7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHQvKipcblx0ICogVGhlIEludGVyb3AgQ2xpZW50IEFQSSBpcyBicm9rZW4gdXAgaW50byB0d28gZ3JvdXBzOlxuXHQgKlxuXHQgKiAqKkNvbnRlbnQgRmFjaW5nIEFQSXMqKiAtIEZvciBBcHBsaWNhdGlvbiBEZXZlbG9wZXJzIHB1dHRpbmcgVmlld3MgaW50byBhIFBsYXRmb3JtIFdpbmRvdywgd2hvIGNhcmUgYWJvdXQgQ29udGV4dC4gVGhlc2UgYXJlIEFQSXMgdGhhdCBzZW5kIG91dCBhbmQgcmVjZWl2ZSB0aGUgQ29udGV4dCBkYXRhIHRoYXQgZmxvd3MgYmV0d2VlbiBhcHBsaWNhdGlvbnMuIFRoaW5rIG9mIHRoaXMgYXMgdGhlIFdhdGVyIGluIHRoZSBJbnRlcm9wIFBpcGVzLlxuXHQgKlxuXHQgKiAqKkNvbnRleHQgR3JvdXBpbmcgQVBJcyoqIC0gRm9yIFBsYXRmb3JtIERldmVsb3BlcnMsIHRvIGFkZCBhbmQgcmVtb3ZlIFZpZXdzIHRvIGFuZCBmcm9tIENvbnRleHQgR3JvdXBzLiBUaGVzZSBBUElzIGFyZSB1dGlsaXplZCB1bmRlci10aGUtaG9vZCBpbiBQbGF0Zm9ybXMsIHNvIHRoZXkgZG9uJ3QgbmVlZCB0byBiZSB1c2VkIHRvIHBhcnRpY2lwYXRlIGluIEludGVyb3AuIFRoZXNlIGFyZSB0aGUgQVBJcyB0aGF0IGRlY2lkZSB3aGljaCBlbnRpdGllcyB0aGUgY29udGV4dCBkYXRhIGZsb3dzIGJldHdlZW4uIFRoaW5rIG9mIHRoZXNlIGFzIHRoZSB2YWx2ZXMgb3IgcGlwZXMgdGhhdCBjb250cm9sIHRoZSBmbG93IG9mIENvbnRleHQgRGF0YSBmb3IgSW50ZXJvcC5cblx0ICpcblx0ICogLS0tXG5cdCAqXG5cdCAqIEFsbCBBUElzIGFyZSBhdmFpbGFibGUgYXQgdGhlIGBmaW4ubWUuaW50ZXJvcGAgbmFtZXNwYWNlLlxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogKipZb3Ugb25seSBuZWVkIDIgdGhpbmdzIHRvIHBhcnRpY2lwYXRlIGluIEludGVyb3AgQ29udGV4dCBHcm91cGluZzoqKlxuXHQgKiAqIEEgQ29udGV4dCBIYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0OiB7QGxpbmsgSW50ZXJvcENsaWVudCNhZGRDb250ZXh0SGFuZGxlciBhZGRDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBjb250ZXh0VHlwZT8pfVxuXHQgKiAqIENhbGwgc2V0Q29udGV4dCBvbiB5b3VyIGNvbnRleHQgZ3JvdXAgd2hlbiB5b3Ugd2FudCB0byBzaGFyZSBjb250ZXh0IHdpdGggb3RoZXIgZ3JvdXAgbWVtYmVyczoge0BsaW5rIEludGVyb3BDbGllbnQjc2V0Q29udGV4dCBzZXRDb250ZXh0KGNvbnRleHQpfVxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogIyMjIyMgQ29uc3RydWN0b3Jcblx0ICogUmV0dXJuZWQgYnkge0BsaW5rIEludGVyb3AuY29ubmVjdFN5bmMgSW50ZXJvcC5jb25uZWN0U3luY30uXG5cdCAqXG5cdCAqIC0tLVxuXHQgKlxuXHQgKiAjIyMjIyBJbnRlcm9wIG1ldGhvZHMgaW50ZW5kZWQgZm9yIFZpZXdzXG5cdCAqXG5cdCAqXG5cdCAqICoqQ29udGV4dCBHcm91cHMgQVBJKipcblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjYWRkQ29udGV4dEhhbmRsZXIgYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlciwgY29udGV4dFR5cGU/KX1cblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjc2V0Q29udGV4dCBzZXRDb250ZXh0KGNvbnRleHQpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNnZXRDdXJyZW50Q29udGV4dCBnZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZT8pfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNqb2luU2Vzc2lvbkNvbnRleHRHcm91cCBqb2luU2Vzc2lvbkNvbnRleHRHcm91cChzZXNzaW9uQ29udGV4dEdyb3VwSWQpfVxuXHQgKlxuXHQgKlxuXHQgKiAqKkludGVudHMgQVBJKipcblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjZmlyZUludGVudCBmaXJlSW50ZW50KGludGVudCl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I3JlZ2lzdGVySW50ZW50SGFuZGxlciByZWdpc3RlckludGVudEhhbmRsZXIoaW50ZW50SGFuZGxlciwgaW50ZW50TmFtZSl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JJbnRlbnQgZ2V0SW5mb0ZvckludGVudChpbmZvRm9ySW50ZW50T3B0aW9ucyl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0IGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNmaXJlSW50ZW50Rm9yQ29udGV4dCBmaXJlSW50ZW50Rm9yQ29udGV4dChjb250ZXh0Rm9ySW50ZW50KX1cblx0ICpcblx0ICogIyMjIyMgSW50ZXJvcCBtZXRob2RzIGludGVuZGVkIGZvciBXaW5kb3dzXG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldENvbnRleHRHcm91cHMgZ2V0Q29udGV4dEdyb3VwcygpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNqb2luQ29udGV4dEdyb3VwIGpvaW5Db250ZXh0R3JvdXAoY29udGV4dEdyb3VwSWQsIHRhcmdldD8pfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNyZW1vdmVGcm9tQ29udGV4dEdyb3VwIHJlbW92ZUZyb21Db250ZXh0R3JvdXAodGFyZ2V0Pyl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JDb250ZXh0R3JvdXAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cChjb250ZXh0R3JvdXBJZCl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCBnZXRBbGxDbGllbnRzSW5Db250ZXh0R3JvdXAoY29udGV4dEdyb3VwSWQpfVxuXHQgKlxuXHQgKi9cblx0bGV0IEludGVyb3BDbGllbnQkMSA9IGNsYXNzIEludGVyb3BDbGllbnQgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICovXG5cdCAgICBjb25zdHJ1Y3Rvcih3aXJlLCBjbGllbnRQcm9taXNlKSB7XG5cdCAgICAgICAgc3VwZXIod2lyZSk7XG5cdCAgICAgICAgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZS5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3Vwcy5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X3Nlc3Npb25Db250ZXh0R3JvdXBzLCBuZXcgTWFwKCksIFwiZlwiKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIGNsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBDbGllbnQgQVBJc1xuXHQgICAgKi9cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBhIGNvbnRleHQgZm9yIHRoZSBjb250ZXh0IGdyb3VwIG9mIHRoZSBjdXJyZW50IGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBUaGUgZW50aXR5IG11c3QgYmUgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAgaW4gb3JkZXIgc2V0IGEgY29udGV4dC5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCAtIE5ldyBjb250ZXh0IHRvIHNldC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIHNldEluc3RydW1lbnRDb250ZXh0ID0gYXN5bmMgKHRpY2tlcikgPT4ge1xuXHQgICAgICogICAgIGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoe3R5cGU6ICdpbnN0cnVtZW50JywgaWQ6IHt0aWNrZXJ9fSlcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiAvLyBUaGUgdXNlciBjbGlja3MgYW4gaW5zdHJ1bWVudCBvZiBpbnRlcmVzdC4gV2Ugd2FudCB0byBzZXQgdGhhdCBJbnN0cnVtZW50IGNvbnRleHQgc28gdGhhdCB0aGUgcmVzdCBvZiBvdXIgd29ya2Zsb3cgdXBkYXRlcyB3aXRoIGluZm9ybWF0aW9uIGZvciB0aGF0IGluc3RydW1lbnRcblx0ICAgICAqIGluc3RydW1lbnRFbGVtZW50Lm9uKCdjbGljaycsIChldnQpID0+IHtcblx0ICAgICAqICAgICBzZXRJbnN0cnVtZW50Q29udGV4dChldnQudGlja2VyKVxuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtc2V0LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdzZXRDb250ZXh0JywgeyBjb250ZXh0IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBZGQgYSBjb250ZXh0IGhhbmRsZXIgZm9yIGluY29taW5nIGNvbnRleHQuIElmIGFuIGVudGl0eSBpcyBwYXJ0IG9mIGEgY29udGV4dCBncm91cCwgYW5kIHRoZW4gc2V0cyBpdHMgY29udGV4dCBoYW5kbGVyLFxuXHQgICAgICogaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGhhbmRsZXIgLSBIYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlIC0gVGhlIHR5cGUgb2YgY29udGV4dCB5b3Ugd2lzaCB0byBoYW5kbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmdW5jdGlvbiBoYW5kbGVJbmNvbWluZ0NvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBzd2l0Y2ggKHR5cGUpIHtcblx0ICAgICAqICAgICAgICAgY2FzZSAnaW5zdHJ1bWVudCc6XG5cdCAgICAgKiAgICAgICAgICAgICBoYW5kbGVJbnN0cnVtZW50Q29udGV4dChjb250ZXh0SW5mbyk7XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqICAgICAgICAgY2FzZSAnY291bnRyeSc6XG5cdCAgICAgKiAgICAgICAgICAgICBoYW5kbGVDb3VudHJ5Q29udGV4dChjb250ZXh0SW5mbyk7XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqXG5cdCAgICAgKiAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIGZ1bmN0aW9uIGhhbmRsZUluc3RydW1lbnRDb250ZXh0KGNvbnRleHRJbmZvKSB7XG5cdCAgICAgKiAgICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gY29udGV4dEluZm87XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coJ2NvbnRleHRJbmZvIGZvciBpbnN0cnVtZW50JywgY29udGV4dEluZm8pXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZnVuY3Rpb24gaGFuZGxlQ291bnRyeUNvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygnY29udGV4dEluZm8gZm9yIGNvdW50cnknLCBjb250ZXh0SW5mbylcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5hZGRDb250ZXh0SGFuZGxlcihoYW5kbGVJbmNvbWluZ0NvbnRleHQpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIFBhc3NpbmcgaW4gYSBjb250ZXh0IHR5cGUgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgd2lsbCBjYXVzZSB0aGUgaGFuZGxlciB0byBvbmx5IGJlIGludm9rZWQgd2l0aCB0aGF0IGNvbnRleHQgdHlwZS5cblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZnVuY3Rpb24gaGFuZGxlSW5zdHJ1bWVudENvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygnY29udGV4dEluZm8gZm9yIGluc3RydW1lbnQnLCBjb250ZXh0SW5mbylcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBmdW5jdGlvbiBoYW5kbGVDb3VudHJ5Q29udGV4dChjb250ZXh0SW5mbykge1xuXHQgICAgICogICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGNvbnRleHRJbmZvO1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKCdjb250ZXh0SW5mbyBmb3IgY291bnRyeScsIGNvbnRleHRJbmZvKVxuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5hZGRDb250ZXh0SGFuZGxlcihoYW5kbGVJbnN0cnVtZW50Q29udGV4dCwgJ2luc3RydW1lbnQnKVxuXHQgICAgICogZmluLm1lLmludGVyb3AuYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlQ291bnRyeUNvbnRleHQsICdjb3VudHJ5Jylcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBhZGRDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBjb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1hZGQtY29udGV4dC1oYW5kbGVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vbi1mdW5jdGlvbiBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZpcnN0IHBhcmFtZXRlciAnaGFuZGxlcicuIEJlIGF3YXJlIHRoYXQgdGhlIGFyZ3VtZW50IG9yZGVyIGRvZXMgbm90IG1hdGNoIHRoZSBGREMzIHN0YW5kYXJkLlwiKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgbGV0IGhhbmRsZXJJZDtcblx0ICAgICAgICBpZiAoY29udGV4dFR5cGUpIHtcblx0ICAgICAgICAgICAgaGFuZGxlcklkID0gYGludm9rZUNvbnRleHRIYW5kbGVyLSR7Y29udGV4dFR5cGV9LSR7KDAsIHV0aWxzXzEuZ2VuZXJhdGVJZCkoKX1gO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgaGFuZGxlcklkID0gJ2ludm9rZUNvbnRleHRIYW5kbGVyJztcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3Qgd3JhcHBlZEhhbmRsZXIgPSAoMCwgdXRpbHNfMS53cmFwQ29udGV4dEhhbmRsZXIpKGhhbmRsZXIsIGhhbmRsZXJJZCk7XG5cdCAgICAgICAgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgd3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkJywgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0pO1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHVuc3Vic2NyaWJlOiBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjbGllbnQucmVtb3ZlKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlbW92ZUNvbnRleHRIYW5kbGVyJywgeyBoYW5kbGVySWQgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLypcblx0ICAgIFBsYXRmb3JtIFdpbmRvdyBBUElzXG5cdCAgICAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBJbnRlcm9wLUJyb2tlci1kZWZpbmVkIGNvbnRleHQgZ3JvdXBzIGF2YWlsYWJsZSBmb3IgYW4gZW50aXR5IHRvIGpvaW4uXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5nZXRDb250ZXh0R3JvdXBzKClcblx0ICAgICAqICAgICAgICAgLnRoZW4oY29udGV4dEdyb3VwcyA9PiB7XG5cdCAgICAgKiAgICAgICAgICAgICBjb250ZXh0R3JvdXBzLmZvckVhY2goY29udGV4dEdyb3VwID0+IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhjb250ZXh0R3JvdXAuZGlzcGxheU1ldGFkYXRhLm5hbWUpXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwLmRpc3BsYXlNZXRhZGF0YS5jb2xvcilcblx0ICAgICAqICAgICAgICAgICAgIH0pXG5cdCAgICAgKiAgICAgICAgIH0pXG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0Q29udGV4dEdyb3VwcygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZ2V0LWNvbnRleHQtZ3JvdXBzJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0Q29udGV4dEdyb3VwcycpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFsbCBJbnRlcm9wIENsaWVudHMgYXQgdGhlIGdpdmVuIGlkZW50aXR5IHRvIGNvbnRleHQgZ3JvdXAgYGNvbnRleHRHcm91cElkYC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IGFkZHMgdGhlIHNlbmRlciB0byB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBCZWNhdXNlIG11bHRpcGxlIENoYW5uZWwgY29ubmVjdGlvbnMvSW50ZXJvcCBDbGllbnRzIGNhbiBwb3RlbnRpYWxseSBleGlzdCBhdCBhIGB1dWlkYC9gbmFtZWAgY29tYm8sIHdlIGN1cnJlbnRseSBqb2luIGFsbCBDaGFubmVsIGNvbm5lY3Rpb25zL0ludGVyb3AgQ2xpZW50cyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBJZiBhbiBgZW5kcG9pbnRJZGAgaXMgcHJvdmlkZWQgKHdoaWNoIGlzIHVubGlrZWx5LCB1bmxlc3MgdGhlIGNhbGwgaXMgY29taW5nIGZyb20gYW4gZXh0ZXJuYWwgYWRhcHRlciksIHRoZW4gd2Ugb25seSBqb2luIHRoYXQgc2luZ2xlIGNvbm5lY3Rpb24gdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBGb3IgYWxsIGludGVudHMgYW5kIHB1cnBvc2VzLCB0aGVyZSB3aWxsIG9ubHkgYmUgMSBjb25uZWN0aW9uIHByZXNlbnQgaW4gUGxhdGZvcm0gYW5kIEJyb3dzZXIgaW1wbG1lbnRhdGlvbnMsIHNvIHRoaXMgcG9pbnQgaXMgbW9yZS1vci1sZXNzIG1vb3QuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRHcm91cElkIC0gSWQgb2YgdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gSWRlbnRpdHkgb2YgdGhlIGVudGl0eSB5b3Ugd2lzaCB0byBqb2luIHRvIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGpvaW5WaWV3VG9Db250ZXh0R3JvdXAgPSBhc3luYyAoY29udGV4dEdyb3VwSWQsIHZpZXcpID0+IHtcblx0ICAgICAqICAgICBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkLCB2aWV3KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRMYXN0Rm9jdXNlZFZpZXcoKVxuXHQgICAgICogICAgIC50aGVuKGxhc3RGb2N1c2VkVmlld0lkZW50aXR5ID0+IHtcblx0ICAgICAqICAgICAgICAgam9pblZpZXdUb0NvbnRleHRHcm91cCgncmVkJywgbGFzdEZvY3VzZWRWaWV3SWRlbnRpdHkpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkLCB0YXJnZXQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtam9pbi1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgaWYgKCFjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbnRleHRHcm91cElkIHNwZWNpZmllZCBmb3Igam9pbkNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnam9pbkNvbnRleHRHcm91cCcsIHsgY29udGV4dEdyb3VwSWQsIHRhcmdldCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHRhcmdldCBmcm9tIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IHJlbW92ZXMgdGhlIHNlbmRlciBmcm9tIHRoZWlyIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHRhcmdldCAtIElkZW50aXR5IG9mIHRoZSBlbnRpdHkgeW91IHdpc2ggdG8gam9pbiB0byBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiByZW1vdmVWaWV3RnJvbUNvbnRleHRHcm91cCA9IGFzeW5jICh2aWV3KSA9PiB7XG5cdCAgICAgKiAgICAgYXdhaXQgZmluLm1lLmludGVyb3AucmVtb3ZlRnJvbUNvbnRleHRHcm91cCh2aWV3KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRMYXN0Rm9jdXNlZFZpZXcoKVxuXHQgICAgICogICAgIC50aGVuKGxhc3RGb2N1c2VkVmlld0lkZW50aXR5ID0+IHtcblx0ICAgICAqICAgICAgICAgcmVtb3ZlVmlld0Zyb21Db250ZXh0R3JvdXAobGFzdEZvY3VzZWRWaWV3SWRlbnRpdHkpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyByZW1vdmVGcm9tQ29udGV4dEdyb3VwKHRhcmdldCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1yZW1vdmUtZnJvbS1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgncmVtb3ZlRnJvbUNvbnRleHRHcm91cCcsIHsgdGFyZ2V0IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGFsbCBjbGllbnRzIGZvciBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgKipUaGlzIGlzIHByaW1hcmlseSB1c2VkIGZvciBwbGF0Zm9ybSB3aW5kb3dzLiBWaWV3cyB3aXRoaW4gYSBwbGF0Zm9ybSBzaG91bGQgbm90IGhhdmUgdG8gdXNlIHRoaXMgQVBJLioqXG5cdCAgICAgKlxuXHQgICAgICogUmV0dXJucyB0aGUgSW50ZXJvcC1Ccm9rZXItZGVmaW5lZCBjb250ZXh0IGdyb3VwcyBhdmFpbGFibGUgZm9yIGFuIGVudGl0eSB0byBqb2luLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRHcm91cElkIC0gVGhlIGlkIG9mIGNvbnRleHQgZ3JvdXAgeW91IHdpc2ggdG8gZ2V0IGNsaWVudHMgZm9yLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLm1lLmludGVyb3AuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKCdyZWQnKVxuXHQgICAgICogICAgIC50aGVuKGNsaWVudHNJbkNvbnRleHRHcm91cCA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGNsaWVudHNJbkNvbnRleHRHcm91cClcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cChjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1nZXQtYWxsLWNsaWVudHMtaW4tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuXHQgICAgICAgIGlmICghY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb250ZXh0R3JvdXBJZCBzcGVjaWZpZWQgZm9yIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwJywgeyBjb250ZXh0R3JvdXBJZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBkaXNwbGF5IGluZm8gZm9yIGEgY29udGV4dCBncm91cFxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0R3JvdXBJZCAtIFRoZSBpZCBvZiBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBkaXNwbGF5IGluZm8gZm9yLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLm1lLmludGVyb3AuZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgncmVkJylcblx0ICAgICAqICAgICAudGhlbihjb250ZXh0R3JvdXBJbmZvID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mby5kaXNwbGF5TWV0YWRhdGEubmFtZSlcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mby5kaXNwbGF5TWV0YWRhdGEuY29sb3IpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRJbmZvRm9yQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWdldC1pbmZvLWZvci1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgaWYgKCFjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbnRleHRHcm91cElkIHNwZWNpZmllZCBmb3IgZ2V0SW5mb0ZvckNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0SW5mb0ZvckNvbnRleHRHcm91cCcsIHsgY29udGV4dEdyb3VwSWQgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNlbmRzIGFuIGludGVudCB0byB0aGUgSW50ZXJvcCBCcm9rZXIgdG8gcmVzb2x2ZS5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgLSBUaGUgY29tYmluYXRpb24gb2YgYW4gYWN0aW9uIGFuZCBhIGNvbnRleHQgdGhhdCBpcyBwYXNzZWQgdG8gYW4gYXBwbGljYXRpb24gZm9yIHJlc29sdXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyBWaWV3IHdhbnRzIHRvIGZpcmUgYW4gSW50ZW50IGFmdGVyIGEgdXNlciBjbGlja3Mgb24gYSB0aWNrZXJcblx0ICAgICAqIHRpY2tlckVsZW1lbnQub24oJ2NsaWNrJywgKGVsZW1lbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB0aWNrZXIgPSBlbGVtZW50LmlubmVyVGV4dDtcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnQgPSB7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdWaWV3Q2hhcnQnLFxuXHQgICAgICogICAgICAgICBjb250ZXh0OiB7dHlwZTogJ2ZkYzMuaW5zdHJ1bWVudCcsIGlkOiB7IHRpY2tlciB9fVxuXHQgICAgICogICAgIH1cblx0ICAgICAqXG5cdCAgICAgKiAgICAgZmluLm1lLmludGVyb3AuZmlyZUludGVudChpbnRlbnQpO1xuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBmaXJlSW50ZW50KGludGVudCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1maXJlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgdGhpcyBpcyBvbmx5IGZvciBhcGkgYW5hbHl0aWNzIHB1cnBvc2VzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZmlyZUludGVudCcsIGludGVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEFkZHMgYW4gaW50ZW50IGhhbmRsZXIgZm9yIGluY29taW5nIGludGVudHMuIFRoZSBsYXN0IGludGVudCBzZW50IG9mIHRoZSBuYW1lIHN1YnNjcmliZWQgdG8gd2lsbCBiZSByZWNlaXZlZC5cblx0ICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gUmVnaXN0ZXJlZCBmdW5jdGlvbiBtZWFudCB0byBoYW5kbGUgYSBzcGVjaWZpYyBpbnRlbnQgdHlwZS5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnROYW1lIC0gVGhlIG5hbWUgb2YgYW4gaW50ZW50LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgaW50ZW50SGFuZGxlciA9IChpbnRlbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB7IGNvbnRleHQgfSA9IGludGVudDtcblx0ICAgICAqICAgICBteVZpZXdDaGFydEhhbmRsZXIoY29udGV4dCk7XG5cdCAgICAgKiB9O1xuXHQgICAgICpcblx0ICAgICAqIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLnJlZ2lzdGVySW50ZW50SGFuZGxlcihpbnRlbnRIYW5kbGVyLCAnVmlld0NoYXJ0Jyk7XG5cdCAgICAgKlxuXHQgICAgICogZnVuY3Rpb24gbXlBcHBDbG9zZVNlcXVlbmNlKCkge1xuXHQgICAgICogICAgIC8vIHRvIHVuc3Vic2NyaWJlIHRoZSBoYW5kbGVyLCBzaW1wbHkgY2FsbDpcblx0ICAgICAqICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyByZWdpc3RlckludGVudEhhbmRsZXIoaGFuZGxlciwgaW50ZW50TmFtZSwgb3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1yZWdpc3Rlci1pbnRlbnQtaGFuZGxlcicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgdGhpcyBpcyBvbmx5IGZvciBhcGkgYW5hbHl0aWNzIHB1cnBvc2VzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYGludGVudC1oYW5kbGVyLSR7aW50ZW50TmFtZX1gO1xuXHQgICAgICAgIGNvbnN0IHdyYXBwZWRIYW5kbGVyID0gKDAsIHV0aWxzXzEud3JhcEludGVudEhhbmRsZXIpKGhhbmRsZXIsIGhhbmRsZXJJZCk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgd3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ2ludGVudEhhbmRsZXJSZWdpc3RlcmVkJywgeyBoYW5kbGVySWQsIC4uLm9wdGlvbnMgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byByZWdpc3RlciBpbnRlbnQgaGFuZGxlcicpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICB1bnN1YnNjcmliZTogYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50LnJlbW92ZShoYW5kbGVySWQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgbGFzdCBjb250ZXh0IG9mIHRoZSBDb250ZXh0IEdyb3VwIGN1cnJlbnRseSBzdWJzY3JpYmVkIHRvLiBJdCB0YWtlcyBhbiBvcHRpb25hbCBDb250ZXh0IFR5cGUgYW5kIHJldHVybnMgdGhlXG5cdCAgICAgKiBsYXN0IGNvbnRleHQgb2YgdGhhdCB0eXBlLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKCd5ZWxsb3cnKTtcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoeyB0eXBlOiAnaW5zdHJ1bWVudCcsIGlkOiB7IHRpY2tlcjogJ0ZPTycgfX0pO1xuXHQgICAgICogY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCBmaW4ubWUuaW50ZXJvcC5nZXRDdXJyZW50Q29udGV4dCgpO1xuXHQgICAgICpcblx0ICAgICAqIC8vIHdpdGggYSBzcGVjaWZpYyBjb250ZXh0XG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKCd5ZWxsb3cnKTtcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoeyB0eXBlOiAnY291bnRyeScsIGlkOiB7IElTT0FMUEhBMzogJ1VTJyB9fSk7XG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5zZXRDb250ZXh0KHsgdHlwZTogJ2luc3RydW1lbnQnLCBpZDogeyB0aWNrZXI6ICdGT08nIH19KTtcblx0ICAgICAqIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gYXdhaXQgZmluLm1lLmludGVyb3AuZ2V0Q3VycmVudENvbnRleHQoJ2NvdW50cnknKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1nZXQtY3VycmVudC1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0Q3VycmVudENvbnRleHQnLCB7IGNvbnRleHRUeXBlIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXQgaW5mb3JtYXRpb24gZm9yIGEgcGFydGljdWxhciBJbnRlbnQgZnJvbSB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVJbmZvRm9ySW50ZW50IGlzIG1lYW50IHRvIGJlIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3AgQnJva2VyLlxuXHQgICAgICogVGhlIGZvcm1hdCBmb3IgdGhlIHJlc3BvbnNlIHdpbGwgYmUgZGV0ZXJtaW5lZCBieSB0aGUgQXBwIFByb3ZpZGVyIG92ZXJyaWRpbmcgdGhlIGZ1bmN0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBpbnRlbnRJbmZvID0gYXdhaXQgZmluLm1lLmludGVyb3AuZ2V0SW5mb0ZvckludGVudCgnVmlld0NoYXJ0Jyk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0SW5mb0ZvckludGVudChvcHRpb25zKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWdldC1pbmZvLWZvci1pbnRlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXRJbmZvRm9ySW50ZW50Jywgb3B0aW9ucyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdldCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBJbnRlcm9wIEJyb2tlciBvbiBhbGwgSW50ZW50cyB0aGF0IGFyZSBtZWFudCB0byBoYW5kbGUgYSBwYXJ0aWN1bGFyIGNvbnRleHQuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIGluIHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoZSBmb3JtYXQgZm9yIHRoZSByZXNwb25zZSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIEFwcCBQcm92aWRlciBvdmVycmlkaW5nIHRoZSBmdW5jdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogdGlja2VyRWxlbWVudC5vbignY2xpY2snLCAoZWxlbWVudCkgPT4ge1xuXHQgICAgICogICAgIGNvbnN0IHRpY2tlciA9IGVsZW1lbnQuaW5uZXJUZXh0O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBjb250ZXh0ID0ge1xuXHQgICAgICogICAgICAgICB0eXBlOiAnZmRjMy5pbnN0cnVtZW50Jyxcblx0ICAgICAqICAgICAgICAgaWQ6IHtcblx0ICAgICAqICAgICAgICAgICAgIHRpY2tlclxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnRzSW5mbyA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLmdldEluZm9Gb3JJbnRlbnRCeUNvbnRleHQoY29udGV4dCk7XG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZ2V0LWluZm8tZm9yLWludGVudHMtYnktY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuXHQgICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2dldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0JywgY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNlbmRzIGEgQ29udGV4dCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgdG8gYW4gSW50ZW50IGJ5IHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoaXMgY29udGV4dCBhY2NlcHRzIGEgbWV0YWRhdGEgcHJvcGVydHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVGaXJlZEludGVudEJ5Q29udGV4dCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIGluIHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoZSBmb3JtYXQgZm9yIHRoZSByZXNwb25zZSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIEFwcCBQcm92aWRlciBvdmVycmlkaW5nIHRoZSBmdW5jdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogdGlja2VyRWxlbWVudC5vbignY2xpY2snLCAoZWxlbWVudCkgPT4ge1xuXHQgICAgICogICAgIGNvbnN0IHRpY2tlciA9IGVsZW1lbnQuaW5uZXJUZXh0O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBjb250ZXh0ID0ge1xuXHQgICAgICogICAgICAgICB0eXBlOiAnZmRjMy5pbnN0cnVtZW50Jyxcblx0ICAgICAqICAgICAgICAgaWQ6IHtcblx0ICAgICAqICAgICAgICAgICAgIHRpY2tlclxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnRSZXNvbHV0aW9uID0gYXdhaXQgZmluLm1lLmludGVyb3AuZmlyZUludGVudEZvckNvbnRleHQoY29udGV4dCk7XG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpcmVJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZmlyZS1pbnRlbnQtZm9yLWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdmaXJlSW50ZW50Rm9yQ29udGV4dCcsIGNvbnRleHQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIHRoZSBjdXJyZW50IGVudGl0eSB0byBzZXNzaW9uIGNvbnRleHQgZ3JvdXAgYHNlc3Npb25Db250ZXh0R3JvdXBJZGAgYW5kIHJldHVybiBhIHNlc3Npb25Db250ZXh0R3JvdXAgaW5zdGFuY2UuXG5cdCAgICAgKiBJZiB0aGUgc2Vzc2lvbkNvbnRleHRHcm91cCBkb2Vzbid0IGV4aXN0LCBvbmUgd2lsbCBnZXQgY3JlYXRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBTZXNzaW9uIENvbnRleHQgR3JvdXBzIGRvIG5vdCBwZXJzaXN0IGJldHdlZW4gcnVucyBhbmQgYXJlbid0IHByZXNlbnQgb24gc25hcHNob3RzLlxuXHQgICAgICogQHBhcmFtIHNlc3Npb25Db250ZXh0R3JvdXBJZCAtIElkIG9mIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBTYXkgd2Ugd2FudCB0byBoYXZlIGEgU2Vzc2lvbiBDb250ZXh0IEdyb3VwIHRoYXQgaG9sZHMgVUkgdGhlbWUgaW5mb3JtYXRpb24gZm9yIGFsbCBhcHBzIHRvIGNvbnN1bWU6XG5cdCAgICAgKlxuXHQgICAgICogTXkgY29sb3ItcGlja2VyIFZpZXc6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogICAgIGNvbnN0IHRoZW1lU2Vzc2lvbkNvbnRleHRHcm91cCA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLmpvaW5TZXNzaW9uQ29udGV4dEdyb3VwKCd0aGVtZScpO1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBteUNvbG9yUGlja2VyRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb2xvci1wYWxldHRlLXBpY2tlcicpO1xuXHQgICAgICogICAgIG15Q29sb3JQaWNrZXJFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGV2ZW50ID0+IHtcblx0ICAgICAqICAgICAgICAgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwLnNldENvbnRleHQoeyB0eXBlOiAnY29sb3ItcGFsZXR0ZScsIHNlbGVjdGlvbjogZXZlbnQudmFsdWUgfSk7XG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBJbiBvdGhlciB2aWV3czpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgY29uc3QgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwID0gYXdhaXQgZmluLm1lLmludGVyb3Auam9pblNlc3Npb25Db250ZXh0R3JvdXAoJ3RoZW1lJyk7XG5cdCAgICAgKlxuXHQgICAgICogICAgIGNvbnN0IGNoYW5nZUNvbG9yUGFsZXR0ZSA9ICh7IHNlbGVjdGlvbiB9KSA9PiB7XG5cdCAgICAgKiAgICAgICAgIC8vIGNoYW5nZSB0aGUgY29sb3IgcGFsZXR0ZSB0byB0aGUgc2VsZWN0aW9uXG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqXG5cdCAgICAgKiAgICAgLy8gSWYgdGhlIGNvbnRleHQgaXMgYWxyZWFkeSBzZXQgYnkgdGhlIHRpbWUgdGhlIGhhbmRsZXIgd2FzIHNldCwgdGhlIGhhbmRsZXIgd2lsbCBnZXQgaW52b2tlZCBpbW1lZGlhdGVseSB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQuXG5cdCAgICAgKiAgICAgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwLmFkZENvbnRleHRIYW5kbGVyKGNoYW5nZUNvbG9yUGFsZXR0ZSwgJ2NvbG9yLXBhbGV0dGUnKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luU2Vzc2lvbkNvbnRleHRHcm91cChzZXNzaW9uQ29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50U2Vzc2lvbkNvbnRleHRHcm91cCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfc2Vzc2lvbkNvbnRleHRHcm91cHMsIFwiZlwiKS5nZXQoc2Vzc2lvbkNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgaWYgKGN1cnJlbnRTZXNzaW9uQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFNlc3Npb25Db250ZXh0R3JvdXAuZ2V0VXNlckluc3RhbmNlKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgaGFzQ29uZmxpY3QgfSA9IGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnc2Vzc2lvbkNvbnRleHRHcm91cDpjcmVhdGVJZk5lZWRlZCcsIHtcblx0ICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXBJZFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgaWYgKGhhc0NvbmZsaWN0KSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEEgKG5vbi1zZXNzaW9uKSBjb250ZXh0IGdyb3VwIHdpdGggdGhlIG5hbWUgXCIke3Nlc3Npb25Db250ZXh0R3JvdXBJZH1cIiBhbHJlYWR5IGV4aXN0cy4gSWYgeW91IGFyZSB0cnlpbmcgdG8gam9pbiBhIENvbnRleHQgR3JvdXAsIGNhbGwgam9pbkNvbnRleHRHcm91cCBpbnN0ZWFkLmApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb25Db250ZXh0R3JvdXAgPSBuZXcgU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudF8xLmRlZmF1bHQodGhpcy53aXJlLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKSwgc2Vzc2lvbkNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3VwcywgXCJmXCIpLnNldChzZXNzaW9uQ29udGV4dEdyb3VwSWQsIG5ld1Nlc3Npb25Db250ZXh0R3JvdXApO1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3U2Vzc2lvbkNvbnRleHRHcm91cC5nZXRVc2VySW5zdGFuY2UoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHRocm93biB0cnlpbmcgdG8gY3JlYXRlIFNlc3Npb24gQ29udGV4dCBHcm91cCB3aXRoIGlkIFwiJHtzZXNzaW9uQ29udGV4dEdyb3VwSWR9XCI6ICR7ZXJyb3J9YCk7XG5cdCAgICAgICAgICAgIHRocm93IGVycm9yO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBJbnRlcm9wIENsaWVudCBoYXMgYmVlbiBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKiBPbmx5IG9uZSBsaXN0ZW5lciBwZXIgSW50ZXJvcCBDbGllbnQgY2FuIGJlIHNldC5cblx0ICAgICAqIEBwYXJhbSBsaXN0ZW5lclxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgbGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIHRvcGljLCBicm9rZXJOYW1lfSA9IGV2ZW50O1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKGBEaXNjb25uZWN0ZWQgZnJvbSBJbnRlcm9wIEJyb2tlciAke2Jyb2tlck5hbWV9IGApO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLm9uRGlzY29ubmVjdGlvbihsaXN0ZW5lcik7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgb25EaXNjb25uZWN0aW9uKGxpc3RlbmVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWFkZC1vbmRpc2Nvbm5lY3Rpb24tbGlzdGVuZXInKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50Lm9uRGlzY29ubmVjdGlvbigoZXZlbnQpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyB1dWlkIH0gPSBldmVudDtcblx0ICAgICAgICAgICAgbGlzdGVuZXIoeyB0eXBlOiAnaW50ZXJvcC1icm9rZXInLCB0b3BpYzogJ2Rpc2Nvbm5lY3RlZCcsIGJyb2tlck5hbWU6IHV1aWQgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBnZXRGREMzU3luYyh2ZXJzaW9uKSB7XG5cdCAgICAgICAgc3dpdGNoICh2ZXJzaW9uKSB7XG5cdCAgICAgICAgICAgIGNhc2UgJzEuMic6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGZkYzNfMV8yXzEuRmRjM01vZHVsZSgoKSA9PiB0aGlzLCB0aGlzLndpcmUpO1xuXHQgICAgICAgICAgICBjYXNlICcyLjAnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBmZGMzXzJfMF8xLkZkYzNNb2R1bGUyKCgpID0+IHRoaXMsIHRoaXMud2lyZSk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgRkRDMyB2ZXJzaW9uIHByb3ZpZGVkOiAke3ZlcnNpb259LiBNdXN0IGJlICcxLjInIG9yICcyLjAnYCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgZ2V0RkRDMyh2ZXJzaW9uKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RkRDM1N5bmModmVyc2lvbik7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICpcblx0ICAgICAqIFVzZWQgdG8gZmVycnkgZmRjMy1vbmx5IGNhbGxzIGZyb20gdGhlIGZkYzMgc2hpbSB0byB0aGUgSW50ZXJvcCBCcm9rZXJcblx0ICAgICAqL1xuXHQgICAgc3RhdGljIGFzeW5jIGZlcnJ5RmRjM0NhbGwoaW50ZXJvcENsaWVudCwgYWN0aW9uLCBwYXlsb2FkKSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldChpbnRlcm9wQ2xpZW50LCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaChhY3Rpb24sIHBheWxvYWQgfHwgbnVsbCk7XG5cdCAgICB9XG5cdH07XG5cdEludGVyb3BDbGllbnQuSW50ZXJvcENsaWVudCA9IEludGVyb3BDbGllbnQkMTtcblx0X0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSA9IG5ldyBXZWFrTWFwKCksIF9JbnRlcm9wQ2xpZW50X3Nlc3Npb25Db250ZXh0R3JvdXBzID0gbmV3IFdlYWtNYXAoKTtcblx0cmV0dXJuIEludGVyb3BDbGllbnQ7XG59XG5cbnZhciBvdmVycmlkZUNoZWNrID0ge307XG5cbnZhciBoYXNSZXF1aXJlZE92ZXJyaWRlQ2hlY2s7XG5cbmZ1bmN0aW9uIHJlcXVpcmVPdmVycmlkZUNoZWNrICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkT3ZlcnJpZGVDaGVjaykgcmV0dXJuIG92ZXJyaWRlQ2hlY2s7XG5cdGhhc1JlcXVpcmVkT3ZlcnJpZGVDaGVjayA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvdmVycmlkZUNoZWNrLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0b3ZlcnJpZGVDaGVjay5vdmVycmlkZUNoZWNrID0gb3ZlcnJpZGVDaGVjay5jaGVja0ZEQzMyT3ZlcnJpZGVzID0gb3ZlcnJpZGVDaGVjay5nZXREZWZhdWx0Vmlld0ZkYzNWZXJzaW9uRnJvbUFwcEluZm8gPSB2b2lkIDA7XG5cdGNvbnN0IEludGVyb3BCcm9rZXJfMSA9IHJlcXVpcmVJbnRlcm9wQnJva2VyKCk7XG5cdGZ1bmN0aW9uIGdldERlZmF1bHRWaWV3RmRjM1ZlcnNpb25Gcm9tQXBwSW5mbyh7IG1hbmlmZXN0LCBpbml0aWFsT3B0aW9ucyB9KSB7XG5cdCAgICBjb25zdCBzZXRWZXJzaW9uID0gbWFuaWZlc3Q/LnBsYXRmb3JtPy5kZWZhdWx0Vmlld09wdGlvbnM/LmZkYzNJbnRlcm9wQXBpID8/IGluaXRpYWxPcHRpb25zLmRlZmF1bHRWaWV3T3B0aW9ucz8uZmRjM0ludGVyb3BBcGk7XG5cdCAgICByZXR1cm4gWycxLjInLCAnMi4wJ10uaW5jbHVkZXMoc2V0VmVyc2lvbiA/PyAnJykgPyBzZXRWZXJzaW9uIDogdW5kZWZpbmVkO1xuXHR9XG5cdG92ZXJyaWRlQ2hlY2suZ2V0RGVmYXVsdFZpZXdGZGMzVmVyc2lvbkZyb21BcHBJbmZvID0gZ2V0RGVmYXVsdFZpZXdGZGMzVmVyc2lvbkZyb21BcHBJbmZvO1xuXHRmdW5jdGlvbiBjaGVja0ZEQzMyT3ZlcnJpZGVzKG92ZXJyaWRkZW5Ccm9rZXIpIHtcblx0ICAgIC8vIFRoZXNlIGFyZSB0aGUgQVBJcyB0aGF0IG11c3QgYmUgb3ZlcnJpZGRlbiBmb3IgRkRDMyAyLjAgY29tcGxpYW5jZVxuXHQgICAgY29uc3QgbXVzdE92ZXJyaWRlQVBJcyA9IFtcblx0ICAgICAgICAnZmRjM0hhbmRsZUZpbmRJbnN0YW5jZXMnLFxuXHQgICAgICAgICdoYW5kbGVJbmZvRm9ySW50ZW50Jyxcblx0ICAgICAgICAnaGFuZGxlSW5mb0ZvckludGVudHNCeUNvbnRleHQnLFxuXHQgICAgICAgICdmZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEnLFxuXHQgICAgICAgICdmZGMzSGFuZGxlR2V0SW5mbycsXG5cdCAgICAgICAgJ2ZkYzNIYW5kbGVPcGVuJyxcblx0ICAgICAgICAnaGFuZGxlRmlyZWRJbnRlbnQnLFxuXHQgICAgICAgICdoYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQnXG5cdCAgICBdO1xuXHQgICAgcmV0dXJuIG11c3RPdmVycmlkZUFQSXMuZmlsdGVyKChhcGkpID0+IHtcblx0ICAgICAgICByZXR1cm4gb3ZlcnJpZGRlbkJyb2tlclthcGldID09PSBJbnRlcm9wQnJva2VyXzEuSW50ZXJvcEJyb2tlci5wcm90b3R5cGVbYXBpXTtcblx0ICAgIH0pO1xuXHR9XG5cdG92ZXJyaWRlQ2hlY2suY2hlY2tGREMzMk92ZXJyaWRlcyA9IGNoZWNrRkRDMzJPdmVycmlkZXM7XG5cdGZ1bmN0aW9uIG92ZXJyaWRlQ2hlY2skMShvdmVycmlkZGVuQnJva2VyLCBmZGMzSW50ZXJvcEFwaSkge1xuXHQgICAgaWYgKGZkYzNJbnRlcm9wQXBpICYmIGZkYzNJbnRlcm9wQXBpID09PSAnMi4wJykge1xuXHQgICAgICAgIGNvbnN0IG5vdE92ZXJyaWRkZW4gPSBjaGVja0ZEQzMyT3ZlcnJpZGVzKG92ZXJyaWRkZW5Ccm9rZXIpO1xuXHQgICAgICAgIGlmIChub3RPdmVycmlkZGVuLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKGBXQVJOSU5HOiBGREMzIDIuMCBoYXMgYmVlbiBzZXQgYXMgYSBkZWZhdWx0IG9wdGlvbiBmb3IgVmlld3MgaW4gdGhpcyBQbGF0Zm9ybSwgYnV0IHRoZSByZXF1aXJlZCBJbnRlcm9wQnJva2VyIEFQSXMgZm9yIEZEQzMgMi4wIGNvbXBsaWFuY2UgaGF2ZSBub3QgYWxsIGJlZW4gb3ZlcnJpZGRlbi5cXG5UaGUgZm9sbG93aW5nIEFQSXMgbmVlZCB0byBiZSBvdmVycmlkZGVuOlxcbiR7bm90T3ZlcnJpZGRlbi5qb2luKCdcXG4nKX1gKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdH1cblx0b3ZlcnJpZGVDaGVjay5vdmVycmlkZUNoZWNrID0gb3ZlcnJpZGVDaGVjayQxO1xuXHRyZXR1cm4gb3ZlcnJpZGVDaGVjaztcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeTtcblxuZnVuY3Rpb24gcmVxdWlyZUZhY3RvcnkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGYWN0b3J5KSByZXR1cm4gRmFjdG9yeSQxO1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkgPSAxO1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDEuSW50ZXJvcE1vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgY2xvbmVEZWVwXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMCQxKTtcblx0Y29uc3QgaW5hY2Nlc3NpYmxlT2JqZWN0XzEgPSBpbmFjY2Vzc2libGVPYmplY3Q7XG5cdGNvbnN0IGJhc2VfMSA9IGJhc2U7XG5cdGNvbnN0IEludGVyb3BCcm9rZXJfMSA9IHJlcXVpcmVJbnRlcm9wQnJva2VyKCk7XG5cdGNvbnN0IEludGVyb3BDbGllbnRfMSA9IHJlcXVpcmVJbnRlcm9wQ2xpZW50KCk7XG5cdGNvbnN0IG92ZXJyaWRlQ2hlY2tfMSA9IHJlcXVpcmVPdmVycmlkZUNoZWNrKCk7XG5cdGNvbnN0IGNvbW1vbl91dGlsc18xID0gY29tbW9uVXRpbHM7XG5cdGNvbnN0IGRlZmF1bHRPdmVycmlkZSA9IChDbGFzcykgPT4gbmV3IENsYXNzKCk7XG5cdGNvbnN0IEJyb2tlclBhcmFtQWNjZXNzRXJyb3IgPSAnWW91IGhhdmUgYXR0ZW1wdGVkIHRvIHVzZSBvciBtb2RpZnkgSW50ZXJvcEJyb2tlciBwYXJhbWV0ZXJzLCB3aGljaCBpcyBub3QgYWxsb3dlZC4gWW91IGFyZSBsaWtlbHkgdXNpbmcgYW4gb2xkZXIgSW50ZXJvcEJyb2tlciBvdmVycmlkZSBzY2hlbWUuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nO1xuXHQvKipcblx0ICogTWFuYWdlcyBjcmVhdGlvbiBvZiBJbnRlcm9wIEJyb2tlcnMgYW5kIEludGVyb3AgQ2xpZW50cy4gVGhlc2UgQVBJcyBhcmUgY2FsbGVkIHVuZGVyLXRoZS1ob29kIGluIFBsYXRmb3Jtcy5cblx0ICpcblx0ICovXG5cdGNsYXNzIEludGVyb3BNb2R1bGUgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEluaXRpYWxpemVzIGFuIEludGVyb3AgQnJva2VyLiBUaGlzIGlzIGNhbGxlZCB1bmRlci10aGUtaG9vZCBmb3IgUGxhdGZvcm1zLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIEZvciBQbGF0Zm9ybXMsIHRoaXMgaXMgc2V0IHVwIGF1dG9tYXRpY2FsbHkuIFdlIGFkdmlzZSB0byBvbmx5IGNyZWF0ZSB5b3VyIG93biBJbnRlcm9wIEJyb2tlclxuXHQgICAgICogd2hlbiBub3QgdXNpbmcgYSBQbGF0Zm9ybSBhcHAuIFlvdSBjYW4gb3ZlcnJpZGUgZnVuY3Rpb25zIGluIHRoZSBJbnRlcm9wIEJyb2tlci4gTW9yZSBpbmZvIHtAbGluayBJbnRlcm9wQnJva2VyIGhlcmV9LlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBuYW1lIC0gTmFtZSBvZiB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKiBAcGFyYW0gb3ZlcnJpZGUgLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGNhbGxiYWNrIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGV4dGVuZCBvciByZXBsYWNlIGRlZmF1bHQgSW50ZXJvcCBCcm9rZXIgYmVoYXZpb3IuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYCBqc1xuXHQgICAgICogY29uc3QgaW50ZXJvcEJyb2tlciA9IGF3YWl0IGZpbi5JbnRlcm9wLmluaXQoJ29wZW5maW4nKTtcblx0ICAgICAqIGNvbnN0IGNvbnRleHRHcm91cHMgPSBhd2FpdCBpbnRlcm9wQnJva2VyLmdldENvbnRleHRHcm91cHMoKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKGNvbnRleHRHcm91cHMpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGluaXQobmFtZSwgb3ZlcnJpZGUgPSBkZWZhdWx0T3ZlcnJpZGUpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1pbml0JykuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvLyBBbGxvd3MgZm9yIG1hbmlmZXN0LWxldmVsIGNvbmZpZ3VyYXRpb24sIHdpdGhvdXQgaGF2aW5nIHRvIG92ZXJyaWRlLiAoZS5nLiBzcGVjaWZ5aW5nIGN1c3RvbSBjb250ZXh0IGdyb3Vwcylcblx0ICAgICAgICBjb25zdCBvcHRpb25zID0gYXdhaXQgdGhpcy53aXJlLmVudmlyb25tZW50LmdldEludGVyb3BJbmZvKHRoaXMud2lyZS5nZXRGaW4oKSk7XG5cdCAgICAgICAgY29uc3Qgb2JqZWN0VGhhdFRocm93cyA9ICgwLCBpbmFjY2Vzc2libGVPYmplY3RfMS5jcmVhdGVVbnVzYWJsZU9iamVjdCkoQnJva2VyUGFyYW1BY2Nlc3NFcnJvcik7XG5cdCAgICAgICAgY29uc3Qgd2FybmluZ09wdHNDbG9uZSA9ICgwLCBpbmFjY2Vzc2libGVPYmplY3RfMS5jcmVhdGVXYXJuaW5nT2JqZWN0KShCcm9rZXJQYXJhbUFjY2Vzc0Vycm9yLCAoMCwgY2xvbmVEZWVwXzEuZGVmYXVsdCkob3B0aW9ucykpO1xuXHQgICAgICAgIGNvbnN0IGdldFByb3ZpZGVyID0gKCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShgaW50ZXJvcC1icm9rZXItJHtuYW1lfWApO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgdGhyb3dpbmdHZXRQcm92aWRlciA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEJyb2tlclBhcmFtQWNjZXNzRXJyb3IpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgT3ZlcnJpZGVhYmxlQnJva2VyID0gSW50ZXJvcEJyb2tlcl8xLkludGVyb3BCcm9rZXIuY3JlYXRlQ2xvc2VkQ29uc3RydWN0b3IodGhpcy53aXJlLCBnZXRQcm92aWRlciwgb3B0aW9ucyk7XG5cdCAgICAgICAgbGV0IGJyb2tlcjtcblx0ICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvdmVycmlkZSkpIHtcblx0ICAgICAgICAgICAgY29uc3QgQnJva2VyQ29uc3RydWN0b3IgPSAoMCwgY29tbW9uX3V0aWxzXzEub3ZlcnJpZGVGcm9tQ29tcG9zYWJsZXMpKC4uLm92ZXJyaWRlKShPdmVycmlkZWFibGVCcm9rZXIpO1xuXHQgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHVzZSB0aGVzZSBvYmplY3RzIGJlY2F1c2UgcmVtb3ZpbmcgdGhlbSBlbnRpcmVseSB3b3VsZCBiZSBhIGJyZWFraW5nIGNoYW5nZSBhbmQgd2Ugd2FudCBhbiBpbmZvcm1hdGl2ZSBlcnJvclxuXHQgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG5cdCAgICAgICAgICAgIGJyb2tlciA9IG5ldyBCcm9rZXJDb25zdHJ1Y3RvcihvYmplY3RUaGF0VGhyb3dzLCB0aHJvd2luZ0dldFByb3ZpZGVyLCB3YXJuaW5nT3B0c0Nsb25lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gdXNlIHRoZXNlIG9iamVjdHMgYmVjYXVzZSByZW1vdmluZyB0aGVtIGVudGlyZWx5IHdvdWxkIGJlIGEgYnJlYWtpbmcgY2hhbmdlIGFuZCB3ZSB3YW50IGFuIGluZm9ybWF0aXZlIGVycm9yXG5cdCAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3Jcblx0ICAgICAgICAgICAgYnJva2VyID0gYXdhaXQgb3ZlcnJpZGUoT3ZlcnJpZGVhYmxlQnJva2VyLCBvYmplY3RUaGF0VGhyb3dzLCB0aHJvd2luZ0dldFByb3ZpZGVyLCB3YXJuaW5nT3B0c0Nsb25lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgKDAsIG92ZXJyaWRlQ2hlY2tfMS5vdmVycmlkZUNoZWNrKShicm9rZXIsIG9wdGlvbnMuZmRjM1ZlcnNpb24pO1xuXHQgICAgICAgIHJldHVybiBicm9rZXI7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENvbm5lY3RzIGEgY2xpZW50IHRvIGFuIEludGVyb3AgYnJva2VyLiBUaGlzIGlzIGNhbGxlZCB1bmRlci10aGUtaG9vZCBmb3IgVmlld3MgaW4gYSBQbGF0Zm9ybS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrc1xuXHQgICAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgSW50ZXJvcCBCcm9rZXIgdG8gY29ubmVjdCB0by4gRm9yIFBsYXRmb3JtcywgdGhpcyB3aWxsIGRlZmF1bHQgdG8gdGhlIHV1aWQgb2YgdGhlIFBsYXRmb3JtLlxuXHQgICAgICogQHBhcmFtIGludGVyb3BDb25maWcgLSBJbmZvcm1hdGlvbiByZWxldmFudCB0byB0aGUgSW50ZXJvcCBCcm9rZXIuIFR5cGljYWxseSBhIGRlY2xhcmF0aW9uIG9mXG5cdCAgICAgKiB3aGF0IGNvbnRleHQocykgdGhlIGVudGl0eSB3YW50cyB0byBzdWJzY3JpYmUgdG8sIGFuZCB0aGUgY3VycmVudCBDb250ZXh0IEdyb3VwIG9mIHRoZSBlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBpbnRlcm9wQ29uZmlnID0ge1xuXHQgICAgICogICAgIGN1cnJlbnRDb250ZXh0R3JvdXA6ICdncmVlbidcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjb25zdCBpbnRlcm9wQnJva2VyID0gYXdhaXQgZmluLkludGVyb3AuaW5pdCgnb3BlbmZpbicpO1xuXHQgICAgICogY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyb3AuY29ubmVjdFN5bmMoJ29wZW5maW4nLCBpbnRlcm9wQ29uZmlnKTtcblx0ICAgICAqIGNvbnN0IGNvbnRleHRHcm91cEluZm8gPSBhd2FpdCBjbGllbnQuZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpO1xuXHQgICAgICogY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mbyk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY29ubmVjdFN5bmMobmFtZSwgaW50ZXJvcENvbmZpZykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNvbm5lY3Qtc3luYycpLmNhdGNoKCgpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm9wQ2xpZW50XzEuSW50ZXJvcENsaWVudCh0aGlzLndpcmUsIHRoaXMud2lyZS5lbnZpcm9ubWVudC53aGVuUmVhZHkoKS50aGVuKCgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGBpbnRlcm9wLWJyb2tlci0ke25hbWV9YCwge1xuXHQgICAgICAgICAgICAgICAgcGF5bG9hZDogaW50ZXJvcENvbmZpZ1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9KSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQxLkludGVyb3BNb2R1bGUgPSBJbnRlcm9wTW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQxO1xufVxuXG52YXIgaGFzUmVxdWlyZWRJbnRlcm9wO1xuXG5mdW5jdGlvbiByZXF1aXJlSW50ZXJvcCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEludGVyb3ApIHJldHVybiBpbnRlcm9wO1xuXHRoYXNSZXF1aXJlZEludGVyb3AgPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYEludGVyb3BgIEFQSSAoYGZpbi5JbnRlcm9wYCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBJbnRlcm9wTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEludGVyb3BgIEFQSSAoYXZhaWxhYmxlIHVuZGVyIGBmaW4uSW50ZXJvcGApXG5cdFx0ICogKiB7QGxpbmsgSW50ZXJvcENsaWVudH0gYW5kIHtAbGluayBJbnRlcm9wQnJva2VyfSBkb2N1bWVudCBpbnN0YW5jZXMgb2YgdGhlaXIgcmVzcGVjdGl2ZSBjbGFzc2VzLlxuXHRcdCAqXG5cdFx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdFx0ICovXG5cdFx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdFx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdFx0ICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcblx0XHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0XHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHRcdCAgICB9XG5cdFx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdFx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgb1trMl0gPSBtW2tdO1xuXHRcdH0pKTtcblx0XHR2YXIgX19leHBvcnRTdGFyID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fZXhwb3J0U3RhcikgfHwgZnVuY3Rpb24obSwgZXhwb3J0cykge1xuXHRcdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdFx0fTtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFx0X19leHBvcnRTdGFyKHJlcXVpcmVGYWN0b3J5KCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW50ZXJvcENsaWVudCgpLCBleHBvcnRzKTtcblx0XHRfX2V4cG9ydFN0YXIocmVxdWlyZUludGVyb3BCcm9rZXIoKSwgZXhwb3J0cyk7IFxuXHR9IChpbnRlcm9wKSk7XG5cdHJldHVybiBpbnRlcm9wO1xufVxuXG52YXIgc25hcHNob3RTb3VyY2UgPSB7fTtcblxudmFyIEZhY3RvcnkgPSB7fTtcblxudmFyIEluc3RhbmNlID0ge307XG5cbnZhciB1dGlscyA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodXRpbHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudXRpbHMuZ2V0U25hcHNob3RTb3VyY2VDaGFubmVsTmFtZSA9IHZvaWQgMDtcbmNvbnN0IGNoYW5uZWxQcmVmaXggPSAnc25hcHNob3Qtc291cmNlLXByb3ZpZGVyLSc7XG5jb25zdCBnZXRTbmFwc2hvdFNvdXJjZUNoYW5uZWxOYW1lID0gKGlkKSA9PiBgJHtjaGFubmVsUHJlZml4fSR7aWQudXVpZH1gO1xudXRpbHMuZ2V0U25hcHNob3RTb3VyY2VDaGFubmVsTmFtZSA9IGdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWU7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9TbmFwc2hvdFNvdXJjZV9pZGVudGl0eSwgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIF9TbmFwc2hvdFNvdXJjZV9nZXRDbGllbnQsIF9TbmFwc2hvdFNvdXJjZV9zdGFydENvbm5lY3Rpb24sIF9TbmFwc2hvdFNvdXJjZV9zZXRVcENvbm5lY3Rpb25MaXN0ZW5lcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZS5TbmFwc2hvdFNvdXJjZSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cbmNvbnN0IGJhc2VfMSQxID0gYmFzZTtcbmNvbnN0IHV0aWxzXzEkMSA9IHV0aWxzO1xuY29uc3QgY29ubmVjdGlvbk1hcCA9IG5ldyBNYXAoKTtcbi8qKlxuICogRW5hYmxlcyBjb25maWd1cmluZyBhIFNuYXBzaG90U291cmNlIHdpdGggY3VzdG9tIGdldFNuYXBzaG90IGFuZCBhcHBseVNuYXBzaG90IG1ldGhvZHMuXG4gKlxuICogQHR5cGVQYXJhbSBTbmFwc2hvdCBJbXBsZW1lbnRhdGlvbi1kZWZpbmVkIHNoYXBlIG9mIGFuIGFwcGxpY2F0aW9uIHNuYXBzaG90LiAgQWxsb3dzXG4gKiBjdXN0b20gc25hcHNob3QgaW1wbGVtZW50YXRpb25zIGZvciBsZWdhY3kgYXBwbGljYXRpb25zIHRvIGRlZmluZSB0aGVpciBvd24gc25hcHNob3QgZm9ybWF0LlxuICovXG5jbGFzcyBTbmFwc2hvdFNvdXJjZSBleHRlbmRzIGJhc2VfMSQxLkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIGlkKSB7XG4gICAgICAgIHN1cGVyKHdpcmUpO1xuICAgICAgICBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHkuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWNvbm5lY3Rpb25NYXAuaGFzKHRoaXMuaWRlbnRpdHkudXVpZCkpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uTWFwLnNldCh0aGlzLmlkZW50aXR5LnV1aWQsIHsgZXZlbnRGaXJlZDogbnVsbCwgY2xpZW50UHJvbWlzZTogbnVsbCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb25uZWN0aW9uTWFwLmdldCh0aGlzLmlkZW50aXR5LnV1aWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgX1NuYXBzaG90U291cmNlX2dldENsaWVudC5zZXQodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmNsaWVudFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmNsaWVudFByb21pc2UgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLCBcImZcIikuY2FsbCh0aGlzKS5jbGllbnRQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbi5zZXQodGhpcywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSAoMCwgdXRpbHNfMSQxLmdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWUpKHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX3NldFVwQ29ubmVjdGlvbkxpc3RlbmVyLCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbE5hbWUsIHsgd2FpdDogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgY2xpZW50Lm9uRGlzY29ubmVjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuY2xpZW50UHJvbWlzZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLCBcImZcIikuY2FsbCh0aGlzKS5jbGllbnRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgdGFyZ2V0ZWQgU25hcHNob3RTb3VyY2UgaXMgbm90IGN1cnJlbnRseSBpbml0aWFsaXplZC4gQXdhaXQgdGhpcyBvYmplY3QncyByZWFkeSgpIG1ldGhvZC5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfU25hcHNob3RTb3VyY2Vfc2V0VXBDb25uZWN0aW9uTGlzdGVuZXIuc2V0KHRoaXMsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gKDAsIHV0aWxzXzEkMS5nZXRTbmFwc2hvdFNvdXJjZUNoYW5uZWxOYW1lKSh0aGlzLmlkZW50aXR5KTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlO1xuICAgICAgICAgICAgbGV0IHJlamVjdDtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RmlyZWQgPSBuZXcgUHJvbWlzZSgoeSwgbikgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUgPSB5O1xuICAgICAgICAgICAgICAgIHJlamVjdCA9IG47XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCA9IGV2ZW50RmlyZWQ7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUuY2hhbm5lbE5hbWUgPT09IGNoYW5uZWxOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwucmVtb3ZlTGlzdGVuZXIoJ2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwub24oJ2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHksIGlkLCBcImZcIik7XG4gICAgfVxuICAgIGdldCBpZGVudGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHksIFwiZlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRvIGRldGVybWluZSBpZiB0aGUgU25hcHNob3RTb3VyY2UgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBVc2Ugd2hlbiB0aGUgcGFyZW50IGFwcGxpY2F0aW9uIGlzIHN0YXJ0aW5nIHVwIHRvIGVuc3VyZSB0aGUgU25hcHNob3RTb3VyY2UgaXMgYWJsZSB0byBhY2NlcHQgYW5kXG4gICAgICogYXBwbHkgYSBzbmFwc2hvdCB1c2luZyB0aGUge0BsaW5rIFNuYXBzaG90U291cmNlI2FwcGx5U25hcHNob3QgYXBwbHlTbmFwc2hvdH0gbWV0aG9kLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCBzbmFwc2hvdFNvdXJjZSA9IGZpbi5TbmFwc2hvdFNvdXJjZS53cmFwU3luYyhmaW4ubWUpO1xuICAgICAqXG4gICAgICogY29uc3Qgc25hcHNob3RQcm92aWRlciA9IHtcbiAgICAgKiAgICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7IHJldHVybiAnZm9vJyB9LFxuICAgICAqICAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICogICAgICAgY29uc29sZS5sb2coc25hcHNob3QpO1xuICAgICAqICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICogICAgIH1cbiAgICAgKiB9XG4gICAgICogYXdhaXQgZmluLlNuYXBzaG90U291cmNlLmluaXQoc25hcHNob3RQcm92aWRlcik7XG4gICAgICpcbiAgICAgKiB0cnkge1xuICAgICAqICAgYXdhaXQgc25hcHNob3RTb3VyY2UucmVhZHkoKTtcbiAgICAgKiAgIGF3YWl0IHNuYXBzaG90U291cmNlLmFwcGx5U25hcHNob3QoJ2ZvbycpO1xuICAgICAqIH0gY2F0Y2ggKGVycikge1xuICAgICAqICAgY29uc29sZS5sb2coZXJyKVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyByZWFkeSgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NuYXBzaG90LXNvdXJjZS1yZWFkeScpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBJZiBnZXRDbGllbnQgd2FzIGFscmVhZHkgY2FsbGVkIGJlZm9yZSB0aGlzLCBkbyB3ZSBoYXZlIGEgdGltaW5nIGlzc3VlIHdoZXJlIHRoZSBjaGFubmVsIG1pZ2h0IGhhdmUgYmVlbiBjcmVhdGVkIGJ1dCB3ZSBtaXNzZWQgdGhlIGV2ZW50IGJ1dCB0aGlzIHN0aWxsIGZhaWxzP1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDbGllbnQsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBpdCB3YXMgbm90IHJ1bm5pbmcuXG4gICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmV2ZW50RmlyZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbCB0aGUgU25hcHNob3RTb3VyY2UncyBnZXRTbmFwc2hvdCBtZXRob2QgZGVmaW5lZCBieSB7QGxpbmsgU25hcHNob3RTb3VyY2UuU25hcHNob3RTb3VyY2VNb2R1bGUjaW5pdCBpbml0fS5cbiAgICAgKlxuICAgICAqL1xuICAgIGFzeW5jIGdldFNuYXBzaG90KCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLWdldC1zbmFwc2hvdCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q2xpZW50LCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdnZXQtc25hcHNob3QnKSk7XG4gICAgICAgIHJldHVybiAoYXdhaXQgcmVzcG9uc2UpLnNuYXBzaG90O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoZSBTbmFwc2hvdFNvdXJjZSdzIGFwcGx5U25hcHNob3QgbWV0aG9kIGRlZmluZWQgYnkge0BsaW5rIFNuYXBzaG90U291cmNlLlNuYXBzaG90U291cmNlTW9kdWxlI2luaXQgaW5pdH0uXG4gICAgICpcbiAgICAgKi9cbiAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzbmFwc2hvdC1zb3VyY2UtYXBwbHktc25hcHNob3QnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENsaWVudCwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2FwcGx5LXNuYXBzaG90JywgeyBzbmFwc2hvdCB9KTtcbiAgICB9XG59XG5JbnN0YW5jZS5TbmFwc2hvdFNvdXJjZSA9IFNuYXBzaG90U291cmNlO1xuX1NuYXBzaG90U291cmNlX2lkZW50aXR5ID0gbmV3IFdlYWtNYXAoKSwgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24gPSBuZXcgV2Vha01hcCgpLCBfU25hcHNob3RTb3VyY2VfZ2V0Q2xpZW50ID0gbmV3IFdlYWtNYXAoKSwgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9TbmFwc2hvdFNvdXJjZV9zZXRVcENvbm5lY3Rpb25MaXN0ZW5lciA9IG5ldyBXZWFrTWFwKCk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbkZhY3RvcnkuU25hcHNob3RTb3VyY2VNb2R1bGUgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEgPSBiYXNlO1xuY29uc3QgSW5zdGFuY2VfMSA9IEluc3RhbmNlO1xuY29uc3QgdXRpbHNfMSA9IHV0aWxzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIFNuYXBzaG90U291cmNlfSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uU25hcHNob3RTb3VyY2VgLlxuICovXG5jbGFzcyBTbmFwc2hvdFNvdXJjZU1vZHVsZSBleHRlbmRzIGJhc2VfMS5CYXNlIHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhIFNuYXBzaG90U291cmNlIHdpdGggdGhlIGdldFNuYXBzaG90IGFuZCBhcHBseVNuYXBzaG90IG1ldGhvZHMgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIEB0eXBlUGFyYW0gU25hcHNob3QgSW1wbGVtZW50YXRpb24tZGVmaW5lZCBzaGFwZSBvZiBhbiBhcHBsaWNhdGlvbiBzbmFwc2hvdC4gIEFsbG93c1xuICAgICAqIGN1c3RvbSBzbmFwc2hvdCBpbXBsZW1lbnRhdGlvbnMgZm9yIGxlZ2FjeSBhcHBsaWNhdGlvbnMgdG8gZGVmaW5lIHRoZWlyIG93biBzbmFwc2hvdCBmb3JtYXQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgc25hcHNob3RQcm92aWRlciA9IHtcbiAgICAgKiAgICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7XG4gICAgICogICAgICAgY29uc3QgYm91bmRzID0gYXdhaXQgZmluLm1lLmdldEJvdW5kcygpO1xuICAgICAqICAgICAgIHJldHVybiBib3VuZHM7XG4gICAgICogICAgICB9LFxuICAgICAqICAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICogICAgICAgYXdhaXQgZmluLm1lLnNldEJvdW5kcyhzbmFwc2hvdCk7XG4gICAgICogICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgKiAgICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGF3YWl0IGZpbi5TbmFwc2hvdFNvdXJjZS5pbml0KHNuYXBzaG90UHJvdmlkZXIpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICovXG4gICAgYXN5bmMgaW5pdChwcm92aWRlcikge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLWluaXQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZW9mIHByb3ZpZGVyICE9PSAnb2JqZWN0JyB8fFxuICAgICAgICAgICAgdHlwZW9mIHByb3ZpZGVyLmdldFNuYXBzaG90ICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICAgICB0eXBlb2YgcHJvdmlkZXIuYXBwbHlTbmFwc2hvdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd5b3UgbXVzdCBwYXNzIGluIGEgdmFsaWQgU25hcHNob3RQcm92aWRlcicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCgwLCB1dGlsc18xLmdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWUpKHRoaXMuZmluLm1lKSk7XG4gICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldC1zbmFwc2hvdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcHJvdmlkZXIuZ2V0U25hcHNob3QoKTtcbiAgICAgICAgICAgIHJldHVybiB7IHNuYXBzaG90IH07XG4gICAgICAgIH0pO1xuICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdhcHBseS1zbmFwc2hvdCcsICh7IHNuYXBzaG90IH0pID0+IHByb3ZpZGVyLmFwcGx5U25hcHNob3Qoc25hcHNob3QpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgU25hcHNob3RTb3VyY2Ugb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBTbmFwc2hvdFNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBzbmFwc2hvdFNvdXJjZSA9IGZpbi5TbmFwc2hvdFNvdXJjZS53cmFwU3luYyhmaW4ubWUpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlJ3MgZ2V0U25hcHNob3QgbWV0aG9kLCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc25hcHNob3RTb3VyY2UuZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLXdyYXAtc3luYycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMS5TbmFwc2hvdFNvdXJjZSh0aGlzLndpcmUsIGlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIFNuYXBzaG90U291cmNlIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgU25hcHNob3RTb3VyY2UuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgc25hcHNob3RTb3VyY2UgPSBhd2FpdCBmaW4uU25hcHNob3RTb3VyY2Uud3JhcChmaW4ubWUpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlJ3MgZ2V0U25hcHNob3QgbWV0aG9kLCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc25hcHNob3RTb3VyY2UuZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cmFwKGlkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzbmFwc2hvdC1zb3VyY2Utd3JhcCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBTeW5jKGlkZW50aXR5KTtcbiAgICB9XG59XG5GYWN0b3J5LlNuYXBzaG90U291cmNlTW9kdWxlID0gU25hcHNob3RTb3VyY2VNb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgU25hcHNob3RTb3VyY2VgIEFQSSAoYGZpbi5TbmFwc2hvdFNvdXJjZWApLlxuXHQgKlxuXHQgKiAqIHtAbGluayBTbmFwc2hvdFNvdXJjZU1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBTbmFwc2hvdFNvdXJjZWAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5TbmFwc2hvdFNvdXJjZWAuXG5cdCAqICoge0BsaW5rIFNuYXBzaG90U291cmNlfSBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gT3BlbkZpbiBTbmFwc2hvdFNvdXJjZSwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlNuYXBzaG90U291cmNlLndyYXBgLlxuXHQgKlxuXHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnksIGV4cG9ydHMpO1xuXHRfX2V4cG9ydFN0YXIoSW5zdGFuY2UsIGV4cG9ydHMpOyBcbn0gKHNuYXBzaG90U291cmNlKSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShmaW4kMiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRmluXzEgPSBmaW4kMi5GaW4gPSB2b2lkIDA7XG5jb25zdCBldmVudHNfMSQzID0gcmVxdWlyZSQkMDtcbi8vIEltcG9ydCBmcm9tIHRoZSBmaWxlIHJhdGhlciB0aGFuIHRoZSBkaXJlY3RvcnkgaW4gY2FzZSBzb21lb25lIGNvbnN1bWluZyB0eXBlcyBpcyB1c2luZyBtb2R1bGUgcmVzb2x1dGlvbiBvdGhlciB0aGFuIFwibm9kZVwiXG5jb25zdCBpbmRleF8xID0gc3lzdGVtO1xuY29uc3QgaW5kZXhfMiA9IHJlcXVpcmVXaW5kb3coKTtcbmNvbnN0IGluZGV4XzMgPSByZXF1aXJlQXBwbGljYXRpb24oKTtcbmNvbnN0IGluZGV4XzQgPSBpbnRlcmFwcGJ1cztcbmNvbnN0IGluZGV4XzUgPSBjbGlwYm9hcmQ7XG5jb25zdCBpbmRleF82ID0gZXh0ZXJuYWxBcHBsaWNhdGlvbjtcbmNvbnN0IGluZGV4XzcgPSBmcmFtZTtcbmNvbnN0IGluZGV4XzggPSBnbG9iYWxIb3RrZXk7XG5jb25zdCBpbmRleF85ID0gcmVxdWlyZVZpZXcoKTtcbmNvbnN0IGluZGV4XzEwID0gcGxhdGZvcm07XG5jb25zdCBtZV8xJDIgPSBtZTtcbmNvbnN0IGludGVyb3BfMSA9IHJlcXVpcmVJbnRlcm9wKCk7XG5jb25zdCBzbmFwc2hvdF9zb3VyY2VfMSA9IHNuYXBzaG90U291cmNlO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgRmluIGV4dGVuZHMgZXZlbnRzXzEkMy5FdmVudEVtaXR0ZXIge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy53aXJlID0gd2lyZTtcbiAgICAgICAgdGhpcy5TeXN0ZW0gPSBuZXcgaW5kZXhfMS5TeXN0ZW0od2lyZSk7XG4gICAgICAgIHRoaXMuV2luZG93ID0gbmV3IGluZGV4XzIuX1dpbmRvd01vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5BcHBsaWNhdGlvbiA9IG5ldyBpbmRleF8zLkFwcGxpY2F0aW9uTW9kdWxlKHdpcmUpO1xuICAgICAgICB0aGlzLkludGVyQXBwbGljYXRpb25CdXMgPSBuZXcgaW5kZXhfNC5JbnRlckFwcGxpY2F0aW9uQnVzKHdpcmUpO1xuICAgICAgICB0aGlzLkNsaXBib2FyZCA9IG5ldyBpbmRleF81LkNsaXBib2FyZCh3aXJlKTtcbiAgICAgICAgdGhpcy5FeHRlcm5hbEFwcGxpY2F0aW9uID0gbmV3IGluZGV4XzYuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5GcmFtZSA9IG5ldyBpbmRleF83Ll9GcmFtZU1vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5HbG9iYWxIb3RrZXkgPSBuZXcgaW5kZXhfOC5HbG9iYWxIb3RrZXkod2lyZSk7XG4gICAgICAgIHRoaXMuUGxhdGZvcm0gPSBuZXcgaW5kZXhfMTAuUGxhdGZvcm1Nb2R1bGUod2lyZSwgdGhpcy5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwpO1xuICAgICAgICB0aGlzLlZpZXcgPSBuZXcgaW5kZXhfOS5WaWV3TW9kdWxlKHdpcmUpO1xuICAgICAgICB0aGlzLkludGVyb3AgPSBuZXcgaW50ZXJvcF8xLkludGVyb3BNb2R1bGUod2lyZSk7XG4gICAgICAgIHRoaXMuU25hcHNob3RTb3VyY2UgPSBuZXcgc25hcHNob3Rfc291cmNlXzEuU25hcHNob3RTb3VyY2VNb2R1bGUod2lyZSk7XG4gICAgICAgIHdpcmUucmVnaXN0ZXJGaW4odGhpcyk7XG4gICAgICAgIHRoaXMubWUgPSAoMCwgbWVfMSQyLmdldE1lKSh3aXJlKTtcbiAgICAgICAgLy8gSGFuZGxlIGRpc2Nvbm5lY3QgZXZlbnRzXG4gICAgICAgIHdpcmUub24oJ2Rpc2Nvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdGVkJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbkZpbl8xID0gZmluJDIuRmluID0gRmluO1xuXG52YXIgdHJhbnNwb3J0ID0ge307XG5cbnZhciB3aXJlID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aXJlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbndpcmUuaXNJbnRlcm5hbENvbm5lY3RDb25maWcgPSB3aXJlLmlzUG9ydERpc2NvdmVyeUNvbmZpZyA9IHdpcmUuaXNOZXdDb25uZWN0Q29uZmlnID0gd2lyZS5pc0NvbmZpZ1dpdGhSZWNlaXZlciA9IHdpcmUuaXNSZW1vdGVDb25maWcgPSB3aXJlLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnID0gd2lyZS5pc0V4dGVybmFsQ29uZmlnID0gdm9pZCAwO1xuZnVuY3Rpb24gaXNFeHRlcm5hbENvbmZpZyhjb25maWcpIHtcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5tYW5pZmVzdFVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbndpcmUuaXNFeHRlcm5hbENvbmZpZyA9IGlzRXh0ZXJuYWxDb25maWc7XG5mdW5jdGlvbiBpc0V4aXN0aW5nQ29ubmVjdENvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaGFzVXVpZChjb25maWcpICYmIHR5cGVvZiBjb25maWcuYWRkcmVzcyA9PT0gJ3N0cmluZyc7XG59XG53aXJlLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnID0gaXNFeGlzdGluZ0Nvbm5lY3RDb25maWc7XG5mdW5jdGlvbiBpc1JlbW90ZUNvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaXNFeGlzdGluZ0Nvbm5lY3RDb25maWcoY29uZmlnKSAmJiB0eXBlb2YgY29uZmlnLnRva2VuID09PSAnc3RyaW5nJztcbn1cbndpcmUuaXNSZW1vdGVDb25maWcgPSBpc1JlbW90ZUNvbmZpZztcbmZ1bmN0aW9uIGlzQ29uZmlnV2l0aFJlY2VpdmVyKGNvbmZpZykge1xuICAgIHJldHVybiB0eXBlb2YgY29uZmlnLnJlY2VpdmVyID09PSAnb2JqZWN0JyAmJiBpc1JlbW90ZUNvbmZpZyh7IC4uLmNvbmZpZywgYWRkcmVzczogJycgfSk7XG59XG53aXJlLmlzQ29uZmlnV2l0aFJlY2VpdmVyID0gaXNDb25maWdXaXRoUmVjZWl2ZXI7XG5mdW5jdGlvbiBoYXNVdWlkKGNvbmZpZykge1xuICAgIHJldHVybiB0eXBlb2YgY29uZmlnLnV1aWQgPT09ICdzdHJpbmcnO1xufVxuZnVuY3Rpb24gaGFzUnVudGltZVZlcnNpb24oY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ydW50aW1lICYmIHR5cGVvZiBjb25maWcucnVudGltZS52ZXJzaW9uID09PSAnc3RyaW5nJztcbn1cbmZ1bmN0aW9uIGlzTmV3Q29ubmVjdENvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaGFzVXVpZChjb25maWcpICYmIGhhc1J1bnRpbWVWZXJzaW9uKGNvbmZpZyk7XG59XG53aXJlLmlzTmV3Q29ubmVjdENvbmZpZyA9IGlzTmV3Q29ubmVjdENvbmZpZztcbmZ1bmN0aW9uIGlzUG9ydERpc2NvdmVyeUNvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gKGlzRXh0ZXJuYWxDb25maWcoY29uZmlnKSAmJiBoYXNSdW50aW1lVmVyc2lvbihjb25maWcpKSB8fCBpc05ld0Nvbm5lY3RDb25maWcoY29uZmlnKTtcbn1cbndpcmUuaXNQb3J0RGlzY292ZXJ5Q29uZmlnID0gaXNQb3J0RGlzY292ZXJ5Q29uZmlnO1xuZnVuY3Rpb24gaXNJbnRlcm5hbENvbm5lY3RDb25maWcoY29uZmlnKSB7XG4gICAgcmV0dXJuIGlzRXhpc3RpbmdDb25uZWN0Q29uZmlnKGNvbmZpZykgfHwgaXNOZXdDb25uZWN0Q29uZmlnKGNvbmZpZyk7XG59XG53aXJlLmlzSW50ZXJuYWxDb25uZWN0Q29uZmlnID0gaXNJbnRlcm5hbENvbm5lY3RDb25maWc7XG5cbnZhciBldmVudEFnZ3JlZ2F0b3IgPSB7fTtcblxudmFyIGVtaXR0ZXJNYXAgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVtaXR0ZXJNYXAsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZW1pdHRlck1hcC5FbWl0dGVyTWFwID0gdm9pZCAwO1xuY29uc3QgZXZlbnRzXzEkMiA9IHJlcXVpcmUkJDA7XG5jbGFzcyBFbWl0dGVyTWFwIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yYWdlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICAgIGhhc2hLZXlzKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaGVkID0ga2V5cy5tYXAobm9ybWFsaXplU3RyaW5nKTtcbiAgICAgICAgcmV0dXJuIGhhc2hlZC5qb2luKCcvJyk7XG4gICAgfVxuICAgIGdldE9yQ3JlYXRlKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaEtleXMoa2V5cyk7XG4gICAgICAgIGlmICghdGhpcy5zdG9yYWdlLmhhcyhoYXNoKSkge1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnNldChoYXNoLCBuZXcgZXZlbnRzXzEkMi5FdmVudEVtaXR0ZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2Ugc2V0IGl0IGFib3ZlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KGhhc2gpO1xuICAgIH1cbiAgICBoYXMoa2V5cykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmhhcyh0aGlzLmhhc2hLZXlzKGtleXMpKTtcbiAgICB9XG4gICAgZGVsZXRlKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaEtleXMoa2V5cyk7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZGVsZXRlKGhhc2gpO1xuICAgIH1cbn1cbmVtaXR0ZXJNYXAuRW1pdHRlck1hcCA9IEVtaXR0ZXJNYXA7XG5mdW5jdGlvbiBub3JtYWxpemVTdHJpbmcocykge1xuICAgIGNvbnN0IGIgPSBCdWZmZXIuZnJvbShzKTtcbiAgICByZXR1cm4gYi50b1N0cmluZygnYmFzZTY0Jyk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShldmVudEFnZ3JlZ2F0b3IsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgZW1pdHRlck1hcF8xID0gZW1pdHRlck1hcDtcbmZ1bmN0aW9uIGlzRXZlbnRNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbWVzc2FnZS5hY3Rpb24gPT09ICdwcm9jZXNzLWRlc2t0b3AtZXZlbnQnO1xufVxuZnVuY3Rpb24gbWFwS2V5RnJvbUV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgeyB0b3BpYyB9ID0gZXZlbnQ7XG4gICAgaWYgKHRvcGljID09PSAnZnJhbWUnIHx8IHRvcGljID09PSAnd2luZG93JyB8fCB0b3BpYyA9PT0gJ3ZpZXcnKSB7XG4gICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gZXZlbnQ7XG4gICAgICAgIHJldHVybiBbdG9waWMsIHV1aWQsIG5hbWVdO1xuICAgIH1cbiAgICBpZiAodG9waWMgPT09ICdhcHBsaWNhdGlvbicpIHtcbiAgICAgICAgY29uc3QgeyB1dWlkIH0gPSBldmVudDtcbiAgICAgICAgcmV0dXJuIFt0b3BpYywgdXVpZF07XG4gICAgfVxuICAgIHJldHVybiBbdG9waWNdO1xufVxuY2xhc3MgRXZlbnRBZ2dyZWdhdG9yIGV4dGVuZHMgZW1pdHRlck1hcF8xLkVtaXR0ZXJNYXAge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQgPSAobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzRXZlbnRNZXNzYWdlKG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBtZXNzYWdlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc29yID0gbWFwS2V5RnJvbUV2ZW50KHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhcyhhY2Nlc3NvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckNyZWF0ZShhY2Nlc3NvcikuZW1pdChwYXlsb2FkLnR5cGUsIHBheWxvYWQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfVxufVxuZXZlbnRBZ2dyZWdhdG9yLmRlZmF1bHQgPSBFdmVudEFnZ3JlZ2F0b3I7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgXCJkZWZhdWx0XCI6IG1vZCB9O1xufTtcbnZhciBfVHJhbnNwb3J0X3dpcmUsIF9UcmFuc3BvcnRfZmluO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHRyYW5zcG9ydCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgVHJhbnNwb3J0XzEgPSB0cmFuc3BvcnQuVHJhbnNwb3J0ID0gdm9pZCAwO1xuY29uc3QgZXZlbnRzXzEkMSA9IHJlcXVpcmUkJDA7XG5jb25zdCB3aXJlXzEgPSB3aXJlO1xuY29uc3QgdHJhbnNwb3J0X2Vycm9yc18xID0gdHJhbnNwb3J0RXJyb3JzO1xuY29uc3QgZXZlbnRBZ2dyZWdhdG9yXzEgPSBfX2ltcG9ydERlZmF1bHQoZXZlbnRBZ2dyZWdhdG9yKTtcbmNvbnN0IG1lXzEkMSA9IG1lO1xuY29uc3QgZXJyb3JzXzEgPSBlcnJvcnM7XG5jbGFzcyBUcmFuc3BvcnQgZXh0ZW5kcyBldmVudHNfMSQxLkV2ZW50RW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IoV2lyZVR5cGUsIGVudmlyb25tZW50LCBjb25maWcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy53aXJlTGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLnRvcGljUmVmTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLmV2ZW50QWdncmVnYXRvciA9IG5ldyBldmVudEFnZ3JlZ2F0b3JfMS5kZWZhdWx0KCk7XG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXJzID0gW3RoaXMuZXZlbnRBZ2dyZWdhdG9yLmRpc3BhdGNoRXZlbnRdO1xuICAgICAgICBfVHJhbnNwb3J0X3dpcmUuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8vIFR5cGluZyBhcyB1bmtub3duIHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHNob3VsZCBub3QgYmUgdXNlZCBkaXJlY3RseS5cbiAgICAgICAgX1RyYW5zcG9ydF9maW4uc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIHRoaXMuY29ubmVjdFN5bmMgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3aXJlID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKTtcbiAgICAgICAgICAgIHdpcmUuY29ubmVjdFN5bmMoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IHVzZWQgaW4gb3VyIHRlc3RzLlxuICAgICAgICB0aGlzLmdldFBvcnQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3aXJlID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKTtcbiAgICAgICAgICAgIHJldHVybiB3aXJlLmdldFBvcnQoKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIG5ldyBXaXJlVHlwZSh0aGlzLm9ubWVzc2FnZS5iaW5kKHRoaXMpKSwgXCJmXCIpO1xuICAgICAgICB0aGlzLmVudmlyb25tZW50ID0gZW52aXJvbm1lbnQ7XG4gICAgICAgIHRoaXMuc2VuZFJhdyA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIikuc2VuZC5iaW5kKF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIikpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5oYW5kbGVNZXNzYWdlLmJpbmQodGhpcykpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpLm9uKCdkaXNjb25uZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFssIHsgaGFuZGxlTmFjayB9XSBvZiB0aGlzLndpcmVMaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVOYWNrKHsgcmVhc29uOiAnUmVtb3RlIGNvbm5lY3Rpb24gaGFzIGNsb3NlZCcgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndpcmVMaXN0ZW5lcnMuY2xlYXIoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdGVkJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNvbmZpZztcbiAgICAgICAgY29uc3QgZW50aXR5VHlwZSA9IHRoaXMuZW52aXJvbm1lbnQuZ2V0Q3VycmVudEVudGl0eVR5cGUoKTtcbiAgICAgICAgdGhpcy5tZSA9ICgwLCBtZV8xJDEuZ2V0QmFzZU1lKShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKTtcbiAgICB9XG4gICAgZ2V0RmluKCkge1xuICAgICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIFwiZlwiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBGaW4gb2JqZWN0IHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHJhbnNwb3J0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIFwiZlwiKTtcbiAgICB9XG4gICAgcmVnaXN0ZXJGaW4oX2Zpbikge1xuICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X2ZpbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpbiBvYmplY3QgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGZvciB0aGlzIHRyYW5zcG9ydCcpO1xuICAgICAgICB9XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIF9maW4sIFwiZlwiKTtcbiAgICB9XG4gICAgc2h1dGRvd24oKSB7XG4gICAgICAgIGNvbnN0IHdpcmUgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpO1xuICAgICAgICByZXR1cm4gd2lyZS5zaHV0ZG93bigpO1xuICAgIH1cbiAgICBhc3luYyBjb25uZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoKDAsIHdpcmVfMS5pc0NvbmZpZ1dpdGhSZWNlaXZlcikoY29uZmlnKSkge1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKS5jb25uZWN0KGNvbmZpZy5yZWNlaXZlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdXRob3JpemUoY29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKDAsIHdpcmVfMS5pc1JlbW90ZUNvbmZpZykoY29uZmlnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdFJlbW90ZShjb25maWcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoMCwgd2lyZV8xLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnKShjb25maWcpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0QnlQb3J0KGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCgwLCB3aXJlXzEuaXNOZXdDb25uZWN0Q29uZmlnKShjb25maWcpKSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0ID0gYXdhaXQgdGhpcy5lbnZpcm9ubWVudC5yZXRyaWV2ZVBvcnQoY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RCeVBvcnQoeyAuLi5jb25maWcsIGFkZHJlc3M6IGB3czovL2xvY2FsaG9zdDoke3BvcnR9YCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBhc3luYyBjb25uZWN0UmVtb3RlKGNvbmZpZykge1xuICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpLmNvbm5lY3QobmV3ICh0aGlzLmVudmlyb25tZW50LmdldFdzQ29uc3RydWN0b3IoKSkoY29uZmlnLmFkZHJlc3MpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aG9yaXplKGNvbmZpZyk7XG4gICAgfVxuICAgIGFzeW5jIGNvbm5lY3RCeVBvcnQoY29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHsgYWRkcmVzcywgdXVpZCB9ID0gY29uZmlnO1xuICAgICAgICBjb25zdCByZXFBdXRoUGF5bG9hZCA9IHsgLi4uY29uZmlnLCB0eXBlOiAnZmlsZS10b2tlbicgfTtcbiAgICAgICAgY29uc3Qgd2lyZSA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIik7XG4gICAgICAgIGF3YWl0IHdpcmUuY29ubmVjdChuZXcgKHRoaXMuZW52aXJvbm1lbnQuZ2V0V3NDb25zdHJ1Y3RvcigpKShjb25maWcuYWRkcmVzcykpO1xuICAgICAgICBjb25zdCByZXF1ZXN0RXh0QXV0aFJldCA9IGF3YWl0IHRoaXMuc2VuZEFjdGlvbigncmVxdWVzdC1leHRlcm5hbC1hdXRob3JpemF0aW9uJywge1xuICAgICAgICAgICAgdXVpZCxcbiAgICAgICAgICAgIHR5cGU6ICdmaWxlLXRva2VuJ1xuICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgaWYgKHJlcXVlc3RFeHRBdXRoUmV0LmFjdGlvbiAhPT0gJ2V4dGVybmFsLWF1dGhvcml6YXRpb24tcmVzcG9uc2UnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgdHJhbnNwb3J0X2Vycm9yc18xLlVuZXhwZWN0ZWRBY3Rpb25FcnJvcihyZXF1ZXN0RXh0QXV0aFJldC5hY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuZW52aXJvbm1lbnQud3JpdGVUb2tlbihyZXF1ZXN0RXh0QXV0aFJldC5wYXlsb2FkLmZpbGUsIHJlcXVlc3RFeHRBdXRoUmV0LnBheWxvYWQudG9rZW4pO1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRob3JpemUocmVxQXV0aFBheWxvYWQpO1xuICAgIH1cbiAgICBhc3luYyBhdXRob3JpemUocmVxQXV0aFBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdEF1dGhSZXQgPSBhd2FpdCB0aGlzLnNlbmRBY3Rpb24oJ3JlcXVlc3QtYXV0aG9yaXphdGlvbicsIHJlcUF1dGhQYXlsb2FkLCB0cnVlKTtcbiAgICAgICAgaWYgKHJlcXVlc3RBdXRoUmV0LmFjdGlvbiAhPT0gJ2F1dGhvcml6YXRpb24tcmVzcG9uc2UnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgdHJhbnNwb3J0X2Vycm9yc18xLlVuZXhwZWN0ZWRBY3Rpb25FcnJvcihyZXF1ZXN0QXV0aFJldC5hY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJlcXVlc3RBdXRoUmV0LnBheWxvYWQuc3VjY2VzcyAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5SdW50aW1lRXJyb3IocmVxdWVzdEF1dGhSZXQucGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2VuZEFjdGlvbihhY3Rpb24sIHBheWxvYWQgPSB7fSwgdW5jb3JyZWxhdGVkID0gZmFsc2VcbiAgICAvLyBzcGVjaWFsUmVzcG9uc2UgdHlwZSBpcyBvbmx5IHVzZWQgZm9yICdyZXF1ZXN0QXV0aG9yaXphdGlvbidcbiAgICApIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICAgICAgICBsZXQgY2FuY2VsID0gKCkgPT4geyB9O1xuICAgICAgICAvLyBXZSB3YW50IHRoZSBjYWxsc2l0ZSBmcm9tIHRoZSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiwgbm90IGZyb20gaGVyZS5cbiAgICAgICAgY29uc3QgY2FsbFNpdGVzID0gdHJhbnNwb3J0X2Vycm9yc18xLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgxKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZUlkID0gdGhpcy5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCk7XG4gICAgICAgIGNvbnN0IHByb20gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjYW5jZWwgPSByZWplY3Q7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgd2lyZSA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIik7XG4gICAgICAgICAgICB0aGlzLmFkZFdpcmVMaXN0ZW5lcihtZXNzYWdlSWQsIHJlc29sdmUsIChwYXlsb2FkKSA9PiB0aGlzLm5hY2tIYW5kbGVyKHBheWxvYWQsIHJlamVjdCwgY2FsbFNpdGVzKSwgdW5jb3JyZWxhdGVkKTtcbiAgICAgICAgICAgIHJldHVybiB3aXJlLnNlbmQobXNnKS5jYXRjaChyZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocHJvbSwgeyBjYW5jZWwsIG1lc3NhZ2VJZCB9KTtcbiAgICB9XG4gICAgbmFja0hhbmRsZXIocGF5bG9hZE9yTWVzc2FnZSwgcmVqZWN0LCBjYWxsU2l0ZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkT3JNZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gTk9URTogdGhpcyBpcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdG8gc3VwcG9ydCBwbGFpbiBzdHJpbmcgcmVqZWN0aW9uc1xuICAgICAgICAgICAgcmVqZWN0KHBheWxvYWRPck1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyB0cmFuc3BvcnRfZXJyb3JzXzEuUnVudGltZUVycm9yKHBheWxvYWRPck1lc3NhZ2UsIGNhbGxTaXRlcykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZlcnJ5QWN0aW9uKG9yaWdEYXRhKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpO1xuICAgICAgICAgICAgb3JpZ0RhdGEubWVzc2FnZUlkID0gaWQ7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlciA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnBheWxvYWQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHdpcmUgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHdpcmVcbiAgICAgICAgICAgICAgICAuc2VuZChvcmlnRGF0YSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmFkZFdpcmVMaXN0ZW5lcihpZCwgcmVzb2x2ZXIsIChwYXlsb2FkKSA9PiB0aGlzLm5hY2tIYW5kbGVyKHBheWxvYWQsIHJlamVjdCksIGZhbHNlKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gocmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgIH1cbiAgICBhZGRXaXJlTGlzdGVuZXIoaWQsIHJlc29sdmUsIGhhbmRsZU5hY2ssIHVuY29ycmVsYXRlZCkge1xuICAgICAgICBpZiAodW5jb3JyZWxhdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnVuY29ycmVsYXRlZExpc3RlbmVyID0gcmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLndpcmVMaXN0ZW5lcnMuaGFzKGlkKSkge1xuICAgICAgICAgICAgaGFuZGxlTmFjayh7XG4gICAgICAgICAgICAgICAgcmVhc29uOiAnRHVwbGljYXRlIGhhbmRsZXIgaWQnLFxuICAgICAgICAgICAgICAgIGVycm9yOiAoMCwgZXJyb3JzXzEuZXJyb3JUb1BPSk8pKG5ldyB0cmFuc3BvcnRfZXJyb3JzXzEuRHVwbGljYXRlQ29ycmVsYXRpb25FcnJvcihTdHJpbmcoaWQpKSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53aXJlTGlzdGVuZXJzLnNldChpZCwgeyByZXNvbHZlLCBoYW5kbGVOYWNrIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRpbWVvdXQgYW5kIHJlamVjdCgpP1xuICAgIH1cbiAgICAvLyBUaGlzIG1ldGhvZCBleGVjdXRlcyBtZXNzYWdlIGhhbmRsZXJzIHVudGlsIHRoZSBfb25lXyB0aGF0IGhhbmRsZXMgdGhlIG1lc3NhZ2UgKHJldHVybnMgdHJ1dGh5KSBoYXMgcnVuXG4gICAgb25tZXNzYWdlKGRhdGEpIHtcbiAgICAgICAgZm9yIChjb25zdCBoIG9mIHRoaXMubWVzc2FnZUhhbmRsZXJzKSB7XG4gICAgICAgICAgICBoLmNhbGwobnVsbCwgZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlTWVzc2FnZShkYXRhKSB7XG4gICAgICAgIGNvbnN0IGlkID0gZGF0YS5jb3JyZWxhdGlvbklkIHx8IE5hTjtcbiAgICAgICAgaWYgKCEoJ2NvcnJlbGF0aW9uSWQnIGluIGRhdGEpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy51bmNvcnJlbGF0ZWRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMudW5jb3JyZWxhdGVkTGlzdGVuZXIuY2FsbChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudW5jb3JyZWxhdGVkTGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZW1wdHkgYmxvY2tcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRoaXMud2lyZUxpc3RlbmVycy5oYXMoaWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBXZSBqdXN0IGNoZWNrZWQgZm9yIGV4aXN0ZW5jZSBhYm92ZVxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIGNvbnN0IHsgcmVzb2x2ZSwgaGFuZGxlTmFjayB9ID0gdGhpcy53aXJlTGlzdGVuZXJzLmdldChpZCk7XG4gICAgICAgICAgICBpZiAoZGF0YS5hY3Rpb24gIT09ICdhY2snKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlTmFjayh7IHJlYXNvbjogJ0RpZCBub3QgcmVjZWl2ZSBhY2sgYWN0aW9uJywgZXJyb3I6ICgwLCBlcnJvcnNfMS5lcnJvclRvUE9KTykobmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5Ob0Fja0Vycm9yKGRhdGEuYWN0aW9uKSkgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghKCdwYXlsb2FkJyBpbiBkYXRhKSkge1xuICAgICAgICAgICAgICAgIC8vIEknbSBub3Qgc3VyZSB3aGVuIHRoaXMgY29kZSB3b3VsZCBhY3R1YWxseSBydW4sIGJ1dCBwYXNzaW5nIGluIHNvbWV0aGluZyB0aGF0IGRvZWVzbid0IGhhdmUgYSByZWFzb24gdG8gdGhlIHJ1bnRpbWVlcnJvciBjb25zdHJ1Y3RvciB3aWxsIG5vdCBlbmQgd2VsbC5cbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnJlYXNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFjayhkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUmVjZWl2ZWQgaW52YWxpZCByZXNwb25zZSBmcm9tIGNvcmUnLCBkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFjayh7IHJlYXNvbjogJ2ludmFsaWQgcmVzcG9uc2Ugc2hhcGUnIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFkYXRhLnBheWxvYWQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGhhbmRsZU5hY2soZGF0YS5wYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmUuY2FsbChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2lyZUxpc3RlbmVycy5kZWxldGUoaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cblRyYW5zcG9ydF8xID0gdHJhbnNwb3J0LlRyYW5zcG9ydCA9IFRyYW5zcG9ydDtcbl9UcmFuc3BvcnRfd2lyZSA9IG5ldyBXZWFrTWFwKCksIF9UcmFuc3BvcnRfZmluID0gbmV3IFdlYWtNYXAoKTtcblxudmFyIG1vY2tFbnZpcm9ubWVudCA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobW9ja0Vudmlyb25tZW50LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNb2NrRW52aXJvbm1lbnRfMSA9IG1vY2tFbnZpcm9ubWVudC5Nb2NrRW52aXJvbm1lbnQgPSB2b2lkIDA7XG5jb25zdCBtZV8xID0gbWU7XG5jbGFzcyBNb2NrRW52aXJvbm1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAnb3RoZXInO1xuICAgICAgICB0aGlzLmNoaWxkVmlld3MgPSB0cnVlO1xuICAgIH1cbiAgICBnZXRBZGFwdGVyVmVyc2lvblN5bmMoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0SW50ZXJvcEluZm8oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0RGVmYXVsdENoYW5uZWxPcHRpb25zKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGdldFJ0Y1BlZXIoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgbGF5b3V0QWxsb3dlZEluQ29udGV4dChfZmluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgaW5pdExheW91dE1hbmFnZXIoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXBwbHlMYXlvdXRTbmFwc2hvdCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBhc3luYyBjcmVhdGVMYXlvdXQoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXN5bmMgZGVzdHJveUxheW91dCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBhc3luYyByZXNvbHZlTGF5b3V0KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGluaXRQbGF0Zm9ybSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBvYnNlcnZlQm91bmRzKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIHdyaXRlVG9rZW4ocGF0aCwgdG9rZW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICByZXRyaWV2ZVBvcnQoY29uZmlnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0TmV4dE1lc3NhZ2VJZCgpIHtcbiAgICAgICAgcmV0dXJuIGBtb2NrLW1lc3NhZ2UtaWQtJHtNYXRoLnJhbmRvbSgpfWA7XG4gICAgfVxuICAgIGdldFJhbmRvbUlkKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGNyZWF0ZUNoaWxkQ29udGVudChvcHRpb25zKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0V2ViV2luZG93KGlkZW50aXR5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0Q3VycmVudEVudGl0eUlkZW50aXR5KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGdldEN1cnJlbnRFbnRpdHlUeXBlKCkge1xuICAgICAgICByZXR1cm4gJ3Vua25vd24nO1xuICAgIH1cbiAgICByYWlzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnRBcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0VXJsKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIHdoZW5SZWFkeSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBnZXRXc0NvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gICAgfVxufVxuTW9ja0Vudmlyb25tZW50XzEgPSBtb2NrRW52aXJvbm1lbnQuTW9ja0Vudmlyb25tZW50ID0gTW9ja0Vudmlyb25tZW50O1xuXG52YXIgbW9ja1dpcmUgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vY2tXaXJlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNb2NrV2lyZV8xID0gbW9ja1dpcmUuTW9ja1dpcmUgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IGV2ZW50c18xID0gcmVxdWlyZSQkMDtcbmNsYXNzIE1vY2tXaXJlIGV4dGVuZHMgZXZlbnRzXzEuRXZlbnRFbWl0dGVyIHtcbiAgICBjb25uZWN0KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IHJ1bm5pbmcgaW4gT3BlbkZpbi4nKTtcbiAgICB9XG4gICAgY29ubmVjdFN5bmMoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgcnVubmluZyBpbiBPcGVuRmluLicpO1xuICAgIH1cbiAgICBzZW5kKGRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBydW5uaW5nIGluIE9wZW5GaW4uJyk7XG4gICAgfVxuICAgIHNodXRkb3duKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IHJ1bm5pbmcgaW4gT3BlbkZpbi4nKTtcbiAgICB9XG4gICAgZ2V0UG9ydCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHRyYW5zcG9ydCBoYXMgbm8gcG9ydCcpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1jb25zdHJ1Y3RvclxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cbn1cbk1vY2tXaXJlXzEgPSBtb2NrV2lyZS5Nb2NrV2lyZSA9IE1vY2tXaXJlO1xuXG5jb25zdCBmaW4kMSA9ICgodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Py5maW4pIHx8XG4gICAgKCgpID0+IHtcbiAgICAgICAgY29uc3QgZW52aXJvbm1lbnQgPSBuZXcgTW9ja0Vudmlyb25tZW50XzEoKTtcbiAgICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydF8xKE1vY2tXaXJlXzEsIGVudmlyb25tZW50LCB7XG4gICAgICAgICAgICB1dWlkOiAnJyxcbiAgICAgICAgICAgIG5hbWU6ICcnXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IEZpbl8xKHRyYW5zcG9ydCk7XG4gICAgfSkoKSk7XG5cbmV4cG9ydHMuT3BlbkZpbiA9IE9wZW5GaW4kMTtcbmV4cG9ydHMuZGVmYXVsdCA9IE9wZW5GaW4kMTtcbmV4cG9ydHMuZmluID0gZmluJDE7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShyb290LCAnRGF0YVZpZXcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhVmlldztcbiIsInZhciBoYXNoQ2xlYXIgPSByZXF1aXJlKCcuL19oYXNoQ2xlYXInKSxcbiAgICBoYXNoRGVsZXRlID0gcmVxdWlyZSgnLi9faGFzaERlbGV0ZScpLFxuICAgIGhhc2hHZXQgPSByZXF1aXJlKCcuL19oYXNoR2V0JyksXG4gICAgaGFzaEhhcyA9IHJlcXVpcmUoJy4vX2hhc2hIYXMnKSxcbiAgICBoYXNoU2V0ID0gcmVxdWlyZSgnLi9faGFzaFNldCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBoYXNoIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gSGFzaChlbnRyaWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gIHRoaXMuY2xlYXIoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC5cbkhhc2gucHJvdG90eXBlLmNsZWFyID0gaGFzaENsZWFyO1xuSGFzaC5wcm90b3R5cGVbJ2RlbGV0ZSddID0gaGFzaERlbGV0ZTtcbkhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7XG5IYXNoLnByb3RvdHlwZS5oYXMgPSBoYXNoSGFzO1xuSGFzaC5wcm90b3R5cGUuc2V0ID0gaGFzaFNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoO1xuIiwidmFyIGxpc3RDYWNoZUNsZWFyID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlQ2xlYXInKSxcbiAgICBsaXN0Q2FjaGVEZWxldGUgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVEZWxldGUnKSxcbiAgICBsaXN0Q2FjaGVHZXQgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVHZXQnKSxcbiAgICBsaXN0Q2FjaGVIYXMgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVIYXMnKSxcbiAgICBsaXN0Q2FjaGVTZXQgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGxpc3QgY2FjaGUgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBMaXN0Q2FjaGUoZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgTGlzdENhY2hlYC5cbkxpc3RDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBsaXN0Q2FjaGVDbGVhcjtcbkxpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlO1xuTGlzdENhY2hlLnByb3RvdHlwZS5nZXQgPSBsaXN0Q2FjaGVHZXQ7XG5MaXN0Q2FjaGUucHJvdG90eXBlLmhhcyA9IGxpc3RDYWNoZUhhcztcbkxpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IExpc3RDYWNoZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgTWFwID0gZ2V0TmF0aXZlKHJvb3QsICdNYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXA7XG4iLCJ2YXIgbWFwQ2FjaGVDbGVhciA9IHJlcXVpcmUoJy4vX21hcENhY2hlQ2xlYXInKSxcbiAgICBtYXBDYWNoZURlbGV0ZSA9IHJlcXVpcmUoJy4vX21hcENhY2hlRGVsZXRlJyksXG4gICAgbWFwQ2FjaGVHZXQgPSByZXF1aXJlKCcuL19tYXBDYWNoZUdldCcpLFxuICAgIG1hcENhY2hlSGFzID0gcmVxdWlyZSgnLi9fbWFwQ2FjaGVIYXMnKSxcbiAgICBtYXBDYWNoZVNldCA9IHJlcXVpcmUoJy4vX21hcENhY2hlU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gIHRoaXMuY2xlYXIoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBNYXBDYWNoZWAuXG5NYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyO1xuTWFwQ2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IG1hcENhY2hlRGVsZXRlO1xuTWFwQ2FjaGUucHJvdG90eXBlLmdldCA9IG1hcENhY2hlR2V0O1xuTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzO1xuTWFwQ2FjaGUucHJvdG90eXBlLnNldCA9IG1hcENhY2hlU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcENhY2hlO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBQcm9taXNlID0gZ2V0TmF0aXZlKHJvb3QsICdQcm9taXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgU2V0ID0gZ2V0TmF0aXZlKHJvb3QsICdTZXQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTZXQ7XG4iLCJ2YXIgTWFwQ2FjaGUgPSByZXF1aXJlKCcuL19NYXBDYWNoZScpLFxuICAgIHNldENhY2hlQWRkID0gcmVxdWlyZSgnLi9fc2V0Q2FjaGVBZGQnKSxcbiAgICBzZXRDYWNoZUhhcyA9IHJlcXVpcmUoJy4vX3NldENhY2hlSGFzJyk7XG5cbi8qKlxuICpcbiAqIENyZWF0ZXMgYW4gYXJyYXkgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gU2V0Q2FjaGUodmFsdWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gdmFsdWVzID09IG51bGwgPyAwIDogdmFsdWVzLmxlbmd0aDtcblxuICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHRoaXMuYWRkKHZhbHVlc1tpbmRleF0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBTZXRDYWNoZWAuXG5TZXRDYWNoZS5wcm90b3R5cGUuYWRkID0gU2V0Q2FjaGUucHJvdG90eXBlLnB1c2ggPSBzZXRDYWNoZUFkZDtcblNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhcztcblxubW9kdWxlLmV4cG9ydHMgPSBTZXRDYWNoZTtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBzdGFja0NsZWFyID0gcmVxdWlyZSgnLi9fc3RhY2tDbGVhcicpLFxuICAgIHN0YWNrRGVsZXRlID0gcmVxdWlyZSgnLi9fc3RhY2tEZWxldGUnKSxcbiAgICBzdGFja0dldCA9IHJlcXVpcmUoJy4vX3N0YWNrR2V0JyksXG4gICAgc3RhY2tIYXMgPSByZXF1aXJlKCcuL19zdGFja0hhcycpLFxuICAgIHN0YWNrU2V0ID0gcmVxdWlyZSgnLi9fc3RhY2tTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gU3RhY2soZW50cmllcykge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuXG5TdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuU3RhY2sucHJvdG90eXBlWydkZWxldGUnXSA9IHN0YWNrRGVsZXRlO1xuU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0O1xuU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuU3RhY2sucHJvdG90eXBlLnNldCA9IHN0YWNrU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0YWNrO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIFN5bWJvbCA9IHJvb3QuU3ltYm9sO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN5bWJvbDtcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBVaW50OEFycmF5ID0gcm9vdC5VaW50OEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFVpbnQ4QXJyYXk7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIFdlYWtNYXAgPSBnZXROYXRpdmUocm9vdCwgJ1dlYWtNYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBXZWFrTWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RWFjaDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheUZpbHRlcihhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICByZXNJbmRleCA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUZpbHRlcjtcbiIsInZhciBiYXNlVGltZXMgPSByZXF1aXJlKCcuL19iYXNlVGltZXMnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vX2lzSW5kZXgnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGluaGVyaXRlZCBTcGVjaWZ5IHJldHVybmluZyBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VLZXlzKHZhbHVlLCBpbmhlcml0ZWQpIHtcbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICBpc0J1ZmYgPSAhaXNBcnIgJiYgIWlzQXJnICYmIGlzQnVmZmVyKHZhbHVlKSxcbiAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmICgoaW5oZXJpdGVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgIGtleSA9PSAnbGVuZ3RoJyB8fFxuICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy5cbiAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgaXNJbmRleChrZXksIGxlbmd0aClcbiAgICAgICAgKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlMaWtlS2V5cztcbiIsIi8qKlxuICogQXBwZW5kcyB0aGUgZWxlbWVudHMgb2YgYHZhbHVlc2AgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtvZmZzZXQgKyBpbmRleF0gPSB2YWx1ZXNbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVB1c2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAqIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5U29tZTtcbiIsInZhciBiYXNlQXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19iYXNlQXNzaWduVmFsdWUnKSxcbiAgICBlcSA9IHJlcXVpcmUoJy4vZXEnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBc3NpZ25zIGB2YWx1ZWAgdG8gYGtleWAgb2YgYG9iamVjdGAgaWYgdGhlIGV4aXN0aW5nIHZhbHVlIGlzIG5vdCBlcXVpdmFsZW50XG4gKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gKi9cbmZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XTtcbiAgaWYgKCEoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYgZXEob2JqVmFsdWUsIHZhbHVlKSkgfHxcbiAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NpZ25WYWx1ZTtcbiIsInZhciBlcSA9IHJlcXVpcmUoJy4vZXEnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSBrZXkgVGhlIGtleSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHtcbiAgICAgIHJldHVybiBsZW5ndGg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NvY0luZGV4T2Y7XG4iLCJ2YXIgY29weU9iamVjdCA9IHJlcXVpcmUoJy4vX2NvcHlPYmplY3QnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXNcbiAqIG9yIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25JbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnbkluKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ25JbjtcbiIsInZhciBkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2RlZmluZVByb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGFzc2lnblZhbHVlYCBhbmQgYGFzc2lnbk1lcmdlVmFsdWVgIHdpdGhvdXRcbiAqIHZhbHVlIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgPT0gJ19fcHJvdG9fXycgJiYgZGVmaW5lUHJvcGVydHkpIHtcbiAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIGtleSwge1xuICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAnZW51bWVyYWJsZSc6IHRydWUsXG4gICAgICAndmFsdWUnOiB2YWx1ZSxcbiAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFzc2lnblZhbHVlO1xuIiwidmFyIFN0YWNrID0gcmVxdWlyZSgnLi9fU3RhY2snKSxcbiAgICBhcnJheUVhY2ggPSByZXF1aXJlKCcuL19hcnJheUVhY2gnKSxcbiAgICBhc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Fzc2lnblZhbHVlJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ24nKSxcbiAgICBiYXNlQXNzaWduSW4gPSByZXF1aXJlKCcuL19iYXNlQXNzaWduSW4nKSxcbiAgICBjbG9uZUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQnVmZmVyJyksXG4gICAgY29weUFycmF5ID0gcmVxdWlyZSgnLi9fY29weUFycmF5JyksXG4gICAgY29weVN5bWJvbHMgPSByZXF1aXJlKCcuL19jb3B5U3ltYm9scycpLFxuICAgIGNvcHlTeW1ib2xzSW4gPSByZXF1aXJlKCcuL19jb3B5U3ltYm9sc0luJyksXG4gICAgZ2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2dldEFsbEtleXMnKSxcbiAgICBnZXRBbGxLZXlzSW4gPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzSW4nKSxcbiAgICBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZUFycmF5JyksXG4gICAgaW5pdENsb25lQnlUYWcgPSByZXF1aXJlKCcuL19pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc01hcCA9IHJlcXVpcmUoJy4vaXNNYXAnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKSxcbiAgICBpc1NldCA9IHJlcXVpcmUoJy4vaXNTZXQnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgY2xvbmluZy4gKi9cbnZhciBDTE9ORV9ERUVQX0ZMQUcgPSAxLFxuICAgIENMT05FX0ZMQVRfRkxBRyA9IDIsXG4gICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBzdXBwb3J0ZWQgYnkgYF8uY2xvbmVgLiAqL1xudmFyIGNsb25lYWJsZVRhZ3MgPSB7fTtcbmNsb25lYWJsZVRhZ3NbYXJnc1RhZ10gPSBjbG9uZWFibGVUYWdzW2FycmF5VGFnXSA9XG5jbG9uZWFibGVUYWdzW2FycmF5QnVmZmVyVGFnXSA9IGNsb25lYWJsZVRhZ3NbZGF0YVZpZXdUYWddID1cbmNsb25lYWJsZVRhZ3NbYm9vbFRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGVUYWddID1cbmNsb25lYWJsZVRhZ3NbZmxvYXQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID1cbmNsb25lYWJsZVRhZ3NbaW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9XG5jbG9uZWFibGVUYWdzW251bWJlclRhZ10gPSBjbG9uZWFibGVUYWdzW29iamVjdFRhZ10gPVxuY2xvbmVhYmxlVGFnc1tyZWdleHBUYWddID0gY2xvbmVhYmxlVGFnc1tzZXRUYWddID1cbmNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3ltYm9sVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgYW5kIGBfLmNsb25lRGVlcGAgd2hpY2ggdHJhY2tzXG4gKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gKiAgMSAtIERlZXAgY2xvbmVcbiAqICAyIC0gRmxhdHRlbiBpbmhlcml0ZWQgcHJvcGVydGllc1xuICogIDQgLSBDbG9uZSBzeW1ib2xzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgcGFyZW50IG9iamVjdCBvZiBgdmFsdWVgLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGFuZCB0aGVpciBjbG9uZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgb2JqZWN0LCBzdGFjaykge1xuICB2YXIgcmVzdWx0LFxuICAgICAgaXNEZWVwID0gYml0bWFzayAmIENMT05FX0RFRVBfRkxBRyxcbiAgICAgIGlzRmxhdCA9IGJpdG1hc2sgJiBDTE9ORV9GTEFUX0ZMQUcsXG4gICAgICBpc0Z1bGwgPSBiaXRtYXNrICYgQ0xPTkVfU1lNQk9MU19GTEFHO1xuXG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QsIHN0YWNrKSA6IGN1c3RvbWl6ZXIodmFsdWUpO1xuICB9XG4gIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSk7XG4gIGlmIChpc0Fycikge1xuICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgcmV0dXJuIGNvcHlBcnJheSh2YWx1ZSwgcmVzdWx0KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHRhZyA9IGdldFRhZyh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7XG5cbiAgICBpZiAoaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY2xvbmVCdWZmZXIodmFsdWUsIGlzRGVlcCk7XG4gICAgfVxuICAgIGlmICh0YWcgPT0gb2JqZWN0VGFnIHx8IHRhZyA9PSBhcmdzVGFnIHx8IChpc0Z1bmMgJiYgIW9iamVjdCkpIHtcbiAgICAgIHJlc3VsdCA9IChpc0ZsYXQgfHwgaXNGdW5jKSA/IHt9IDogaW5pdENsb25lT2JqZWN0KHZhbHVlKTtcbiAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgIHJldHVybiBpc0ZsYXRcbiAgICAgICAgICA/IGNvcHlTeW1ib2xzSW4odmFsdWUsIGJhc2VBc3NpZ25JbihyZXN1bHQsIHZhbHVlKSlcbiAgICAgICAgICA6IGNvcHlTeW1ib2xzKHZhbHVlLCBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjbG9uZWFibGVUYWdzW3RhZ10pIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBpc0RlZXApO1xuICAgIH1cbiAgfVxuICAvLyBDaGVjayBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyBhbmQgcmV0dXJuIGl0cyBjb3JyZXNwb25kaW5nIGNsb25lLlxuICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldCh2YWx1ZSk7XG4gIGlmIChzdGFja2VkKSB7XG4gICAgcmV0dXJuIHN0YWNrZWQ7XG4gIH1cbiAgc3RhY2suc2V0KHZhbHVlLCByZXN1bHQpO1xuXG4gIGlmIChpc1NldCh2YWx1ZSkpIHtcbiAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlKSB7XG4gICAgICByZXN1bHQuYWRkKGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3ViVmFsdWUsIHZhbHVlLCBzdGFjaykpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGlzTWFwKHZhbHVlKSkge1xuICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0LnNldChrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBrZXlzRnVuYyA9IGlzRnVsbFxuICAgID8gKGlzRmxhdCA/IGdldEFsbEtleXNJbiA6IGdldEFsbEtleXMpXG4gICAgOiAoaXNGbGF0ID8ga2V5c0luIDoga2V5cyk7XG5cbiAgdmFyIHByb3BzID0gaXNBcnIgPyB1bmRlZmluZWQgOiBrZXlzRnVuYyh2YWx1ZSk7XG4gIGFycmF5RWFjaChwcm9wcyB8fCB2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIGlmIChwcm9wcykge1xuICAgICAga2V5ID0gc3ViVmFsdWU7XG4gICAgICBzdWJWYWx1ZSA9IHZhbHVlW2tleV07XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IHBvcHVsYXRlIGNsb25lIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgYXNzaWduVmFsdWUocmVzdWx0LCBrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNsb25lO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAqIHByb3BlcnRpZXMgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdG8gVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgaWYgKCFpc09iamVjdChwcm90bykpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgaWYgKG9iamVjdENyZWF0ZSkge1xuICAgICAgcmV0dXJuIG9iamVjdENyZWF0ZShwcm90byk7XG4gICAgfVxuICAgIG9iamVjdC5wcm90b3R5cGUgPSBwcm90bztcbiAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDcmVhdGU7XG4iLCJ2YXIgYXJyYXlQdXNoID0gcmVxdWlyZSgnLi9fYXJyYXlQdXNoJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlc1xuICogYGtleXNGdW5jYCBhbmQgYHN5bWJvbHNGdW5jYCB0byBnZXQgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3ltYm9sc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0Z1bmMsIHN5bWJvbHNGdW5jKSB7XG4gIHZhciByZXN1bHQgPSBrZXlzRnVuYyhvYmplY3QpO1xuICByZXR1cm4gaXNBcnJheShvYmplY3QpID8gcmVzdWx0IDogYXJyYXlQdXNoKHJlc3VsdCwgc3ltYm9sc0Z1bmMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldEFsbEtleXM7XG4iLCJ2YXIgU3ltYm9sID0gcmVxdWlyZSgnLi9fU3ltYm9sJyksXG4gICAgZ2V0UmF3VGFnID0gcmVxdWlyZSgnLi9fZ2V0UmF3VGFnJyksXG4gICAgb2JqZWN0VG9TdHJpbmcgPSByZXF1aXJlKCcuL19vYmplY3RUb1N0cmluZycpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJyxcbiAgICB1bmRlZmluZWRUYWcgPSAnW29iamVjdCBVbmRlZmluZWRdJztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICovXG5mdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWRUYWcgOiBudWxsVGFnO1xuICB9XG4gIHJldHVybiAoc3ltVG9TdHJpbmdUYWcgJiYgc3ltVG9TdHJpbmdUYWcgaW4gT2JqZWN0KHZhbHVlKSlcbiAgICA/IGdldFJhd1RhZyh2YWx1ZSlcbiAgICA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0VGFnO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LFxuICovXG5mdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNBcmd1bWVudHM7XG4iLCJ2YXIgYmFzZUlzRXF1YWxEZWVwID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gKiBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAqICAxIC0gVW5vcmRlcmVkIGNvbXBhcmlzb25cbiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gIH1cbiAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzRXF1YWw7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9fZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9fZXF1YWxCeVRhZycpLFxuICAgIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vX2VxdWFsT2JqZWN0cycpLFxuICAgIGdldFRhZyA9IHJlcXVpcmUoJy4vX2dldFRhZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyA9IDE7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZztcbiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihvdGhlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgb2JqSXNBcnIgPSB0cnVlO1xuICAgIG9iaklzT2JqID0gZmFsc2U7XG4gIH1cbiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHtcbiAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICA/IGVxdWFsQXJyYXlzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spXG4gICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgfVxuICBpZiAoIShiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcpKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgZ2V0VGFnID0gcmVxdWlyZSgnLi9fZ2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWFwYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXAodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBtYXBUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzTWFwO1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc01hc2tlZCA9IHJlcXVpcmUoJy4vX2lzTWFza2VkJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgdG9Tb3VyY2UgPSByZXF1aXJlKCcuL190b1NvdXJjZScpO1xuXG4vKipcbiAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGBcbiAqIFtzeW50YXggY2hhcmFjdGVyc10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcGF0dGVybnMpLlxuICovXG52YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZSxcbiAgICBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmdW5jVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSkucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXFxcJCYnKVxuICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbik7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYXRpdmVgIHdpdGhvdXQgYmFkIHNoaW0gY2hlY2tzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICghaXNPYmplY3QodmFsdWUpIHx8IGlzTWFza2VkKHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgcGF0dGVybiA9IGlzRnVuY3Rpb24odmFsdWUpID8gcmVJc05hdGl2ZSA6IHJlSXNIb3N0Q3RvcjtcbiAgcmV0dXJuIHBhdHRlcm4udGVzdCh0b1NvdXJjZSh2YWx1ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc05hdGl2ZTtcbiIsInZhciBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNTZXRgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc2V0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc1NldCh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBnZXRUYWcodmFsdWUpID09IHNldFRhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNTZXQ7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxudHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxudHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzVHlwZWRBcnJheTtcbiIsInZhciBpc1Byb3RvdHlwZSA9IHJlcXVpcmUoJy4vX2lzUHJvdG90eXBlJyksXG4gICAgbmF0aXZlS2V5cyA9IHJlcXVpcmUoJy4vX25hdGl2ZUtleXMnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VLZXlzKG9iamVjdCkge1xuICBpZiAoIWlzUHJvdG90eXBlKG9iamVjdCkpIHtcbiAgICByZXR1cm4gbmF0aXZlS2V5cyhvYmplY3QpO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VLZXlzO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBuYXRpdmVLZXlzSW4gPSByZXF1aXJlKCcuL19uYXRpdmVLZXlzSW4nKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzSW5gIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gYmFzZUtleXNJbihvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIG5hdGl2ZUtleXNJbihvYmplY3QpO1xuICB9XG4gIHZhciBpc1Byb3RvID0gaXNQcm90b3R5cGUob2JqZWN0KSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlS2V5c0luO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50aW1lc2Agd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzXG4gKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUaW1lcyhuLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KG4pO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbikge1xuICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVGltZXM7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuYXJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0b3JpbmcgbWV0YWRhdGEuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlVW5hcnkoZnVuYykge1xuICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVVuYXJ5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gY2FjaGVIYXMoY2FjaGUsIGtleSkge1xuICByZXR1cm4gY2FjaGUuaGFzKGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FjaGVIYXM7XG4iLCJ2YXIgVWludDhBcnJheSA9IHJlcXVpcmUoJy4vX1VpbnQ4QXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYGFycmF5QnVmZmVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYXJyYXlCdWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gY2xvbmVBcnJheUJ1ZmZlcihhcnJheUJ1ZmZlcikge1xuICB2YXIgcmVzdWx0ID0gbmV3IGFycmF5QnVmZmVyLmNvbnN0cnVjdG9yKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpO1xuICBuZXcgVWludDhBcnJheShyZXN1bHQpLnNldChuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lQXJyYXlCdWZmZXI7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbnZhciBmcmVlRXhwb3J0cyA9IHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqL1xudmFyIGZyZWVNb2R1bGUgPSBmcmVlRXhwb3J0cyAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcblxuLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbnZhciBtb2R1bGVFeHBvcnRzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBCdWZmZXIgPSBtb2R1bGVFeHBvcnRzID8gcm9vdC5CdWZmZXIgOiB1bmRlZmluZWQsXG4gICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mICBgYnVmZmVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBUaGUgYnVmZmVyIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIGNsb25lQnVmZmVyKGJ1ZmZlciwgaXNEZWVwKSB7XG4gIGlmIChpc0RlZXApIHtcbiAgICByZXR1cm4gYnVmZmVyLnNsaWNlKCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IGJ1ZmZlci5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBhbGxvY1Vuc2FmZSA/IGFsbG9jVW5zYWZlKGxlbmd0aCkgOiBuZXcgYnVmZmVyLmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgYnVmZmVyLmNvcHkocmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZUJ1ZmZlcjtcbiIsInZhciBjbG9uZUFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fY2xvbmVBcnJheUJ1ZmZlcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgZGF0YVZpZXdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVZpZXcgVGhlIGRhdGEgdmlldyB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgZGF0YSB2aWV3LlxuICovXG5mdW5jdGlvbiBjbG9uZURhdGFWaWV3KGRhdGFWaWV3LCBpc0RlZXApIHtcbiAgdmFyIGJ1ZmZlciA9IGlzRGVlcCA/IGNsb25lQXJyYXlCdWZmZXIoZGF0YVZpZXcuYnVmZmVyKSA6IGRhdGFWaWV3LmJ1ZmZlcjtcbiAgcmV0dXJuIG5ldyBkYXRhVmlldy5jb25zdHJ1Y3RvcihidWZmZXIsIGRhdGFWaWV3LmJ5dGVPZmZzZXQsIGRhdGFWaWV3LmJ5dGVMZW5ndGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lRGF0YVZpZXc7XG4iLCIvKiogVXNlZCB0byBtYXRjaCBgUmVnRXhwYCBmbGFncyBmcm9tIHRoZWlyIGNvZXJjZWQgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUZsYWdzID0gL1xcdyokLztcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHJlZ2V4cGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSByZWdleHAgVGhlIHJlZ2V4cCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCByZWdleHAuXG4gKi9cbmZ1bmN0aW9uIGNsb25lUmVnRXhwKHJlZ2V4cCkge1xuICB2YXIgcmVzdWx0ID0gbmV3IHJlZ2V4cC5jb25zdHJ1Y3RvcihyZWdleHAuc291cmNlLCByZUZsYWdzLmV4ZWMocmVnZXhwKSk7XG4gIHJlc3VsdC5sYXN0SW5kZXggPSByZWdleHAubGFzdEluZGV4O1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lUmVnRXhwO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBzeW1ib2wgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgcmV0dXJuIHN5bWJvbFZhbHVlT2YgPyBPYmplY3Qoc3ltYm9sVmFsdWVPZi5jYWxsKHN5bWJvbCkpIDoge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVTeW1ib2w7XG4iLCJ2YXIgY2xvbmVBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQXJyYXlCdWZmZXInKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHR5cGVkQXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gdHlwZWRBcnJheSBUaGUgdHlwZWQgYXJyYXkgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHR5cGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKHR5cGVkQXJyYXkuYnVmZmVyKSA6IHR5cGVkQXJyYXkuYnVmZmVyO1xuICByZXR1cm4gbmV3IHR5cGVkQXJyYXkuY29uc3RydWN0b3IoYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkubGVuZ3RoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZVR5cGVkQXJyYXk7XG4iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5QXJyYXk7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGJhc2VBc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ25WYWx1ZScpO1xuXG4vKipcbiAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICA/IGN1c3RvbWl6ZXIob2JqZWN0W2tleV0sIHNvdXJjZVtrZXldLCBrZXksIG9iamVjdCwgc291cmNlKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbmV3VmFsdWUgPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gICAgaWYgKGlzTmV3KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5T2JqZWN0O1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKTtcblxuLyoqXG4gKiBDb3BpZXMgb3duIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlTeW1ib2xzKHNvdXJjZSwgb2JqZWN0KSB7XG4gIHJldHVybiBjb3B5T2JqZWN0KHNvdXJjZSwgZ2V0U3ltYm9scyhzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvcHlTeW1ib2xzO1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgZ2V0U3ltYm9sc0luID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9sc0luJyk7XG5cbi8qKlxuICogQ29waWVzIG93biBhbmQgaW5oZXJpdGVkIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlTeW1ib2xzSW4oc291cmNlLCBvYmplY3QpIHtcbiAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzSW4oc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5U3ltYm9sc0luO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbnZhciBjb3JlSnNEYXRhID0gcm9vdFsnX19jb3JlLWpzX3NoYXJlZF9fJ107XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZUpzRGF0YTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgZnVuYyh7fSwgJycsIHt9KTtcbiAgICByZXR1cm4gZnVuYztcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydHk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vX2FycmF5U29tZScpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYGFycmF5YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcsXG4gICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLlxuICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gIH1cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgc2VlbiA9IChiaXRtYXNrICYgQ09NUEFSRV9VTk9SREVSRURfRkxBRykgPyBuZXcgU2V0Q2FjaGUgOiB1bmRlZmluZWQ7XG5cbiAgc3RhY2suc2V0KGFycmF5LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdO1xuXG4gICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIGFyclZhbHVlLCBpbmRleCwgb3RoZXIsIGFycmF5LCBzdGFjaylcbiAgICAgICAgOiBjdXN0b21pemVyKGFyclZhbHVlLCBvdGhWYWx1ZSwgaW5kZXgsIGFycmF5LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNvbXBhcmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoc2Vlbikge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlLCBvdGhJbmRleCkge1xuICAgICAgICAgICAgaWYgKCFjYWNoZUhhcyhzZWVuLCBvdGhJbmRleCkgJiZcbiAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShcbiAgICAgICAgICBhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHxcbiAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICApKSB7XG4gICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpLFxuICAgIFVpbnQ4QXJyYXkgPSByZXF1aXJlKCcuL19VaW50OEFycmF5JyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyksXG4gICAgZXF1YWxBcnJheXMgPSByZXF1aXJlKCcuL19lcXVhbEFycmF5cycpLFxuICAgIG1hcFRvQXJyYXkgPSByZXF1aXJlKCcuL19tYXBUb0FycmF5JyksXG4gICAgc2V0VG9BcnJheSA9IHJlcXVpcmUoJy4vX3NldFRvQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqL1xudmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgKG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IG9iamVjdC5idWZmZXI7XG4gICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjtcblxuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgIWVxdWFsRnVuYyhuZXcgVWludDhBcnJheShvYmplY3QpLCBuZXcgVWludDhBcnJheShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLlxuICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncywgcHJpbWl0aXZlcyBhbmQgb2JqZWN0cyxcbiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmdcbiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcblxuICAgIGNhc2UgbWFwVGFnOlxuICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHO1xuICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIGlmIChzeW1ib2xWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpO1xuICAgICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGdldEFsbEtleXMgPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xudmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgIG9ialByb3BzID0gZ2V0QWxsS2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzUGFydGlhbCA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIHZhciBvYmpTdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBvYmpTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gb2JqZWN0O1xuICB9XG4gIHZhciByZXN1bHQgPSB0cnVlO1xuICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTtcblxuICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICkpIHtcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAocmVzdWx0ICYmICFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsIi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZUdsb2JhbDtcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0QWxsS2V5cztcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9sc0luID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9sc0luJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICovXG5mdW5jdGlvbiBnZXRBbGxLZXlzSW4ob2JqZWN0KSB7XG4gIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNJbiwgZ2V0U3ltYm9sc0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRBbGxLZXlzSW47XG4iLCJ2YXIgaXNLZXlhYmxlID0gcmVxdWlyZSgnLi9faXNLZXlhYmxlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187XG4gIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgOiBkYXRhLm1hcDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXBEYXRhO1xuIiwidmFyIGJhc2VJc05hdGl2ZSA9IHJlcXVpcmUoJy4vX2Jhc2VJc05hdGl2ZScpLFxuICAgIGdldFZhbHVlID0gcmVxdWlyZSgnLi9fZ2V0VmFsdWUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG4iLCJ2YXIgb3ZlckFyZyA9IHJlcXVpcmUoJy4vX292ZXJBcmcnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgZ2V0UHJvdG90eXBlID0gb3ZlckFyZyhPYmplY3QuZ2V0UHJvdG90eXBlT2YsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UHJvdG90eXBlO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC5cbiAqL1xuZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gIHZhciBpc093biA9IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHN5bVRvU3RyaW5nVGFnKSxcbiAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICB0cnkge1xuICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHVuZGVmaW5lZDtcbiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIHZhciByZXN1bHQgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgaWYgKHVubWFza2VkKSB7XG4gICAgaWYgKGlzT3duKSB7XG4gICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB0YWc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UmF3VGFnO1xuIiwidmFyIGFycmF5RmlsdGVyID0gcmVxdWlyZSgnLi9fYXJyYXlGaWx0ZXInKSxcbiAgICBzdHViQXJyYXkgPSByZXF1aXJlKCcuL3N0dWJBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLlxuICovXG52YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9scztcbiIsInZhciBhcnJheVB1c2ggPSByZXF1aXJlKCcuL19hcnJheVB1c2gnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBnZXRTeW1ib2xzID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9scycpLFxuICAgIHN0dWJBcnJheSA9IHJlcXVpcmUoJy4vc3R1YkFycmF5Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVHZXRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAqL1xudmFyIGdldFN5bWJvbHNJbiA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgd2hpbGUgKG9iamVjdCkge1xuICAgIGFycmF5UHVzaChyZXN1bHQsIGdldFN5bWJvbHMob2JqZWN0KSk7XG4gICAgb2JqZWN0ID0gZ2V0UHJvdG90eXBlKG9iamVjdCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9sc0luO1xuIiwidmFyIERhdGFWaWV3ID0gcmVxdWlyZSgnLi9fRGF0YVZpZXcnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBQcm9taXNlID0gcmVxdWlyZSgnLi9fUHJvbWlzZScpLFxuICAgIFNldCA9IHJlcXVpcmUoJy4vX1NldCcpLFxuICAgIFdlYWtNYXAgPSByZXF1aXJlKCcuL19XZWFrTWFwJyksXG4gICAgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICB0b1NvdXJjZSA9IHJlcXVpcmUoJy4vX3RvU291cmNlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICBwcm9taXNlVGFnID0gJ1tvYmplY3QgUHJvbWlzZV0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBtYXBzLCBzZXRzLCBhbmQgd2Vha21hcHMuICovXG52YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXcpLFxuICAgIG1hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShNYXApLFxuICAgIHByb21pc2VDdG9yU3RyaW5nID0gdG9Tb3VyY2UoUHJvbWlzZSksXG4gICAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCksXG4gICAgd2Vha01hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShXZWFrTWFwKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC5cbiAqL1xudmFyIGdldFRhZyA9IGJhc2VHZXRUYWc7XG5cbi8vIEZhbGxiYWNrIGZvciBkYXRhIHZpZXdzLCBtYXBzLCBzZXRzLCBhbmQgd2VhayBtYXBzIGluIElFIDExIGFuZCBwcm9taXNlcyBpbiBOb2RlLmpzIDwgNi5cbmlmICgoRGF0YVZpZXcgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoMSkpKSAhPSBkYXRhVmlld1RhZykgfHxcbiAgICAoTWFwICYmIGdldFRhZyhuZXcgTWFwKSAhPSBtYXBUYWcpIHx8XG4gICAgKFByb21pc2UgJiYgZ2V0VGFnKFByb21pc2UucmVzb2x2ZSgpKSAhPSBwcm9taXNlVGFnKSB8fFxuICAgIChTZXQgJiYgZ2V0VGFnKG5ldyBTZXQpICE9IHNldFRhZykgfHxcbiAgICAoV2Vha01hcCAmJiBnZXRUYWcobmV3IFdlYWtNYXApICE9IHdlYWtNYXBUYWcpKSB7XG4gIGdldFRhZyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLFxuICAgICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICBjdG9yU3RyaW5nID0gQ3RvciA/IHRvU291cmNlKEN0b3IpIDogJyc7XG5cbiAgICBpZiAoY3RvclN0cmluZykge1xuICAgICAgc3dpdGNoIChjdG9yU3RyaW5nKSB7XG4gICAgICAgIGNhc2UgZGF0YVZpZXdDdG9yU3RyaW5nOiByZXR1cm4gZGF0YVZpZXdUYWc7XG4gICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzogcmV0dXJuIG1hcFRhZztcbiAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzogcmV0dXJuIHByb21pc2VUYWc7XG4gICAgICAgIGNhc2Ugc2V0Q3RvclN0cmluZzogcmV0dXJuIHNldFRhZztcbiAgICAgICAgY2FzZSB3ZWFrTWFwQ3RvclN0cmluZzogcmV0dXJuIHdlYWtNYXBUYWc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0VGFnO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0VmFsdWUob2JqZWN0LCBrZXkpIHtcbiAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0VmFsdWU7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKi9cbmZ1bmN0aW9uIGhhc2hDbGVhcigpIHtcbiAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9O1xuICB0aGlzLnNpemUgPSAwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hDbGVhcjtcbiIsIi8qKlxuICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGhhc2guXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIFRoZSBoYXNoIHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBoYXNoRGVsZXRlKGtleSkge1xuICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaERlbGV0ZTtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqL1xudmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEdldHMgdGhlIGhhc2ggdmFsdWUgZm9yIGBrZXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBnZXRcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gaGFzaEdldChrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAobmF0aXZlQ3JlYXRlKSB7XG4gICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSBIQVNIX1VOREVGSU5FRCA/IHVuZGVmaW5lZCA6IHJlc3VsdDtcbiAgfVxuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpID8gZGF0YVtrZXldIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hHZXQ7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgaGFzaCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gKGRhdGFba2V5XSAhPT0gdW5kZWZpbmVkKSA6IGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoSGFzO1xuIiwidmFyIG5hdGl2ZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX25hdGl2ZUNyZWF0ZScpO1xuXG4vKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKlxuICogU2V0cyB0aGUgaGFzaCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIGhhc2hTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7XG4gIGRhdGFba2V5XSA9IChuYXRpdmVDcmVhdGUgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkgPyBIQVNIX1VOREVGSU5FRCA6IHZhbHVlO1xuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoU2V0O1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IG5ldyBhcnJheS5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gIC8vIEFkZCBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgcmVzdWx0LmluZGV4ID0gYXJyYXkuaW5kZXg7XG4gICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVBcnJheTtcbiIsInZhciBjbG9uZUFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fY2xvbmVBcnJheUJ1ZmZlcicpLFxuICAgIGNsb25lRGF0YVZpZXcgPSByZXF1aXJlKCcuL19jbG9uZURhdGFWaWV3JyksXG4gICAgY2xvbmVSZWdFeHAgPSByZXF1aXJlKCcuL19jbG9uZVJlZ0V4cCcpLFxuICAgIGNsb25lU3ltYm9sID0gcmVxdWlyZSgnLi9fY2xvbmVTeW1ib2wnKSxcbiAgICBjbG9uZVR5cGVkQXJyYXkgPSByZXF1aXJlKCcuL19jbG9uZVR5cGVkQXJyYXknKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY2xvbmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE1hcGAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgYFNldGAsIG9yIGBTdHJpbmdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUJ5VGFnKG9iamVjdCwgdGFnLCBpc0RlZXApIHtcbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBhcnJheUJ1ZmZlclRhZzpcbiAgICAgIHJldHVybiBjbG9uZUFycmF5QnVmZmVyKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgIHJldHVybiBjbG9uZURhdGFWaWV3KG9iamVjdCwgaXNEZWVwKTtcblxuICAgIGNhc2UgZmxvYXQzMlRhZzogY2FzZSBmbG9hdDY0VGFnOlxuICAgIGNhc2UgaW50OFRhZzogY2FzZSBpbnQxNlRhZzogY2FzZSBpbnQzMlRhZzpcbiAgICBjYXNlIHVpbnQ4VGFnOiBjYXNlIHVpbnQ4Q2xhbXBlZFRhZzogY2FzZSB1aW50MTZUYWc6IGNhc2UgdWludDMyVGFnOlxuICAgICAgcmV0dXJuIGNsb25lVHlwZWRBcnJheShvYmplY3QsIGlzRGVlcCk7XG5cbiAgICBjYXNlIG1hcFRhZzpcbiAgICAgIHJldHVybiBuZXcgQ3RvcjtcblxuICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKG9iamVjdCk7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVJlZ0V4cChvYmplY3QpO1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVN5bWJvbChvYmplY3QpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX2Jhc2VDcmVhdGUnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBpc1Byb3RvdHlwZSA9IHJlcXVpcmUoJy4vX2lzUHJvdG90eXBlJyk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNQcm90b3R5cGUob2JqZWN0KSlcbiAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpXG4gICAgOiB7fTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCIvKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAodHlwZSA9PSAnbnVtYmVyJyB8fFxuICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAodHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicpXG4gICAgPyAodmFsdWUgIT09ICdfX3Byb3RvX18nKVxuICAgIDogKHZhbHVlID09PSBudWxsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleWFibGU7XG4iLCJ2YXIgY29yZUpzRGF0YSA9IHJlcXVpcmUoJy4vX2NvcmVKc0RhdGEnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbnZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhICYmIGNvcmVKc0RhdGEua2V5cyAmJiBjb3JlSnNEYXRhLmtleXMuSUVfUFJPVE8gfHwgJycpO1xuICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG59KCkpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc01hc2tlZDtcbiIsIi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgcHJvdG8gPSAodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG5cbiAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1Byb3RvdHlwZTtcbiIsIi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gIHRoaXMuX19kYXRhX18gPSBbXTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVDbGVhcjtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBkZWxldGVcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgZGF0YS5wb3AoKTtcbiAgfSBlbHNlIHtcbiAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gIH1cbiAgLS10aGlzLnNpemU7XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZURlbGV0ZTtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZ2V0XG4gKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVHZXQ7XG4iLCJ2YXIgYXNzb2NJbmRleE9mID0gcmVxdWlyZSgnLi9fYXNzb2NJbmRleE9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZUhhcztcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIExpc3RDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICArK3RoaXMuc2l6ZTtcbiAgICBkYXRhLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSBlbHNlIHtcbiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZVNldDtcbiIsInZhciBIYXNoID0gcmVxdWlyZSgnLi9fSGFzaCcpLFxuICAgIExpc3RDYWNoZSA9IHJlcXVpcmUoJy4vX0xpc3RDYWNoZScpLFxuICAgIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpO1xuXG4vKipcbiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICB0aGlzLnNpemUgPSAwO1xuICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgJ21hcCc6IG5ldyAoTWFwIHx8IExpc3RDYWNoZSksXG4gICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVDbGVhcjtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZURlbGV0ZTtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7XG4gIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVHZXQ7XG4iLCJ2YXIgZ2V0TWFwRGF0YSA9IHJlcXVpcmUoJy4vX2dldE1hcERhdGEnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgaGFzXG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZUhhcztcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFNldHMgdGhlIG1hcCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIG1hcENhY2hlU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVTZXQ7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gKi9cbmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcFRvQXJyYXk7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBuYXRpdmVDcmVhdGUgPSBnZXROYXRpdmUoT2JqZWN0LCAnY3JlYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlQ3JlYXRlO1xuIiwidmFyIG92ZXJBcmcgPSByZXF1aXJlKCcuL19vdmVyQXJnJyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVLZXlzID0gb3ZlckFyZyhPYmplY3Qua2V5cywgT2JqZWN0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXRpdmVLZXlzO1xuIiwiLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2VcbiAqIFtgT2JqZWN0LmtleXNgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGV4Y2VwdCB0aGF0IGl0IGluY2x1ZGVzIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIG5hdGl2ZUtleXNJbihvYmplY3QpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBpZiAob2JqZWN0ICE9IG51bGwpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlS2V5c0luO1xuIiwidmFyIGZyZWVHbG9iYWwgPSByZXF1aXJlKCcuL19mcmVlR2xvYmFsJyk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG52YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovXG52YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBwcm9jZXNzYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZVByb2Nlc3MgPSBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwucHJvY2VzcztcblxuLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovXG52YXIgbm9kZVV0aWwgPSAoZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuXG4gICAgdmFyIHR5cGVzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlKCd1dGlsJykudHlwZXM7XG5cbiAgICBpZiAodHlwZXMpIHtcbiAgICAgIHJldHVybiB0eXBlcztcbiAgICB9XG5cbiAgICAvLyBMZWdhY3kgYHByb2Nlc3MuYmluZGluZygndXRpbCcpYCBmb3IgTm9kZS5qcyA8IDEwLlxuICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTtcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gbm9kZVV0aWw7XG4iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvYmplY3RUb1N0cmluZztcbiIsIi8qKlxuICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkge1xuICByZXR1cm4gZnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIGZ1bmModHJhbnNmb3JtKGFyZykpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG92ZXJBcmc7XG4iLCJ2YXIgZnJlZUdsb2JhbCA9IHJlcXVpcmUoJy4vX2ZyZWVHbG9iYWwnKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbnZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmO1xuXG4vKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbnZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJvb3Q7XG4iLCIvKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKlxuICogQWRkcyBgdmFsdWVgIHRvIHRoZSBhcnJheSBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgYWRkXG4gKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAqIEBhbGlhcyBwdXNoXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjYWNoZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBzZXRDYWNoZUFkZCh2YWx1ZSkge1xuICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpO1xuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRDYWNoZUFkZDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTZXRDYWNoZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRDYWNoZUhhcztcbiIsIi8qKlxuICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0VG9BcnJheTtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBTdGFja1xuICovXG5mdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0NsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrRGVsZXRlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrR2V0O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTdGFja1xuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0hhcztcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xudmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbi8qKlxuICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187XG4gICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpO1xuICB9XG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrU2V0O1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZ1bmNUb1N0cmluZyA9IGZ1bmNQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc291cmNlIGNvZGUuXG4gKi9cbmZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHtcbiAgaWYgKGZ1bmMgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZnVuY1RvU3RyaW5nLmNhbGwoZnVuYyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIChmdW5jICsgJycpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvU291cmNlO1xuIiwidmFyIGJhc2VDbG9uZSA9IHJlcXVpcmUoJy4vX2Jhc2VDbG9uZScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBjbG9uaW5nLiAqL1xudmFyIENMT05FX0RFRVBfRkxBRyA9IDEsXG4gICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBjbG9uZXMgYHZhbHVlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmVjdXJzaXZlbHkgY2xvbmUuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gKiBAc2VlIF8uY2xvbmVcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbeyAnYSc6IDEgfSwgeyAnYic6IDIgfV07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAqIGNvbnNvbGUubG9nKGRlZXBbMF0gPT09IG9iamVjdHNbMF0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gY2xvbmVEZWVwKHZhbHVlKSB7XG4gIHJldHVybiBiYXNlQ2xvbmUodmFsdWUsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVEZWVwO1xuIiwiLyoqXG4gKiBQZXJmb3JtcyBhXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGVxdWl2YWxlbnQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9O1xuICpcbiAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoJ2EnLCAnYScpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoTmFOLCBOYU4pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBvdGhlciB8fCAodmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXE7XG4iLCJ2YXIgYmFzZUlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9fYmFzZUlzQXJndW1lbnRzJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQXJndW1lbnRzID0gYmFzZUlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID8gYmFzZUlzQXJndW1lbnRzIDogZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwodmFsdWUsICdjYWxsZWUnKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzXG4gKiBub3QgYSBmdW5jdGlvbiBhbmQgaGFzIGEgYHZhbHVlLmxlbmd0aGAgdGhhdCdzIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIG9yXG4gKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZSgnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhaXNGdW5jdGlvbih2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKSxcbiAgICBzdHViRmFsc2UgPSByZXF1aXJlKCcuL3N0dWJGYWxzZScpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG52YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4vKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xudmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMgPyByb290LkJ1ZmZlciA6IHVuZGVmaW5lZDtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4zLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNCdWZmZXIobmV3IEJ1ZmZlcigyKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0J1ZmZlcihuZXcgVWludDhBcnJheSgyKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNCdWZmZXIgPSBuYXRpdmVJc0J1ZmZlciB8fCBzdHViRmFsc2U7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNCdWZmZXI7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL19iYXNlSXNFcXVhbCcpO1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmVcbiAqIGVxdWl2YWxlbnQuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGNvbXBhcmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLFxuICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICogc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkIGFycmF5cy4gYE9iamVjdGAgb2JqZWN0cyBhcmUgY29tcGFyZWRcbiAqIGJ5IHRoZWlyIG93biwgbm90IGluaGVyaXRlZCwgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLiBGdW5jdGlvbnMgYW5kIERPTVxuICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEgfTtcbiAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gKlxuICogXy5pc0VxdWFsKG9iamVjdCwgb3RoZXIpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIG9iamVjdCA9PT0gb3RoZXI7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VxdWFsKHZhbHVlLCBvdGhlcikge1xuICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VxdWFsO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIHByb3h5VGFnID0gJ1tvYmplY3QgUHJveHldJztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oXyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0Z1bmN0aW9uKC9hYmMvKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIFNhZmFyaSA5IHdoaWNoIHJldHVybnMgJ29iamVjdCcgZm9yIHR5cGVkIGFycmF5cyBhbmQgb3RoZXIgY29uc3RydWN0b3JzLlxuICB2YXIgdGFnID0gYmFzZUdldFRhZyh2YWx1ZSk7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsIi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0xlbmd0aCgzKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzTGVuZ3RoKEluZmluaXR5KTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aCgnMycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsInZhciBiYXNlSXNNYXAgPSByZXF1aXJlKCcuL19iYXNlSXNNYXAnKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzTWFwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNNYXA7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBNYXBgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMy4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTWFwKG5ldyBNYXApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNNYXAobmV3IFdlYWtNYXApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzTWFwID0gbm9kZUlzTWFwID8gYmFzZVVuYXJ5KG5vZGVJc01hcCkgOiBiYXNlSXNNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNNYXA7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0TGlrZTtcbiIsInZhciBiYXNlSXNTZXQgPSByZXF1aXJlKCcuL19iYXNlSXNTZXQnKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzU2V0ID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNTZXQ7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMy4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNldCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU2V0KG5ldyBTZXQpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTZXQobmV3IFdlYWtTZXQpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzU2V0ID0gbm9kZUlzU2V0ID8gYmFzZVVuYXJ5KG5vZGVJc1NldCkgOiBiYXNlSXNTZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTZXQ7XG4iLCJ2YXIgYmFzZUlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vX2Jhc2VJc1R5cGVkQXJyYXknKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVHlwZWRBcnJheTtcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzID0gcmVxdWlyZSgnLi9fYmFzZUtleXMnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy5rZXlzKCdoaScpO1xuICogLy8gPT4gWycwJywgJzEnXVxuICovXG5mdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5cztcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzSW4gPSByZXF1aXJlKCcuL19iYXNlS2V5c0luJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDMuMC4wXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXNJbihuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJywgJ2MnXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBrZXlzSW4ob2JqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5TGlrZShvYmplY3QpID8gYXJyYXlMaWtlS2V5cyhvYmplY3QsIHRydWUpIDogYmFzZUtleXNJbihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBhcnJheS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMTMuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgYXJyYXlzID0gXy50aW1lcygyLCBfLnN0dWJBcnJheSk7XG4gKlxuICogY29uc29sZS5sb2coYXJyYXlzKTtcbiAqIC8vID0+IFtbXSwgW11dXG4gKlxuICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gc3R1YkFycmF5KCkge1xuICByZXR1cm4gW107XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3R1YkFycmF5O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEzLjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRpbWVzKDIsIF8uc3R1YkZhbHNlKTtcbiAqIC8vID0+IFtmYWxzZSwgZmFsc2VdXG4gKi9cbmZ1bmN0aW9uIHN0dWJGYWxzZSgpIHtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0dWJGYWxzZTtcbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0aWQ6IG1vZHVsZUlkLFxuXHRcdGxvYWRlZDogZmFsc2UsXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuXHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIl9fd2VicGFja19yZXF1aXJlX18uZyA9IChmdW5jdGlvbigpIHtcblx0aWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSAnb2JqZWN0JykgcmV0dXJuIGdsb2JhbFRoaXM7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIHRoaXMgfHwgbmV3IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHJldHVybiB3aW5kb3c7XG5cdH1cbn0pKCk7IiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsImltcG9ydCB0eXBlIE9wZW5GaW4gZnJvbSBcIkBvcGVuZmluL2NvcmVcIjtcbmltcG9ydCB7IGZpbiB9IGZyb20gXCJAb3BlbmZpbi9jb3JlXCI7XG5cbmNvbnN0IGNoYW5uZWxOYW1lID0gYCR7ZmluLm1lLmlkZW50aXR5LnV1aWR9LWxvZ2dlcmA7XG5sZXQgY2hhbm5lbENsaWVudDogT3BlbkZpbi5DaGFubmVsQ2xpZW50O1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgYXN5bmMgKCkgPT4ge1xuXHRjb25zdCBjb25zb2xlTG9nQnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MQnV0dG9uRWxlbWVudD4oXCIjY29uc29sZS1hcHAtbG9nXCIpO1xuXHRpZiAoY29uc29sZUxvZ0J0bikge1xuXHRcdGNvbnNvbGVMb2dCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGNvbnNvbGVMb2dNZXNzYWdlKTtcblx0fVxuXG5cdGNvbnN0IGNoYW5uZWxMb2dCdG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxCdXR0b25FbGVtZW50PihcIiNjaGFubmVsLWFwcC1sb2dcIik7XG5cdGlmIChjaGFubmVsTG9nQnRuKSB7XG5cdFx0Y2hhbm5lbExvZ0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgY2hhbm5lbExvZ01lc3NhZ2UpO1xuXHR9XG5cblx0Y29uc3QgY2xlYXJQcmV2aWV3QnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MQnV0dG9uRWxlbWVudD4oXCIjY2xlYXItcHJldmlld1wiKTtcblx0aWYgKGNsZWFyUHJldmlld0J0bikge1xuXHRcdGNsZWFyUHJldmlld0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgY2xlYXJQcmV2aWV3KTtcblx0fVxuXHRhd2FpdCBzZXR1cENoYW5uZWxDbGllbnQoKTtcbn0pO1xuXG4vKipcbiAqIFNlbmRzIGEgbWVzc2FnZSB0byBjb25zb2xlIGxvZy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY29uc29sZUxvZ01lc3NhZ2UoKTogUHJvbWlzZTx2b2lkPiB7XG5cdGNvbnN0IGxvZ1ByZXZpZXcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI3ByZXZpZXdcIik7XG5cdHRyeSB7XG5cdFx0Y29uc3QgbWVzc2FnZSA9IGBTZW5kaW5nIHZpZXcgY29uc29sZSBsb2cgbWVzc2FnZTogJHtEYXRlLm5vdygpfWA7XG5cdFx0Y29uc29sZS5sb2cobWVzc2FnZSk7XG5cdFx0aWYgKGxvZ1ByZXZpZXcpIHtcblx0XHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgKz0gYFxuQ29uc29sZSBMb2dnZWQgdGhlIGZvbGxvd2luZyBtZXNzYWdlOiBcblwiJHttZXNzYWdlfVwiYDtcblx0XHR9XG5cdH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuXHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRsb2dQcmV2aWV3LnRleHRDb250ZW50ICs9IGBFcnJvciBjb25zb2xlIGxvZ2dpbmcgbWVzc2FnZTogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogU2VuZHMgYSBtZXNzYWdlIHRvIGNvbnNvbGUgbG9nIHRocm91Z2ggdGhlIENoYW5uZWwgQVBJLlxuICovXG5hc3luYyBmdW5jdGlvbiBjaGFubmVsTG9nTWVzc2FnZSgpOiBQcm9taXNlPHZvaWQ+IHtcblx0Y29uc3QgbG9nUHJldmlldyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjcHJldmlld1wiKTtcblx0dHJ5IHtcblx0XHRjb25zdCBtZXNzYWdlID0gYFNlbmRpbmcgdmlldyBjaGFubmVsIGxvZyBtZXNzYWdlOiAke0RhdGUubm93KCl9YDtcblx0XHRpZiAobG9nUHJldmlldykge1xuXHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBgXG5TZW5kaW5nIHRoZSBmb2xsb3dpbmcgbWVzc2FnZSB0aHJvdWdoIHRoZSBDaGFubmVsIEFQSTogXG5cIiR7bWVzc2FnZX1cImA7XG5cdFx0fVxuXHRcdGF3YWl0IGNoYW5uZWxDbGllbnQuZGlzcGF0Y2goXCJsb2dcIiwgbWVzc2FnZSk7XG5cdH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuXHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRsb2dQcmV2aWV3LnRleHRDb250ZW50ICs9IGBFcnJvciBzZW5kaW5nIG1lc3NhZ2UgdGhyb3VnaCBDaGFubmVsIEFQSTogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogU2V0cyB1cCB0aGUgQ2hhbm5lbCBDbGllbnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNldHVwQ2hhbm5lbENsaWVudCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0aWYgKGNoYW5uZWxDbGllbnQgPT09IHVuZGVmaW5lZCkge1xuXHRcdGNoYW5uZWxDbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbE5hbWUpO1xuXHR9XG59XG5cbi8qKlxuICogQ2xlYXJzIHRoZSBwcmV2aWV3IGxvZy5cbiAqL1xuZnVuY3Rpb24gY2xlYXJQcmV2aWV3KCk6IHZvaWQge1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHRpZiAobG9nUHJldmlldykge1xuXHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgPSBcIlwiO1xuXHR9XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/dev/john/update-logging-example/use-logging-apis/js/provider.bundle.js b/dev/john/update-logging-example/use-logging-apis/js/provider.bundle.js new file mode 100644 index 00000000..edaa8c7b --- /dev/null +++ b/dev/john/update-logging-example/use-logging-apis/js/provider.bundle.js @@ -0,0 +1,22885 @@ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "../../node_modules/@openfin/core/out/mock.js": +/*!****************************************************!*\ + !*** ../../node_modules/@openfin/core/out/mock.js ***! + \****************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var require$$0 = __webpack_require__(/*! events */ "../../node_modules/events/events.js"); +var require$$0$1 = __webpack_require__(/*! lodash/cloneDeep */ "../../node_modules/lodash/cloneDeep.js"); +var require$$3 = __webpack_require__(/*! lodash/isEqual */ "../../node_modules/lodash/isEqual.js"); + +function _mergeNamespaces(n, m) { + m.forEach(function (e) { + e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) { + if (k !== 'default' && !(k in n)) { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + }); + return Object.freeze(n); +} + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +var OpenFin$2 = {}; + +var events = {}; + +var application$1 = {}; + +/** + * Namespace for events that can be emitted by an {@link OpenFin.Application}. Includes events + * re-propagated from the {@link OpenFin.Window} (and, transitively, {@link OpenFin.View}) level, prefixed with `window-` (and also, if applicable, `view-`). + * For example, a view's "attached" event will fire as 'window-view-attached' at the application level. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * This namespace contains only payload shapes for events that are unique to `Application`. Events that propagate to `Application` from + * child {@link OpenFin.Window windows} and {@link OpenFin.View views} are defined in the {@link OpenFin.WindowEvents} and + * {@link OpenFin.ViewEvents} namespaces. For a list of valid string keys for *all* application events, see {@link Application.on Application.on}. + * + * {@link ApplicationSourcedEvent Application-sourced events} (i.e. those that have not propagated from {@link OpenFin.ViewEvents Views} + * or {@link OpenFin.WindowEvents Windows} re-propagate to {@link OpenFin.SystemEvents System} with their type string prefixed with `application-`. + * {@link ApplicationWindowEvent Application events that are tied to Windows but do not propagate from them} + * are propagated to `System` without any type string prefixing. + * + * "Requested" events (e.g. {@link RunRequestedEvent}) do not propagate. + * + * @packageDocumentation + */ +Object.defineProperty(application$1, "__esModule", { value: true }); + +var base$1 = {}; + +/** + * Namespace for shared event payloads and utility types common to all event emitters. + * + * @packageDocumentation + */ +Object.defineProperty(base$1, "__esModule", { value: true }); + +var externalApplication$1 = {}; + +/** + * Namespace for events that can be transmitted by an {@link OpenFin.ExternalApplication}. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * For a list of valid string keys for external application events, see {@link ExternalApplication.on ExternalApplication.on}. + * + * @packageDocumentation + */ +Object.defineProperty(externalApplication$1, "__esModule", { value: true }); + +var frame$1 = {}; + +Object.defineProperty(frame$1, "__esModule", { value: true }); + +var globalHotkey$1 = {}; + +/** + * + * Namespace for events that can be transmitted by {@link GlobalHotkey.GlobalHotkey}. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * For a list of valid string keys for global hotkey events, see {@link GlobalHotkey.GlobalHotkey.on GlobalHotkey.on}. + * + * @packageDocumentation + */ +Object.defineProperty(globalHotkey$1, "__esModule", { value: true }); + +var platform$1 = {}; + +/** + * + * Namespace for events that can emitted by a {@link OpenFin.Platform}. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * The Platform `EventEmitter` is a superset of the {@link OpenFin.Application} `EventEmitter`, + * meaning it can listen to all {@link OpenFin.ApplicationEvents Application events} in addition to the + * Platform-specific events listed here. For a list of valid string keys for *all* platform events, see + * {@link Platform.on Platform.on}. + * + * @packageDocumentation + */ +Object.defineProperty(platform$1, "__esModule", { value: true }); + +var system$1 = {}; + +/** + * Namespace for runtime-wide OpenFin events emitted by {@link System.System}. Includes events + * re-propagated from {@link OpenFin.Application}, {@link OpenFin.Window}, and {@link OpenFin.View} (prefixed with `application-`, `window-`, and `view-`). All + * event propagations are visible at the System level. Propagated events from WebContents (windows, views, frames) to the Application level will *not* + * transitively re-propagate to the System level, because they are already visible at the system level and contain the identity + * of the application. For example, an application's "closed" event will fire as 'application-closed' at the system level. A view's 'shown' event + * will be visible as 'view-shown' at the system level, but *not* as `application-window-view-shown`. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * This namespace contains only payload shapes for events that are unique to `System`. Events that propagate to `System` from + * child {@link OpenFin.Application applications}, {@link OpenFin.Window windows}, and {@link OpenFin.View views} are defined in the + * {@link OpenFin.ApplicationEvents}, {@link OpenFin.WindowEvents}, and {@link OpenFin.ViewEvents} namespaces. For a list of valid string keys for *all* + * system events, see {@link System.on System.on}. + * + * @packageDocumentation + */ +Object.defineProperty(system$1, "__esModule", { value: true }); + +var view$1 = {}; + +/** + * Namespace for events that can be emitted by a {@link OpenFin.View}. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * This namespace contains only payload shapes for events that are unique to `View`. Events that are shared between all `WebContents` + * (i.e. {@link OpenFin.Window}, {@link OpenFin.View}) are defined in {@link OpenFin.WebContentsEvents}. For a list + * of valid string keys for *all* View events, see {@link View.on View.on}. + * + * View events propagate to their parent {@link OpenFin.WindowEvents Window}, {@link OpenFin.ApplicationEvents Application}, + * and {@link OpenFin.SystemEvents System} with an added `viewIdentity` property and their event types prefixed with `'view-'`. + * + * @packageDocumentation + */ +Object.defineProperty(view$1, "__esModule", { value: true }); + +var webcontents = {}; + +/** + * Namespace for events shared by all OpenFin WebContents elements (i.e. {@link OpenFin.Window}, + * {@link OpenFin.View}). + * + * WebContents events will re-emit on parent entities - e.g., a propagating event in a view will also be emitted on the view's + * parent window, and propagating events in a window will also be emitted on the window's parent {@link OpenFin.Application}. + * + * @packageDocumentation + */ +Object.defineProperty(webcontents, "__esModule", { value: true }); + +var window$2 = {}; + +/** + * Namespace for events that can be emitted by a {@link OpenFin.Window}. + * + * Event payloads are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * Events gain metadata as they propagate, which is *not* present on the explicit payload interfaces. To refer to the full type + * of an event as it would be raised on this emitter, use {@link Payload}. + * + * This namespace contains only payload shapes for events that are unique to `Window`. Events that are shared between all `WebContents` + * (i.e. {@link OpenFin.Window}, {@link OpenFin.View}) are defined in {@link OpenFin.WebContentsEvents}. Events that + * propagate from `View` are defined in {@link OpenFin.ViewEvents}. For a list of valid string keys for *all* Window events, see + * {@link Window.on Window.on} + * + * {@link OpenFin.WindowEvents.WindowSourcedEvent Window-sourced events} (i.e. those that are not propagated from a + * {@link OpenFin.ViewEvents View}) propagate to their parent {@link OpenFin.ApplicationEvents Application} and + * {@link OpenFin.SystemEvents System} with their event types prefixed with `'window-'`). + * + * "Requested" events (e.g. {@link AuthRequestedEvent}) do not propagate to `System. The {@link OpenFin.WindowEvents.WindowCloseRequestedEvent} + * does not propagate at all. + * + * @packageDocumentation + */ +Object.defineProperty(window$2, "__esModule", { value: true }); + +/** + * Namespace for OpenFin event types. Each entity that emits OpenFin events has its own sub-namespace. Event payloads + * themselves are documented as interfaces, while algebraic helper types and derived types are documented as type aliases. + * + * #### Event emitters + * + * The following entities emit OpenFin events, and have corresponding sub-namespaces: + * + * * {@link OpenFin.Application}: {@link OpenFin.ApplicationEvents} + * * {@link OpenFin.ExternalApplication}: {@link OpenFin.ExternalApplicationEvents} + * * {@link OpenFin.Frame}: {@link OpenFin.FrameEvents} + * * {@link OpenFin.GlobalHotkey}: {@link OpenFin.GlobalHotkeyEvents} + * * {@link OpenFin.Platform}: {@link OpenFin.PlatformEvents} + * * {@link OpenFin.System}: {@link OpenFin.SystemEvents} + * * {@link OpenFin.View}: {@link OpenFin.ViewEvents} + * * {@link OpenFin.Window}: {@link OpenFin.WindowEvents} + * + * These `EventEmitter` entities share a common set of methods for interacting with the OpenFin event bus, which can be + * seen on the individual documentation pages for each entity type. + * + * Registering event handlers is an asynchronous operation. It is important to ensure that the returned Promises are awaited to reduce the + * risk of race conditions. + * + * When the `EventEmitter` receives an event from the browser process and emits on the renderer, all of the functions attached to that + * specific event are called synchronously. Any values returned by the called listeners are ignored and will be discarded. If the window document + * is destroyed by page navigation or reload, its registered event listeners will be removed. + * + * We recommend using Arrow Functions for event listeners to ensure the this scope is consistent with the original function context. + * + * Events re-propagate from smaller/more-local scopes to larger/more-global scopes. For example, an event emitted on a specific + * view will propagate to the window in which the view is embedded, and then to the application in which the window is running, and + * finally to the OpenFin runtime itself at the "system" level. For details on propagation semantics, see the namespace for + * the propagating (or propagated-to) entity. + * + * If you need the payload type for a specific type of event (especially propagated events), use the emitting topic's `Payload` generic + * (e.g. {@link WindowEvents.Payload}) with the event's `type` string. For example, the payload of + * a {@link ViewEvents.CreatedEvent} after it has propagated to its parent {@link WindowEvents Window} can be found with + * `WindowEvents.Payload<'view-created'>`. + * + * @packageDocumentation + */ +var __createBinding$1 = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault$1 = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar$1 = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding$1(result, mod, k); + __setModuleDefault$1(result, mod); + return result; +}; +Object.defineProperty(events, "__esModule", { value: true }); +events.WindowEvents = events.WebContentsEvents = events.ViewEvents = events.SystemEvents = events.PlatformEvents = events.GlobalHotkeyEvents = events.FrameEvents = events.ExternalApplicationEvents = events.BaseEvents = events.ApplicationEvents = void 0; +const ApplicationEvents = __importStar$1(application$1); +events.ApplicationEvents = ApplicationEvents; +const BaseEvents = __importStar$1(base$1); +events.BaseEvents = BaseEvents; +const ExternalApplicationEvents = __importStar$1(externalApplication$1); +events.ExternalApplicationEvents = ExternalApplicationEvents; +const FrameEvents = __importStar$1(frame$1); +events.FrameEvents = FrameEvents; +const GlobalHotkeyEvents = __importStar$1(globalHotkey$1); +events.GlobalHotkeyEvents = GlobalHotkeyEvents; +const PlatformEvents = __importStar$1(platform$1); +events.PlatformEvents = PlatformEvents; +const SystemEvents = __importStar$1(system$1); +events.SystemEvents = SystemEvents; +const ViewEvents = __importStar$1(view$1); +events.ViewEvents = ViewEvents; +const WebContentsEvents = __importStar$1(webcontents); +events.WebContentsEvents = WebContentsEvents; +const WindowEvents = __importStar$1(window$2); +events.WindowEvents = WindowEvents; + +(function (exports) { + /** + * Top-level namespace for types referenced by the OpenFin API. Contains: + * + * * The type of the global `fin` entry point ({@link FinApi}) + * * Classes that act as static namespaces returned from the `fin` global (e.g. {@link ApplicationModule}, accessible via `fin.Application`) + * * Instance classes that are returned from API calls (e.g. {@link Application}, accessible via `fin.Application.getCurrentSync()`) + * * Parameter shapes for API methods (e.g. {@link ApplicationOptions}, used in `fin.Application.start()`) + * * Event namespaces and payload union types (e.g. {@link ApplicationEvents} and {@link ApplicationEvent}) + * + * @packageDocumentation + */ + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + // Deprecated shim to preserve v30 namespace names + __exportStar(events, exports); +} (OpenFin$2)); + +var OpenFin = /*@__PURE__*/getDefaultExportFromCjs(OpenFin$2); + +var OpenFin$1 = /*#__PURE__*/_mergeNamespaces({ + __proto__: null, + default: OpenFin +}, [OpenFin$2]); + +var fin$2 = {}; + +var system = {}; + +var base = {}; + +var promises = {}; + +Object.defineProperty(promises, "__esModule", { value: true }); +promises.promiseMapSerial = promises.serial = promises.promiseMap = promises.promisify = void 0; +function promisify(func) { + return (...args) => new Promise((resolve, reject) => { + func(...args, (err, val) => (err ? reject(err) : resolve(val))); + }); +} +promises.promisify = promisify; +async function promiseMap(arr, asyncF) { + return Promise.all(arr.map(asyncF)); +} +promises.promiseMap = promiseMap; +async function serial(arr) { + const ret = []; + for (const func of arr) { + // eslint-disable-next-line no-await-in-loop + const next = await func(); + ret.push(next); + } + return ret; +} +promises.serial = serial; +async function promiseMapSerial(arr, func) { + return serial(arr.map((value, index, array) => () => func(value, index, array))); +} +promises.promiseMapSerial = promiseMapSerial; + +var __classPrivateFieldSet$c = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$e = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _EmitterBase_emitterAccessor; +Object.defineProperty(base, "__esModule", { value: true }); +base.Reply = base.EmitterBase = base.Base = void 0; +const promises_1 = promises; +class Base { + /** + * @internal + */ + constructor(wire) { + /** + * @internal + * @deprecated + */ + this.isNodeEnvironment = () => { + return this.wire.environment.type === 'node'; + }; + /** + * @internal + * @deprecated + */ + this.isOpenFinEnvironment = () => { + return this.wire.environment.type === 'openfin'; + }; + /** + * @internal + * @deprecated + */ + this.isBrowserEnvironment = () => { + return this.wire.environment.type === 'other'; + }; + this.wire = wire; + } + get fin() { + return this.wire.getFin(); + } + /** + * Provides access to the OpenFin representation of the current code context (usually a document + * such as a {@link OpenFin.View} or {@link OpenFin.Window}), as well as to the current `Interop` context. + * + * Useful for debugging in the devtools console, where this will intelligently type itself based + * on the context in which the devtools panel was opened. + */ + get me() { + return this.wire.me; + } +} +base.Base = Base; +/** + * An entity that emits OpenFin events. + * + * @remarks Event-binding methods are asynchronous as they must cross process boundaries + * and setup the listener in the browser process. When the `EventEmitter` receives an event from the browser process + * and emits on the renderer, all of the functions attached to that specific event are called synchronously. Any values + * returned by the called listeners are ignored and will be discarded. If the execution context of the window is destroyed + * by page navigation or reload, any events that have been setup in that context will be destroyed. + * + * It is important to keep in mind that when an ordinary listener function is called, the standard `this` keyword is intentionally + * set to reference the `EventEmitter` instance to which the listener is attached. It is possible to use ES6 Arrow Functions as + * listeners, however, when doing so, the `this` keyword will no longer reference the `EventEmitter` instance. + * + * Events re-propagate from smaller/more-local scopes to larger/more-global scopes. For example, an event emitted on a specific + * view will propagate to the window in which the view is embedded, and then to the application in which the window is running, and + * finally to the OpenFin runtime itself at the "system" level. Re-propagated events are prefixed with the name of the scope in which + * they originated - for example, a "shown" event emitted on a view will be re-propagated at the window level as "view-shown", and + * then to the application as "window-view-shown", and finally at the system level as "application-window-view-shown". + * + * All event propagations are visible at the System level, regardless of source, so transitive re-propagations (e.g. from view to window + * to application) are visible in their entirety at the system level. So, we can listen to the above event as "shown", "view-shown", + * "window-view-shown", or "application-window-view-shown." + */ +class EmitterBase extends Base { + constructor(wire, topic, ...additionalAccessors) { + super(wire); + this.topic = topic; + _EmitterBase_emitterAccessor.set(this, void 0); + this.eventNames = () => (this.hasEmitter() ? this.getOrCreateEmitter().eventNames() : []); + /** + * @internal + */ + this.emit = (eventType, payload, ...args) => { + return this.hasEmitter() ? this.getOrCreateEmitter().emit(eventType, payload, ...args) : false; + }; + this.hasEmitter = () => this.wire.eventAggregator.has(__classPrivateFieldGet$e(this, _EmitterBase_emitterAccessor, "f")); + this.getOrCreateEmitter = () => this.wire.eventAggregator.getOrCreate(__classPrivateFieldGet$e(this, _EmitterBase_emitterAccessor, "f")); + this.listeners = (type) => this.hasEmitter() ? this.getOrCreateEmitter().listeners(type) : []; + this.listenerCount = (type) => this.hasEmitter() ? this.getOrCreateEmitter().listenerCount(type) : 0; + this.registerEventListener = async (eventType, options = {}, applySubscription, undoSubscription) => { + const runtimeEvent = { + ...this.identity, + timestamp: options.timestamp || Date.now(), + topic: this.topic, + type: eventType + }; + const emitter = this.getOrCreateEmitter(); + // We apply the subscription and then undo if the async call fails to avoid + // indeterminacy in subscription application order, which can break things elsewhere + applySubscription(emitter); + try { + await this.wire.sendAction('subscribe-to-desktop-event', runtimeEvent); + } + catch (e) { + undoSubscription(emitter); + this.deleteEmitterIfNothingRegistered(emitter); + throw e; + } + }; + this.deregisterEventListener = async (eventType, options = {}) => { + if (this.hasEmitter()) { + const runtimeEvent = { + ...this.identity, + timestamp: options.timestamp || Date.now(), + topic: this.topic, + type: eventType + }; + await this.wire.sendAction('unsubscribe-to-desktop-event', runtimeEvent).catch(() => null); + const emitter = this.getOrCreateEmitter(); + return emitter; + } + // This will only be reached if unsubscribe from event that does not exist but do not want to error here + return Promise.resolve(); + }; + __classPrivateFieldSet$c(this, _EmitterBase_emitterAccessor, [topic, ...additionalAccessors], "f"); + this.listeners = (event) => this.hasEmitter() ? this.getOrCreateEmitter().listeners(event) : []; + } + /** + * Adds a listener to the end of the listeners array for the specified event. + * + * @remarks Event payloads are documented in the {@link OpenFin.Events} namespace. + */ + async on(eventType, listener, options) { + await this.registerEventListener(eventType, options, (emitter) => { + emitter.on(eventType, listener); + }, (emitter) => { + emitter.removeListener(eventType, listener); + }); + return this; + } + /** + * Adds a listener to the end of the listeners array for the specified event. + */ + async addListener(eventType, listener, options) { + return this.on(eventType, listener, options); + } + /** + * Adds a one time listener for the event. The listener is invoked only the first time the event is fired, after which it is removed. + * + * @remarks Event payloads are documented in the {@link OpenFin.Events} namespace. + */ + async once(eventType, listener, options) { + const deregister = () => this.deregisterEventListener(eventType); + await this.registerEventListener(eventType, options, (emitter) => { + emitter.once(eventType, deregister); + emitter.once(eventType, listener); + }, (emitter) => { + emitter.removeListener(eventType, deregister); + emitter.removeListener(eventType, listener); + }); + return this; + } + /** + * Adds a listener to the beginning of the listeners array for the specified event. + * + * @remarks Event payloads are documented in the {@link OpenFin.Events} namespace. + */ + async prependListener(eventType, listener, options) { + await this.registerEventListener(eventType, options, (emitter) => { + emitter.prependListener(eventType, listener); + }, (emitter) => { + emitter.removeListener(eventType, listener); + }); + return this; + } + /** + * Adds a one time listener for the event. The listener is invoked only the first time the event is fired, + * after which it is removed. The listener is added to the beginning of the listeners array. + * + * @remarks Event payloads are documented in the {@link OpenFin.Events} namespace. + */ + async prependOnceListener(eventType, listener, options) { + const deregister = () => this.deregisterEventListener(eventType); + await this.registerEventListener(eventType, options, (emitter) => { + emitter.prependOnceListener(eventType, listener); + emitter.once(eventType, deregister); + }, (emitter) => { + emitter.removeListener(eventType, listener); + emitter.removeListener(eventType, deregister); + }); + return this; + } + /** + * Remove a listener from the listener array for the specified event. + * + * @remarks Caution: Calling this method changes the array indices in the listener array behind the listener. + */ + async removeListener(eventType, listener, options) { + const emitter = await this.deregisterEventListener(eventType, options); + if (emitter) { + emitter.removeListener(eventType, listener); + this.deleteEmitterIfNothingRegistered(emitter); + } + return this; + } + async deregisterAllListeners(eventType) { + const runtimeEvent = { ...this.identity, type: eventType, topic: this.topic }; + if (this.hasEmitter()) { + const emitter = this.getOrCreateEmitter(); + const refCount = emitter.listenerCount(runtimeEvent.type); + const unsubscribePromises = []; + for (let i = 0; i < refCount; i++) { + unsubscribePromises.push(this.wire.sendAction('unsubscribe-to-desktop-event', runtimeEvent).catch(() => null)); + } + await Promise.all(unsubscribePromises); + return emitter; + } + return undefined; + } + /** + * Removes all listeners, or those of the specified event. + * + */ + async removeAllListeners(eventType) { + const removeByEvent = async (event) => { + const emitter = await this.deregisterAllListeners(event); + if (emitter) { + emitter.removeAllListeners(event); + this.deleteEmitterIfNothingRegistered(emitter); + } + }; + if (eventType) { + await removeByEvent(eventType); + } + else if (this.hasEmitter()) { + const events = this.getOrCreateEmitter().eventNames(); + await (0, promises_1.promiseMap)(events, removeByEvent); + } + return this; + } + deleteEmitterIfNothingRegistered(emitter) { + if (emitter.eventNames().length === 0) { + this.wire.eventAggregator.delete(__classPrivateFieldGet$e(this, _EmitterBase_emitterAccessor, "f")); + } + } +} +base.EmitterBase = EmitterBase; +_EmitterBase_emitterAccessor = new WeakMap(); +class Reply { +} +base.Reply = Reply; + +var transportErrors = {}; + +Object.defineProperty(transportErrors, "__esModule", { value: true }); +transportErrors.RuntimeError = transportErrors.NotSupportedError = transportErrors.NotImplementedError = transportErrors.NoAckError = transportErrors.DuplicateCorrelationError = transportErrors.UnexpectedActionError = transportErrors.DisconnectedError = void 0; +class DisconnectedError extends Error { + constructor(readyState) { + super(`Expected websocket state OPEN but found ${readyState}`); + this.readyState = readyState; + } +} +transportErrors.DisconnectedError = DisconnectedError; +class UnexpectedActionError extends Error { +} +transportErrors.UnexpectedActionError = UnexpectedActionError; +class DuplicateCorrelationError extends Error { +} +transportErrors.DuplicateCorrelationError = DuplicateCorrelationError; +class NoAckError extends Error { +} +transportErrors.NoAckError = NoAckError; +class NotImplementedError extends Error { +} +transportErrors.NotImplementedError = NotImplementedError; +class NotSupportedError extends Error { +} +transportErrors.NotSupportedError = NotSupportedError; +class InternalError extends Error { + constructor(err) { + const { message, name, stack, ...rest } = err; + super(message); + this.name = name || 'Error'; + this.stack = stack ?? this.toString(); + Object.keys(rest).forEach(key => { + this[key] = rest[key]; + }); + } +} +// For documentation of the error methods being used see here: https://v8.dev/docs/stack-trace-api +class RuntimeError extends Error { + static getCallSite(callsToRemove = 0) { + const length = Error.stackTraceLimit; + const realCallsToRemove = callsToRemove + 1; // remove this call; + Error.stackTraceLimit = length + realCallsToRemove; + // eslint-disable-next-line no-underscore-dangle + const _prepareStackTrace = Error.prepareStackTrace; + // This will be called when we access the `stack` property + Error.prepareStackTrace = (_, stack) => stack; + // stack is optional in non chromium contexts + const stack = new Error().stack?.slice(realCallsToRemove) ?? []; + Error.prepareStackTrace = _prepareStackTrace; + Error.stackTraceLimit = length; + return stack; + } + static prepareStackTrace(err, callSites) { + if (typeof Error.prepareStackTrace === 'function') { + return Error.prepareStackTrace(err, callSites); + } + let string = ""; + string += err.name || "Error"; + string += `: ${err.message || ""}`; + for (const callSite of callSites) { + string += `\n at ${callSite.toString()}`; + } + return string; + } + ; + constructor(payload, callSites) { + const { reason, error } = payload; + super(reason); + this.name = 'RuntimeError'; + if (error?.stack) { + this.cause = new InternalError(error); + } + if (callSites) { + this.stack = RuntimeError.prepareStackTrace(this, callSites); + } + } +} +transportErrors.RuntimeError = RuntimeError; + +var window$1 = {}; + +var Factory$8 = {}; + +var validate = {}; + +Object.defineProperty(validate, "__esModule", { value: true }); +validate.validateIdentity = void 0; +function validateIdentity(identity) { + let errorMsg; + if (typeof identity !== 'object' || typeof identity.uuid !== 'string') { + errorMsg = 'Not a valid identity object'; + } + return errorMsg; +} +validate.validateIdentity = validateIdentity; + +var Instance$7 = {}; + +var application = {}; + +var Factory$7 = {}; + +var Instance$6 = {}; + +var view = {}; + +var Factory$6 = {}; + +var warnings = {}; + +Object.defineProperty(warnings, "__esModule", { value: true }); +warnings.handleDeprecatedWarnings = void 0; +const handleDeprecatedWarnings = (options) => { + if (options.contentNavigation?.whitelist || + options.contentNavigation?.blacklist || + options.contentRedirect?.whitelist || + options.contentRedirect?.blacklist) { + console.warn(`The properties 'whitelist' and 'blacklist' have been marked as deprecated and will be removed in a future version. Please use 'allowlist' and 'denylist'.`); + } +}; +warnings.handleDeprecatedWarnings = handleDeprecatedWarnings; + +var hasRequiredFactory$3; + +function requireFactory$3 () { + if (hasRequiredFactory$3) return Factory$6; + hasRequiredFactory$3 = 1; + Object.defineProperty(Factory$6, "__esModule", { value: true }); + Factory$6.ViewModule = void 0; + const base_1 = base; + const validate_1 = validate; + const index_1 = requireView(); + const warnings_1 = warnings; + /** + * Static namespace for OpenFin API methods that interact with the {@link View} class, available under `fin.View`. + */ + class ViewModule extends base_1.Base { + /** + * Creates a new View. + * @param options - View creation options + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameCreate', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * createView() + * .then((createdView) => { + * view = createdView; + * console.log('View created.', view); + * view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * }) + * .catch(err => console.log(err)); + * ``` + * Note that created views needs to navigate somewhere for them to actually render a website. + * @experimental + */ + async create(options) { + const { uuid } = this.wire.me; + if (!options.name || typeof options.name !== 'string') { + throw new Error('Please provide a name property as a string in order to create a View.'); + } + (0, warnings_1.handleDeprecatedWarnings)(options); + if (this.wire.environment.childViews) { + await this.wire.environment.createChildContent({ + entityType: 'view', + options: { ...options, uuid } + }); + } + else { + await this.wire.sendAction('create-view', { ...options, uuid }); + } + return this.wrapSync({ uuid, name: options.name }); + } + /** + * Asynchronously returns an API handle for the given View identity. + * + * @remarks Wrapping a View identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for a View throughout its entire lifecycle. + * + * @example + * ```js + * fin.View.wrap({ uuid: 'testViewUuid', name: 'testViewName' })) + * .then(view => console.log('wrapped view', view)) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + async wrap(identity) { + this.wire.sendAction('view-wrap').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new index_1.View(this.wire, identity); + } + /** + * Synchronously returns an API handle for the given View identity. + * + * @remarks Wrapping a View identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for a View throughout its entire lifecycle. + * + * @example + * ```js + * const view = fin.View.wrapSync({ uuid: 'testView', name: 'testViewName' }); + * await view.hide(); + * ``` + * @experimental + */ + wrapSync(identity) { + this.wire.sendAction('view-wrap-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new index_1.View(this.wire, identity); + } + /** + * Asynchronously returns a View object that represents the current view + * + * @example + * ```js + * fin.View.getCurrent() + * .then(view => console.log('current view', view)) + * .catch(err => console.log(err)); + * + * ``` + * @experimental + */ + getCurrent() { + this.wire.sendAction('view-get-current').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + if (!this.wire.me.isView) { + throw new Error('You are not in a View context'); + } + const { uuid, name } = this.wire.me; + return this.wrap({ uuid, name }); + } + /** + * Synchronously returns a View object that represents the current view + * + * @example + * ```js + * const view = fin.View.getCurrentSync(); + * console.log(view); + * + * ``` + * @experimental + */ + getCurrentSync() { + this.wire.sendAction('view-get-current-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + if (!this.wire.me.isView) { + throw new Error('You are not in a View context'); + } + const { uuid, name } = this.wire.me; + return this.wrapSync({ uuid, name }); + } + } + Factory$6.ViewModule = ViewModule; + return Factory$6; +} + +var Instance$5 = {}; + +var lazy = {}; + +Object.defineProperty(lazy, "__esModule", { value: true }); +lazy.AsyncRetryableLazy = lazy.Lazy = void 0; +/** + * Handy class for managing asynchronous dependencies of classes. + * + * Will call the producer function once and only once when getValue is called, + * returning the resultant value for every subsequent call. + */ +class Lazy { + // eslint-disable-next-line + constructor(producerFn) { + this.producerFn = producerFn; + } + /** + * Lazily get the value returned by the producer. + * @returns The value returned from the producer function + */ + getValue() { + if (!this.value) { + this.value = this.producerFn(); + } + return this.value; + } +} +lazy.Lazy = Lazy; +/** + * Handy class for managing asynchronous dependencies of classes. + * + * Will call asynchronous producer only after `getValue` is called. If the + * deferred code errors, we can try it again by re-calling `getValue` after + * the promise rejects. + */ +class AsyncRetryableLazy { + // eslint-disable-next-line + constructor(producerFn) { + this.producerFn = producerFn; + } + /** + * Lazily get the value returned by the async producer. + * + * @returns The value returned from the producer function + */ + async getValue() { + if (!this.promise) { + this.promise = this.producerFn().catch((e) => { + delete this.promise; + throw e; + }); + } + return this.promise; + } +} +lazy.AsyncRetryableLazy = AsyncRetryableLazy; + +var layoutEntities = {}; + +var apiExposer$1 = {}; + +var apiConsumer = {}; + +Object.defineProperty(apiConsumer, "__esModule", { value: true }); +apiConsumer.ApiConsumer = void 0; +/** + * Consumer for apis exposed with {@see ApiExposer}. + * + * A strategy that matches the strategy used to expose a target API must be provided. + */ +class ApiConsumer { + // eslint-disable-next-line + constructor(strategy) { + this.strategy = strategy; + /** + * Consumes an api exposed using a given transport strategy, and generates a client + * for easy, type safe consumption of that client. + * @param options Strategy specific consumption options. + * @returns An api client matching the given type. + */ + this.consume = async (options) => { + const exposedProperties = await this.strategy.getExposedFunctions(options); + return exposedProperties.reduce((client, prop) => ({ + ...client, + [prop.key]: this.strategy.createFunction(prop, options) + }), {}); + }; + } +} +apiConsumer.ApiConsumer = ApiConsumer; + +var apiExposer = {}; + +var decorators = {}; + +Object.defineProperty(decorators, "__esModule", { value: true }); +decorators.expose = decorators.getExposedProperties = void 0; +const exposedProperties = Symbol('exposedProperties'); +const getExposedProperties = (target) => { + return target[exposedProperties] || target.prototype[exposedProperties] || []; +}; +decorators.getExposedProperties = getExposedProperties; +/** + * Indicates that a class member function can be exposed using {@link ApiExposer}. + * @param options Options specific to the strategy used in {@link ApiExposer} + */ +// Returns any as decorator typing is weird. +const expose = (options) => (target, key, descriptor) => { + target[exposedProperties] = target[exposedProperties] || []; + target[exposedProperties].push({ key, descriptor, options }); +}; +decorators.expose = expose; + +Object.defineProperty(apiExposer, "__esModule", { value: true }); +apiExposer.ApiExposer = void 0; +const decorators_1 = decorators; +/** + * Exposes api services on the transport of choice. + */ +class ApiExposer { + /** + * @param strategy The expose strategy to use to expose instances. + */ + // eslint-disable-next-line + constructor(strategy) { + this.strategy = strategy; + /** + * Exposes an instance of a given api on + * @param instance Instance of a class which has been decorated to indicate which functions can be exposed. + * @param instanceOptions Transport strategy specific options to use when exposing. + */ + this.exposeInstance = async (instance, instanceOptions) => { + const exposableProps = (0, decorators_1.getExposedProperties)(instance); + const exposedProps = await Promise.all(exposableProps.map(async ({ key, options }) => { + const customConsumptionOptions = await this.strategy.exposeFunction(instance[key].bind(instance), { + key, + options, + meta: instanceOptions + }); + return { + key, + options: customConsumptionOptions + }; + })); + await this.strategy.exposeMeta(instanceOptions, exposedProps); + }; + } + ; +} +apiExposer.ApiExposer = ApiExposer; + +var strategies = {}; + +var openfinChannels = {}; + +var channelsConsumer = {}; + +Object.defineProperty(channelsConsumer, "__esModule", { value: true }); +channelsConsumer.ChannelsConsumer = void 0; +class ChannelsConsumer { + // eslint-disable-next-line + constructor(channel) { + this.channel = channel; + this.getExposedFunctions = async (options) => { + const { id } = options; + const { props } = await this.channel.dispatch(`api-meta:${id}`); + return props; + }; + this.createFunction = (prop) => (...args) => { + const { action } = prop.options; + return this.channel.dispatch(action, { args }); + }; + } + ; +} +channelsConsumer.ChannelsConsumer = ChannelsConsumer; + +var channelsExposer = {}; + +Object.defineProperty(channelsExposer, "__esModule", { value: true }); +channelsExposer.ChannelsExposer = void 0; +class ChannelsExposer { + // eslint-disable-next-line + constructor(channelProviderOrClient) { + this.channelProviderOrClient = channelProviderOrClient; + this.exposeFunction = async (target, config) => { + const { key, options, meta } = config; + const { id } = meta; + const action = `${id}.${options?.action || key}`; + await this.channelProviderOrClient.register(action, async ({ args }) => { + return target(...args); + }); + return { action }; + }; + this.exposeMeta = async ({ id }, props) => { + const action = `api-meta:${id}`; + await this.channelProviderOrClient.register(action, () => ({ props })); + }; + } +} +channelsExposer.ChannelsExposer = ChannelsExposer; + +(function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(channelsConsumer, exports); + __exportStar(channelsExposer, exports); +} (openfinChannels)); + +(function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(openfinChannels, exports); +} (strategies)); + +(function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(apiConsumer, exports); + __exportStar(apiExposer, exports); + __exportStar(strategies, exports); + __exportStar(decorators, exports); +} (apiExposer$1)); + +var channelApiRelay = {}; + +Object.defineProperty(channelApiRelay, "__esModule", { value: true }); +channelApiRelay.createRelayedDispatch = channelApiRelay.relayChannelClientApi = void 0; +const EXPECTED_ERRORS = [ + 'no longer connected', + 'RTCDataChannel closed unexpectedly', + 'The client you are trying to dispatch from is disconnected from the target provider', +]; +// Checks possible error messages that we want to trap, client error message can originate +// from ChannelProvider::dispatch OR ClassicStrategy::closeEndpoint OR RTCEndPoint::dataChannel::onclose +const isDisconnectedError = (errorMsg) => { + return EXPECTED_ERRORS.some(e => errorMsg.includes(e)); +}; +/** + * @internal + * Create a channel relay for a given channel exposition, allowing a single provider to route + * actions to the designated clients. + * + * Designed to be used in conjunction with @expose + * + * @param channelProvider The channel provider to relay the actions on. + * @param config Determines which actions to relay. Please ensure action prefix matches the exposed api. + */ +const relayChannelClientApi = async (channelProvider, relayId) => { + channelProvider.register(`relay:${relayId}`, ({ action, target, payload }) => { + return channelProvider.dispatch(target, action, payload); + }); + await Promise.resolve(); +}; +channelApiRelay.relayChannelClientApi = relayChannelClientApi; +const createRelayedDispatch = (client, target, relayId, relayErrorMsg) => async (action, payload) => { + try { + return await client.dispatch(`relay:${relayId}`, { + action, + payload, + target + }); + } + catch (e) { + if (isDisconnectedError(e.message) && relayErrorMsg) { + throw new Error(relayErrorMsg); + } + throw e; + } +}; +channelApiRelay.createRelayedDispatch = createRelayedDispatch; + +var __classPrivateFieldSet$b = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$d = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _LayoutNode_client, _TabStack_client, _ColumnOrRow_client; +Object.defineProperty(layoutEntities, "__esModule", { value: true }); +layoutEntities.ColumnOrRow = layoutEntities.TabStack = layoutEntities.LayoutNode = void 0; +const api_exposer_1 = apiExposer$1; +const channel_api_relay_1 = channelApiRelay; +/* + This file includes LayoutNode, ColumnOrRow and TabStack classes, which are all closely + intertwined, and share members via parent abstract class LayoutNode. To prevent circular + refs, we define and export all the classes here. +*/ +/** + * @ignore + * @internal + * Supplies an ApiClient for {@link LayoutEntitiesController} and helper methods + * for the entities {@link TabStack} AND {@link ColumnOrRow} to use. + */ +class LayoutNode { + /** + * @internal + * @ignore + */ + constructor(client, entityId) { + /** + * @ignore + * @internal + * ApiClient for {@link LayoutEntitiesController} + */ + _LayoutNode_client.set(this, void 0); + /** + * Checks if the TabStack or ColumnOrRow is the root content item + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * const isRoot = await stack.isRoot(); + * // The TabStack is root: false + * console.log(`The TabStack is root: ${isRoot}`); + * + * // Retrieves the parent ColumnOrRow + * const parent = await stack.getParent(); + * const parentIsRoot = await parent.isRoot(); + * // The parent ColumnOrRow is root: true + * console.log(`The parent ColumnOrRow is root: ${parentIsRoot}`); + * ``` + */ + this.isRoot = () => __classPrivateFieldGet$d(this, _LayoutNode_client, "f").isRoot(this.entityId); + /** + * Checks if the TabStack or ColumnOrRow exists + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * // Retrieves the parent ColumnOrRow + * const columnOrRow = await stack.getParent(); + * let exists = await stack.exists(); + * // or + * let exists = await columnOrRow.exists(); + * // The entity exists: true + * console.log(`The entity exists: ${exists}`); + * ``` + */ + this.exists = () => __classPrivateFieldGet$d(this, _LayoutNode_client, "f").exists(this.entityId); + /** + * Retrieves the parent of the TabStack or ColumnOrRow + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * // Retrieves the parent ColumnOrRow + * const columnOrRow = await stack.getParent(); + * + * // undefined if entity is the root item + * let parent = await columnOrRow.getParent(); + * // or + * let parent = await stack.getParent(); + * ``` + */ + this.getParent = async () => { + const parent = await __classPrivateFieldGet$d(this, _LayoutNode_client, "f").getParent(this.entityId); + if (!parent) { + return undefined; + } + return LayoutNode.getEntity(parent, __classPrivateFieldGet$d(this, _LayoutNode_client, "f")); + }; + /** + * Creates a new TabStack adjacent to the given TabStack or ColumnOrRow. Inputs can be new views to create, or existing views. + * + * Known Issue: If the number of views to add overflows the tab-container, the added views will be set as active + * during each render, and then placed at the front of the tab-stack, while the underlying order of tabs will remain unchanged. + * This means the views you pass to createAdjacentStack() may not render in the order given by the array. + * Until fixed, this problem can be avoided only if your window is wide enough to fit creating all the views in the tabstack. + * + * @param views The views that will populate the new TabStack. + * @param options Additional options that control new TabStack creation. + * @returns The newly-created TabStack. + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * const columnOrRow = await stack.getParent(); + * + * // Create view references by supplying a 'name' and 'url' + * const views = [ + * // if 'name' is undefined, one will be generated + * // if 'url' is undefined, it will default the view URL to 'about:blank' + * { name: 'google-view', url: 'http://google.com/'}, + * { name: 'of-developers-view', url: 'http://developers.openfin.co/'}, + * ]; + * + * // Create a view beforehand to be included in the new tab stack + * const outsideView = await fin.View.create({ + * name: 'outside-bloomberg-view', + * url: 'https://bloomberg.com/', + * target: fin.me.identity, + * }); + * + * // Views to add can be identities, or the reference views mentioned above + * const viewsToAdd = [outsideView.identity, ...views]; + * + * // Possible position inputs: 'right' | 'left' | 'top' | 'bottom' + * let stackFrom = await columnOrRow.createAdjacentStack(viewsToAdd, { position: 'right' }); + * // Or + * let newStack = await stack.createAdjacentStack(viewsToAdd, { position: 'right' }); + * console.log(`A new TabStack created to the right has ${newStack.length} views in it`); + * + * ``` + * @experimental + */ + this.createAdjacentStack = async (views, options) => { + const entityId = await __classPrivateFieldGet$d(this, _LayoutNode_client, "f").createAdjacentStack(this.entityId, views, options); + return LayoutNode.getEntity({ entityId, type: 'stack' }, __classPrivateFieldGet$d(this, _LayoutNode_client, "f")); + }; + /** + * Retrieves the adjacent TabStacks of the given TabStack or ColumnOrRow. + * + * @param edge Edge whose adjacent TabStacks will be returned. + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * const columnOrRow = await stack.getParent(); + * // Possible position inputs: 'right' | 'left' | 'top' | 'bottom' + * let rightStacks = await columnOrRow.getAdjacentStacks('right'); + * let leftStacks = await columnOrRow.getAdjacentStacks('left'); + * // or + * let rightStacks = await stack.getAdjacentStacks('right'); + * let leftStacks = await stack.getAdjacentStacks('left'); + * + * console.log(`The entity has ${rightStacks.length} stacks to the right, and ${leftStacks.length} stacks to the left`); + * + * ``` + * @experimental + */ + this.getAdjacentStacks = async (edge) => { + const adjacentStacks = await __classPrivateFieldGet$d(this, _LayoutNode_client, "f").getAdjacentStacks({ + targetId: this.entityId, + edge + }); + return adjacentStacks.map((stack) => LayoutNode.getEntity({ + type: 'stack', + entityId: stack.entityId + }, __classPrivateFieldGet$d(this, _LayoutNode_client, "f"))); + }; + __classPrivateFieldSet$b(this, _LayoutNode_client, client, "f"); + this.entityId = entityId; + } +} +layoutEntities.LayoutNode = LayoutNode; +_LayoutNode_client = new WeakMap(); +/** + * @ignore + * @internal + * Encapsulates Api consumption of {@link LayoutEntitiesClient} with a relayed dispatch + * @param client + * @param controllerId + * @param identity + * @returns a new instance of {@link LayoutEntitiesClient} with bound to the controllerId + */ +LayoutNode.newLayoutEntitiesClient = async (client, controllerId, identity) => { + const dispatch = (0, channel_api_relay_1.createRelayedDispatch)(client, identity, 'layout-relay', 'You are trying to interact with a layout component on a window that does not exist or has been destroyed.'); + const consumer = new api_exposer_1.ApiConsumer(new api_exposer_1.ChannelsConsumer({ dispatch })); + return consumer.consume({ id: controllerId }); +}; +LayoutNode.getEntity = (definition, client) => { + const { entityId, type } = definition; + switch (type) { + case 'column': + case 'row': + return new ColumnOrRow(client, entityId, type); + case 'stack': + return new TabStack(client, entityId); + default: + throw new Error(`Unrecognised Layout Entity encountered ('${JSON.stringify(definition)})`); + } +}; +/** + * A TabStack is used to manage the state of a stack of tabs within an OpenFin Layout. + */ +class TabStack extends LayoutNode { + /** @internal */ + constructor(client, entityId) { + super(client, entityId); + /** + * @internal + * ApiClient for {@link LayoutEntitiesController} + */ + _TabStack_client.set(this, void 0); + /** + * Type of the content item. Always stack, but useful for distinguishing between a {@link TabStack} and {@link ColumnOrRow}. + */ + this.type = 'stack'; + /** + * Retrieves a list of all views belonging to this {@link TabStack}. + * + * Known Issue: If adding a view overflows the tab-container width, the added view will be set as active + * and rendered at the front of the tab-stack, while the underlying order of tabs will remain unchanged. + * If that happens and then getViews() is called, it will return the identities in a different order than + * than the currently rendered tab order. + * + * + * @throws If the {@link TabStack} has been destroyed. + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * // Alternatively, you can wrap any view and get the stack from there + * // const viewFromSomewhere = fin.View.wrapSync(someView.identity); + * // const stack = await viewFromSomewhere.getCurrentStack(); + * const views = await stack.getViews(); + * console.log(`Stack contains ${views.length} view(s)`); + * ``` + * @experimental + */ + this.getViews = () => __classPrivateFieldGet$d(this, _TabStack_client, "f").getStackViews(this.entityId); + /** + * Adds or creates a view in this {@link TabStack}. + * + * @remarks Known Issue: If adding a view overflows the tab-container, the added view will be set as active + * and rendered at the front of the tab-stack, while the underlying order of tabs will remain unchanged. + * + * @param view The identity of an existing view to add, or options to create a view. + * @param options Optional view options: index number used to insert the view into the stack at that index. Defaults to 0 (front of the stack) + * @returns Resolves with the {@link OpenFin.Identity identity} of the added view. + * @throws If the view does not exist or fails to create. + * @throws If the {@link TabStack} has been destroyed. + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * // Alternatively, you can wrap any view and get the stack from there + * // const viewFromSomewhere = fin.View.wrapSync(someView.identity); + * // const stack = await viewFromSomewhere.getCurrentStack(); + * const googleViewIdentity = await stack.addView({ name: 'google-view', url: 'http://google.com/' }); + * console.log('Identity of the google view just added', { googleViewIdentity }); + * // pass in { index: number } to set the index in the stack. Here 1 means, end of the stack (defaults to 0) + * const appleViewIdentity = await stack.addView({ name: 'apple-view', url: 'http://apple.com/' }, { index: 1 }); + * console.log('Identity of the apple view just added', { appleViewIdentity }); + * ``` + * @experimental + */ + this.addView = async (view, options = { index: 0 }) => __classPrivateFieldGet$d(this, _TabStack_client, "f").addViewToStack(this.entityId, view, options); + /** + * Removes a view from this {@link TabStack}. + * + * @remarks Throws an exception if the view identity does not exist or was already destroyed. + * + * @param view - Identity of the view to remove. + * @throws If the view does not exist or does not belong to the stack. + * @throws If the {@link TabStack} has been destroyed. + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * const googleViewIdentity = await stack.addView({ name: 'google-view', url: 'http://google.com/' }); + * + * await stack.removeView(googleViewIdentity); + * + * try { + * await stack.removeView(googleViewIdentity); + * } catch (error) { + * // Tried to remove a view ('google-view') which does not belong to the stack. + * console.log(error); + * } + * ``` + */ + this.removeView = async (view) => { + await __classPrivateFieldGet$d(this, _TabStack_client, "f").removeViewFromStack(this.entityId, view); + }; + /** + * Sets the active view of the {@link TabStack} without focusing it. + * @param view - Identity of the view to activate. + * @returns Promise which resolves with void once the view has been activated. + * @throws If the {@link TabStack} has been destroyed. + * @throws If the view does not exist. + * @example + * Change the active tab of a known View's TabStack: + * ```js + * const targetView = fin.View.wrapSync({ uuid: 'uuid', name: 'view-name' }); + * const stack = await targetView.getCurrentStack(); + * await stack.setActiveView(targetView.identity); + * ``` + * + * Set the current View as active within its TabStack: + * ```js + * const stack = await fin.me.getCurrentStack(); + * await stack.setActiveView(fin.me.identity); + * ``` + * @experimental + */ + this.setActiveView = async (view) => { + await __classPrivateFieldGet$d(this, _TabStack_client, "f").setStackActiveView(this.entityId, view); + }; + __classPrivateFieldSet$b(this, _TabStack_client, client, "f"); + } +} +layoutEntities.TabStack = TabStack; +_TabStack_client = new WeakMap(); +/** + * A ColumnOrRow is used to manage the state of Column and Rows within an OpenFin Layout. + */ +class ColumnOrRow extends LayoutNode { + /** + * @internal + */ + constructor(client, entityId, type) { + super(client, entityId); + /** + * @ignore + * @internal + * ApiClient for {@link LayoutEntitiesController} + */ + _ColumnOrRow_client.set(this, void 0); + /** + * Retrieves the content array of the ColumnOrRow + * + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * // Retrieves the parent ColumnOrRow + * const columnOrRow = await stack.getParent(); + * + * // returns [TabStack] + * const contentArray = await columnOrRow.getContent(); + * console.log(`The ColumnOrRow has ${contentArray.length} item(s)`); + * ``` + */ + this.getContent = async () => { + const contentItemEntities = await __classPrivateFieldGet$d(this, _ColumnOrRow_client, "f").getContent(this.entityId); + return contentItemEntities.map((entity) => LayoutNode.getEntity(entity, __classPrivateFieldGet$d(this, _ColumnOrRow_client, "f"))); + }; + __classPrivateFieldSet$b(this, _ColumnOrRow_client, client, "f"); + this.type = type; + } +} +layoutEntities.ColumnOrRow = ColumnOrRow; +_ColumnOrRow_client = new WeakMap(); + +var layout_constants = {}; + +Object.defineProperty(layout_constants, "__esModule", { value: true }); +layout_constants.DEFAULT_LAYOUT_KEY = layout_constants.LAYOUT_CONTROLLER_ID = void 0; +layout_constants.LAYOUT_CONTROLLER_ID = 'layout-entities'; +// TODO: eventually export this somehow +layout_constants.DEFAULT_LAYOUT_KEY = '__default__'; + +var main = {}; + +Object.defineProperty(main, "__esModule", { value: true }); +main.WebContents = void 0; +const base_1$j = base; +class WebContents extends base_1$j.EmitterBase { + /** + * @param identity The identity of the {@link OpenFin.WebContentsEvents WebContents}. + * @param entityType The type of the {@link OpenFin.WebContentsEvents WebContents}. + */ + constructor(wire, identity, entityType) { + super(wire, entityType, identity.uuid, identity.name); + this.identity = identity; + this.entityType = entityType; + } + /** + * Gets a base64 encoded image of all or part of the WebContents. + * @param options Options for the capturePage call. + * + * @example + * + * View: + * ```js + * const view = fin.View.getCurrentSync(); + * + * // PNG image of a full visible View + * console.log(await view.capturePage()); + * + * // Low-quality JPEG image of a defined visible area of the view + * const options = { + * area: { + * height: 100, + * width: 100, + * x: 10, + * y: 10, + * }, + * format: 'jpg', + * quality: 20 + * } + * console.log(await view.capturePage(options)); + * ``` + * + * Window: + * ```js + * const wnd = await fin.Window.getCurrent(); + * + * // PNG image of a full visible window + * console.log(await wnd.capturePage()); + * + * // Low-quality JPEG image of a defined visible area of the window + * const options = { + * area: { + * height: 100, + * width: 100, + * x: 10, + * y: 10, + * }, + * format: 'jpg', + * quality: 20 + * } + * console.log(await wnd.capturePage(options)); + * ``` + * + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + capturePage(options) { + return this.wire.sendAction('capture-page', { options, ...this.identity }).then(({ payload }) => payload.data); + } + /** + * Executes Javascript on the WebContents, restricted to contents you own or contents owned by + * applications you have created. + * @param code JavaScript code to be executed on the view. + * + * @example + * View: + * ```js + * async function executeJavaScript(code) { + * const view = await fin.View.wrap({uuid: 'uuid', name: 'view name'}); + * return await view.executeJavaScript(code); + * } + * + * executeJavaScript(`console.log('Hello, Openfin')`).then(() => console.log('Javascript excuted')).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function executeJavaScript(code) { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.executeJavaScript.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.executeJavaScript(code); + * } + * + * executeJavaScript(`console.log('Hello, Openfin')`).then(() => console.log('Javascript excuted')).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + executeJavaScript(code) { + return this.wire + .sendAction('execute-javascript-in-window', { ...this.identity, code }) + .then(({ payload }) => payload.data); + } + /** + * Returns the zoom level of the WebContents. + * + * @example + * View: + * ```js + * async function getZoomLevel() { + * const view = await fin.View.getCurrent(); + * return await view.getZoomLevel(); + * } + * + * getZoomLevel().then(zoomLevel => console.log(zoomLevel)).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getZoomLevel.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function getZoomLevel() { + * const win = await createWin(); + * return await win.getZoomLevel(); + * } + * + * getZoomLevel().then(zoomLevel => console.log(zoomLevel)).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + getZoomLevel() { + return this.wire.sendAction('get-zoom-level', this.identity).then(({ payload }) => payload.data); + } + /** + * Sets the zoom level of the WebContents. + * @param level The zoom level + * + * @example + * View: + * ```js + * async function setZoomLevel(number) { + * const view = await fin.View.getCurrent(); + * return await view.setZoomLevel(number); + * } + * + * setZoomLevel(4).then(() => console.log('Setting a zoom level')).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.setZoomLevel.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function setZoomLevel(number) { + * const win = await createWin(); + * return await win.setZoomLevel(number); + * } + * + * setZoomLevel(4).then(() => console.log('Setting a zoom level')).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + setZoomLevel(level) { + return this.wire.sendAction('set-zoom-level', { ...this.identity, level }).then(() => undefined); + } + /** + * Navigates the WebContents to a specified URL. + * + * Note: The url must contain the protocol prefix such as http:// or https://. + * @param url - The URL to navigate the WebContents to. + * + * @example + * View: + * ```js + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewName', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * createView() + * .then(view => view.navigate('https://example.com')) + * .then(() => console.log('navigation complete')) + * .catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function navigate() { + * const win = await fin.Window.getCurrent(); + * return await win.navigate('https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.navigate.html'); + * } + * navigate().then(() => console.log('Navigate to tutorial')).catch(err => console.log(err)); + * ``` + * @experimental + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + navigate(url) { + return this.wire.sendAction('navigate-window', { ...this.identity, url }).then(() => undefined); + } + /** + * Navigates the WebContents back one page. + * + * @example + * View: + * ```js + * async function navigateBack() { + * const view = await fin.View.wrap({ name: 'testapp-view', uuid: 'testapp' }); + * await view.navigate('https://www.google.com'); + * return await view.navigateBack(); + * } + * navigateBack().then(() => console.log('Navigated back')).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function navigateBack() { + * const win = await fin.Window.wrap({ name: 'testapp', uuid: 'testapp' }); + * await win.navigate('https://www.google.com'); + * return await win.navigateBack(); + * } + * navigateBack().then(() => console.log('Navigated back')).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + navigateBack() { + return this.wire.sendAction('navigate-window-back', { ...this.identity }).then(() => undefined); + } + /** + * Navigates the WebContents forward one page. + * + * @example + * View: + * ```js + * async function navigateForward() { + * const view = await fin.View.getCurrent(); + * await view.navigate('https://www.google.com'); + * await view.navigateBack(); + * return await view.navigateForward(); + * } + * navigateForward().then(() => console.log('Navigated forward')).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function navigateForward() { + * const win = await fin.Window.getCurrent(); + * await win.navigate('https://www.google.com'); + * await win.navigateBack(); + * return await win.navigateForward(); + * } + * navigateForward().then(() => console.log('Navigated forward')).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async navigateForward() { + await this.wire.sendAction('navigate-window-forward', { ...this.identity }); + } + /** + * Stops any current navigation the WebContents is performing. + * + * @example + * View: + * ```js + * async function stopNavigation() { + * const view = await fin.View.wrap({ name: 'testapp-view', uuid: 'testapp' }); + * await view.navigate('https://www.google.com'); + * return await view.stopNavigation(); + * } + * stopNavigation().then(() => console.log('you shall not navigate')).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function stopNavigation() { + * const win = await fin.Window.wrap({ name: 'testapp', uuid: 'testapp' }); + * await win.navigate('https://www.google.com'); + * return await win.stopNavigation(); + * } + * stopNavigation().then(() => console.log('you shall not navigate')).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + stopNavigation() { + return this.wire.sendAction('stop-window-navigation', { ...this.identity }).then(() => undefined); + } + /** + * Reloads the WebContents + * + * @example + * View: + * ```js + * async function reload() { + * const view = await fin.View.getCurrent(); + * return await view.reload(); + * } + * + * reload().then(() => { + * console.log('Reloaded view') + * }).catch(err => console.log(err)); + * ``` + * + * Window: + * ```js + * async function reloadWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.reload.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.reload(); + * } + * + * reloadWindow().then(() => { + * console.log('Reloaded window') + * }).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + reload(ignoreCache = false) { + return this.wire + .sendAction('reload-window', { + ignoreCache, + ...this.identity + }) + .then(() => undefined); + } + /** + * Prints the WebContents. + * @param options Printer Options + * + * Note: When `silent` is set to `true`, the API will pick the system's default printer if deviceName + * is empty and the default settings for printing. + * + * Use the CSS style `page-break-before: always;` to force print to a new page. + * + * @example + * ```js + * const view = fin.View.getCurrentSync(); + * + * view.print({ silent: false, deviceName: 'system-printer-name' }).then(() => { + * console.log('print call has been sent to the system'); + * }); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + print(options = {}) { + return this.wire.sendAction('print', { ...this.identity, options }).then(() => undefined); + } + /** + * Find and highlight text on a page. + * @param searchTerm Term to find in page + * @param options Search options + * + * Note: By default, each subsequent call will highlight the next text that matches the search term. + * + * Returns a promise with the results for the request. By subscribing to the + * found-in-page event, you can get the results of this call as well. + * + * @example + * View: + * ```js + * const view = fin.View.getCurrentSync(); + * + * //By subscribing to the 'found in page' event we can get the results of each findInPage call made. + * view.addListener('found-in-page', (event) => { + * console.log(event); + * }); + * + * // The promise also returns the results for the request + * view.findInPage('a').then((result) => { + * console.log(result) + * }); + * ``` + * + * Window: + * ```js + * const win = fin.Window.getCurrentSync(); + * + * //By subscribing to the 'found in page' event we can get the results of each findInPage call made. + * win.addListener('found-in-page', (event) => { + * console.log(event); + * }); + * + * // The promise also returns the results for the request + * win.findInPage('a').then((result) => { + * console.log(result) + * }); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + findInPage(searchTerm, options) { + return this.wire + .sendAction('find-in-page', { ...this.identity, searchTerm, options }) + .then(({ payload }) => payload.data); + } + /** + * Stop a {@link View#findInPage findInPage} call by specifying any of these actions: + * + * * clearSelection - Clear the selection. + * * keepSelection - Translate the selection into a normal selection. + * * activateSelection - Focus and click the selection node. + * + * @example + * View: + * ```js + * const view = fin.View.getCurrentSync(); + * + * view.addListener('found-in-page', (event) => { + * setTimeout(() => { + * view.stopFindInPage('clearSelection'); + * }, 5000); + * }); + * + * view.findInPage('a').then(results => { + * console.log(results); + * }); + * ``` + * + * Window: + * ```js + * const win = fin.Window.getCurrentSync(); + * + * win.addListener('found-in-page', (event) => { + * setTimeout(() => { + * win.stopFindInPage('clearSelection'); + * }, 5000); + * }); + * + * win.findInPage('a').then(results => { + * console.log(results); + * }); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + stopFindInPage(action) { + return this.wire.sendAction('stop-find-in-page', { ...this.identity, action }).then(() => undefined); + } + /** + * Returns an array with all system printers + * @deprecated use System.getPrinters instead + * + * @example + * View: + * ```js + * const view = fin.View.getCurrentSync(); + * + * view.getPrinters() + * .then((printers) => { + * printers.forEach((printer) => { + * if (printer.isDefault) { + * console.log(printer); + * } + * }); + * }) + * .catch((err) => { + * console.log(err); + * }); + * ``` + * + * Window: + * ```js + * const win = fin.Window.getCurrentSync(); + * + * win.getPrinters() + * .then((printers) => { + * printers.forEach((printer) => { + * if (printer.isDefault) { + * console.log(printer); + * } + * }); + * }) + * .catch((err) => { + * console.log(err); + * }); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + getPrinters() { + return this.wire.sendAction('get-printers', { ...this.identity }).then(({ payload }) => payload.data); + } + /** + * Gives focus to the WebContents. + * + * @example + * ```js + * async function focusWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.focus.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.focus(); + * } + * + * focusWindow().then(() => console.log('Window focused')).catch(err => console.log(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async focus({ emitSynthFocused } = { emitSynthFocused: true }) { + await this.wire.sendAction('focus-window', { emitSynthFocused, ...this.identity }); + } + /** + * Shows the Chromium Developer Tools + * + * @example + * View: + * ```js + * async function showDeveloperTools() { + * const view = await fin.View.getCurrent(); + * return view.showDeveloperTools(); + * } + * + * showDevelopertools() + * .then(() => console.log('Showing dev tools')) + * .catch(err => console.error(err)); + * ``` + * + * Window: + * ```js + * async function showDeveloperTools() { + * const win = await fin.Window.getCurrent(); + * return win.showDeveloperTools(); + * } + * + * showDevelopertools() + * .then(() => console.log('Showing dev tools')) + * .catch(err => console.error(err)); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async showDeveloperTools() { + // Note this hits the system action map in core state for legacy reasons. + await this.wire.sendAction('show-developer-tools', this.identity); + } + /** + * Retrieves the process information associated with a WebContents. + * + * Note: This includes any iframes associated with the WebContents + * + * @example + * View: + * ```js + * const view = await fin.View.getCurrent(); + * const processInfo = await view.getProcessInfo(); + * ``` + * + * Window: + * ```js + * const win = await fin.Window.getCurrent(); + * const processInfo = await win.getProcessInfo(); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async getProcessInfo() { + const { payload: { data } } = await this.wire.sendAction('get-process-info', this.identity); + return data; + } + /** + * Retrieves information on all Shared Workers. + * + * @example + * View: + * ```js + * const view = await fin.View.create({ + * name: 'viewName', + * target: fin.me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * + * await view.navigate('https://mdn.github.io/dom-examples/web-workers/simple-shared-worker/'); + * + * const sharedWorkers = await view.getSharedWorkers(); + * ``` + * + * Window: + * ```js + * const winOption = { + * name:'child', + * defaultWidth: 300, + * defaultHeight: 300, + * url: 'https://mdn.github.io/dom-examples/web-workers/simple-shared-worker/', + * frame: true, + * autoShow: true + * }; + * const win = await fin.Window.create(winOption); + * const sharedWorkers = await win.getSharedWorkers(); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async getSharedWorkers() { + return this.wire.sendAction('get-shared-workers', this.identity).then(({ payload }) => payload.data); + } + /** + * Opens the developer tools for the shared worker context. + * + * @example + * View: + * ```js + * const view = await fin.View.create({ + * name: 'viewName', + * target: fin.me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * + * await view.navigate('https://mdn.github.io/dom-examples/web-workers/simple-shared-worker/'); + * + * await view.inspectSharedWorker(); + * ``` + * + * Example: + * ```js + * const winOption = { + * name:'child', + * defaultWidth: 300, + * defaultHeight: 300, + * url: 'https://mdn.github.io/dom-examples/web-workers/simple-shared-worker/', + * frame: true, + * autoShow: true + * }; + * const win = await fin.Window.create(winOption); + * await win.inspectSharedWorker(); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async inspectSharedWorker() { + await this.wire.sendAction('inspect-shared-worker', { ...this.identity }); + } + /** + * Inspects the shared worker based on its ID. + * @param workerId - The id of the shared worker. + * + * @example + * View: + * ```js + * const view = await fin.View.create({ + * name: 'viewName', + * target: fin.me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * + * await view.navigate('https://mdn.github.io/dom-examples/web-workers/simple-shared-worker/'); + * + * const sharedWorkers = await view.getSharedWorkers(); + * await view.inspectSharedWorkerById(sharedWorkers[0].id); + * ``` + * + * Window: + * ```js + * const winOption = { + * name:'child', + * defaultWidth: 300, + * defaultHeight: 300, + * url: 'https://mdn.github.io/dom-examples/web-workers/simple-shared-worker/', + * frame: true, + * autoShow: true + * }; + * const win = await fin.Window.create(winOption); + * const sharedWorkers = await win.getSharedWorkers(); + * await win.inspectSharedWorkerById(sharedWorkers[0].id); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async inspectSharedWorkerById(workerId) { + await this.wire.sendAction('inspect-shared-worker-by-id', { ...this.identity, workerId }); + } + /** + * Opens the developer tools for the service worker context. + * + * @example + * View: + * ```js + * const view = await fin.View.create({ + * name: 'viewName', + * target: fin.me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * + * await view.navigate('http://googlechrome.github.io/samples/service-worker/basic/index.html'); + * + * await view.inspectServiceWorker(); + * ``` + * + * Window: + * ```js + * const winOption = { + * name:'child', + * defaultWidth: 300, + * defaultHeight: 300, + * url: 'http://googlechrome.github.io/samples/service-worker/basic/index.html', + * frame: true, + * autoShow: true + * }; + * const win = await fin.Window.create(winOption); + * await win.inspectServiceWorker(); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async inspectServiceWorker() { + await this.wire.sendAction('inspect-service-worker', { ...this.identity }); + } + /** + * Shows a popup window. + * + * Note: If this WebContents is a view and its attached window has a popup open, this will close it. + * + * Shows a popup window. Including a `name` in `options` will attempt to show an existing window as a popup, if + * that window doesn't exist or no `name` is included a window will be created. If the caller view or the caller + * view's parent window currently has a popup window open, calling `showPopupWindow` again will dismiss the currently + * open popup window before showing the new popup window. Also, if the caller view is destroyed or detached, the popup + * will be dismissed. + * + * Note: in the case where the window being shown as a popup needs to be created, it is a child of the caller view's parent window. + * + * @example + * + * Create and show a single-use popup window that returns a single result to the caller. `initialOptions` allows + * us to pass window options to the popup window that will be created. `resultDispatchBehavior: 'close'` ensures + * that once the popup window calls `dispatchPopupResult` it is closed. `blurBehavior: 'close'` will yield a dismissed + * result should the popup window lose focus. + * + * ```js + * const result = await fin.me.showPopupWindow({ + * initialOptions: { + * frame: false + * }, + * url: '', + * resultDispatchBehavior: 'close', + * blurBehavior: 'close', + * focus: true, + * height: 300, + * width: 300, + * x: 0, + * y: 0 + * }); + * ``` + * + * Same as above but using an existing window as a popup by referencing its `name`: + * + * Note: if a window with the `name` provided doesn't exist, it will be created. + * + * ```js + * const result = await fin.me.showPopupWindow({ + * initialOptions: { + * frame: true + * }, + * name: 'my-popup', // shows the 'my-popup' window if it exists, otherwise creates it + * url: '', // navigates to this url if it doesn't match the location.href of the 'my-popup' window + * resultDispatchBehavior: 'close', + * blurBehavior: 'close', + * focus: true, + * hideOnClose: true, // persist window on 'dismissed' result, alternatively change onResultDispatch and blurBehavior to 'hide' + * height: 300, + * width: 300, + * x: 0, + * y: 0 + * }); + * ``` + * + * Create and show a popup window that is able to return multiple results to the caller via an `onPopupResult` callback. Each + * time the popup window calls `dispatchPopupResult`, the callback will be executed on the result. Once the popup window is + * closed or hidden, the `showPopupWindow` promise will resolve with a `dismissed` result that will include the most recently + * dispatched result as `lastDispatchResult`: + * + * ```js + * const popupResultCallback = (payload) => { + * if (payload.result === 'clicked') { + * if (payload.data.topic === 'color-changed') { + * // do something like + * // setColor(payload.data.value); + * } + * } + * }; + * + * await fin.me.showPopupWindow({ + * initialOptions: { + * frame: false + * }, + * url: '', + * resultDispatchBehavior: 'none', + * blurBehavior: 'close', + * focus: true, + * height: 300, + * width: 300, + * x: 0, + * y: 0, + * onPopupResult: popupResultCallback + * }); + * ``` + * + * Same as above but using an existing window as a popup: + * + * ```js + * const popupResultCallback = (payload) => { + * if (payload.result === 'clicked') { + * if (payload.data.topic === 'color-changed') { + * // do something like + * // setColor(payload.data.value); + * } + * } + * }; + * + * await fin.me.showPopupWindow({ + * initialOptions: { + * frame: false + * }, + * name: 'my-popup', // shows the 'my-popup' window if it exists, otherwise creates it + * url: '', // navigates to this url if it doesn't match the location.href of the 'my-popup' window + * resultDispatchBehavior: 'none', + * blurBehavior: 'hide', + * focus: true, + * hideOnClose: true, // we can just use this or we can change blurBehavior to 'hide' + * height: 300, + * width: 300, + * x: 0, + * y: 0, + * onPopupResult: popupResultCallback + * }); + * ``` + * + * Create or show a popup window that disables user movement (positioning and resizing) in the caller + * view's parent window by using `blurBehavior: 'modal'`: + * + * ```js + * const result = await fin.me.showPopupWindow({ + * initialOptions: { + * frame: false + * }, + * url: '', + * resultDispatchBehavior: 'close', + * blurBehavior: 'modal', + * focus: true, + * height: 300, + * width: 300, + * x: 0, + * y: 0 + * }); + * ``` + * + * Create a popup window as a modal: + * + * Note: The only way to ensure true modal behavior is to create the window being shown as a popup with a + * `modalParentIdentity` that uses the caller view's parent window identity. + * + * ```js + * const result = await fin.me.showPopupWindow({ + * initialOptions: { + * frame: false, + * modalParentIdentity: fin.me.identity + * }, + * url: '', + * resultDispatchBehavior: 'close', + * blurBehavior: 'modal', + * focus: true, + * height: 300, + * width: 300, + * x: 0, + * y: 0 + * }); + * ``` + * + * Pass data to a popup window that is available when the popup is shown. + * + * Note: this is just one example for a use of `additionalOptions`, it can be used to update any updatable + * window options when creating or showing an existing window as a popup. + * + * ```js + * const result = await fin.me.showPopupWindow({ + * additionalOptions: { + * customData: { + * foo: 'bar' + * } + * }, + * url: '', + * resultDispatchBehavior: 'close', + * blurBehavior: 'close', + * focus: true, + * height: 300, + * width: 300, + * x: 0, + * y: 0 + * }); + * + * // Access from the popup window context like so: + * const { customData } = await fin.me.getOptions(); + * const { foo } = customData; + * ``` + * + * Execute a callback on the popup's OpenFin window when the popup is shown: + * + * ```js + * const popupWindowCallback = async (win) => { + * await win.flash(); + * }; + * + * const result = await fin.me.showPopupWindow({ + * url: '', + * resultDispatchBehavior: 'close', + * blurBehavior: 'close', + * focus: true, + * height: 300, + * width: 300, + * x: 0, + * y: 0, + * onPopupReady: popupWindowCallback; + * }); + * ``` + * @remarks + * `WebContents` refers to shared functionality between {@link OpenFin.Window} and {@link OpenFin.View}. + * We do not expose an explicit superclass for this functionality, but it does have its own + * {@link OpenFin.WebContentsEvents event namespace}. + */ + async showPopupWindow(options) { + this.wire.sendAction(`${this.entityType}-show-popup-window`, this.identity).catch(() => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + if (options?.onPopupReady) { + const readyListener = async ({ popupName }) => { + try { + const popupWindow = this.fin.Window.wrapSync({ uuid: this.fin.me.uuid, name: popupName }); + await options.onPopupReady(popupWindow); + } + catch (error) { + throw new Error(`Something went wrong during onPopupReady execution: ${error}`); + } + }; + // TODO: fix typing (internal) + // @ts-expect-error + await this.once('popup-ready', readyListener); + } + const { payload: tryCreatePayload } = await this.wire.sendAction('try-create-popup-window', { + options: { + ...options, + // Internal use only. + // @ts-expect-error + hasResultCallback: !!options?.onPopupResult, + hasReadyCallback: !!options?.onPopupReady + }, + ...this.identity + }); + const { data: { willOpen, options: popupOptions } } = tryCreatePayload; + if (willOpen) { + // Solve the issue where Interop in a popup window with non cross-origin url is not working(core-1076). + await this.fin.Window.create(popupOptions.initialOptions); + } + const normalizePopupResult = (payload) => { + const { name, uuid, result, data } = payload; + const popupResult = { + identity: { + name, + uuid + }, + result + }; + if (data) { + popupResult.data = data; + } + return popupResult; + }; + if (options?.onPopupResult) { + const dispatchResultListener = async (payload) => { + await options.onPopupResult(normalizePopupResult(payload)); + }; + const teardownListener = async () => { + // TODO: fix typing (internal) + // @ts-expect-error + await this.removeListener('popup-result', dispatchResultListener); + }; + // TODO: fix typing (internal) + // @ts-expect-error + await this.on('popup-result', dispatchResultListener); + // TODO: fix typing (internal) + // hilariously this does not need a ts-expect-error - this is gap in type soundness + // should investigate - probably due to `teardownListener` taking a void argument + // which might play nicely with the `never` type? huh... + await this.once('popup-teardown', teardownListener); + } + const { payload } = await this.wire.sendAction('show-popup-window', { + options: popupOptions, + ...this.identity + }); + return payload.data; + } +} +main.WebContents = WebContents; + +var hasRequiredInstance$2; + +function requireInstance$2 () { + if (hasRequiredInstance$2) return Instance$5; + hasRequiredInstance$2 = 1; + var __classPrivateFieldGet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + var _View_providerChannelClient; + Object.defineProperty(Instance$5, "__esModule", { value: true }); + Instance$5.View = void 0; + const transport_errors_1 = transportErrors; + const lazy_1 = lazy; + const layout_entities_1 = layoutEntities; + const layout_constants_1 = layout_constants; + const main_1 = main; + const window_1 = requireWindow(); + /** + * A View can be used to embed additional web content into a Window. + * It is like a child window, except it is positioned relative to its owning window. + * It has the ability to listen for {@link OpenFin.ViewEvents View-specific events}. + * + * By default, a View will try to share the same renderer process as other Views owned by its parent Application. + * To change that behavior, see the processAffinity {@link OpenFin.ViewOptions view option}. + * + * A View's lifecycle is tied to its owning window and can be re-attached to a different window at any point during its lifecycle. + */ + class View extends main_1.WebContents { + /** + * @internal + */ + constructor(wire, identity) { + super(wire, identity, 'view'); + this.identity = identity; + _View_providerChannelClient.set(this, new lazy_1.Lazy(() => { + const platform = this.fin.Platform.wrapSync(this.identity); + return platform.getClient(); + })); + /** + * Attaches the current view to the given window identity. + * Identity must be the identity of a window in the same application. + * This detaches the view from its current window, and sets the view to be destroyed when its new window closes. + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameAttach', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function attachView() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * + * const winOption = { + * name:'winOptionName', + * defaultWidth: 300, + * defaultHeight: 300, + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.create.html', + * frame: true, + * autoShow: true + * }; + * const newWindow = await fin.Window.create(winOption); + * view.attach(newWindow.identity); + * } + * + * attachView() + * .then(() => console.log('View attached to new window.')) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.attach = async (target) => { + await this.wire.sendAction('attach-view', { target, ...this.identity }); + }; + /** + * Destroys the current view + * + * @example + * ```js + * const view = fin.View.wrapSync({ uuid: 'viewUuid', name: 'viewName' }); + * view.destroy(); + * ``` + * @experimental + */ + this.destroy = async () => { + await this.wire.sendAction('destroy-view', { ...this.identity }); + }; + /** + * Shows the current view if it is currently hidden. + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameShow', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function hideAndShowView() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url option.'); + * + * await view.hide(); + * console.log("View hidden."); + * + * view.show(); + * console.log("View shown."); + * } + * + * hideAndShowView() + * .then(() => console.log('View hidden and shown.')) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.show = async () => { + await this.wire.sendAction('show-view', { ...this.identity }); + }; + /** + * Sets the bounds (top, left, width, height) of the view relative to its window and shows it if it is hidden. + * This method ensures the view is both positioned and showing. It will reposition a visible view and both show and reposition a hidden view. + * + * @remarks View position is relative to the bounds of the window. + * ({top: 0, left: 0} represents the top left corner of the window) + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameSetBounds', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function showViewAt() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * + * await view.showAt({ + * top: 100, + * left: 100, + * width: 300, + * height: 300 + * }, { + * bringToFront : true + * }); + * } + * + * showViewAt() + * .then(() => console.log('View set to new bounds and shown.')) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.showAt = async (bounds, options = {}) => { + await this.wire.sendAction('show-view-at', { bounds, ...this.identity, options }); + }; + /** + * Brings the specified view to the front of its current window. This ensures the view will be visible on top of any other views + * which have overlapping bounds with it. + * + * Please note, this is not a permanent action - when a new view is created or attached to the window, it will display on top of all other views + * in the window that share bounds with it. + */ + this.bringToFront = async () => { + await this.wire.sendAction('bring-view-to-front', { ...this.identity }); + }; + /** + * Hides the current view if it is currently visible. + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameHide', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function hideView() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * + * await view.hide(); + * } + * + * hideView() + * .then(() => console.log('View hidden.')) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.hide = async () => { + await this.wire.sendAction('hide-view', { ...this.identity }); + }; + /** + * Sets the bounds (top, left, width, height) of the view relative to its window. + * + * @remarks View position is relative to the bounds of the window. + * ({top: 0, left: 0} represents the top left corner of the window) + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameSetBounds', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function setViewBounds() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * + * await view.setBounds({ + * top: 100, + * left: 100, + * width: 300, + * height: 300 + * }); + * } + * + * setViewBounds() + * .then(() => console.log('View set to new bounds.')) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.setBounds = async (bounds) => { + await this.wire.sendAction('set-view-bounds', { bounds, ...this.identity }); + }; + /** + * Gets the bounds (top, left, width, height) of the view relative to its window. + * + * @remarks View position is relative to the bounds of the window. + * ({top: 0, left: 0} represents the top left corner of the window) + * + * @example + * ```js + * const view = await fin.View.create({ + * name: 'viewNameSetBounds', + * target: fin.me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * + * await view.navigate('https://google.com'); + * + * await view.setBounds({ + * top: 100, + * left: 100, + * width: 300, + * height: 300 + * }); + * + * console.log(await view.getBounds()); + * ``` + * @experimental + */ + this.getBounds = async () => { + const ack = await this.wire.sendAction('get-view-bounds', { ...this.identity }); + return ack.payload.data; + }; + /** + * Gets the View's info. + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameGetInfo', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function getViewInfo() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * + * return view.getInfo(); + * } + * + * getViewInfo() + * .then((info) => console.log('View info fetched.', info)) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.getInfo = async () => { + const ack = await this.wire.sendAction('get-view-info', { ...this.identity }); + return ack.payload.data; + }; + /** + * Retrieves the layout for the window the view is attached to. + * + * @example + * ```js + * //get the current View + * const view = await fin.View.getCurrent(); + * + * //get a reference to the Layout for the Window the view is part of + * const layout = await view.getParentLayout(); + * ``` + * @experimental + */ + this.getParentLayout = async () => { + this.wire.sendAction('view-get-parent-layout', { ...this.identity }).catch(() => { + // don't expose + }); + const layoutWindow = await this.getCurrentWindow(); + let layoutWindowIdentity = layoutWindow.identity; + // TODO: CORE-1857 - when we tearout active layout or drag a view out of a window, the above identity includes the whole window info. + if (layoutWindowIdentity.identity) { + layoutWindowIdentity = layoutWindowIdentity.identity; + } + try { + const providerChannelClient = await __classPrivateFieldGet(this, _View_providerChannelClient, "f").getValue(); + const client = await layout_entities_1.LayoutNode.newLayoutEntitiesClient(providerChannelClient, layout_constants_1.LAYOUT_CONTROLLER_ID, layoutWindowIdentity); + const layoutIdentity = await client.getLayoutIdentityForViewOrThrow(this.identity); + return this.fin.Platform.Layout.wrap(layoutIdentity); + } + catch (e) { + const allowedErrors = [ + 'No action registered at target for', + 'getLayoutIdentityForViewOrThrow is not a function' + ]; + if (!allowedErrors.some((m) => e.message.includes(m))) { + throw e; + } + // fallback logic for missing endpoint + return this.fin.Platform.Layout.wrap(layoutWindowIdentity); + } + }; + /** + * Gets the View's options. + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * name: 'viewNameGetOptions', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function getViewOptions() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url.'); + * + * const me = await fin.Window.getCurrent(); + * view = fin.View.wrapSync({ uuid: me.identity.uuid, name: 'viewNameGetOptions' }); + * return view.getOptions(); + * } + * + * getViewOptions() + * .then((info) => console.log('View options fetched.', info)) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.getOptions = async () => { + return this.wire.sendAction('get-view-options', { ...this.identity }).then(({ payload }) => payload.data); + }; + /** + * Updates the view's options. + * + * @example + * ```js + * let view; + * async function createView() { + * const me = await fin.Window.getCurrent(); + * return fin.View.create({ + * url: 'https://google.com', + * name: 'viewNameUpdateOptions', + * target: me.identity, + * bounds: {top: 10, left: 10, width: 200, height: 200} + * }); + * } + * + * async function updateViewOptions() { + * view = await createView(); + * console.log('View created.'); + * + * await view.navigate('https://google.com'); + * console.log('View navigated to given url option.'); + * + * const newOptions = { autoResize: { + * width: true, + * horizontal: true + * }}; + * return view.updateOptions(newOptions); + * } + * + * updateViewOptions() + * .then(payload => console.log('View options updated: ', payload)) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + this.updateOptions = async (options) => { + return this.wire.sendAction('update-view-options', { options, ...this.identity }).then(() => undefined); + }; + /** + * Retrieves the window the view is currently attached to. + * + * @example + * ```js + * const view = fin.View.wrapSync({ uuid: 'viewUuid', name: 'viewName' }); + * view.getCurrentWindow() + * .then(win => console.log('current window', win)) + * .catch(err => console.log(err));) + * ``` + * @experimental + */ + this.getCurrentWindow = async () => { + const { payload: { data } } = await this.wire.sendAction('get-view-window', { ...this.identity }); + return new window_1._Window(this.wire, data); + }; + /** + * Retrieves the current {@link OpenFin.TabStack} of the view if it belongs to one. + * @returns this view belongs to. + * @throws if this view does not belong to a TabStack or if the window has been destroyed. + * @example + * ```js + * if (!fin.me.isView) { + * throw new Error('Not running in a platform View.'); + * } + * + * const stack = await fin.me.getCurrentStack(); + * // Alternatively, you can wrap any view and get the stack from there + * // const viewFromSomewhere = fin.View.wrapSync(someView.identity); + * // const stack = await viewFromSomewhere.getCurrentStack(); + * const views = await stack.getViews(); + * console.log(`Stack contains ${views.length} view(s)`); + * ``` + */ + this.getCurrentStack = async () => { + this.wire.sendAction('view-get-current-stack').catch(() => { + // don't expose + }); + try { + const layoutWindow = await this.getCurrentWindow(); + const providerChannelClient = await __classPrivateFieldGet(this, _View_providerChannelClient, "f").getValue(); + const client = await layout_entities_1.LayoutNode.newLayoutEntitiesClient(providerChannelClient, layout_constants_1.LAYOUT_CONTROLLER_ID, layoutWindow.identity); + const stackDefinition = (await client.getStackByView(this.identity)); + return layout_entities_1.LayoutNode.getEntity(stackDefinition, client); + } + catch (error) { + throw new transport_errors_1.RuntimeError({ reason: 'This view does not belong to a stack.', error }); + } + }; + /** + * Triggers the before-unload handler for the View, if one is set. + * + * @remarks Returns `true` if the handler is trying to prevent the View from unloading, and `false` if it isn't. + * Only enabled when setting enableBeforeUnload: true in your View options. If this option is not enabled it will + * always return false. + * + * This method is used internally by the Platform Provider to determine the status of each before unload handler in Views when closing the Window. + * + * @example + * + * ```js + * // from inside a View context + * const unloadPrevented = await fin.me.triggerBeforeUnload(); + * ``` + * + * @experimental + */ + this.triggerBeforeUnload = async () => { + const message = await this.wire.sendAction('trigger-before-unload', { ...this.identity }); + return message.payload.data; + }; + /** + * **NOTE**: Internal use only. + * Attaches this view to an HTML element in the current context. The view will resize responsively when the element bounds change. + * + * **Known issue**: View.bindToElement does not track position changes, if the element has fixed px width and height values it is possible for the view to not update responsively. + * + * **Known issue**: When View.bindToElement is used on a element that takes up the entire page in a platform window, the bound view will not respond responsively when the window is resized to be smaller. + * + * @param element - HTML element to attach the view to. + * @returns - Cleanup function that will disconnect the element resize observer. + * @internal + * @experimental + * @remarks View will resize accordingly when the element is resized. If the element is repositioned in the DOM the view will not be repositioned, to handle this case call `bindToElement` again once the element changes position. + * + * @example + * ```html + *
+ * + * ``` + */ + this.bindToElement = async (element) => { + if (!element) { + throw new Error('Element not found.'); + } + const onChange = async (bounds) => this.setBounds(bounds); + return this.wire.environment.observeBounds(element, onChange); + }; + } + /** + * Focuses the view + * + * @example + * ```js + * const view = fin.View.wrapSync({ uuid: 'viewUuid', name: 'viewName' }); + * await view.focus(); + * // do things with the focused view + * ``` + * @experimental + */ + async focus({ emitSynthFocused } = { emitSynthFocused: true }) { + const win = await this.getCurrentWindow(); + await win.focusedWebViewWasChanged(); + await super.focus({ emitSynthFocused }); + } + } + Instance$5.View = View; + _View_providerChannelClient = new WeakMap(); + return Instance$5; +} + +var hasRequiredView; + +function requireView () { + if (hasRequiredView) return view; + hasRequiredView = 1; + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + /** + * Entry points for the OpenFin `View` API (`fin.View`). + * + * * {@link ViewModule} contains static members of the `View` API, accessible through `fin.View`. + * * {@link View} describes an instance of an OpenFin View, e.g. as returned by `fin.View.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * @packageDocumentation + */ + __exportStar(requireFactory$3(), exports); + __exportStar(requireInstance$2(), exports); + } (view)); + return view; +} + +var hasRequiredInstance$1; + +function requireInstance$1 () { + if (hasRequiredInstance$1) return Instance$6; + hasRequiredInstance$1 = 1; + Object.defineProperty(Instance$6, "__esModule", { value: true }); + Instance$6.Application = void 0; + /* eslint-disable import/prefer-default-export */ + const base_1 = base; + const window_1 = requireWindow(); + const view_1 = requireView(); + /** + * An object representing an application. Allows the developer to create, + * execute, show/close an application as well as listen to {@link OpenFin.ApplicationEvents application events}. + */ + class Application extends base_1.EmitterBase { + /** + * @internal + */ + constructor(wire, identity) { + super(wire, 'application', identity.uuid); + this.identity = identity; + this.window = new window_1._Window(this.wire, { + uuid: this.identity.uuid, + name: this.identity.uuid + }); + } + windowListFromIdentityList(identityList) { + const windowList = []; + identityList.forEach((identity) => { + windowList.push(new window_1._Window(this.wire, { + uuid: identity.uuid, + name: identity.name + })); + }); + return windowList; + } + /** + * Determines if the application is currently running. + * + * @example + * + * ```js + * async function isAppRunning() { + * const app = await fin.Application.getCurrent(); + * return await app.isRunning(); + * } + * isAppRunning().then(running => console.log(`Current app is running: ${running}`)).catch(err => console.log(err)); + * ``` + */ + isRunning() { + return this.wire.sendAction('is-application-running', this.identity).then(({ payload }) => payload.data); + } + /** + * Closes the application and any child windows created by the application. + * Cleans the application from state so it is no longer found in getAllApplications. + * @param force Close will be prevented from closing when force is false and + * ‘close-requested’ has been subscribed to for application’s main window. + * + * @example + * + * ```js + * async function closeApp() { + * const allApps1 = await fin.System.getAllApplications(); //[{uuid: 'app1', isRunning: true}, {uuid: 'app2', isRunning: true}] + * const app = await fin.Application.wrap({uuid: 'app2'}); + * await app.quit(); + * const allApps2 = await fin.System.getAllApplications(); //[{uuid: 'app1', isRunning: true}] + * + * } + * closeApp().then(() => console.log('Application quit')).catch(err => console.log(err)); + * ``` + */ + async quit(force = false) { + try { + await this._close(force); + await this.wire.sendAction('destroy-application', { force, ...this.identity }); + } + catch (error) { + const acceptableErrors = ['Remote connection has closed', 'Could not locate the requested application']; + if (!acceptableErrors.some((msg) => error.message.includes(msg))) { + throw error; + } + } + } + async _close(force = false) { + try { + await this.wire.sendAction('close-application', { force, ...this.identity }); + } + catch (error) { + if (!error.message.includes('Remote connection has closed')) { + throw error; + } + } + } + /** + * @deprecated use Application.quit instead + * Closes the application and any child windows created by the application. + * @param force - Close will be prevented from closing when force is false and ‘close-requested’ has been subscribed to for application’s main window. + * @param callback - called if the method succeeds. + * @param errorCallback - called if the method fails. The reason for failure is passed as an argument. + * + * @example + * + * ```js + * async function closeApp() { + * const app = await fin.Application.getCurrent(); + * return await app.close(); + * } + * closeApp().then(() => console.log('Application closed')).catch(err => console.log(err)); + * ``` + */ + close(force = false) { + console.warn('Deprecation Warning: Application.close is deprecated Please use Application.quit'); + this.wire.sendAction('application-close', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this._close(force); + } + /** + * Retrieves an array of wrapped fin.Windows for each of the application’s child windows. + * + * @example + * + * ```js + * async function getChildWindows() { + * const app = await fin.Application.getCurrent(); + * return await app.getChildWindows(); + * } + * + * getChildWindows().then(children => console.log(children)).catch(err => console.log(err)); + * ``` + */ + getChildWindows() { + return this.wire.sendAction('get-child-windows', this.identity).then(({ payload }) => { + const identityList = []; + payload.data.forEach((winName) => { + identityList.push({ uuid: this.identity.uuid, name: winName }); + }); + return this.windowListFromIdentityList(identityList); + }); + } + /** + * Retrieves the JSON manifest that was used to create the application. Invokes the error callback + * if the application was not created from a manifest. + * + * @example + * + * ```js + * async function getManifest() { + * const app = await fin.Application.getCurrent(); + * return await app.getManifest(); + * } + * + * getManifest().then(manifest => console.log(manifest)).catch(err => console.log(err)); + * ``` + */ + getManifest() { + return this.wire.sendAction('get-application-manifest', this.identity).then(({ payload }) => payload.data); + } + /** + * Retrieves UUID of the application that launches this application. Invokes the error callback + * if the application was created from a manifest. + * + * @example + * + * ```js + * async function getParentUuid() { + * const app = await fin.Application.start({ + * uuid: 'app-1', + * name: 'myApp', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Application.getParentUuid.html', + * autoShow: true + * }); + * return await app.getParentUuid(); + * } + * + * getParentUuid().then(parentUuid => console.log(parentUuid)).catch(err => console.log(err)); + * ``` + */ + getParentUuid() { + return this.wire.sendAction('get-parent-application', this.identity).then(({ payload }) => payload.data); + } + /** + * Retrieves current application's shortcut configuration. + * + * @example + * + * ```js + * async function getShortcuts() { + * const app = await fin.Application.wrap({ uuid: 'testapp' }); + * return await app.getShortcuts(); + * } + * getShortcuts().then(config => console.log(config)).catch(err => console.log(err)); + * ``` + */ + getShortcuts() { + return this.wire.sendAction('get-shortcuts', this.identity).then(({ payload }) => payload.data); + } + /** + * Retrieves current application's views. + * @experimental + * + * @example + * + * ```js + * async function getViews() { + * const app = await fin.Application.getCurrent(); + * return await app.getViews(); + * } + * getViews().then(views => console.log(views)).catch(err => console.log(err)); + * ``` + */ + async getViews() { + const { payload } = await this.wire.sendAction('application-get-views', this.identity); + return payload.data.map((id) => new view_1.View(this.wire, id)); + } + /** + * Returns the current zoom level of the application. + * + * @example + * + * ```js + * async function getZoomLevel() { + * const app = await fin.Application.getCurrent(); + * return await app.getZoomLevel(); + * } + * + * getZoomLevel().then(zoomLevel => console.log(zoomLevel)).catch(err => console.log(err)); + * ``` + */ + getZoomLevel() { + return this.wire.sendAction('get-application-zoom-level', this.identity).then(({ payload }) => payload.data); + } + /** + * Returns an instance of the main Window of the application + * + * @example + * + * ```js + * async function getWindow() { + * const app = await fin.Application.start({ + * uuid: 'app-1', + * name: 'myApp', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Application.getWindow.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * getWindow().then(win => { + * win.showAt(0, 400); + * win.flash(); + * }).catch(err => console.log(err)); + * ``` + */ + getWindow() { + this.wire.sendAction('application-get-window', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return Promise.resolve(this.window); + } + /** + * Manually registers a user with the licensing service. The only data sent by this call is userName and appName. + * @param userName - username to be passed to the RVM. + * @param appName - app name to be passed to the RVM. + * + * @example + * + * ```js + * async function registerUser() { + * const app = await fin.Application.getCurrent(); + * return await app.registerUser('user', 'myApp'); + * } + * + * registerUser().then(() => console.log('Successfully registered the user')).catch(err => console.log(err)); + * ``` + */ + registerUser(userName, appName) { + return this.wire.sendAction('register-user', { userName, appName, ...this.identity }).then(() => undefined); + } + /** + * Removes the application’s icon from the tray. + * + * @example + * + * ```js + * async function removeTrayIcon() { + * const app = await fin.Application.getCurrent(); + * return await app.removeTrayIcon(); + * } + * + * removeTrayIcon().then(() => console.log('Removed the tray icon.')).catch(err => console.log(err)); + * ``` + */ + removeTrayIcon() { + return this.wire.sendAction('remove-tray-icon', this.identity).then(() => undefined); + } + /** + * Restarts the application. + * + * @example + * + * ```js + * async function restartApp() { + * const app = await fin.Application.getCurrent(); + * return await app.restart(); + * } + * restartApp().then(() => console.log('Application restarted')).catch(err => console.log(err)); + * ``` + */ + restart() { + return this.wire.sendAction('restart-application', this.identity).then(() => undefined); + } + /** + * DEPRECATED method to run the application. + * Needed when starting application via {@link Application.create}, but NOT needed when starting via {@link Application.start}. + * + * @example + * + * ```js + * async function run() { + * const app = await fin.Application.create({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Application.run.html', + * autoShow: true + * }); + * await app.run(); + * } + * run().then(() => console.log('Application is running')).catch(err => console.log(err)); + * ``` + * + * @ignore + */ + run() { + console.warn('Deprecation Warning: Application.run is deprecated Please use fin.Application.start'); + this.wire.sendAction('application-run', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this._run(); + } + _run(opts = {}) { + return this.wire + .sendAction('run-application', { + manifestUrl: this._manifestUrl, + opts, + ...this.identity + }) + .then(() => undefined); + } + /** + * Instructs the RVM to schedule one restart of the application. + * + * @example + * + * ```js + * async function scheduleRestart() { + * const app = await fin.Application.getCurrent(); + * return await app.scheduleRestart(); + * } + * + * scheduleRestart().then(() => console.log('Application is scheduled to restart')).catch(err => console.log(err)); + * ``` + */ + scheduleRestart() { + return this.wire.sendAction('relaunch-on-close', this.identity).then(() => undefined); + } + /** + * Sends a message to the RVM to upload the application's logs. On success, + * an object containing logId is returned. + * + * @example + * + * ```js + * async function sendLog() { + * const app = await fin.Application.getCurrent(); + * return await app.sendApplicationLog(); + * } + * + * sendLog().then(info => console.log(info.logId)).catch(err => console.log(err)); + * ``` + */ + async sendApplicationLog() { + const { payload } = await this.wire.sendAction('send-application-log', this.identity); + return payload.data; + } + /** + * Sets or removes a custom JumpList for the application. Only applicable in Windows OS. + * If categories is null the previously set custom JumpList (if any) will be replaced by the standard JumpList for the app (managed by Windows). + * + * Note: If the "name" property is omitted it defaults to "tasks". + * @param jumpListCategories An array of JumpList Categories to populate. If null, remove any existing JumpList configuration and set to Windows default. + * + * + * @remarks If categories is null the previously set custom JumpList (if any) will be replaced by the standard JumpList for the app (managed by Windows). + * + * The bottommost item in the jumplist will always be an item pointing to the current app. Its name is taken from the manifest's + * **` shortcut.name `** and uses **` shortcut.company `** as a fallback. Clicking that item will launch the app from its current manifest. + * + * Note: If the "name" property is omitted it defaults to "tasks". + * + * Note: Window OS caches jumplists icons, therefore an icon change might only be visible after the cache is removed or the + * uuid or shortcut.name is changed. + * + * @example + * + * ```js + * const app = fin.Application.getCurrentSync(); + * const appName = 'My App'; + * const jumpListConfig = [ // array of JumpList categories + * { + * // has no name and no type so `type` is assumed to be "tasks" + * items: [ // array of JumpList items + * { + * type: 'task', + * title: `Launch ${appName}`, + * description: `Runs ${appName} with the default configuration`, + * deepLink: 'fins://path.to/app/manifest.json', + * iconPath: 'https://path.to/app/icon.ico', + * iconIndex: 0 + * }, + * { type: 'separator' }, + * { + * type: 'task', + * title: `Restore ${appName}`, + * description: 'Restore to last configuration', + * deepLink: 'fins://path.to/app/manifest.json?$$use-last-configuration=true', + * iconPath: 'https://path.to/app/icon.ico', + * iconIndex: 0 + * }, + * ] + * }, + * { + * name: 'Tools', + * items: [ // array of JumpList items + * { + * type: 'task', + * title: 'Tool A', + * description: 'Runs Tool A', + * deepLink: 'fins://path.to/tool-a/manifest.json', + * iconPath: 'https://path.to/tool-a/icon.ico', + * iconIndex: 0 + * }, + * { + * type: 'task', + * title: 'Tool B', + * description: 'Runs Tool B', + * deepLink: 'fins://path.to/tool-b/manifest.json', + * iconPath: 'https://path.to/tool-b/icon.ico', + * iconIndex: 0 + * }] + * } + * ]; + * + * app.setJumpList(jumpListConfig).then(() => console.log('JumpList applied')).catch(e => console.log(`JumpList failed to apply: ${e.toString()}`)); + * ``` + * + * To handle deeplink args: + * ```js + * function handleUseLastConfiguration() { + * // this handler is called when the app is being launched + * app.on('run-requested', event => { + * if(event.userAppConfigArgs['use-last-configuration']) { + * // your logic here + * } + * }); + * // this handler is called when the app was already running when the launch was requested + * fin.desktop.main(function(args) { + * if(args && args['use-last-configuration']) { + * // your logic here + * } + * }); + * } + * ``` + */ + async setJumpList(jumpListCategories) { + await this.wire.sendAction('set-jump-list', { config: jumpListCategories, ...this.identity }); + } + /** + * Adds a customizable icon in the system tray. To listen for a click on the icon use the `tray-icon-clicked` event. + * @param icon Image URL or base64 encoded string to be used as the icon + * + * @example + * + * ```js + * const imageUrl = "http://cdn.openfin.co/assets/testing/icons/circled-digit-one.png"; + * const base64EncodedImage = "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX\ + * ///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII"; + * const dataURL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DH\ + * xgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; + * + * async function setTrayIcon(icon) { + * const app = await fin.Application.getCurrent(); + * return await app.setTrayIcon(icon); + * } + * + * // use image url to set tray icon + * setTrayIcon(imageUrl).then(() => console.log('Setting tray icon')).catch(err => console.log(err)); + * + * // use base64 encoded string to set tray icon + * setTrayIcon(base64EncodedImage).then(() => console.log('Setting tray icon')).catch(err => console.log(err)); + * + * // use a dataURL to set tray icon + * setTrayIcon(dataURL).then(() => console.log('Setting tray icon')).catch(err => console.log(err)); + * ``` + */ + setTrayIcon(icon) { + return this.wire + .sendAction('set-tray-icon', { + enabledIcon: icon, + ...this.identity + }) + .then(() => undefined); + } + /** + * Sets new application's shortcut configuration. Windows only. + * @param config New application's shortcut configuration. + * + * @remarks Application has to be launched with a manifest and has to have shortcut configuration (icon url, name, etc.) in its manifest + * to be able to change shortcut states. + * + * @example + * + * ```js + * async function setShortcuts(config) { + * const app = await fin.Application.getCurrent(); + * return app.setShortcuts(config); + * } + * + * setShortcuts({ + * desktop: true, + * startMenu: false, + * systemStartup: true + * }).then(() => console.log('Shortcuts are set.')).catch(err => console.log(err)); + * ``` + */ + setShortcuts(config) { + return this.wire.sendAction('set-shortcuts', { data: config, ...this.identity }).then(() => undefined); + } + /** + * Sets the query string in all shortcuts for this app. Requires RVM 5.5+. + * @param queryString The new query string for this app's shortcuts. + * + * @example + * + * ```js + * const newQueryArgs = 'arg=true&arg2=false'; + * const app = await fin.Application.getCurrent(); + * try { + * await app.setShortcutQueryParams(newQueryArgs); + * } catch(err) { + * console.error(err) + * } + * ``` + */ + async setShortcutQueryParams(queryString) { + await this.wire.sendAction('set-shortcut-query-args', { data: queryString, ...this.identity }); + } + /** + * Sets the zoom level of the application. The original size is 0 and each increment above or below represents zooming 20% + * larger or smaller to default limits of 300% and 50% of original size, respectively. + * @param level The zoom level + * + * @example + * + * ```js + * async function setZoomLevel(number) { + * const app = await fin.Application.getCurrent(); + * return await app.setZoomLevel(number); + * } + * + * setZoomLevel(5).then(() => console.log('Setting a zoom level')).catch(err => console.log(err)); + * ``` + */ + setZoomLevel(level) { + return this.wire.sendAction('set-application-zoom-level', { level, ...this.identity }).then(() => undefined); + } + /** + * Sets a username to correlate with App Log Management. + * @param username Username to correlate with App's Log. + * + * @example + * + * ```js + * async function setAppLogUser() { + * const app = await fin.Application.getCurrent(); + * return await app.setAppLogUsername('username'); + * } + * + * setAppLogUser().then(() => console.log('Success')).catch(err => console.log(err)); + * + * ``` + */ + async setAppLogUsername(username) { + await this.wire.sendAction('set-app-log-username', { data: username, ...this.identity }); + } + /** + * Retrieves information about the system tray. If the system tray is not set, it will throw an error message. + * @remarks The only information currently returned is the position and dimensions. + * + * @example + * + * ```js + * async function getTrayIconInfo() { + * const app = await fin.Application.wrap({ uuid: 'testapp' }); + * return await app.getTrayIconInfo(); + * } + * getTrayIconInfo().then(info => console.log(info)).catch(err => console.log(err)); + * ``` + */ + getTrayIconInfo() { + return this.wire.sendAction('get-tray-icon-info', this.identity).then(({ payload }) => payload.data); + } + /** + * Checks if the application has an associated tray icon. + * + * @example + * + * ```js + * const app = await fin.Application.wrap({ uuid: 'testapp' }); + * const hasTrayIcon = await app.hasTrayIcon(); + * console.log(hasTrayIcon); + * ``` + */ + hasTrayIcon() { + return this.wire.sendAction('has-tray-icon', this.identity).then(({ payload }) => payload.data); + } + /** + * Closes the application by terminating its process. + * + * @example + * + * ```js + * async function terminateApp() { + * const app = await fin.Application.getCurrent(); + * return await app.terminate(); + * } + * terminateApp().then(() => console.log('Application terminated')).catch(err => console.log(err)); + * ``` + */ + terminate() { + return this.wire.sendAction('terminate-application', this.identity).then(() => undefined); + } + /** + * Waits for a hanging application. This method can be called in response to an application + * "not-responding" to allow the application to continue and to generate another "not-responding" + * message after a certain period of time. + * + * @ignore + */ + wait() { + return this.wire.sendAction('wait-for-hung-application', this.identity).then(() => undefined); + } + /** + * Retrieves information about the application. + * + * @remarks If the application was not launched from a manifest, the call will return the closest parent application `manifest` + * and `manifestUrl`. `initialOptions` shows the parameters used when launched programmatically, or the `startup_app` options + * if launched from manifest. The `parentUuid` will be the uuid of the immediate parent (if applicable). + * + * @example + * + * ```js + * async function getInfo() { + * const app = await fin.Application.getCurrent(); + * return await app.getInfo(); + * } + * + * getInfo().then(info => console.log(info)).catch(err => console.log(err)); + * ``` + */ + getInfo() { + return this.wire.sendAction('get-info', this.identity).then(({ payload }) => payload.data); + } + /** + * Retrieves all process information for entities (windows and views) associated with an application. + * + * @example + * ```js + * const app = await fin.Application.getCurrent(); + * const processInfo = await app.getProcessInfo(); + * ``` + * @experimental + */ + async getProcessInfo() { + const { payload: { data } } = await this.wire.sendAction('application-get-process-info', this.identity); + return data; + } + /** + * Sets file auto download location. It's only allowed in the same application. + * + * Note: This method is restricted by default and must be enabled via + * API security settings. + * @param downloadLocation file auto download location + * + * @throws if setting file auto download location on different applications. + * @example + * + * ```js + * const downloadLocation = 'C:\\dev\\temp'; + * const app = await fin.Application.getCurrent(); + * try { + * await app.setFileDownloadLocation(downloadLocation); + * console.log('File download location is set'); + * } catch(err) { + * console.error(err) + * } + * ``` + */ + async setFileDownloadLocation(downloadLocation) { + const { name } = this.wire.me; + const entityIdentity = { uuid: this.identity.uuid, name }; + await this.wire.sendAction('set-file-download-location', { ...entityIdentity, downloadLocation }); + } + /** + * Gets file auto download location. It's only allowed in the same application. If file auto download location is not set, it will return the default location. + * + * Note: This method is restricted by default and must be enabled via + * API security settings. + * + * @throws if getting file auto download location on different applications. + * @example + * + * ```js + * const app = await fin.Application.getCurrent(); + * const fileDownloadDir = await app.getFileDownloadLocation(); + * ``` + */ + async getFileDownloadLocation() { + const { payload: { data } } = await this.wire.sendAction('get-file-download-location', this.identity); + return data; + } + /** + * Shows a menu on the tray icon. Use with tray-icon-clicked event. + * @param options + * @typeParam Data User-defined shape for data returned upon menu item click. Should be a + * [union](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) + * of all possible data shapes for the entire menu, and the click handler should process + * these with a "reducer" pattern. + * @throws if the application has no tray icon set + * @throws if the system tray is currently hidden + * @example + * + * ```js + * const iconUrl = 'http://cdn.openfin.co/assets/testing/icons/circled-digit-one.png'; + * const app = fin.Application.getCurrentSync(); + * + * await app.setTrayIcon(iconUrl); + * + * const template = [ + * { + * label: 'Menu Item 1', + * data: 'hello from item 1' + * }, + * { type: 'separator' }, + * { + * label: 'Menu Item 2', + * type: 'checkbox', + * checked: true, + * data: 'The user clicked the checkbox' + * }, + * { + * label: 'see more', + * enabled: false, + * submenu: [ + * { label: 'submenu 1', data: 'hello from submenu' } + * ] + * } + * ]; + * + * app.addListener('tray-icon-clicked', (event) => { + * // right-click + * if (event.button === 2) { + * app.showTrayIconPopupMenu({ template }).then(r => { + * if (r.result === 'closed') { + * console.log('nothing happened'); + * } else { + * console.log(r.data); + * } + * }); + * } + * }); + * ``` + */ + async showTrayIconPopupMenu(options) { + const { name } = this.wire.me; + const entityIdentity = { uuid: this.identity.uuid, name }; + const { payload } = await this.wire.sendAction('show-tray-icon-popup-menu', { ...entityIdentity, options }); + return payload.data; + } + /** + * Closes the tray icon menu. + * + * @throws if the application has no tray icon set + * @example + * + * ```js + * const app = fin.Application.getCurrentSync(); + * + * await app.closeTrayIconPopupMenu(); + * ``` + */ + async closeTrayIconPopupMenu() { + const { name } = this.wire.me; + const entityIdentity = { uuid: this.identity.uuid, name }; + await this.wire.sendAction('close-tray-icon-popup-menu', { ...entityIdentity }); + } + } + Instance$6.Application = Application; + return Instance$6; +} + +var hasRequiredFactory$2; + +function requireFactory$2 () { + if (hasRequiredFactory$2) return Factory$7; + hasRequiredFactory$2 = 1; + Object.defineProperty(Factory$7, "__esModule", { value: true }); + Factory$7.ApplicationModule = void 0; + const base_1 = base; + const validate_1 = validate; + const Instance_1 = requireInstance$1(); + /** + * Static namespace for OpenFin API methods that interact with the {@link Application} class, available under `fin.Application`. + */ + class ApplicationModule extends base_1.Base { + /** + * Asynchronously returns an API handle for the given Application identity. + * + * @remarks Wrapping an Application identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for an Application throughout its entire lifecycle. + * + * @example + * + * ```js + * fin.Application.wrap({ uuid: 'testapp' }) + * .then(app => app.isRunning()) + * .then(running => console.log('Application is running: ' + running)) + * .catch(err => console.log(err)); + * ``` + * + */ + async wrap(identity) { + this.wire.sendAction('wrap-application').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new Instance_1.Application(this.wire, identity); + } + /** + * Synchronously returns an API handle for the given Application identity. + * + * @remarks Wrapping an Application identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for an Aplication throughout its entire lifecycle. + * + * @example + * + * ```js + * const app = fin.Application.wrapSync({ uuid: 'testapp' }); + * await app.close(); + * ``` + * + */ + wrapSync(identity) { + this.wire.sendAction('wrap-application-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new Instance_1.Application(this.wire, identity); + } + async _create(appOptions) { + // set defaults: + if (appOptions.waitForPageLoad === undefined) { + appOptions.waitForPageLoad = false; + } + if (appOptions.autoShow === undefined && appOptions.isPlatformController === undefined) { + appOptions.autoShow = true; + } + await this.wire.sendAction('create-application', appOptions); + return this.wrap({ uuid: appOptions.uuid }); + } + /** + * DEPRECATED method to create a new Application. Use {@link Application.ApplicationModule.start Application.start} instead. + * + * @example + * + * ```js + * async function createApp() { + * const app = await fin.Application.create({ + * name: 'myApp', + * uuid: 'app-3', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Application.create.html', + * autoShow: true + * }); + * await app.run(); + * } + * + * createApp().then(() => console.log('Application is created')).catch(err => console.log(err)); + * ``` + * + * @ignore + */ + create(appOptions) { + console.warn('Deprecation Warning: fin.Application.create is deprecated. Please use fin.Application.start'); + this.wire.sendAction('application-create').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this._create(appOptions); + } + /** + * Creates and starts a new Application. + * + * @example + * + * ```js + * async function start() { + * return fin.Application.start({ + * name: 'app-1', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Application.start.html', + * autoShow: true + * }); + * } + * start().then(() => console.log('Application is running')).catch(err => console.log(err)); + * ``` + * + */ + async start(appOptions) { + this.wire.sendAction('start-application').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const app = await this._create(appOptions); + await this.wire.sendAction('run-application', { uuid: appOptions.uuid }); + return app; + } + /** + * Asynchronously starts a batch of applications given an array of application identifiers and manifestUrls. + * Returns once the RVM is finished attempting to launch the applications. + * @param opts - Parameters that the RVM will use. + * + * @example + * + * ```js + * + * const applicationInfoArray = [ + * { + * "uuid": 'App-1', + * "manifestUrl": 'http://localhost:5555/app1.json', + * }, + * { + * "uuid": 'App-2', + * "manifestUrl": 'http://localhost:5555/app2.json', + * }, + * { + * "uuid": 'App-3', + * "manifestUrl": 'http://localhost:5555/app3.json', + * } + * ] + * + * fin.Application.startManyManifests(applicationInfoArray) + * .then(() => { + * console.log('RVM has finished launching the application list.'); + * }) + * .catch((err) => { + * console.log(err); + * }) + * ``` + * + * @experimental + */ + async startManyManifests(applications, opts) { + return this.wire.sendAction('run-applications', { applications, opts }).then(() => undefined); + } + /** + * Asynchronously returns an Application object that represents the current application + * + * @example + * + * ```js + * async function isCurrentAppRunning () { + * const app = await fin.Application.getCurrent(); + * return app.isRunning(); + * } + * + * isCurrentAppRunning().then(running => { + * console.log(`Current app is running: ${running}`); + * }).catch(err => { + * console.error(err); + * }); + * + * ``` + */ + getCurrent() { + this.wire.sendAction('get-current-application').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this.wrap({ uuid: this.wire.me.uuid }); + } + /** + * Synchronously returns an Application object that represents the current application + * + * @example + * + * ```js + * async function isCurrentAppRunning () { + * const app = fin.Application.getCurrentSync(); + * return app.isRunning(); + * } + * + * isCurrentAppRunning().then(running => { + * console.log(`Current app is running: ${running}`); + * }).catch(err => { + * console.error(err); + * }); + * + * ``` + */ + getCurrentSync() { + this.wire.sendAction('get-current-application-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this.wrapSync({ uuid: this.wire.me.uuid }); + } + /** + * Retrieves application's manifest and returns a running instance of the application. + * @param manifestUrl - The URL of app's manifest. + * @param opts - Parameters that the RVM will use. + * + * @example + * + * ```js + * fin.Application.startFromManifest('http://localhost:5555/app.json').then(app => console.log('App is running')).catch(err => console.log(err)); + * + * // For a local manifest file: + * fin.Application.startFromManifest('file:///C:/somefolder/app.json').then(app => console.log('App is running')).catch(err => console.log(err)); + * ``` + */ + async startFromManifest(manifestUrl, opts) { + this.wire.sendAction('application-start-from-manifest').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const app = await this._createFromManifest(manifestUrl); + // @ts-expect-error using private method without warning. + await app._run(opts); // eslint-disable-line no-underscore-dangle + return app; + } + /** + * @deprecated Use {@link Application.ApplicationModule.startFromManifest Application.startFromManifest} instead. + * Retrieves application's manifest and returns a wrapped application. + * @param manifestUrl - The URL of app's manifest. + * @param callback - called if the method succeeds. + * @param errorCallback - called if the method fails. The reason for failure is passed as an argument. + * + * @example + * + * ```js + * fin.Application.createFromManifest('http://localhost:5555/app.json').then(app => console.log(app)).catch(err => console.log(err)); + * ``` + * @ignore + */ + createFromManifest(manifestUrl) { + console.warn('Deprecation Warning: fin.Application.createFromManifest is deprecated. Please use fin.Application.startFromManifest'); + this.wire.sendAction('application-create-from-manifest').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this._createFromManifest(manifestUrl); + } + _createFromManifest(manifestUrl) { + return this.wire + .sendAction('get-application-manifest', { manifestUrl }) + .then(({ payload }) => { + const uuid = payload.data.platform ? payload.data.platform.uuid : payload.data.startup_app.uuid; + return this.wrap({ uuid }); + }) + .then((app) => { + app._manifestUrl = manifestUrl; // eslint-disable-line no-underscore-dangle + return app; + }); + } + } + Factory$7.ApplicationModule = ApplicationModule; + return Factory$7; +} + +var hasRequiredApplication; + +function requireApplication () { + if (hasRequiredApplication) return application; + hasRequiredApplication = 1; + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + /** + * Entry points for the OpenFin `Application` API (`fin.Application`). + * + * * {@link ApplicationModule} contains static members of the `Application` API, accessible through `fin.Application`. + * * {@link Application} describes an instance of an OpenFin Application, e.g. as returned by `fin.Application.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * @packageDocumentation + */ + __exportStar(requireFactory$2(), exports); + __exportStar(requireInstance$1(), exports); + } (application)); + return application; +} + +var promisifySubscription$1 = {}; + +Object.defineProperty(promisifySubscription$1, "__esModule", { value: true }); +promisifySubscription$1.promisifySubscription = void 0; +const promisifySubscription = async (emitter, eventName, predicate = () => true, timeout) => { + let resolve; + let reject; + let timer; + const valuePromise = new Promise((y, n) => { + resolve = y; + reject = n; + }); + const listener = (e) => { + if (predicate(e)) { + clearTimeout(timer); + resolve(e); + } + }; + await emitter.on(eventName, listener); + if (timeout) { + timer = setTimeout(() => reject(new Error('event timed out')), timeout); + } + valuePromise.finally(() => { + emitter.removeListener(eventName, listener).catch(() => null); + }); + return { + getValue: () => valuePromise + }; +}; +promisifySubscription$1.promisifySubscription = promisifySubscription; + +var hasRequiredInstance; + +function requireInstance () { + if (hasRequiredInstance) return Instance$7; + hasRequiredInstance = 1; + Object.defineProperty(Instance$7, "__esModule", { value: true }); + Instance$7._Window = void 0; + /* eslint-disable import/prefer-default-export */ + /* eslint-disable @typescript-eslint/no-unused-vars */ + /* eslint-disable no-console */ + /* eslint-disable @typescript-eslint/no-non-null-assertion */ + const application_1 = requireApplication(); + const main_1 = main; + const view_1 = requireView(); + const warnings_1 = warnings; + const promisifySubscription_1 = promisifySubscription$1; + /** + * A basic window that wraps a native HTML window. Provides more fine-grained + * control over the window state such as the ability to minimize, maximize, restore, etc. + * By default a window does not show upon instantiation; instead the window's show() method + * must be invoked manually. The new window appears in the same process as the parent window. + * It has the ability to listen for {@link OpenFin.WindowEvents window specific events}. + */ + // The window.Window name is taken + class _Window extends main_1.WebContents { + /** + * @internal + */ + constructor(wire, identity) { + super(wire, identity, 'window'); + } + async createWindow(options) { + this.wire.sendAction('window-create-window', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const CONSTRUCTOR_CB_TOPIC = 'fire-constructor-callback'; + const responseSubscription = await (0, promisifySubscription_1.promisifySubscription)(this, CONSTRUCTOR_CB_TOPIC); + // set defaults: + if (options.waitForPageLoad === undefined) { + options.waitForPageLoad = false; + } + if (options.autoShow === undefined) { + options.autoShow = true; + } + (0, warnings_1.handleDeprecatedWarnings)(options); + const windowCreation = this.wire.environment.createChildContent({ entityType: 'window', options }); + const [response] = await Promise.all([responseSubscription.getValue(), windowCreation]); + let cbPayload; + const { success } = response; + const responseData = response.data; + const { message } = responseData; + if (success) { + cbPayload = { + httpResponseCode: responseData.httpResponseCode, + apiInjected: responseData.apiInjected + }; + } + else { + cbPayload = { + message: responseData.message, + networkErrorCode: responseData.networkErrorCode, + stack: responseData.stack + }; + } + const pageResolve = { + message, + cbPayload, + success + }; + try { + // this is to enforce a 5.0 contract that the child's main function + // will not fire before the parent's success callback on creation. + // if the child window is not accessible (CORS) this contract does + // not hold. + const webWindow = this.getWebWindow(); + webWindow.fin.__internal_.openerSuccessCBCalled(); + } + catch (e) { + // common for main windows, we do not want to expose this error. here just to have a debug target. + // console.error(e); + } + if (pageResolve.success) { + return this; + } + return Promise.reject(pageResolve); + } + /** + * Retrieves an array of frame info objects representing the main frame and any + * iframes that are currently on the page. + * + * @example + * ```js + * async function getAllFrames() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getAllFrames.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getAllFrames(); + * } + * + * getAllFrames().then(framesInfo => console.log(framesInfo)).catch(err => console.log(err)); + * ``` + */ + getAllFrames() { + return this.wire.sendAction('get-all-frames', this.identity).then(({ payload }) => payload.data); + } + /** + * Gets the current bounds (top, bottom, right, left, width, height) of the window. + * + * @example + * ```js + * async function getBounds() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-3', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getBounds.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getBounds(); + * } + * + * getBounds().then(bounds => console.log(bounds)).catch(err => console.log(err)); + * ``` + */ + getBounds() { + return this.wire + .sendAction('get-window-bounds', this.identity) + .then(({ payload }) => payload.data); + } + /** + * Centers the window on its current screen. + * + * @remarks Does not have an effect on minimized or maximized windows. + * + * @example + * ```js + * async function centerWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.center.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.center(); + * } + * + * centerWindow().then(() => console.log('Window centered')).catch(err => console.log(err)); + * ``` + * + */ + center() { + return this.wire.sendAction('center-window', this.identity).then(() => undefined); + } + /** + * Removes focus from the window. + * + * @example + * ```js + * async function blurWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.blur.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.blur(); + * } + * + * blurWindow().then(() => console.log('Blured Window')).catch(err => console.log(err)); + * ``` + */ + blur() { + return this.wire.sendAction('blur-window', this.identity).then(() => undefined); + } + /** + * Brings the window to the front of the window stack. + * + * @example + * ```js + * async function BringWindowToFront() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.bringToFront.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.bringToFront(); + * } + * + * BringWindowToFront().then(() => console.log('Window is in the front')).catch(err => console.log(err)); + * ``` + */ + bringToFront() { + return this.wire.sendAction('bring-window-to-front', this.identity).then(() => undefined); + } + /** + * Performs the specified window transitions. + * @param transitions - Describes the animations to perform. See the tutorial. + * @param options - Options for the animation. See the tutorial. + * + * @example + * ``` + * async function animateWindow() { + * const transitions = { + * opacity: { + * opacity: 0.7, + * duration: 500 + * }, + * position: { + * top: 100, + * left: 100, + * duration: 500, + * relative: true + * } + * }; + * const options = { + * interrupt: true, + * tween: 'ease-in' + * }; + * + * const win = await fin.Window.getCurrent(); + * return win.animate(transitions, options); + * } + * + * animateWindow() + * .then(() => console.log('Animation done')) + * .catch(err => console.error(err)); + * ``` + */ + animate(transitions, options) { + return this.wire + .sendAction('animate-window', { + transitions, + options, + ...this.identity + }) + .then(() => undefined); + } + /** + * Hides the window. + * + * @example + * ```js + * async function hideWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.hide.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.hide(); + * } + * + * hideWindow().then(() => console.log('Window is hidden')).catch(err => console.log(err)); + * ``` + */ + hide() { + return this.wire.sendAction('hide-window', this.identity).then(() => undefined); + } + /** + * closes the window application + * @param force Close will be prevented from closing when force is false and + * ‘close-requested’ has been subscribed to for application’s main window. + * + * @example + * ```js + * async function closeWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-3', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.close.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.close(); + * } + * + * closeWindow().then(() => console.log('Window closed')).catch(err => console.log(err)); + * ``` + */ + close(force = false) { + return this.wire.sendAction('close-window', { force, ...this.identity }).then(() => { + Object.setPrototypeOf(this, null); + return undefined; + }); + } + focusedWebViewWasChanged() { + return this.wire.sendAction('focused-webview-changed', this.identity).then(() => undefined); + } + /** + * Returns the native OS level Id. + * + * @remarks In Windows, it will return the Windows [handle](https://docs.microsoft.com/en-us/windows/desktop/WinProg/windows-data-types#HWND). + * + * @example + * ```js + * async function getWindowNativeId() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-3', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getNativeId.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getNativeId(); + * } + * + * getWindowNativeId().then(nativeId => console.log(nativeId)).catch(err => console.log(err)); + * ``` + */ + getNativeId() { + return this.wire.sendAction('get-window-native-id', this.identity).then(({ payload }) => payload.data); + } + /** + * Retrieves window's attached views. + * @experimental + * + * @example + * ```js + * const win = fin.Window.getCurrentSync(); + * + * win.getCurrentViews() + * .then(views => console.log(views)) + * .catch(console.error); + * ``` + */ + async getCurrentViews() { + const { payload } = await this.wire.sendAction('window-get-views', this.identity); + return payload.data.map((id) => new view_1.View(this.wire, id)); + } + /** + * @deprecated Use {@link Window._Window.disableUserMovement} instead. + */ + disableFrame() { + console.warn('Function is deprecated; use disableUserMovement instead.'); + return this.wire.sendAction('disable-window-frame', this.identity).then(() => undefined); + } + /** + * Prevents a user from changing a window's size/position when using the window's frame. + * + * @example + * ```js + * async function disableUserMovement() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-3', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.disableFrame.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.disableUserMovement(); + * } + * + * disableUserMovement().then(() => console.log('Window is disabled')).catch(err => console.log(err)); + * ``` + */ + disableUserMovement() { + return this.wire.sendAction('disable-window-frame', this.identity).then(() => undefined); + } + /** + * @deprecated Use {@link Window._Window.enableUserMovement} instead. + */ + enableFrame() { + console.warn('Function is deprecated; use enableUserMovement instead.'); + return this.wire.sendAction('enable-window-frame', this.identity).then(() => undefined); + } + /** + * Re-enables user changes to a window's size/position when using the window's frame. + * + * @example + * ```js + * async function enableUserMovement() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-3', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.enableFrame.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.enableUserMovement(); + * } + * + * enableUserMovement().then(() => console.log('Window is enabled')).catch(err => console.log(err)); + * ``` + */ + enableUserMovement() { + return this.wire.sendAction('enable-window-frame', this.identity).then(() => undefined); + } + /** + * Flashes the window’s frame and taskbar icon until stopFlashing is called or until a focus event is fired. + * + * @remarks On macOS flash only works on inactive windows. + * @example + * ```js + * async function windowFlash() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.flash.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.flash(); + * } + * + * windowFlash().then(() => console.log('Window flashing')).catch(err => console.log(err)); + * ``` + */ + flash() { + return this.wire.sendAction('flash-window', this.identity).then(() => undefined); + } + /** + * Stops the taskbar icon from flashing. + * + * @example + * ```js + * async function stopWindowFlashing() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.stopFlashing.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.stopFlashing(); + * } + * + * stopWindowFlashing().then(() => console.log('Application window flashing')).catch(err => console.log(err)); + * ``` + */ + stopFlashing() { + return this.wire.sendAction('stop-flash-window', this.identity).then(() => undefined); + } + /** + * Gets an information object for the window. + * + * @example + * ```js + * async function getInfo() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getInfo.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getInfo(); + * } + * + * getInfo().then(info => console.log(info)).catch(err => console.log(err)); + * ``` + */ + getInfo() { + return this.wire.sendAction('get-window-info', this.identity).then(({ payload }) => payload.data); + } + /** + * Retrieves the window's Layout + * + * @example + * ```js + * //get the current window + * const window = await fin.Window.getCurrent(); + * + * //get the layout for the window + * const layout = await window.getLayout(); + * ``` + * @experimental + */ + async getLayout(layoutIdentity) { + this.wire.sendAction('window-get-layout', this.identity).catch((e) => { + // don't expose + }); + const opts = await this.getOptions(); + if (!opts.layout && !opts.layoutSnapshot) { + throw new Error('Window does not have a Layout'); + } + return this.fin.Platform.Layout.wrap(layoutIdentity ?? this.identity); + } + /** + * Gets the current settings of the window. + * + * @example + * ```js + * async function getWindowOptions() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getOptions.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getOptions(); + * } + * + * getWindowOptions().then(opts => console.log(opts)).catch(err => console.log(err)); + * ``` + */ + getOptions() { + return this.wire.sendAction('get-window-options', this.identity).then(({ payload }) => payload.data); + } + /** + * Gets the parent application. + * + * @example + * ```js + * async function getParentApplication() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getParentApplication.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getParentApplication(); + * } + * + * getParentApplication().then(parentApplication => console.log(parentApplication)).catch(err => console.log(err)); + * ``` + */ + getParentApplication() { + this.wire.sendAction('window-get-parent-application', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return Promise.resolve(new application_1.Application(this.wire, this.identity)); + } + /** + * Gets the parent window. + * + * @example + * ```js + * async function getParentWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getParentWindow.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getParentWindow(); + * } + * + * getParentWindow().then(parentWindow => console.log(parentWindow)).catch(err => console.log(err)); + * ``` + */ + getParentWindow() { + this.wire.sendAction('window-get-parent-window', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return Promise.resolve(new application_1.Application(this.wire, this.identity)).then((app) => app.getWindow()); + } + /** + * ***DEPRECATED - please use Window.capturePage.*** + * Gets a base64 encoded PNG image of the window or just part a of it. + * @param area The area of the window to be captured. + * Omitting it will capture the whole visible window. + * + * @tutorial Window.capturePage + */ + async getSnapshot(area) { + const req = { area, ...this.identity }; + console.warn('Window.getSnapshot has been deprecated, please use Window.capturePage'); + const res = await this.wire.sendAction('get-window-snapshot', req); + return res.payload.data; + } + /** + * Gets the current state ("minimized", "maximized", or "normal") of the window. + * + * @example + * ```js + * async function getWindowState() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.getState.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.getState(); + * } + * + * getWindowState().then(winState => console.log(winState)).catch(err => console.log(err)); + * ``` + */ + getState() { + return this.wire.sendAction('get-window-state', this.identity).then(({ payload }) => payload.data); + } + /** + * Previously called getNativeWindow. + * Returns the [Window Object](https://developer.mozilla.org/en-US/docs/Web/API/Window) + * that represents the web context of the target window. This is the same object that + * you would get from calling [window.open()](https://developer.mozilla.org/en-US/docs/Web/API/Window/open) in a standard web context. + * The target window needs to be in the same application as the requesting window + * as well as comply with [same-origin](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) policy requirements. + * + * @example + * Injecting content into an empty window: + * + * ```js + * (async ()=> { + * try { + * const winName = `child-window-${Date.now()}`; + * const win = await fin.Window.create({ + * name: winName, + * url: 'about:blank' + * }); + * win.getWebWindow().document.write('

Hello World

'); + * } catch (err) { + * console.error(err); + * } + * })(); + * ``` + * + * Cloning DOM elements from the parent window (in this example we clone an `h3` element from the parent window): + * ```js + * (async ()=> { + * try { + * const currentWindow = await fin.Window.getCurrent(); + * const parentWindow = await currentWindow.getParentWindow(); + * const clonedH3 = parentWindow.getWebWindow().document.querySelector('h3').cloneNode(true); + * document.body.append(clonedH3); + * + * } catch (err) { + * console.error(err); + * } + * })(); + * ``` + * + * Rendering on a child window via a library (in this example we are using the [lit-html](https://lit-html.polymer-project.org/) + * template library to render content on a blank child window. You are not going to be able to copy paste this example without + * configuring the project correctly but this would demonstrate some templating options available): + * ```js + * (async ()=> { + * try { + * const win = await fin.Window.create({ + * name: `child-window-${Date.now()}`, + * url: 'about:blank' + * }); + * const template = html` + *
+ * Click here: + * + *
`; + * render(template, win.getWebWindow().document.body); + * + * } catch (err) { + * console.error(err); + * } + * })(); + * ``` + */ + getWebWindow() { + this.wire.sendAction('window-get-web-window', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this.wire.environment.getWebWindow(this.identity); + } + /** + * Determines if the window is a main window. + * + * @example + * ```js + * const wnd = fin.Window.getCurrentSync(); + * const isMainWnd = wnd.isMainWindow(); + * console.log('Is this a main window? ' + isMainWnd); + * ``` + */ + isMainWindow() { + this.wire.sendAction('window-is-main-window', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this.me.uuid === this.me.name; + } + /** + * Determines if the window is currently showing. + * + * @example + * ```js + * async function isWindowShowing() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.isShowing.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.isShowing(); + * } + * + * isWindowShowing().then(bool => console.log(bool)).catch(err => console.log(err)); + * ``` + */ + isShowing() { + return this.wire.sendAction('is-window-showing', this.identity).then(({ payload }) => payload.data); + } + /** + * Maximizes the window + * + * @example + * ```js + * async function maxWindow() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.maximize.html', + * autoShow: true + * }); + * const win = await app.getWindow(); + * return await win.maximize(); + * } + * + * maxWindow().then(() => console.log('Maximized window')).catch(err => console.log(err)); + * ``` + */ + maximize() { + return this.wire.sendAction('maximize-window', this.identity).then(() => undefined); + } + /** + * Minimizes the window. + * + * @example + * ```js + * async function minWindow() { + * const win = await fin.Window.getCurrent(); + * return await win.minimize(); + * } + * + * minWindow().then(() => console.log('Minimized window')).catch(err => console.log(err)); + * ``` + */ + minimize() { + return this.wire.sendAction('minimize-window', this.identity).then(() => undefined); + } + /** + * Moves the window by a specified amount. + * @param deltaLeft The change in the left position of the window + * @param deltaTop The change in the top position of the window + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.moveBy.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function moveBy(left, top) { + * const win = await createWin(); + * return await win.moveBy(left, top); + * } + * + * moveBy(580, 300).then(() => console.log('Moved')).catch(err => console.log(err)); + * ``` + */ + moveBy(deltaLeft, deltaTop, positioningOptions) { + return this.wire + .sendAction('move-window-by', { + deltaLeft, + deltaTop, + positioningOptions, + ...this.identity + }) + .then(() => undefined); + } + /** + * Moves the window to a specified location. + * @param left The left position of the window + * @param top The top position of the window + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.moveTo.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function moveTo(left, top) { + * const win = await createWin(); + * return await win.moveTo(left, top) + * } + * + * moveTo(580, 300).then(() => console.log('Moved')).catch(err => console.log(err)) + * ``` + */ + moveTo(left, top, positioningOptions) { + return this.wire + .sendAction('move-window', { + left, + top, + positioningOptions, + ...this.identity + }) + .then(() => undefined); + } + /** + * Resizes the window by a specified amount. + * @param deltaWidth The change in the width of the window + * @param deltaHeight The change in the height of the window + * @param anchor Specifies a corner to remain fixed during the resize. + * Can take the values: "top-left", "top-right", "bottom-left", or "bottom-right". + * If undefined, the default is "top-left" + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.resizeBy.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function resizeBy(left, top, anchor) { + * const win = await createWin(); + * return await win.resizeBy(left, top, anchor) + * } + * + * resizeBy(580, 300, 'top-right').then(() => console.log('Resized')).catch(err => console.log(err)); + * ``` + */ + resizeBy(deltaWidth, deltaHeight, anchor, positioningOptions) { + return this.wire + .sendAction('resize-window-by', { + deltaWidth: Math.floor(deltaWidth), + deltaHeight: Math.floor(deltaHeight), + anchor, + positioningOptions, + ...this.identity + }) + .then(() => undefined); + } + /** + * Resizes the window to the specified dimensions. + * @param width The change in the width of the window + * @param height The change in the height of the window + * @param anchor Specifies a corner to remain fixed during the resize. + * Can take the values: "top-left", "top-right", "bottom-left", or "bottom-right". + * If undefined, the default is "top-left" + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.resizeTo.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function resizeTo(left, top, anchor) { + * const win = await createWin(); + * return await win.resizeTo(left, top, anchor); + * } + * + * resizeTo(580, 300, 'top-left').then(() => console.log('Resized')).catch(err => console.log(err)); + * ``` + */ + resizeTo(width, height, anchor, positioningOptions) { + return this.wire + .sendAction('resize-window', { + width: Math.floor(width), + height: Math.floor(height), + anchor, + positioningOptions, + ...this.identity + }) + .then(() => undefined); + } + /** + * Restores the window to its normal state (i.e., unminimized, unmaximized). + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.restore.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function restore() { + * const win = await createWin(); + * return await win.restore(); + * } + * + * restore().then(() => console.log('Restored')).catch(err => console.log(err)); + * ``` + */ + restore() { + return this.wire.sendAction('restore-window', this.identity).then(() => undefined); + } + /** + * Will bring the window to the front of the entire stack and give it focus. + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.setAsForeground.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function setAsForeground() { + * const win = await createWin(); + * return await win.setAsForeground() + * } + * + * setAsForeground().then(() => console.log('In the foreground')).catch(err => console.log(err)); + * ``` + */ + setAsForeground() { + return this.wire.sendAction('set-foreground-window', this.identity).then(() => undefined); + } + /** + * Sets the window's size and position. + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.setBounds.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function setBounds(bounds) { + * const win = await createWin(); + * return await win.setBounds(bounds); + * } + * + * setBounds({ + * height: 100, + * width: 200, + * top: 400, + * left: 400 + * }).then(() => console.log('Bounds set to window')).catch(err => console.log(err)); + * ``` + */ + setBounds(bounds, positioningOptions) { + return this.wire + .sendAction('set-window-bounds', { ...bounds, ...this.identity, positioningOptions }) + .then(() => undefined); + } + /** + * Shows the window if it is hidden. + * @param force Show will be prevented from showing when force is false and + * ‘show-requested’ has been subscribed to for application’s main window. + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.show.html', + * autoShow: false + * }); + * return await app.getWindow(); + * } + * + * async function show() { + * const win = await createWin(); + * return await win.show() + * } + * + * show().then(() => console.log('Showing')).catch(err => console.log(err)); + * ``` + */ + show(force = false) { + return this.wire.sendAction('show-window', { force, ...this.identity }).then(() => undefined); + } + /** + * Shows the window if it is hidden at the specified location. + * + * @param left The left position of the window in pixels + * @param top The top position of the window in pixels + * @param force Show will be prevented from closing when force is false and + * ‘show-requested’ has been subscribed to for application’s main window + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.showAt.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * + * async function showAt(left, top) { + * const win = await createWin(); + * return await win.showAt(left, top) + * } + * + * showAt(580, 300).then(() => console.log('Showing at')).catch(err => console.log(err)); + * ``` + */ + showAt(left, top, force = false) { + return this.wire + .sendAction('show-at-window', { + force, + left: Math.floor(left), + top: Math.floor(top), + ...this.identity + }) + .then(() => undefined); + } + /** + * Shows the Chromium Developer Tools + * + * @tutorial Window.showDeveloperTools + */ + /** + * Updates the window using the passed options. + * + * @remarks Values that are objects are deep-merged, overwriting only the values that are provided. + * @param options Changes a window's options that were defined upon creation. See tutorial + * + * @example + * ```js + * async function updateOptions() { + * const win = await fin.Window.getCurrent(); + * return win.updateOptions({maxWidth: 100}); + * } + * updateOptions().then(() => console.log('options is updated')).catch(err => console.error(err)); + * ``` + */ + updateOptions(options) { + return this.wire.sendAction('update-window-options', { options, ...this.identity }).then(() => undefined); + } + /** + * Provides credentials to authentication requests + * @param userName userName to provide to the authentication challenge + * @param password password to provide to the authentication challenge + * + * @example + * ```js + * fin.Application.wrap({uuid: 'OpenfinPOC'}).then(app => { + * app.on('window-auth-requested', evt => { + * let win = fin.Window.wrap({ uuid: evt.uuid, name: evt.name}); + * win.authenticate('userName', 'P@assw0rd').then(()=> console.log('authenticated')).catch(err => console.log(err)); + * }); + * }); + * ``` + */ + authenticate(userName, password) { + return this.wire + .sendAction('window-authenticate', { userName, password, ...this.identity }) + .then(() => undefined); + } + /** + * Shows a menu on the window. + * + * @remarks Returns a promise that resolves when the user has either selected an item or closed the menu. (This may take longer than other apis). + * Resolves to an object with `{result: 'clicked', data }` where data is the data field on the menu item clicked, or `{result 'closed'}` when the user doesn't select anything. + * Calling this method will close previously opened menus. + * @experimental + * @param options + * @typeParam Data User-defined shape for data returned upon menu item click. Should be a + * [union](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) + * of all possible data shapes for the entire menu, and the click handler should process + * these with a "reducer" pattern. + * @example + * This could be used to show a drop down menu over views in a platform window: + * ```js + * const template = [ + * { + * label: 'Menu Item 1', + * data: 'hello from item 1' + * }, + * { type: 'separator' }, + * { + * label: 'Menu Item 2', + * type: 'checkbox', + * checked: true, + * data: 'The user clicked the checkbox' + * }, + * { + * label: 'see more', + * enabled: false, + * submenu: [ + * { label: 'submenu 1', data: 'hello from submenu' } + * ] + * } + * ] + * fin.me.showPopupMenu({ template }).then(r => { + * if (r.result === 'closed') { + * console.log('nothing happened'); + * } else { + * console.log(r.data) + * } + * }) + * ``` + * + * Overriding the built in context menu (note: that this can be done per element or document wide): + * ```js + * document.addEventListener('contextmenu', e => { + * e.preventDefault(); + * const template = [ + * { + * label: 'Menu Item 1', + * data: 'hello from item 1' + * }, + * { type: 'separator' }, + * { + * label: 'Menu Item 2', + * type: 'checkbox', + * checked: true, + * data: 'The user clicked the checkbox' + * }, + * { + * label: 'see more', + * enabled: false, + * submenu: [ + * { label: 'submenu 1', data: 'hello from submenu' } + * ] + * } + * ] + * fin.me.showPopupMenu({ template, x: e.x, y: e.y }).then(r => { + * if (r.result === 'closed') { + * console.log('nothing happened'); + * } else { + * console.log(r.data) + * } + * }) + * }) + * ``` + */ + async showPopupMenu(options) { + const { payload } = await this.wire.sendAction('show-popup-menu', { options, ...this.identity }); + return payload.data; + } + /** + * Closes the window's popup menu, if one exists. + * @experimental + * + * @remarks Only one popup menu will ever be showing at a time. Calling `showPopupMenu` will automatically close + * any existing popup menu. + * + * + * @example + * This could be used to close a popup menu if the user's mouse leaves an element for example. + * + * ```js + * await fin.me.closePopupMenu(); + * ``` + */ + async closePopupMenu() { + return this.wire.sendAction('close-popup-menu', { ...this.identity }).then(() => undefined); + } + /** + * Dispatch a result to the caller of `showPopupWindow`. + * + * @remarks If this window isn't currently being shown as a popup, this call will silently fail. + * @param data Serializable data to send to the caller window. + * + * @example + * ```js + * await fin.me.dispatchPopupResult({ + * foo: 'bar' + * }); + * ``` + */ + async dispatchPopupResult(data) { + this.wire.sendAction('window-dispatch-popup-result', this.identity).catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + await this.wire.sendAction('dispatch-popup-result', { data, ...this.identity }); + } + /** + * Prints the contents of the window. + * + * @param options Configuration for the print task. + * @remarks When `silent` is set to `true`, the API will pick the system's default printer if deviceName is empty + * and the default settings for printing. + * + * Use the CSS style `page-break-before: always;` to force print to a new page. + * + * @example + * ```js + * const win = fin.Window.getCurrentSync(); + * + * win.print({ silent: false, deviceName: 'system-printer-name' }).then(() => { + * console.log('print call has been sent to the system'); + * }); + * ``` + * + * If a window has embedded views, those views will not print by default. To print a window's contents including embedded views, + * use the `content` option: + * + * ```js + * const win = fin.Window.getCurrentSync(); + * + * // Print embedded views + * win.print({ content: 'views' }); + * + * // Print screenshot of current window + * win.print({ content: 'screenshot' }) + * ``` + * + * When `content` is set to `views`, the embedded views in the platform window will be concatenated and printed as + * individual pages. If `includeSelf` is set to `true`, the platform window itself will be printed as the first + * page - be aware that this page will *not* include the embedded views - it will only include the contents of + * the platform window itself (e.g. tab stacks), with blank spaces where the view contents would be embedded. + * + * Due to a known issue, view contents that are not visible at the time `print` is called will not appear when + * printing `contents: views`. This includes views that are obscured behind other active UI elements. + * + * To print the views embedded in their page context, set `content` to `screenshot`. + */ + async print(options = { content: 'self' }) { + switch (options.content) { + case undefined: + case 'self': + return super.print(options); + case 'screenshot': + return this.wire.sendAction('print-screenshot', this.identity).then(() => undefined); + case 'views': + return this.wire.sendAction('print-views', { ...this.identity, options }).then(() => undefined); + default: + return undefined; + } + } + } + Instance$7._Window = _Window; + return Instance$7; +} + +var hasRequiredFactory$1; + +function requireFactory$1 () { + if (hasRequiredFactory$1) return Factory$8; + hasRequiredFactory$1 = 1; + Object.defineProperty(Factory$8, "__esModule", { value: true }); + Factory$8._WindowModule = void 0; + const base_1 = base; + const validate_1 = validate; + const Instance_1 = requireInstance(); + /** + * Static namespace for OpenFin API methods that interact with the {@link _Window} class, available under `fin.Window`. + */ + class _WindowModule extends base_1.Base { + /** + * Asynchronously returns an API handle for the given Window identity. + * + * @remarks Wrapping a Window identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for a Window throughout its entire lifecycle. + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.wrap.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * createWin().then(() => fin.Window.wrap({ uuid: 'app-1', name: 'myApp' })) + * .then(win => console.log('wrapped window')) + * .catch(err => console.log(err)); + * ``` + */ + async wrap(identity) { + this.wire.sendAction('window-wrap').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new Instance_1._Window(this.wire, identity); + } + /** + * Synchronously returns an API handle for the given Window identity. + * + * @remarks Wrapping a Window identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for a Window throughout its entire lifecycle. + * + * @example + * ```js + * async function createWin() { + * const app = await fin.Application.start({ + * name: 'myApp', + * uuid: 'app-1', + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.wrapSync.html', + * autoShow: true + * }); + * return await app.getWindow(); + * } + * await createWin(); + * let win = fin.Window.wrapSync({ uuid: 'app-1', name: 'myApp' }); + * ``` + */ + wrapSync(identity) { + this.wire.sendAction('window-wrap-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new Instance_1._Window(this.wire, identity); + } + /** + * Creates a new Window. + * @param options - Window creation options + * + * @example + * ```js + * async function createWindow() { + * const winOption = { + * name:'child', + * defaultWidth: 300, + * defaultHeight: 300, + * url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.create.html', + * frame: true, + * autoShow: true + * }; + * return await fin.Window.create(winOption); + * } + * + * createWindow().then(() => console.log('Window is created')).catch(err => console.log(err)); + * ``` + */ + create(options) { + this.wire.sendAction('create-window').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const win = new Instance_1._Window(this.wire, { uuid: this.me.uuid, name: options.name }); + return win.createWindow(options); + } + /** + * Asynchronously returns a Window object that represents the current window + * + * @example + * ```js + * fin.Window.getCurrent() + * .then(wnd => console.log('current window')) + * .catch(err => console.log(err)); + * + * ``` + */ + getCurrent() { + this.wire.sendAction('get-current-window').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + if (!this.wire.me.isWindow) { + throw new Error('You are not in a Window context'); + } + const { uuid, name } = this.wire.me; + return this.wrap({ uuid, name }); + } + /** + * Synchronously returns a Window object that represents the current window + * + * @example + * ```js + * const wnd = fin.Window.getCurrentSync(); + * const info = await wnd.getInfo(); + * console.log(info); + * + * ``` + */ + getCurrentSync() { + this.wire.sendAction('get-current-window-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + if (!this.wire.me.isWindow) { + throw new Error('You are not in a Window context'); + } + const { uuid, name } = this.wire.me; + return this.wrapSync({ uuid, name }); + } + } + Factory$8._WindowModule = _WindowModule; + return Factory$8; +} + +var hasRequiredWindow; + +function requireWindow () { + if (hasRequiredWindow) return window$1; + hasRequiredWindow = 1; + (function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + /** + * Entry points for the OpenFin `Window` API (`fin.Window`). + * + * * {@link _WindowModule} contains static members of the `Window` API, accessible through `fin.Window`. + * * {@link _Window} describes an instance of an OpenFin Window, e.g. as returned by `fin.Window.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * Underscore prefixing of OpenFin types that alias DOM entities will be fixed in a future version. + * + * @packageDocumentation + */ + __exportStar(requireFactory$1(), exports); + __exportStar(requireInstance(), exports); + } (window$1)); + return window$1; +} + +/** + * Entry point for the OpenFin `System` API (`fin.System`). + * + * * {@link System} contains static members of the `System` API (available under `fin.System`) + * + * @packageDocumentation + */ +Object.defineProperty(system, "__esModule", { value: true }); +system.System = void 0; +const base_1$i = base; +const transport_errors_1$1 = transportErrors; +const window_1 = requireWindow(); +const events_1$6 = require$$0; +/** + * An object representing the core of OpenFin Runtime. Allows the developer + * to perform system-level actions, such as accessing logs, viewing processes, + * clearing the cache and exiting the runtime as well as listen to {@link OpenFin.SystemEvents system events}. + * + */ +class System extends base_1$i.EmitterBase { + /** + * @internal + */ + constructor(wire) { + super(wire, 'system'); + } + sendExternalProcessRequest(action, options) { + return new Promise((resolve, reject) => { + const exitEventKey = 'external-process-exited'; + let processUuid; + let exitPayload; + let externalProcessExitHandler; + let ofWindow; + if (typeof options.listener === 'function') { + externalProcessExitHandler = (payload) => { + const data = payload || {}; + exitPayload = { + topic: 'exited', + uuid: data.processUuid || '', + exitCode: data.exitCode || 0 + }; + if (processUuid === payload.processUuid) { + options.listener(exitPayload); + ofWindow.removeListener(exitEventKey, externalProcessExitHandler); + } + }; + // window constructor expects the name is not undefined + if (!this.wire.me.name) { + this.wire.me.name = this.wire.me.uuid; + } + ofWindow = new window_1._Window(this.wire, this.wire.me); + ofWindow.on(exitEventKey, externalProcessExitHandler); + } + this.wire + .sendAction(action, options) + .then(({ payload }) => { + processUuid = payload.data.uuid; + resolve(payload.data); + if (exitPayload && processUuid === exitPayload.uuid) { + options.listener(exitPayload); + ofWindow.removeListener(exitEventKey, externalProcessExitHandler); + } + }) + .catch((err) => { + if (ofWindow) { + ofWindow.removeListener(exitEventKey, externalProcessExitHandler); + } + reject(err); + }); + }); + } + /** + * Returns the version of the runtime. The version contains the major, minor, + * build and revision numbers. + * + * @example + * ```js + * fin.System.getVersion().then(v => console.log(v)).catch(err => console.log(err)); + * ``` + */ + getVersion() { + return this.wire.sendAction('get-version').then(({ payload }) => payload.data); + } + /** + * Clears cached data containing application resource + * files (images, HTML, JavaScript files), cookies, and items stored in the + * Local Storage. + * @param options - See below for details. + * + * @remarks For more information on the accepted options, see the following pages: + * * cache: browsing data cache for html files and images ([caching](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching)) + * * cookies: browser [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) + * * localStorage: browser data that can be used across sessions ([local storage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)) + * * appcache: html5 [application cache](https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache) + * @example + * ```js + * const clearCacheOptions = { + * appcache: true, + * cache: true, + * cookies: true, + * localStorage: true + * }; + * fin.System.clearCache(clearCacheOptions).then(() => console.log('Cache cleared')).catch(err => console.log(err)); + * ``` + * + */ + clearCache(options) { + return this.wire.sendAction('clear-cache', options).then(() => undefined); + } + /** + * Clears all cached data when OpenFin Runtime exits. + * + * @example + * ```js + * fin.System.deleteCacheOnExit().then(() => console.log('Deleted Cache')).catch(err => console.log(err)); + * ``` + */ + deleteCacheOnExit() { + return this.wire.sendAction('delete-cache-request').then(() => undefined); + } + /** + * Exits the Runtime. + * + * @example + * ```js + * fin.System.exit().then(() => console.log('exit')).catch(err => console.log(err)); + * ``` + */ + exit() { + return this.wire.sendAction('exit-desktop').then(() => undefined); + } + /** + * Fetches a JSON manifest using the browser process and returns a Javascript object. + * @param manifestUrl The URL of the manifest to fetch. + * + * @example + * ```js + * const manifest = await fin.System.fetchManifest('https://www.path-to-manifest.com'); + * console.log(manifest); + * ``` + */ + async fetchManifest(manifestUrl) { + const { payload: { data } } = await this.wire.sendAction('fetch-manifest', { manifestUrl }); + return data; + } + /** + * Writes any unwritten cookies data to disk. + * + * @example + * ```js + * fin.System.flushCookieStore() + * .then(() => console.log('success')) + * .catch(err => console.error(err)); + * ``` + */ + flushCookieStore() { + return this.wire.sendAction('flush-cookie-store').then(() => undefined); + } + /** + * Retrieves an array of data (name, ids, bounds) for all application windows. + * + * @example + * ```js + * fin.System.getAllWindows().then(wins => console.log(wins)).catch(err => console.log(err)); + * ``` + */ + getAllWindows() { + return this.wire.sendAction('get-all-windows').then(({ payload }) => payload.data); + } + /** + * Retrieves an array of data for all applications. + * + * @example + * ```js + * fin.System.getAllApplications().then(apps => console.log(apps)).catch(err => console.log(err)); + * ``` + */ + getAllApplications() { + return this.wire.sendAction('get-all-applications').then(({ payload }) => payload.data); + } + /** + * Retrieves the command line argument string that started OpenFin Runtime. + * + * @example + * ```js + * fin.System.getCommandLineArguments().then(args => console.log(args)).catch(err => console.log(err)); + * ``` + */ + getCommandLineArguments() { + return this.wire.sendAction('get-command-line-arguments').then(({ payload }) => payload.data); + } + /** + * Get the current state of the crash reporter. + * + * @example + * ```js + * fin.System.getCrashReporterState().then(state => console.log(state)).catch(err => console.log(err)); + * ``` + */ + async getCrashReporterState() { + const { payload: { data: { diagnosticMode, isRunning } } } = await this.wire.sendAction('get-crash-reporter-state'); + console.warn('diagnosticMode property is deprecated. It will be removed in a future version'); + return { + // diagnosticMode will be removed in a future version + diagnosticMode, + diagnosticsMode: diagnosticMode, + isRunning + }; + } + /** + * Start the crash reporter if not already running. + * @param options - configure crash reporter + * + * @remarks You can optionally specify `diagnosticsMode` to have the logs sent to + * OpenFin on runtime close. (NOTE: `diagnosticsMode` will turn on verbose logging and disable the sandbox + * for newly launched renderer processes. See https://developers.openfin.co/of-docs/docs/debugging#diagnostics-mode for + * more details.) + * + * @example + * ```js + * fin.System.startCrashReporter({diagnosticsMode: true}).then(reporter => console.log(reporter)).catch(err => console.log(err)); + * ``` + */ + async startCrashReporter(options) { + const opts = options; + const newOpts = { ...opts, diagnosticMode: opts.diagnosticsMode || opts.diagnosticMode }; + const { payload: { data: { diagnosticMode, isRunning } } } = await this.wire.sendAction('start-crash-reporter', newOpts); + return { + // diagnosticMode will be removed in a future version + diagnosticMode, + diagnosticsMode: diagnosticMode, + isRunning + }; + } + /** + * Returns a hex encoded hash of the machine id and the currently logged in user name. + * This is the recommended way to uniquely identify a user / machine combination. + * + * @remarks For Windows systems this is a sha256 hash of the machine ID set in the registry key: + * `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\MachineGuid` and `USERNAME`. + * + * For OSX systems, a native-level call is used to get the machine ID. + * + * @example + * ```js + * fin.System.getUniqueUserId().then(id => console.log(id)).catch(err => console.log(err)); + * ``` + */ + getUniqueUserId() { + return this.wire.sendAction('get-unique-user-id').then(({ payload }) => payload.data); + } + /** + * Retrieves a frame info object for the uuid and name passed in + * @param uuid - The UUID of the target. + * @param name - The name of the target. + * + * @remarks The possible types are 'window', 'iframe', 'external connection' or 'unknown'. + * @example + * ```js + * const entityUuid = 'OpenfinPOC'; + * const entityName = '40c74b5d-ed98-40f7-853f-e3d3c2699175'; + * fin.System.getEntityInfo(entityUuid, entityName).then(info => console.log(info)).catch(err => console.log(err)); + * + * // example info shape + * { + * "uuid": "OpenfinPOC", + * "name": "40c74b5d-ed98-40f7-853f-e3d3c2699175", + * "parent": { + * "uuid": "OpenfinPOC", + * "name": "OpenfinPOC" + * }, + * "entityType": "iframe" + * } + * ``` + */ + getEntityInfo(uuid, name) { + return this.wire.sendAction('get-entity-info', { uuid, name }).then(({ payload }) => payload.data); + } + /** + * Gets the value of a given environment variable on the computer on which the runtime is installed + * + * @example + * ```js + * fin.System.getEnvironmentVariable('HOME').then(env => console.log(env)).catch(err => console.log(err)); + * ``` + */ + getEnvironmentVariable(envName) { + return this.wire + .sendAction('get-environment-variable', { + environmentVariables: envName + }) + .then(({ payload }) => payload.data); + } + /** + * Get currently focused Window. + * If a View currently has focus, returns the identity of View's parent Window. + * Use {@link Window._Window#getFocusedContent Window.getFocusedContent} to directly access currently focused Window or View. + * + * @example + * ```js + * fin.System.getFocusedWindow().then(winInfo => console.log(winInfo)).catch(err => console.log(err)); + * ``` + */ + getFocusedWindow() { + return this.wire.sendAction('get-focused-window').then(({ payload }) => payload.data); + } + /** + * Get currently focused content. Returns identity of entity with `entityType`. + * + * @example + * ```js + * fin.System.getFocusedContent().then(contentIdentity => console.log(contentIdentity)).catch(err => console.log(err)); + * ``` + */ + getFocusedContent() { + return this.wire.sendAction('get-focused-content').then(({ payload }) => payload.data); + } + /** + * Returns information about the given app's certification status + * + * @example + * ```js + * const manifestUrl = "http://localhost:1234/app.json" + * try { + * const certificationInfo = await fin.System.isAppCertified(manifestUrl); + * } catch(err) { + * console.error(err) + * } + * ``` + */ + async isAppCertified(manifestUrl) { + const { payload: { data: { certifiedInfo } } } = await this.wire.sendAction('is-app-certified', { manifestUrl }); + return certifiedInfo; + } + /** + * Returns an array of all the installed runtime versions in an object. + * + * @example + * ```js + * fin.System.getInstalledRuntimes().then(runtimes => console.log(runtimes)).catch(err => console.log(err)); + * ``` + */ + // incompatible with standalone node process. + getInstalledRuntimes() { + return this.wire.sendAction('get-installed-runtimes').then(({ payload }) => payload.data.runtimes); + } + // incompatible with standalone node process. + async getInstalledApps() { + const { payload: { data: { installedApps } } } = await this.wire.sendAction('get-installed-apps'); + return installedApps; + } + /** + * Retrieves the contents of the log with the specified filename. + * @param options A object that id defined by the GetLogRequestType interface + * + * @example + * ```js + * async function getLog() { + * const logs = await fin.System.getLogList(); + * return await fin.System.getLog(logs[0]); + * } + * + * getLog().then(log => console.log(log)).catch(err => console.log(err)); + * ``` + */ + getLog(options) { + return this.wire.sendAction('view-log', options).then(({ payload }) => payload.data); + } + /** + * Returns a unique identifier (UUID) provided by the machine. + * + * @example + * ```js + * fin.System.getMachineId().then(id => console.log(id)).catch(err => console.log(err)); + * ``` + */ + getMachineId() { + return this.wire.sendAction('get-machine-id').then(({ payload }) => payload.data); + } + /** + * Returns the minimum (inclusive) logging level that is currently being written to the log. + * + * @example + * ```js + * fin.System.getMinLogLevel().then(level => console.log(level)).catch(err => console.log(err)); + * ``` + */ + getMinLogLevel() { + return this.wire.sendAction('get-min-log-level').then(({ payload }) => payload.data); + } + /** + * Retrieves an array containing information for each log file. + * + * @example + * ```js + * fin.System.getLogList().then(logList => console.log(logList)).catch(err => console.log(err)); + * ``` + */ + getLogList() { + return this.wire.sendAction('list-logs').then(({ payload }) => payload.data); + } + /** + * Retrieves an object that contains data about the monitor setup of the + * computer that the runtime is running on. + * + * @example + * ```js + * fin.System.getMonitorInfo().then(monitorInfo => console.log(monitorInfo)).catch(err => console.log(err)); + * ``` + */ + getMonitorInfo() { + return this.wire.sendAction('get-monitor-info').then(({ payload }) => payload.data); + } + /** + * Returns the mouse in virtual screen coordinates (left, top). + * + * @example + * ```js + * fin.System.getMousePosition().then(mousePosition => console.log(mousePosition)).catch(err => console.log(err)); + * ``` + */ + getMousePosition() { + return this.wire.sendAction('get-mouse-position').then(({ payload }) => payload.data); + } + /** + * Retrieves an array of all of the runtime processes that are currently + * running. Each element in the array is an object containing the uuid + * and the name of the application to which the process belongs. + * @deprecated Please use our new set of process APIs: + * {@link Window._Window#getProcessInfo Window.getProcessInfo} + * {@link View.View#getProcessInfo View.getProcessInfo} + * {@link Application.Application#getProcessInfo Application.getProcessInfo} + * {@link System#getAllProcessInfo System.getAllProcessInfo} + * + * @example + * ```js + * fin.System.getProcessList().then(ProcessList => console.log(ProcessList)).catch(err => console.log(err)); + * ``` + */ + getProcessList() { + // eslint-disable-next-line no-console + console.warn('System.getProcessList has been deprecated. Please consider using our new process APIs: Window.getProcessInfo, View.getProcessInfo, Application.getProcessInfo, System.getAllProcessInfo'); + return this.wire.sendAction('process-snapshot').then(({ payload }) => payload.data); + } + /** + * Retrieves all process information. + * + * @remarks This includes the browser process and every process associated to all entities (windows and views). + * + * @example + * ```js + * const allProcessInfo = await fin.System.getAllProcessInfo(); + * ``` + * @experimental + */ + async getAllProcessInfo() { + const { payload: { data } } = await this.wire.sendAction('get-all-process-info', this.identity); + return data; + } + /** + * Retrieves the Proxy settings. + * + * @example + * ```js + * fin.System.getProxySettings().then(ProxySetting => console.log(ProxySetting)).catch(err => console.log(err)); + * + * //This response has the following shape: + * { + * config: { + * proxyAddress: "proxyAddress", //the configured Proxy Address + * proxyPort: 0, //the configured Proxy port + * type: "system" //Proxy Type + * }, + * system: { + * autoConfigUrl: "", + * bypass: "", + * enabled: false, + * proxy: "" + * } + * } + * ``` + */ + getProxySettings() { + return this.wire.sendAction('get-proxy-settings').then(({ payload }) => payload.data); + } + /** + * Returns information about the running Runtime in an object. + * + * @example + * ```js + * fin.System.getRuntimeInfo().then(RuntimeInfo => console.log(RuntimeInfo)).catch(err => console.log(err)); + * ``` + */ + getRuntimeInfo() { + return this.wire.sendAction('get-runtime-info').then(({ payload }) => payload.data); + } + /** + * Returns information about the running RVM in an object. + * + * @example + * ```js + * fin.System.getRvmInfo().then(RvmInfo => console.log(RvmInfo)).catch(err => console.log(err)); + * ``` + */ + // incompatible with standalone node process. + getRvmInfo() { + return this.wire.sendAction('get-rvm-info').then(({ payload }) => payload.data); + } + /** + * Retrieves general system information. If you need more detailed information about the + * OS and the currently logged in user, use `fin.System.getOSInfo()` instead. + * + * @example + * ```js + * fin.System.getHostSpecs().then(specs => console.log(specs)).catch(err => console.log(err)); + * ``` + */ + getHostSpecs() { + return this.wire.sendAction('get-host-specs').then(({ payload }) => payload.data); + } + /** + * Retrieves information about the OS and the currently logged in user. + * + * @example + * ```js + * fin.System.getOSInfo().then(specs => console.log(specs)).catch(err => console.log(err)); + * ``` + */ + getOSInfo() { + return this.wire.sendAction('get-os-info').then(({ payload }) => payload.data); + } + /** + * Runs an executable or batch file. A path to the file must be included in options. + *
A uuid may be optionally provided. If not provided, OpenFin will create a uuid for the new process. + *
Note: This method is restricted by default and must be enabled via + * API security settings. Also, this api has an enhanced permission set to make it less dangerous. So application owners can only allow to launch the assets owned by the application, the enabled downloaded files or the restricted executables. + * @param options A object that is defined in the ExternalProcessRequestType interface + * + * @remarks If an unused UUID is provided in options, it will be used. If no UUID is provided, OpenFin will assign one. + * This api has an enhanced permission set to make it less dangerous. So application owners can only allow to launch the + * assets owned by the application, the enabled downloaded files or the restricted executables. + * + * **Note:** Since _appAssets_ relies on the RVM, which is missing on MAC_OS, 'alias' is not available. Instead provide + * the full path e.g. _/Applications/Calculator.app/Contents/MacOS/Calculator_. + * + * @example + * Basic Example: + * ```js + * fin.System.launchExternalProcess({ + * path: 'notepad', + * arguments: '', + * listener: function (result) { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * ``` + * + * Promise resolution: + * + * ```js + * //This response has the following shape: + * { + * uuid: "FB3E6E36-0976-4C2B-9A09-FB2E54D2F1BB" // The mapped UUID which identifies the launched process + * } + * ``` + * + * Listener callback: + * ```js + * //This response has the following shape: + * { + * topic: "exited", // Or "released" on a call to releaseExternalProcess + * uuid: "FB3E6E36-0976-4C2B-9A09-FB2E54D2F1BB", // The mapped UUID which identifies the launched process + * exitCode: 0 // Process exit code + * } + * ``` + * + * By specifying a lifetime, an external process can live as long the window/application that launched it or + * persist after the application exits. The default value is null, which is equivalent to 'persist', meaning + * the process lives on after the application exits: + * + * ```js + * fin.System.launchExternalProcess({ + * path: 'notepad', + * arguments: '', + * listener: (result) => { + * console.log('the exit code', result.exitCode); + * }, + * lifetime: 'window' + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * ``` + * + * Note: A process that exits when the window/application exits cannot be released via fin.desktop.System.releaseExternalProcess. + * + * By specifying a cwd, it will set current working directory when launching an external process: + * + * ```js + * fin.System.launchExternalProcess({ + * path: 'cmd.exe', + * cwd: 'c:\\temp', + * arguments: '', + * listener: (result) => { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * ``` + * + * Example using an alias from app.json appAssets property: + * + * ```json + * "appAssets": [ + * { + * "src": "exe.zip", + * "alias": "myApp", + * "version": "4.12.8", + * "target": "myApp.exe", + * "args": "a b c d" + * }, + * ] + * ``` + * + * ```js + * // When called, if no arguments are passed then the arguments (if any) + * // are taken from the 'app.json' file, from the 'args' parameter + * // of the 'appAssets' Object with the relevant 'alias'. + * fin.System.launchExternalProcess({ + * //Additionally note that the executable found in the zip file specified in appAssets + * //will default to the one mentioned by appAssets.target + * //If the the path below refers to a specific path it will override this default + * alias: 'myApp', + * listener: (result) => { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * ``` + * + * Example using an alias but overriding the arguments: + * + * ```json + * "appAssets": [ + * { + * "src": "exe.zip", + * "alias": "myApp", + * "version": "4.12.8", + * "target": "myApp.exe", + * "args": "a b c d" + * }, + * ] + * ``` + * + * ```js + * // If 'arguments' is passed as a parameter it takes precedence + * // over any 'args' set in the 'app.json'. + * fin.System.launchExternalProcess({ + * alias: 'myApp', + * arguments: 'e f g', + * listener: (result) => { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * ``` + * + * It is now possible to optionally perform any combination of the following certificate checks + * against an absolute target via `fin.desktop.System.launchExternalProcess()`: + * + * ```js + * "certificate": { + * "serial": "3c a5 ...", // A hex string with or without spaces + * "subject": "O=OpenFin INC., L=New York, ...", // An internally tokenized and comma delimited string allowing partial or full checks of the subject fields + * "publickey": "3c a5 ...", // A hex string with or without spaces + * "thumbprint": "3c a5 ...", // A hex string with or without spaces + * "trusted": true // A boolean indicating that the certificate is trusted and not revoked + * } + * ``` + * + * Providing this information as part of the default configurations for assets in an application's manifest + * will be added in a future RVM update: + * + * ```js + * fin.System.launchExternalProcess({ + * path: 'C:\\Users\\ExampleUser\\AppData\\Local\\OpenFin\\OpenFinRVM.exe', + * arguments: '--version', + * certificate: { + * trusted: true, + * subject: 'O=OpenFin INC., L=New York, S=NY, C=US', + * thumbprint: '‎3c a5 28 19 83 05 fe 69 88 e6 8f 4b 3a af c5 c5 1b 07 80 5b' + * }, + * listener: (result) => { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * ``` + * + * It is possible to launch files that have been downloaded by the user by listening to the window + * `file-download-completed` event and using the `fileUuid` provided by the event: + * + * ```js + * const win = fin.Window.getCurrentSync(); + * win.addListener('file-download-completed', (evt) => { + * if (evt.state === 'completed') { + * fin.System.launchExternalProcess({ + * fileUuid: evt.fileUuid, + * arguments: '', + * listener: (result) => { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => { + * console.log(processIdentity); + * }).catch(error => { + * console.log(error); + * }); + * } + * }); + * ``` + * + * Launching assets specified in the app manifest: + * + * Sample appAssets section in app.json + * ```js + * "appAssets": [ + * { + * "src": "http://filesamples.com/exe.zip", + * "alias": "myApp", + * "version": "4.12.8", + * "target": "myApp.exe", + * "args": "a b c d" + * }, + * { + * "src": "http://examples.com/exe.zip", + * "alias": "myApp2", + * "version": "5.12.8", + * "target": "myApp2.exe", + * "args": "a b c" + * } + * ] + * ``` + * + * This permission allows for launching of all assets specified in the above appAssets section. ("myApp" and "myApp2"): + * + * ```js + * "permissions": { + * "System": { + * "launchExternalProcess": { + * "enabled": true, + * "assets": { + * "enabled": true + * } + * } + * } + * } + * ``` + * + * This permission allows for launching of _only_ the "myApp" asset in the above appAssets section, as defined in `srcRules`: + * ```js + * "permissions": { + * "System": { + * "launchExternalProcess": { + * "enabled": true, + * "assets": { + * "enabled": true + * "srcRules": [ + * { + * "match": [ + * "*://filesamples.com/*" + * ], + * "behavior": "allow" + * }, + * { + * "match": [ + * "" + * ], + * "behavior": "block" + * } + * ] + * } + * } + * } + * } + * ``` + * + * Launching downloaded files: + * ```js + * "permissions": { + * "System": { + * "launchExternalProcess": { + * "enabled": true, + * "downloads": { + * "enabled": true + * } + * } + * } + * } + * ``` + * + * This permission allows to launch all the executables: + * ```js + * "permissions": { + * "System": { + * "launchExternalProcess": { + * "enabled": true, + * "executables": { + * "enabled": true + * } + * } + * } + * } + * ``` + * + * + * This permission only allows launching of executables whose file paths match the corresponding `pathRules`: + * ```js + * "permissions": { + * "System": { + * "launchExternalProcess": { + * "enabled": true, + * "executables": { + * "enabled": true + * "pathRules": [ + * { + * "match": [ + * "/Windows/System32/*.exe" + * ], + * "behavior": "allow" + * }, + * { + * "match": [ + * "*.exe" + * ], + * "behavior": "block" + * } + * ] + * } + * } + * } + * } + * ``` + */ + launchExternalProcess(options) { + return this.sendExternalProcessRequest('launch-external-process', options); + } + /** + * Monitors a running process. A pid for the process must be included in options. + *
A uuid may be optionally provided. If not provided, OpenFin will create a uuid for the new process. + * + * @remarks If an unused uuid is provided in options, it will be used. If no uuid is provided, OpefinFin will assign a uuid. + * @example + * ```js + * fin.System.monitorExternalProcess({ + * pid: 10208, + * uuid: 'my-external-process', // optional + * listener: function (result) { + * console.log('the exit code', result.exitCode); + * } + * }).then(processIdentity => console.log(processIdentity)).catch(err => console.log(err)); + * ``` + */ + monitorExternalProcess(options) { + return this.sendExternalProcessRequest('monitor-external-process', options); + } + /** + * Writes the passed message into both the log file and the console. + * @param level The log level for the entry. Can be either "info", "warning" or "error" + * @param message The log message text + * + * @example + * ```js + * fin.System.log("info", "An example log message").then(() => console.log('Log info message')).catch(err => console.log(err)); + * ``` + */ + log(level, message) { + return this.wire.sendAction('write-to-log', { level, message }).then(() => undefined); + } + /** + * Opens the passed URL in the default web browser. + * + * @remarks It only supports http(s) and fin(s) protocols by default. + * In order to use other custom protocols, they have to be enabled via + * [API security settings](https://developers.openfin.co/docs/api-security). + * File protocol and file path are not supported. + * @param url The URL to open + * + * @example + * ```js + * fin.System.openUrlWithBrowser('https://cdn.openfin.co/docs/javascript/stable/tutorial-System.openUrlWithBrowser.html') + * .then(() => console.log('Opened URL')) + * .catch(err => console.log(err)); + * ``` + * + * Example of permission definition to enable non-default protocols: + * + * Note: permission definition should be specified in an app manifest file if there is no DOS settings. + * Otherwise it has to be specified in both DOS and app manifest files. + * + * ```js + * "permissions": { + * "System": { + * "openUrlWithBrowser": { + * "enabled": true, + * "protocols": [ "msteams", "slack"] + * } + * } + * } + * ``` + */ + openUrlWithBrowser(url) { + return this.wire.sendAction('open-url-with-browser', { url }).then(() => undefined); + } + /** + * Creates a new registry entry under the HKCU root Windows registry key if the given custom protocol name doesn't exist or + * overwrites the existing registry entry if the given custom protocol name already exists. + * + * Note: This method is restricted by default and must be enabled via + * {@link https://developers.openfin.co/docs/api-security API security settings}. It requires RVM 12 or higher version. + * + * + * @remarks These protocols are reserved and cannot be registered: + * - fin + * - fins + * - openfin + * - URI Schemes registered with {@link https://en.wikipedia.org/wiki/List_of_URI_schemes#Official_IANA-registered_schemes IANA} + * + * @throws if a given custom protocol failed to be registered. + * @throws if a manifest URL contains the '%1' string. + * @throws if a manifest URL contains a query string parameter which name equals to the Protocol Launch Request Parameter Name. + * @throws if the full length of the command string that is to be written to the registry exceeds 2048 bytes. + * + * @example + * ```js + * fin.System.registerCustomProtocol({protocolName:'protocol1'}).then(console.log).catch(console.error); + * ``` + */ + async registerCustomProtocol(options) { + if (typeof options !== 'object') { + throw new Error('Must provide an object with a `protocolName` property having a string value.'); + } + await this.wire.sendAction('register-custom-protocol', options); + } + /** + * Removes the registry entry for a given custom protocol. + * + * Note: This method is restricted by default and must be enabled via + * {@link https://developers.openfin.co/docs/api-security API security settings}. It requires RVM 12 or higher version. + * + * + * @remarks These protocols are reserved and cannot be unregistered: + * - fin + * - fins + * - openfin + * - URI Schemes registered with {@link https://en.wikipedia.org/wiki/List_of_URI_schemes#Official_IANA-registered_schemes IANA} + * + * @throws if a protocol entry failed to be removed in registry. + * + * @example + * ```js + * await fin.System.unregisterCustomProtocol('protocol1'); + * ``` + */ + async unregisterCustomProtocol(protocolName) { + await this.wire.sendAction('unregister-custom-protocol', { protocolName }); + } + /** + * Retrieves the registration state for a given custom protocol. + * + * Note: This method is restricted by default and must be enabled via + * {@link https://developers.openfin.co/docs/api-security API security settings}. It requires RVM 12 or higher version. + * + * @remarks These protocols are reserved and cannot get states for them: + * - fin + * - fins + * - openfin + * - URI Schemes registered with {@link https://en.wikipedia.org/wiki/List_of_URI_schemes#Official_IANA-registered_schemes IANA} + * + * + * @example + * ```js + * const protocolState = await fin.System.getCustomProtocolState('protocol1'); + */ + async getCustomProtocolState(protocolName) { + return this.wire.sendAction('get-custom-protocol-state', { protocolName }).then(({ payload }) => payload.data); + } + /** + * Removes the process entry for the passed UUID obtained from a prior call + * of fin.System.launchExternalProcess(). + * @param uuid The UUID for a process obtained from a prior call to fin.desktop.System.launchExternalProcess() + * + * @example + * ```js + * fin.System.launchExternalProcess({ + * path: "notepad", + * listener: function (result) { + * console.log("The exit code", result.exitCode); + * } + * }) + * .then(identity => fin.System.releaseExternalProcess(identity.uuid)) + * .then(() => console.log('Process has been unmapped!')) + * .catch(err => console.log(err)); + * ``` + */ + releaseExternalProcess(uuid) { + return this.wire.sendAction('release-external-process', { uuid }).then(() => undefined); + } + /** + * Shows the Chromium Developer Tools for the specified window + * @param identity This is a object that is defined by the Identity interface + * + * @tutorial System.showDeveloperTools + */ + showDeveloperTools(identity) { + return this.wire.sendAction('show-developer-tools', identity).then(() => undefined); + } + /** + * Attempt to close an external process. The process will be terminated if it + * has not closed after the elapsed timeout in milliseconds. + * + * Note: This method is restricted by default and must be enabled via + * API security settings. + * @param options A object defined in the TerminateExternalRequestType interface + * + * @example + * ```js + * fin.System.launchExternalProcess({ + * path: "notepad", + * listener: function (result) { + * console.log("The exit code", result.exitCode); + * } + * }) + * .then(identity => fin.System.terminateExternalProcess({uuid: identity.uuid, timeout:2000, killTree: false})) + * .then(() => console.log('Terminate the process')) + * .catch(err => console.log(err)); + * ``` + */ + terminateExternalProcess(options) { + return this.wire.sendAction('terminate-external-process', options).then(() => undefined); + } + /** + * Update the OpenFin Runtime Proxy settings. + * @param options A config object defined in the ProxyConfig interface + * + * @example + * ```js + * fin.System.updateProxySettings({proxyAddress:'127.0.0.1', proxyPort:8080, type:'http'}) + * .then(() => console.log('Update proxy successfully')) + * .catch(err => console.error(err)); + * ``` + */ + updateProxySettings(options) { + return this.wire.sendAction('update-proxy', options).then(() => undefined); + } + /** + * Downloads the given application asset. + * + * Note: This method is restricted by default and must be enabled via + * API security settings. + * @param appAsset App asset object + * + * @example + * ```js + * async function downloadAsset() { + * const appAsset = { + * src: `${ location.origin }/assets.zip`, + * alias: 'dirApp', + * version: '1.23.24', + * target: 'assets/run.bat' + * }; + * + * return fin.System.downloadAsset(appAsset, (progress => { + * //Print progress as we download the asset. + * const downloadedPercent = Math.floor((progress.downloadedBytes / progress.totalBytes) * 100); + * console.log(`Downloaded ${downloadedPercent}%`); + * })); + * } + * + * downloadAsset() + * .then(() => console.log('Success')) + * .catch(err => console.error(err)); + * + * ``` + */ + // incompatible with standalone node process. + async downloadAsset(appAsset, progressListener) { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/no-empty-function + const noop = () => { }; + let resolve = noop; + let reject = noop; + const downloadCompletePromise = new Promise((y, n) => { + resolve = y; + reject = n; + }); + // node.js environment not supported + if (this.wire.environment.type !== 'openfin') { + throw new transport_errors_1$1.NotSupportedError('downloadAsset only supported in an OpenFin Render process'); + } + const callSite = transport_errors_1$1.RuntimeError.getCallSite(); + const downloadId = this.wire.environment.getNextMessageId().toString(); + const dlProgressKey = `asset-download-progress-${downloadId}`; + const dlErrorKey = `asset-download-error-${downloadId}`; + const dlCompleteKey = `asset-download-complete-${downloadId}`; + const dlProgress = (progress) => { + const p = { + downloadedBytes: progress.downloadedBytes, + totalBytes: progress.totalBytes + }; + progressListener(p); + }; + const cleanListeners = () => { + // TODO: fix internal types + // @ts-expect-error + this.removeListener(dlProgressKey, dlProgress); + }; + const dlError = (payload) => { + cleanListeners(); + const { reason, err: error } = payload; + reject(new transport_errors_1$1.RuntimeError({ reason, error }, callSite)); + }; + const dlComplete = () => { + cleanListeners(); + resolve(); + }; + await Promise.all([ + // TODO: fix internal types + // @ts-expect-error + this.on(dlProgressKey, dlProgress), + // TODO: fix internal types + // @ts-expect-error + this.once(dlErrorKey, dlError), + // TODO: fix internal types + // @ts-expect-error + this.once(dlCompleteKey, dlComplete) + ]); + const downloadOptions = Object.assign(appAsset, { downloadId }); + await this.wire.sendAction('download-asset', downloadOptions).catch((err) => { + cleanListeners(); + throw err; + }); + return downloadCompletePromise; + } + /** + * Downloads a version of the runtime. + * @param options - Download options. + * @param progressListener - called as the runtime is downloaded with progress information. + * + * @remarks Only supported in an OpenFin Render process. + * + * @example + * ```js + * var downloadOptions = { + * //Specific version number required, if given a release channel the call will produce an error. + * version: '9.61.30.1' + * }; + * + * function onProgress(progress) { + * console.log(`${Math.floor((progress.downloadedBytes / progress.totalBytes) * 100)}%`); + * } + * + * fin.System.downloadRuntime(downloadOptions, onProgress).then(() => { + * console.log('Download complete'); + * }).catch(err => { + * console.log(`Download Failed, we could retry: ${err.message}`); + * console.log(err); + * }); + * ``` + */ + downloadRuntime(options, progressListener) { + const callsites = transport_errors_1$1.RuntimeError.getCallSite(); + return new Promise((resolve, reject) => { + // node.js environment not supported + if (this.wire.environment.type !== 'openfin') { + reject(new transport_errors_1$1.NotSupportedError('downloadRuntime only supported in an OpenFin Render process')); + return; + } + const downloadId = this.wire.environment.getNextMessageId().toString(); + const dlProgressKey = `runtime-download-progress-${downloadId}`; + const dlErrorKey = `runtime-download-error-${downloadId}`; + const dlCompleteKey = `runtime-download-complete-${downloadId}`; + const dlProgress = (progress) => { + const p = { + downloadedBytes: progress.downloadedBytes, + totalBytes: progress.totalBytes + }; + progressListener(p); + }; + const cleanListeners = () => { + // TODO: fix internal types + // @ts-expect-error + this.removeListener(dlProgressKey, dlProgress); + }; + const dlError = (payload) => { + cleanListeners(); + const { reason, err: error } = payload; + reject(new transport_errors_1$1.RuntimeError({ reason, error }, callsites)); + }; + const dlComplete = () => { + cleanListeners(); + resolve(); + }; + // TODO: fix internal types + // @ts-expect-error + this.on(dlProgressKey, dlProgress); + // TODO: fix internal types + // @ts-expect-error + this.once(dlErrorKey, dlError); + // TODO: fix internal types + // @ts-expect-error + this.once(dlCompleteKey, dlComplete); + const downloadOptions = Object.assign(options, { downloadId }); + this.wire.sendAction('download-runtime', downloadOptions).catch((err) => { + cleanListeners(); + reject(err); + }); + }); + } + /** + * Download preload scripts from given URLs + * @param scripts - URLs of preload scripts. + * + * @example + * ```js + * const scripts = [ + * { url: 'http://.../preload.js' }, + * { url: 'http://.../preload2.js' } + * ]; + * + * fin.System.downloadPreloadScripts(scripts).then(results => { + * results.forEach(({url, success, error}) => { + * console.log(`URL: ${url}`); + * console.log(`Success: ${success}`); + * if (error) { + * console.log(`Error: ${error}`); + * } + * }); + * }); + * ``` + */ + downloadPreloadScripts(scripts) { + return this.wire.sendAction('download-preload-scripts', { scripts }).then(({ payload }) => payload.data); + } + /** + * Retrieves an array of data (name, ids, bounds) for all application windows. + * + * @example + * ```js + * fin.System.getAllExternalApplications() + * .then(externalApps => console.log('Total external apps: ' + externalApps.length)) + * .catch(err => console.log(err)); + * ``` + */ + getAllExternalApplications() { + return this.wire.sendAction('get-all-external-applications').then(({ payload }) => payload.data); + } + /** + * Retrieves app asset information. + * @param options + * + * @example + * ```js + * fin.System.getAppAssetInfo({alias:'procexp'}).then(assetInfo => console.log(assetInfo)).catch(err => console.log(err)); + * ``` + */ + getAppAssetInfo(options) { + return this.wire.sendAction('get-app-asset-info', options).then(({ payload }) => payload.data); + } + /** + * Get additional info of cookies. + * + * @example + * ```js + * fin.System.getCookies({name: 'myCookie'}).then(cookies => console.log(cookies)).catch(err => console.log(err)); + * ``` + */ + getCookies(options) { + const url = this.wire.environment.getUrl(); + const newOptions = Object.assign(options, { url }); + return this.wire.sendAction('get-cookies', newOptions).then(({ payload }) => payload.data); + } + /** + * Set the minimum log level above which logs will be written to the OpenFin log + * @param The minimum level (inclusive) above which all calls to log will be written + * + * @example + * ```js + * fin.System.setMinLogLevel("verbose").then(() => console.log("log level is set to verbose")).catch(err => console.log(err)); + * ``` + */ + setMinLogLevel(level) { + return this.wire.sendAction('set-min-log-level', { level }).then(() => undefined); + } + /** + * Retrieves the UUID of the computer on which the runtime is installed + * @param uuid The uuid of the running application + * + * @example + * ```js + * fin.System.resolveUuid('OpenfinPOC').then(entity => console.log(entity)).catch(err => console.log(err)); + * ``` + */ + resolveUuid(uuid) { + return this.wire + .sendAction('resolve-uuid', { + entityKey: uuid + }) + .then(({ payload }) => payload.data); + } + /** + * Retrieves an array of data for all external applications + * @param requestingIdentity This object is described in the Identity typedef + * @param data Any data type to pass to the method + * + * @ignore + */ + executeOnRemote(requestingIdentity, data) { + data.requestingIdentity = requestingIdentity; + return this.wire.ferryAction(data); + } + /** + * Reads the specifed value from the registry. + * @remarks This method is restricted by default and must be enabled via + * [API security settings](https://developers.openfin.co/docs/api-security). + * @param rootKey - The registry root key. + * @param subkey - The registry key. + * @param value - The registry value name. + * + * @example + * ```js + * fin.System.readRegistryValue("HKEY_LOCAL_MACHINE", "HARDWARE\\DESCRIPTION\\System", "BootArchitecture").then(val => console.log(val)).catch(err => console.log(err)); + * ``` + * + * See {@link https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx here} for Window's error code definitions. + * + * Example payloads of different registry types: + * + * See list of types {@link https://msdn.microsoft.com/en-us/library/windows/desktop/ms724884(v=vs.85).aspx here}. + * + * ```js + * // REG_DWORD + * { + * data: 1, + * rootKey: "HKEY_LOCAL_MACHINE", + * subkey: "Foo\Bar", + * type: "REG_DWORD", + * value: "Baz" + * } + * + * // REG_QWORD + * { + * data: 13108146671334112, + * rootKey: "HKEY_LOCAL_MACHINE", + * subkey: "Foo\Bar", + * type: "REG_QWORD", + * value: "Baz" + * } + * + * // REG_SZ + * { + * data: "FooBarBaz", + * rootKey: "HKEY_LOCAL_MACHINE", + * subkey: "Foo\Bar", + * type: "REG_SZ", + * value: "Baz" + * } + * + * // REG_EXPAND_SZ + * { + * data: "C:\User\JohnDoe\AppData\Local", + * rootKey: "HKEY_CURRENT_USER", + * subkey: "Foo\Bar", + * type: "REG_EXPAND_SZ", + * value: "Baz" + * } + * + * // REG_MULTI_SZ + * { + * data: [ + * "Foo", + * "Bar", + * "Baz" + * ], + * rootKey: "HKEY_CURRENT_USER", + * subkey: "Foo\Bar", + * type: "REG_MULTI_SZ", + * value: "Baz" + * } + * + * // REG_BINARY + * { + * data: { + * data: [ + * 255, + * 255, + * 0, + * 43, + * 55, + * 0, + * 0, + * 255, + * 255 + * ], + * type: "Buffer" + * }, + * rootKey: "HKEY_CURRENT_USER", + * subkey: "Foo\Bar", + * type: "REG_BINARY", + * value: "Baz" + * } + * ``` + */ + readRegistryValue(rootKey, subkey, value) { + return this.wire + .sendAction('read-registry-value', { + rootKey, + subkey, + value + }) + .then(({ payload }) => payload.data); + } + /** + * This function call will register a unique id and produce a token. + * The token can be used to broker an external connection. + * @param uuid - A UUID for the remote connection. + * + * @example + * ```js + * fin.System.registerExternalConnection("remote-connection-uuid").then(conn => console.log(conn)).catch(err => console.log(err)); + * + * + * // object comes back with + * // token: "0489EAC5-6404-4F0D-993B-92BB8EAB445D", // this will be unique each time + * // uuid: "remote-connection-uuid" + * + * ``` + */ + registerExternalConnection(uuid) { + return this.wire.sendAction('register-external-connection', { uuid }).then(({ payload }) => payload.data); + } + /** + * Returns the json blob found in the [desktop owner settings](https://openfin.co/documentation/desktop-owner-settings/) + * for the specified service. + * @param serviceIdentifier An object containing a name key that identifies the service. + * + * @remarks More information about desktop services can be found [here](https://developers.openfin.co/docs/desktop-services). + * This call will reject if the desktop owner settings file is not present, not correctly formatted, or if the service requested is not configured or configured incorrectly. + * + * @example + * ```js + * // Here we are using the [layouts](https://github.com/HadoukenIO/layouts-service) service. + * fin.System.getServiceConfiguration({name:'layouts'}).then(console.log).catch(console.error); + * ``` + */ + async getServiceConfiguration(serviceIdentifier) { + if (typeof serviceIdentifier.name !== 'string') { + throw new Error('Must provide an object with a `name` property having a string value'); + } + const { name } = serviceIdentifier; + return this.wire.sendAction('get-service-configuration', { name }).then(({ payload }) => payload.data); + } + async getSystemAppConfig(name) { + if (typeof name !== 'string') { + throw new Error('Must provide a string value for name of system app'); + } + return this.wire.sendAction('get-system-app-configuration', { name }).then(({ payload }) => payload.data); + } + /** + * Registers a system shutdown handler so user can do some cleanup before system is shutting down. + * @remarks Once system shutdown starts, you are unable to cancel it. + * @param handler system shutdown handler + * + * @example + * ```js + * fin.System.registerShutdownHandler((shutdownEvent) => { + * // save state or cleanup + * console.log('do some cleanup before shutdown'); + * // Notify app is ready for termination. + * shutdownEvent.proceed(); + * }) + * .then(() => console.log('Shutdown handler registered!')) + * .catch(err => console.log(err)); + * ``` + * @experimental + */ + async registerShutdownHandler(handler) { + this.wire.sendAction('system-register-shutdown-handler').catch((e) => { + // don't expose, analytics-only call + }); + const SystemShutdownEventName = 'system-shutdown'; + const SystemShutdownHandledEventName = 'system-shutdown-handled'; + const { uuid, name } = this.wire.me; + const shutdownHandler = (payload) => { + const proceed = () => { + // notify core that the app is ready for shutdown + this.wire.environment.raiseEvent(`application/${SystemShutdownHandledEventName}`, { + uuid, + name, + topic: 'application' + }); + }; + handler({ proceed }); + }; + this.on(SystemShutdownEventName, shutdownHandler); + } + /** + * Signals the RVM to perform a health check and returns the results as json. + * + * @remarks Requires RVM 5.5+ + * + * @example + * ```js + * try { + * const results = await fin.System.runRvmHealthCheck(); + * console.log(results); + * } catch(e) { + * console.error(e); + * } + * ``` + */ + runRvmHealthCheck() { + return this.wire.sendAction('run-rvm-health-check').then(({ payload }) => payload.data); + } + /** + * Launch application using a manifest URL/path. It differs from Application.startFromManifest in that this API can accept a manifest using the fin protocol. + * @param manifestUrl - The manifest's URL or path. + * @param opts - Parameters that the RVM will use. + * + * @experimental + * @remarks Supports protocols http/s and fin/s, and also a local path. + * + * Note: This API is Windows only. + * + * @example + * + * This API can handle most manifest types. Some examples below. + * + * Traditional: + * ```js + * const manifest = await fin.System.launchManifest( + * 'https://demoappdirectory.openf.in/desktop/config/apps/OpenFin/HelloOpenFin/app.json'); + * console.log(manifest); + * ``` + * + * Platform: + * ```js + * const manifest = await fin.System.launchManifest('https://openfin.github.io/platform-api-project-seed/public.json'); + * console.log(manifest); + * ``` + * + * Launching traditional manifest into a platform: + * ```js + * const manifest = await fin.System.launchManifest( + * 'https://openfin.github.io/platform-api-project-seed/public.json?\ + * $$appManifestUrl=https://demoappdirectory.openf.in/desktop/config/\ + * apps/OpenFin/HelloOpenFin/app.json'); + * console.log(manifest); + * ``` + * + * Launching with RVM options: + * ```js + * const manifest = await fin.System.launchManifest('https://openfin.github.io/platform-api-project-seed/public.json', + * { noUi: true, userAppConfigArgs: { abc: '123', xyz: '789' } }); + * console.log(manifest); + * ``` + * + * Local Path: + * ```js + * const manifest = await fin.System.launchManifest('file://c:\\path\\to\\manifest\\file.json'); + * console.log(manifest); + * ``` + * + * Launching with RVM 'subscribe' option: + * + * This option allows users to subscribe to app version resolver events when + * calling launchManifest with fallbackManifests specified. + * + * ```js + * fin.System.launchManifest('fins://system-apps/notifications/app.json', { subscribe: (launch) => { + * launch.on('app-version-progress', (progress) => { + * console.log("Trying manifest " + progress.manifest) + * }); + * + * launch.on('runtime-status', (status) => { + * console.log("Runtime status: " + JSON.stringify(status)); + * }); + * + * // RVM has successfully found the target runtime version + * launch.on('app-version-complete', (complete) => { + * console.log("Parent app " + complete.srcManifest + " resolved to " + complete.manifest); + * launch.removeAllListeners(); + * }); + * + * // RVM failed to find an available runtime version + * launch.on('app-version-error', (error) => { + * console.log("Failed to resolve " + error.srcManifest + " from the fallbackManifests"); + * launch.removeAllListeners(); + * }); + * } + * }); + * ``` + */ + async launchManifest(manifestUrl, opts = {}) { + const { subscribe, ..._sendOpts } = opts; + const sendOpts = _sendOpts; + if (subscribe) { + const launchEmitter = new events_1$6.EventEmitter(); + subscribe(launchEmitter); + const AppVersionProgressEventName = 'app-version-progress'; + const RuntimeStatusEventName = 'runtime-status'; + const AppVersionCompleteEventName = 'app-version-complete'; + const AppVersionErrorEventName = 'app-version-error'; + // add id to avoid multiple api calls getting duplicated events + const id = this.wire.environment.getNextMessageId().toString(); + sendOpts.appVersionId = id; + const supportedEvents = [ + AppVersionCompleteEventName, + AppVersionProgressEventName, + RuntimeStatusEventName, + AppVersionErrorEventName + ]; + const cleanEventPayload = (payload) => { + // We need to do type castings below to make sure the return type is correct. + const { appVersionId, topic, type: typeWithId, ...rest } = payload; + const type = supportedEvents.find((x) => typeWithId.includes(x)); + return { + ...rest, + type + }; + }; + const appVersionListener = (payload) => { + const cleanPayload = cleanEventPayload(payload); + launchEmitter.emit(cleanPayload.type, cleanPayload); + }; + const removeAllListeners = () => { + this.removeListener(`${AppVersionProgressEventName}.${id}`, appVersionListener); + this.removeListener(`${RuntimeStatusEventName}.${id}`, appVersionListener); + this.removeListener(`${AppVersionCompleteEventName}.${id}`, appVersionListener); + this.removeListener(`${AppVersionErrorEventName}.${id}`, appVersionListener); + this.removeListener(`${AppVersionCompleteEventName}.${id}`, removeAllListeners); + this.removeListener(`${AppVersionErrorEventName}.${id}`, removeAllListeners); + }; + await Promise.all([ + this.on(`${AppVersionProgressEventName}.${id}`, appVersionListener), + this.on(`${RuntimeStatusEventName}.${id}`, appVersionListener), + this.once(`${AppVersionCompleteEventName}.${id}`, appVersionListener), + this.once(`${AppVersionErrorEventName}.${id}`, appVersionListener), + this.once(`${AppVersionCompleteEventName}.${id}`, removeAllListeners), + this.once(`${AppVersionErrorEventName}.${id}`, removeAllListeners) + ]); + } + const response = await this.wire.sendAction('launch-manifest', { + manifestUrl, + opts: sendOpts + }); + return response.payload.data.manifest; + } + /** + * Query permission of a secured api in current context. + * + * @param apiName - The full name of a secured API. + * + * @remarks If a function has a structured permission value, the value of `granted` will reflect the `enabled` key + * of the call's permissions literal. In this case, *permission may still be denied to a call* pending arguments or other + * runtime state. This is indicated with `state: unavailable`. + * + * @example + * ```js + * fin.System.queryPermissionForCurrentContext('System.launchExternalProcess').then(result => console.log(result)).catch(err => console.log(err)); + * + * //This response has the following shape: + * { + * permission: 'System.launchExternalProcess', // api full name + * state: 'granted', // state of permission + * granted: true + * } + * ``` + */ + async queryPermissionForCurrentContext(apiName) { + const identity = { uuid: this.wire.me.uuid, name: this.wire.me.name }; + const response = await this.wire.sendAction('query-permission-for-current-context', { + apiName, + identity + }); + return response.payload.data; + } + // Not documenting, internal use only. + async enableNativeWindowIntegrationProvider(permissions) { + const { payload } = await this.wire.sendAction('enable-native-window-integration-provider', { permissions }); + return payload.data; + } + /** + * (Internal) Register the usage of a component with a platform + * @param options - Object with data and type + * + * @example + * ```js + * async function registerUsage() { + * const app = await fin.System.getCurrent(); + * return await fin.System.registerUsage({ + * type: 'workspace-licensing', + * // example values for the following data object + * data: { + * apiVersion: '1.0', + * componentName: 'home', + * componentVersion: '1.0', + * allowed: true, + * rejectionCode: '' + * } + * }); + * } + * + * registerUsage().then(() => console.log('Successfully registered component application')).catch(err => console.log(err)); + * ``` + */ + async registerUsage({ data, type }) { + await this.wire.sendAction('register-usage', { data, type }); + } + /** + * Returns an array with all printers of the caller and not all the printers on the desktop. + * + * @example + * ```js + * fin.System.getPrinters() + * .then((printers) => { + * printers.forEach((printer) => { + * if (printer.isDefault) { + * console.log(printer); + * } + * }); + * }) + * .catch((err) => { + * console.log(err); + * }); + * ``` + */ + async getPrinters() { + const { payload } = await this.wire.sendAction('system-get-printers'); + return payload.data; + } + /** + * Updates Process Logging values: periodic interval and outlier detection entries and interval. + * @param options Process Logging updatable options. + * + * @remarks When enabling verbose mode, additional process information is logged to the debug.log: + * + * 1. Periodically process usage (memory, cpu, etc) will be logged for each PID along with the windows, views and + * iframes that belong to them. The default is every 30 seconds. Updatable by passing the interval option. + * 2. When Windows and Views are created or navigated the PID they belong to and their options will be logged. + * 3. When Windows and Views are destroyed their last known process usage will be logged. + * 4. Whenever an outlier memory usage is detected it will be logged. By default, on an interval of 5 seconds we will + * collect process usage for all PIDs and when 144 such entries are collected, we will start analyzing the data for any + * possible outliers in the following entries. The interval and maximum number of entries stored in the running buffer + * can be updatable by passing the outlierDetection.interval and outlierDetection.entries options. + * + * @example + * + * ```js + * await fin.System.updateProcessLoggingOptions({ + * interval: 10, + * outlierDetection: { + * interval: 15, + * entries: 200 + * } + * }); + * ``` + */ + async updateProcessLoggingOptions(options) { + await this.wire.sendAction('system-update-process-logging-options', { options }); + } + /** + * Returns domain settings for the current application. + * Initial settings are configured with the defaultDomainSettings application option via manifest. + * Domain settings can be overwritten during runtime with System.setDomainSettings. + * @example + * ```js + * const domainSettings = await fin.System.getDomainSettings(); + * // { + * // "rules": [ + * // { + * // "match": [ + * // "https://openfin.co" + * // ], + * // "options": { + * // "downloadSettings": { + * // "rules": [ + * // { + * // "match": [ + * // "" + * // ], + * // "behavior": "prompt" + * // } + * // ] + * // } + * // } + * // } + * // ] + * // } + * ``` + */ + async getDomainSettings() { + const { payload: { data } } = await this.wire.sendAction('get-domain-settings', this.identity); + return data; + } + /** + * Sets the domain settings for the current application. + * @param domainSettings - domain settings object + * @example + * ```js + * const domainSettings = await fin.System.getDomainSettings(); + * // { + * // "rules": [ + * // { + * // "match": [ + * // "https://openfin.co" + * // ], + * // "options": { + * // "downloadSettings": { + * // "rules": [ + * // { + * // "match": [ + * // "" + * // ], + * // "behavior": "prompt" + * // } + * // ] + * // } + * // } + * // } + * // ] + * // } + * + * // Valid rule behaviors are 'prompt' and 'no-prompt' + * domainSettings.rules[0].options.downloadSettings.rules[0].behavior = 'no-prompt'; + * + * await fin.System.setDomainSettings(domainSettings); + * + * const newDomainSettings = await fin.System.getDomainSettings(); + * // { + * // "rules": [ + * // { + * // "match": [ + * // "https://openfin.co" + * // ], + * // "options": { + * // "downloadSettings": { + * // "rules": [ + * // { + * // "match": [ + * // "" + * // ], + * // "behavior": "no-prompt" + * // } + * // ] + * // } + * // } + * // } + * // ] + * // } + * ``` + */ + async setDomainSettings(domainSettings) { + await this.wire.sendAction('set-domain-settings', { domainSettings, ...this.identity }); + } + /** + * Attempts to install and enable extensions for the security realm. Users may want to call this function in response + * to an `extensions-install-failed` event. Only extensions allowed by every application on the current security realm + * will be installed/enabled. + */ + async refreshExtensions() { + const { payload } = await this.wire.sendAction('refresh-extensions'); + return payload.data; + } + /** + * Gets the currently-installed + */ + async getInstalledExtensions() { + const { payload } = await this.wire.sendAction('get-installed-extensions'); + return payload.data; + } +} +system.System = System; + +var interappbus = {}; + +var refCounter = {}; + +Object.defineProperty(refCounter, "__esModule", { value: true }); +refCounter.RefCounter = void 0; +class RefCounter { + constructor() { + this.topicRefMap = new Map(); + } + // returns the ref count after incrementing + incRefCount(key) { + const refCount = this.topicRefMap.get(key); + let returnCount; + if (!refCount) { + this.topicRefMap.set(key, 1); + returnCount = 1; + } + else { + const newRefCount = refCount + 1; + returnCount = newRefCount; + this.topicRefMap.set(key, newRefCount); + } + return returnCount; + } + // returns the ref count after decrementing, or -1 if the key already had no references + decRefCount(key) { + const refCount = this.topicRefMap.get(key); + let returnCount; + if (refCount) { + const newRefCount = refCount - 1; + this.topicRefMap.set(key, newRefCount); + returnCount = newRefCount; + } + else { + returnCount = -1; + } + return returnCount; + } + // Execute firstAction if it is the first such ref, else execute nonFirstAction. + // In either case the return value is that of the action executed + actOnFirst(key, firstAction, nonFirstAction) { + const numRefs = this.incRefCount(key); + const isFirstRef = numRefs === 1; + return isFirstRef ? firstAction() : nonFirstAction(); + } + // Execute lastAction if it is the first such ref, else execute nonLastAction. + // In either case the return value is that of the action executed + actOnLast(key, lastAction, nonLastAction) { + const numRefs = this.decRefCount(key); + const isLastRef = numRefs === 0; + return isLastRef ? lastAction() : nonLastAction(); + } +} +refCounter.RefCounter = RefCounter; + +var channel$1 = {}; + +var client = {}; + +var channel = {}; + +Object.defineProperty(channel, "__esModule", { value: true }); +channel.ChannelBase = channel.ProtectedItems = void 0; +const resultOrPayload = (func) => async (topic, payload, senderIdentity) => { + const res = await func(topic, payload, senderIdentity); + return res === undefined ? payload : res; +}; +class ProtectedItems { + /** + * @internal + */ + // eslint-disable-next-line no-useless-constructor + constructor(providerIdentity, close) { + this.providerIdentity = providerIdentity; + this.close = close; + } +} +channel.ProtectedItems = ProtectedItems; +class ChannelBase { + static defaultAction(topic) { + throw new Error(`No action registered at target for ${topic}`); + } + constructor() { + this.subscriptions = new Map(); + } + async processAction(topic, payload, senderIdentity) { + try { + const mainAction = this.subscriptions.has(topic) + ? this.subscriptions.get(topic) + : (currentPayload, id) => (this.defaultAction ?? ChannelBase.defaultAction)(topic, currentPayload, id); + const preActionProcessed = this.preAction ? await this.preAction(topic, payload, senderIdentity) : payload; + const actionProcessed = await mainAction(preActionProcessed, senderIdentity); + return this.postAction ? await this.postAction(topic, actionProcessed, senderIdentity) : actionProcessed; + } + catch (e) { + if (this.errorMiddleware) { + return this.errorMiddleware(topic, e, senderIdentity); + } + throw e; + } + } + /** + * Register middleware that fires before the action. + * + * @param func + * + * @example + * + * Channel Provider: + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * provider.register('provider-action', (payload, identity) => { + * console.log(payload, identity); + * return { + * echo: payload + * }; + * }); + * + * provider.beforeAction((action, payload, identity) => { + * //The payload can be altered here before handling the action. + * payload.received = Date.now(); + * return payload; + * }); + * + * })(); + * ``` + * + * Channel Client: + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * client.register('client-action', (payload, identity) => { + * console.log(payload, identity); + * return { + * echo: payload + * }; + * }); + * + * client.beforeAction((action, payload, identity) => { + * //The payload can be altered here before handling the action. + * payload.received = Date.now(); + * return payload; + * }); + * + * const providerResponse = await client.dispatch('provider-action', { message: 'Hello From the client' }); + * console.log(providerResponse); + * })(); + * ``` + */ + beforeAction(func) { + if (this.preAction) { + throw new Error('Already registered beforeAction middleware'); + } + this.preAction = resultOrPayload(func); + } + /** + * Register an error handler. This is called before responding on any error. + * + * @param func + * + * Channel Provider: + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * provider.register('provider-action', (payload, identity) => { + * console.log(payload); + * throw new Error('Action error'); + * return { + * echo: payload + * }; + * }); + * + * provider.onError((action, error, identity) => { + * console.log('uncaught Exception in action:', action); + * console.error(error); + * }); + * + * })(); + * ``` + * + * Channel Client: + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * client.register('client-action', (payload, identity) => { + * console.log(payload); + * throw new Error('Action error'); + * return { + * echo: payload + * }; + * }); + * + * client.onError((action, error, identity) => { + * console.log('uncaught Exception in action:', action); + * console.error(error); + * }); + * })(); + * ``` + */ + onError(func) { + if (this.errorMiddleware) { + throw new Error('Already registered error middleware'); + } + this.errorMiddleware = func; + } + /** + * Register middleware that fires after the action. + * + * @param func + * + * @remarks If the action does not return the payload, then the afterAction will not have access to the payload object. + * + * @example + * + * Channel Provider: + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.register('provider-action', (payload, identity) => { + * return { + * echo: payload + * }; + * }); + * + * await provider.afterAction((action, payload, identity) => { + * //the payload can be altered here after handling the action but before sending an acknowledgement. + * payload.sent = date.now(); + * return payload; + * }); + * + * })(); + * ``` + * + * Channel Client: + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * await client.register('client-action', (payload, identity) => { + * return { + * echo: payload + * }; + * }); + * + * await client.afterAction((action, payload, identity) => { + * //the payload can be altered here after handling the action but before sending an acknowledgement. + * payload.sent = date.now(); + * return payload; + * }); + * + * })(); + * ``` + */ + afterAction(func) { + if (this.postAction) { + throw new Error('Already registered afterAction middleware'); + } + this.postAction = resultOrPayload(func); + } + /** + * Remove an action by action name. + * + * @param action + * + * @example + * + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.register('provider-action', (payload, identity) => { + * console.log(payload); + * return { + * echo: payload + * }; + * }); + * + * await provider.remove('provider-action'); + * + * })(); + * ``` + */ + remove(action) { + this.subscriptions.delete(action); + } + /** + * Registers a default action. This is used any time an action that has not been registered is invoked. + * + * @example + * + * Channel Provider: + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.setDefaultAction((action, payload, identity) => { + * console.log(`Client with identity ${JSON.stringify(identity)} has attempted to dispatch unregistered action: ${action}.`); + * + * return { + * echo: payload + * }; + * }); + * + * })(); + * ``` + * + * Channel Client: + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * await client.setDefaultAction((action, payload, identity) => { + * console.log(`Provider with identity ${JSON.stringify(identity)} has attempted to dispatch unregistered action: ${action}.`); + * + * return { + * echo: payload + * }; + * }); + * + * })(); + * ``` + * @param func + */ + setDefaultAction(func) { + if (this.defaultAction) { + throw new Error('default action can only be set once'); + } + else { + this.defaultAction = func; + } + } + /** + * Register an action to be called by dispatching from any channelClient or channelProvider. + * + * @param topic + * @param listener + * + * @remarks The return value will be sent back as an acknowledgement to the original caller. You can throw an + * error to send a negative-acknowledgement and the error will reject the promise returned to the sender by the + * dispatch call. Once a listener is registered for a particular action, it stays in place receiving and responding + * to incoming messages until it is removed. This messaging mechanism works exactly the same when messages are + * dispatched from the provider to a client. However, the provider has an additional publish method that sends messages + * to all connected clients. + * + * Because multiple clients can share the same `name` and `uuid`, in order to distinguish between individual clients, + * the `identity` argument in a provider's registered action callback contains an `endpointId` property. When dispatching + * from a provider to a client, the `endpointId` property must be provided in order to send an action to a specific client. + * + * @example + * + * Channel Provider: + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.register('provider-action', (payload, identity) => { + * console.log('Action dispatched by client: ', identity); + * console.log('Payload sent in dispatch: ', payload); + * + * return { echo: payload }; + * }); + * })(); + * ``` + * + * Channel Client: + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * await client.register('client-action', (payload, identity) => { + * console.log('Action dispatched by client: ', identity); + * console.log('Payload sent in dispatch: ', payload); + * + * return { echo: payload }; + * }); + * })(); + * ``` + */ + register(topic, listener) { + if (this.subscriptions.has(topic)) { + throw new Error(`Subscription already registered for action: ${topic}. Unsubscribe before adding new subscription`); + } + else { + this.subscriptions.set(topic, listener); + return true; + } + } +} +channel.ChannelBase = ChannelBase; + +var __classPrivateFieldGet$c = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet$a = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var _ChannelClient_protectedObj, _ChannelClient_strategy, _ChannelClient_close; +Object.defineProperty(client, "__esModule", { value: true }); +client.ChannelClient = void 0; +const channel_1$1 = channel; +const channelClientsByEndpointId = new Map(); +/** + * Instance created to enable use of a channel as a client. Allows for communication with the + * {@link ChannelProvider ChannelProvider} by invoking an action on the + * provider via {@link ChannelClient#dispatch dispatch} and to listen for communication + * from the provider by registering an action via {@link ChannelClient#register register}. + * + * ### Synchronous Methods: + * * {@link ChannelClient#onDisconnection onDisconnection(listener)} + * * {@link ChannelClient#register register(action, listener)} + * * {@link ChannelClient#remove remove(action)} + * + * ### Asynchronous Methods: + * * {@link ChannelClient#disconnect disconnect()} + * * {@link ChannelClient#dispatch dispatch(action, payload)} + * + * ### Middleware: + * Middleware functions receive the following arguments: (action, payload, senderId). + * The return value of the middleware function will be passed on as the payload from beforeAction, to the action listener, to afterAction + * unless it is undefined, in which case the original payload is used. Middleware can be used for side effects. + * * {@link ChannelClient#setDefaultAction setDefaultAction(middleware)} + * * {@link ChannelClient#onError onError(middleware)} + * * {@link ChannelClient#beforeAction beforeAction(middleware)} + * * {@link ChannelClient#afterAction afterAction(middleware)} + */ +class ChannelClient extends channel_1$1.ChannelBase { + /** + * @internal + */ + static closeChannelByEndpointId(id) { + const channel = channelClientsByEndpointId.get(id); + if (channel) { + __classPrivateFieldGet$c(channel, _ChannelClient_close, "f").call(channel); + } + } + /** + * @internal + * closes the corresponding channel and invokes the disconnect listener if an event payload is passed. + */ + static handleProviderDisconnect(eventPayload) { + for (const channelClient of channelClientsByEndpointId.values()) { + if (channelClient.providerIdentity.channelId === eventPayload.channelId) { + channelClient.disconnectListener(eventPayload); + __classPrivateFieldGet$c(channelClient, _ChannelClient_close, "f").call(channelClient); + } + } + } + /** + * @internal + */ + constructor(routingInfo, close, strategy) { + super(); + _ChannelClient_protectedObj.set(this, void 0); + _ChannelClient_strategy.set(this, void 0); + // needs to be bound; + this.processAction = (action, payload, senderIdentity) => super.processAction(action, payload, senderIdentity); + _ChannelClient_close.set(this, () => { + channelClientsByEndpointId.delete(this.endpointId); + __classPrivateFieldGet$c(this, _ChannelClient_strategy, "f").close(); + }); + __classPrivateFieldSet$a(this, _ChannelClient_protectedObj, new channel_1$1.ProtectedItems(routingInfo, close), "f"); + this.disconnectListener = () => undefined; + this.endpointId = routingInfo.endpointId; + __classPrivateFieldSet$a(this, _ChannelClient_strategy, strategy, "f"); + channelClientsByEndpointId.set(this.endpointId, this); + strategy.receive(this.processAction); + } + /** + * a read-only provider identity + */ + get providerIdentity() { + const protectedObj = __classPrivateFieldGet$c(this, _ChannelClient_protectedObj, "f"); + return protectedObj.providerIdentity; + } + /** + * Dispatch the given action to the channel provider. Returns a promise that resolves with the response from + * the provider for that action. + * + * @param action + * @param payload + * + * @example + * + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * await client.register('client-action', (payload, identity) => { + * console.log(payload, identity); + * return { + * echo: payload + * }; + * }); + * + * const providerResponse = await client.dispatch('provider-action', { message: 'Hello From the client'}); + * console.log(providerResponse); + * })(); + * ``` + */ + async dispatch(action, payload) { + if (__classPrivateFieldGet$c(this, _ChannelClient_strategy, "f").isEndpointConnected(this.providerIdentity.channelId)) { + return __classPrivateFieldGet$c(this, _ChannelClient_strategy, "f").send(this.providerIdentity.channelId, action, payload); + } + throw new Error('The client you are trying to dispatch from is disconnected from the target provider.'); + } + /** + * Register a listener that is called on provider disconnection. It is passed the disconnection event of the + * disconnecting provider. + * + * @param listener + * + * @example + * + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * await client.onDisconnection(evt => { + * console.log('Provider disconnected', `uuid: ${evt.uuid}, name: ${evt.name}`); + * }); + * })(); + * ``` + */ + onDisconnection(listener) { + this.disconnectListener = (payload) => { + try { + listener(payload); + } + catch (err) { + throw new Error(`Error while calling the onDisconnection callback: ${err.message}`); + } + finally { + this.disconnectListener = () => undefined; + } + }; + } + /** + * Disconnects the client from the channel. + * + * @example + * + * ```js + * (async ()=> { + * const client = await fin.InterApplicationBus.Channel.connect('channelName'); + * + * await client.disconnect(); + * })(); + * ``` + */ + async disconnect() { + await this.sendDisconnectAction(); + __classPrivateFieldGet$c(this, _ChannelClient_close, "f").call(this); + } + async sendDisconnectAction() { + const protectedObj = __classPrivateFieldGet$c(this, _ChannelClient_protectedObj, "f"); + await protectedObj.close(); + } + /** + * @internal + * Writing this as a static to keep code together, but in environments with a wire, this will be DI'd into the protectedObject class as close. + */ + static async wireClose(wire, providerIdentity, endpointId) { + const { channelName, uuid, name } = providerIdentity; + await wire.sendAction('disconnect-from-channel', { + channelName, + uuid, + name, + endpointId + }); + } +} +client.ChannelClient = ChannelClient; +_ChannelClient_protectedObj = new WeakMap(), _ChannelClient_strategy = new WeakMap(), _ChannelClient_close = new WeakMap(); + +var connectionManager = {}; + +var exhaustive = {}; + +Object.defineProperty(exhaustive, "__esModule", { value: true }); +exhaustive.exhaustiveCheck = void 0; +function exhaustiveCheck(value, allowed) { + throw new Error(`Unsupported value: ${value}${allowed ? `\n Supported values are: ${allowed.join('')}` : ''}`); +} +exhaustive.exhaustiveCheck = exhaustiveCheck; + +var strategy$3 = {}; + +var __classPrivateFieldSet$9 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$b = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _ClassicStrategy_wire, _ClassicStrategy_endpointIdentityMap, _ClassicStrategy_pendingMessagesByEndpointId; +Object.defineProperty(strategy$3, "__esModule", { value: true }); +strategy$3.ClassicInfo = strategy$3.ClassicStrategy = void 0; +/* +This is used to abstract out ipc messaging from the channels implementation. It is only concerned with sending messages and registration with the MessageReceiver +*/ +class ClassicStrategy { + constructor(wire, messageReceiver, endpointId, // Provider endpointId is channelId + providerIdentity) { + this.messageReceiver = messageReceiver; + this.endpointId = endpointId; + this.providerIdentity = providerIdentity; + _ClassicStrategy_wire.set(this, void 0); + // Store full endpointIdentity by endpointId of all known endpoints for this strategy instance. + // (clients will only have 1: the provider, the provider will have all clients) + _ClassicStrategy_endpointIdentityMap.set(this, new Map()); + // Store a set of cancellable promises to be able to reject them when client + // connection problems occur + _ClassicStrategy_pendingMessagesByEndpointId.set(this, new Map); + this.send = async (endpointId, action, payload) => { + const to = __classPrivateFieldGet$b(this, _ClassicStrategy_endpointIdentityMap, "f").get(endpointId); + if (!to) { + throw new Error(`Could not locate routing info for endpoint ${endpointId}`); + } + // as casting to any because typescript complains. The following is only relevant if this is a locally set endpointId on a ClientIdentity. + // We delete these properties to not change backwards compatibility. + const cleanId = { ...to }; + if (cleanId.isLocalEndpointId) { + delete cleanId.endpointId; + } + delete cleanId.isLocalEndpointId; + // grab the promise before awaiting it to save in our pending messages map + const p = __classPrivateFieldGet$b(this, _ClassicStrategy_wire, "f") + .sendAction('send-channel-message', { + ...cleanId, + providerIdentity: this.providerIdentity, + action, + payload + }); + __classPrivateFieldGet$b(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").get(endpointId)?.add(p); + const raw = await p.catch((error) => { + throw new Error(error.message); + }).finally(() => { + // clean up the pending promise + __classPrivateFieldGet$b(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").get(endpointId)?.delete(p); + }); + return raw.payload.data.result; + }; + this.close = async () => { + this.messageReceiver.removeEndpoint(this.providerIdentity.channelId, this.endpointId); + [...__classPrivateFieldGet$b(this, _ClassicStrategy_endpointIdentityMap, "f").keys()].forEach((id) => this.closeEndpoint(id)); + __classPrivateFieldSet$9(this, _ClassicStrategy_endpointIdentityMap, new Map(), "f"); + }; + __classPrivateFieldSet$9(this, _ClassicStrategy_wire, wire, "f"); + } + onEndpointDisconnect(endpointId, listener) { + // Never fires for 'classic'. + } + receive(listener) { + this.messageReceiver.addEndpoint(listener, this.providerIdentity.channelId, this.endpointId); + } + async closeEndpoint(endpointId) { + const id = __classPrivateFieldGet$b(this, _ClassicStrategy_endpointIdentityMap, "f").get(endpointId); + __classPrivateFieldGet$b(this, _ClassicStrategy_endpointIdentityMap, "f").delete(endpointId); + const pendingSet = __classPrivateFieldGet$b(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").get(endpointId); + pendingSet?.forEach((p) => { + const errorMsg = `Channel connection with identity uuid: ${id?.uuid} / name: ${id?.name} / endpointId: ${endpointId} no longer connected.`; + p.cancel(new Error(errorMsg)); + }); + } + isEndpointConnected(endpointId) { + return __classPrivateFieldGet$b(this, _ClassicStrategy_endpointIdentityMap, "f").has(endpointId); + } + addEndpoint(endpointId, payload) { + __classPrivateFieldGet$b(this, _ClassicStrategy_endpointIdentityMap, "f").set(endpointId, payload.endpointIdentity); + __classPrivateFieldGet$b(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").set(endpointId, new Set()); + } + isValidEndpointPayload(payload) { + return (typeof payload?.endpointIdentity?.endpointId === 'string' || + typeof payload?.endpointIdentity?.channelId === 'string'); + } +} +strategy$3.ClassicStrategy = ClassicStrategy; +_ClassicStrategy_wire = new WeakMap(), _ClassicStrategy_endpointIdentityMap = new WeakMap(), _ClassicStrategy_pendingMessagesByEndpointId = new WeakMap(); +// Arbitrarily starting at 5 to leave the door open to backfilling pre endpointId etc. +strategy$3.ClassicInfo = { version: 5, minimumVersion: 0, type: 'classic' }; + +var strategy$2 = {}; + +var endpoint = {}; + +var errors = {}; + +Object.defineProperty(errors, "__esModule", { value: true }); +errors.errorToPOJO = void 0; +function errorToPOJO(error) { + return { + stack: error.stack, + name: error.name, + message: error.message, + // support the case where stack is empty or missing + toString: () => error.stack || error.toString() + }; +} +errors.errorToPOJO = errorToPOJO; + +var __classPrivateFieldGet$a = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet$8 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var _RTCEndpoint_processAction, _RTCEndpoint_disconnectListener; +Object.defineProperty(endpoint, "__esModule", { value: true }); +endpoint.RTCEndpoint = void 0; +/* eslint-disable @typescript-eslint/no-unused-vars */ +const errors_1$1 = errors; +/* +This handles sending RTC messages between RTC connections over the request and response data channels. +*/ +class RTCEndpoint { + static isValidEndpointPayload(payload) { + const isObject = (x) => { + return typeof x === 'object' && x !== null; + }; + return ( + // TODO in factory PR: + // payload.type === 'rtc' && + isObject(payload) && + isObject(payload.endpointIdentity) && + isObject(payload.rtc) && + typeof payload.endpointIdentity.endpointId === 'string'); + } + constructor({ rtc, endpointIdentity }) { + this.responseMap = new Map(); + _RTCEndpoint_processAction.set(this, null); + _RTCEndpoint_disconnectListener.set(this, void 0); + this.connectionStateChangeHandler = (event) => { + if (this.rtc.rtcClient.connectionState !== 'connected') { + this.rtc.rtcClient.removeEventListener('connectionstatechange', this.connectionStateChangeHandler); + this.close(); + if (__classPrivateFieldGet$a(this, _RTCEndpoint_disconnectListener, "f")) { + __classPrivateFieldGet$a(this, _RTCEndpoint_disconnectListener, "f").call(this); + } + } + }; + this.send = async (action, payload) => { + const messageId = `message-${Math.random()}`; + const promise = new Promise((resolve, reject) => { + this.responseMap.set(messageId, { resolve, reject }); + }); + this.rtc.channels.request.send(JSON.stringify({ action, payload, messageId })); + return promise; + }; + this.close = () => { + this.responseMap.forEach((response) => response.reject('Connection has closed.')); + this.responseMap = new Map(); + this.rtc.channels.request.close(); + this.rtc.channels.response.close(); + this.rtc.rtcClient.close(); + }; + this.rtc = rtc; + this.endpointIdentity = endpointIdentity; + this.rtc.channels.response.addEventListener('message', (e) => { + let { data } = e; + if (e.data instanceof ArrayBuffer) { + data = new TextDecoder().decode(e.data); + } + const { messageId, payload, success, error } = JSON.parse(data); + const { resolve, reject } = this.responseMap.get(messageId) ?? {}; + if (resolve && reject) { + this.responseMap.delete(messageId); + if (success) { + resolve(payload); + } + else { + reject(error); + } + } + else { + console.log('Could not find id in responseMap.'); + console.log(e); + } + }); + this.rtc.channels.request.addEventListener('message', async (e) => { + let { data } = e; + if (e.data instanceof ArrayBuffer) { + data = new TextDecoder().decode(e.data); + } + const { messageId, action, payload } = JSON.parse(data); + if (__classPrivateFieldGet$a(this, _RTCEndpoint_processAction, "f")) { + try { + const res = await __classPrivateFieldGet$a(this, _RTCEndpoint_processAction, "f").call(this, action, payload, endpointIdentity); + this.rtc.channels.response.send(JSON.stringify({ + messageId, + payload: res, + success: true + })); + } + catch (error) { + // Check if RTCDataChannel is open before sending, error gets swallowed here in the case where + // client dispatched then closed or disconnected before the dispatch resolves. + if (this.rtc.channels.response.readyState === 'open') { + this.rtc.channels.response.send(JSON.stringify({ + messageId, + error: (0, errors_1$1.errorToPOJO)(error), + success: false + })); + } + } + // Check if RTCDataChannel is open for same reason as catch block above. + } + else if (this.rtc.channels.response.readyState === 'open') { + this.rtc.channels.response.send(JSON.stringify({ + messageId, + success: false, + error: 'Connection not ready.' + })); + } + }); + this.rtc.rtcClient.addEventListener('connectionstatechange', this.connectionStateChangeHandler); + // Disconnect if data channels close unexpectedly, e.g. can happen due to message size > ~255kB (RTCPeerConnection.sctp.maxMessageSizeLimit: 262144) + Object.values(this.rtc.channels).forEach((datachannel) => { + datachannel.onclose = (e) => { + [...this.responseMap.values()].forEach((promise) => promise.reject(new Error('RTCDataChannel closed unexpectedly, this is most commonly caused by message size. Note: RTC Channels have a message size limit of ~255kB.'))); + this.close(); + if (__classPrivateFieldGet$a(this, _RTCEndpoint_disconnectListener, "f")) { + __classPrivateFieldGet$a(this, _RTCEndpoint_disconnectListener, "f").call(this); + } + }; + }); + } + onDisconnect(listener) { + if (!__classPrivateFieldGet$a(this, _RTCEndpoint_disconnectListener, "f")) { + __classPrivateFieldSet$8(this, _RTCEndpoint_disconnectListener, listener, "f"); + } + else { + throw new Error('RTCEndpoint disconnectListener cannot be set twice.'); + } + } + receive(listener) { + if (__classPrivateFieldGet$a(this, _RTCEndpoint_processAction, "f")) { + throw new Error('You have already set a listener for this RTC Endpoint.'); + } + __classPrivateFieldSet$8(this, _RTCEndpoint_processAction, listener, "f"); + } + get connected() { + return this.rtc.rtcClient.connectionState === 'connected'; + } +} +endpoint.RTCEndpoint = RTCEndpoint; +_RTCEndpoint_processAction = new WeakMap(), _RTCEndpoint_disconnectListener = new WeakMap(); + +var strategy$1 = {}; + +var __classPrivateFieldGet$9 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet$7 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var _EndpointStrategy_processAction, _EndpointStrategy_endpointMap, _EndpointStrategy_connected; +Object.defineProperty(strategy$1, "__esModule", { value: true }); +strategy$1.EndpointStrategy = void 0; +class EndpointStrategy { + // Need to pass in validate endpoint separately from constructor because ts interfaces don't do well with static methods + constructor(EndpointType, validateEndpoint, StrategyName) { + this.EndpointType = EndpointType; + this.StrategyName = StrategyName; + _EndpointStrategy_processAction.set(this, null); + _EndpointStrategy_endpointMap.set(this, new Map()); + _EndpointStrategy_connected.set(this, true); + this.send = async (endpointId, action, payload) => { + return this.getEndpointById(endpointId).send(action, payload); + }; + this.close = async () => { + if (__classPrivateFieldGet$9(this, _EndpointStrategy_connected, "f")) { + __classPrivateFieldGet$9(this, _EndpointStrategy_endpointMap, "f").forEach((endpoint) => endpoint.close()); + __classPrivateFieldSet$7(this, _EndpointStrategy_endpointMap, new Map(), "f"); + } + __classPrivateFieldSet$7(this, _EndpointStrategy_connected, false, "f"); + }; + this.isValidEndpointPayload = validateEndpoint; + } + onEndpointDisconnect(endpointId, listener) { + this.getEndpointById(endpointId).onDisconnect(listener); + } + receive(listener) { + if (__classPrivateFieldGet$9(this, _EndpointStrategy_processAction, "f")) { + throw new Error(`You have already set a listener for this ${this.StrategyName} Strategy`); + } + __classPrivateFieldSet$7(this, _EndpointStrategy_processAction, listener, "f"); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + __classPrivateFieldGet$9(this, _EndpointStrategy_endpointMap, "f").forEach((endpoint) => endpoint.receive(__classPrivateFieldGet$9(this, _EndpointStrategy_processAction, "f"))); + } + getEndpointById(endpointId) { + const endpoint = __classPrivateFieldGet$9(this, _EndpointStrategy_endpointMap, "f").get(endpointId); + if (!endpoint) { + throw new Error(`Client with endpoint id ${endpointId} is not connected`); + } + return endpoint; + } + get connected() { + return __classPrivateFieldGet$9(this, _EndpointStrategy_connected, "f"); + } + isEndpointConnected(endpointId) { + return __classPrivateFieldGet$9(this, _EndpointStrategy_endpointMap, "f").has(endpointId); + } + addEndpoint(endpointId, payload) { + if (!__classPrivateFieldGet$9(this, _EndpointStrategy_connected, "f")) { + console.warn(`Adding endpoint to disconnected ${this.StrategyName} Strategy`); + return; + } + const clientStrat = new this.EndpointType(payload); + if (__classPrivateFieldGet$9(this, _EndpointStrategy_processAction, "f")) { + clientStrat.receive(__classPrivateFieldGet$9(this, _EndpointStrategy_processAction, "f")); + } + __classPrivateFieldGet$9(this, _EndpointStrategy_endpointMap, "f").set(endpointId, clientStrat); + } + async closeEndpoint(endpointId) { + __classPrivateFieldGet$9(this, _EndpointStrategy_endpointMap, "f").delete(endpointId); + } +} +strategy$1.EndpointStrategy = EndpointStrategy; +_EndpointStrategy_processAction = new WeakMap(), _EndpointStrategy_endpointMap = new WeakMap(), _EndpointStrategy_connected = new WeakMap(); + +Object.defineProperty(strategy$2, "__esModule", { value: true }); +strategy$2.RTCInfo = strategy$2.RTCStrategy = void 0; +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable class-methods-use-this */ +const endpoint_1 = endpoint; +const strategy_1$1 = strategy$1; +/* +This is used to abstract out rtc messaging from the channels implementation using RTCEndpoints. +*/ +class RTCStrategy extends strategy_1$1.EndpointStrategy { + constructor() { + super(endpoint_1.RTCEndpoint, endpoint_1.RTCEndpoint.isValidEndpointPayload, 'RTC'); + } +} +strategy$2.RTCStrategy = RTCStrategy; +strategy$2.RTCInfo = { version: 2, minimumVersion: 0, type: 'rtc' }; + +var iceManager = {}; + +Object.defineProperty(iceManager, "__esModule", { value: true }); +iceManager.RTCICEManager = void 0; +const base_1$h = base; +/* +Singleton that facilitates Offer and Answer exchange required for establishing RTC connections. +*/ +class RTCICEManager extends base_1$h.EmitterBase { + constructor(wire) { + super(wire, 'channel'); + this.ensureChannelOpened = (channel) => { + return new Promise((resolve, reject) => { + if (channel.readyState === 'open') { + resolve(); + } + else if (channel.readyState === 'connecting') { + const listener = () => { + channel.removeEventListener('open', listener); + resolve(); + }; + channel.addEventListener('open', listener); + } + else { + reject(new Error('This Channel has already closed')); + } + }); + }; + } + static createDataChannelPromise(label, rtcClient) { + let resolver; + const promise = new Promise((resolve) => { + resolver = resolve; + }); + const listener = (e) => { + const openListener = () => { + e.channel.removeEventListener('open', openListener); + resolver(e.channel); + }; + if (e.channel.label === label) { + e.channel.addEventListener('open', openListener); + rtcClient.removeEventListener('datachannel', listener); + } + }; + rtcClient.addEventListener('datachannel', listener); + return promise; + } + async listenForProviderIce(rtcConnectionId, listener) { + await this.on(this.createProviderEventName(rtcConnectionId), listener, { timestamp: Date.now() }); + } + async raiseProviderIce(rtcConnectionId, payload) { + await this.wire.environment.raiseEvent(this.createRouteString(this.createProviderEventName(rtcConnectionId)), payload); + } + async listenForClientIce(rtcConnectionId, listener) { + await this.on(this.createClientEventName(rtcConnectionId), listener, { timestamp: Date.now() }); + } + async raiseClientIce(rtcConnectionId, payload) { + await this.wire.environment.raiseEvent(this.createRouteString(this.createClientEventName(rtcConnectionId)), payload); + } + cleanupIceListeners(rtcConnectionId) { + this.removeAllListeners(this.createClientEventName(rtcConnectionId)); + this.removeAllListeners(this.createProviderEventName(rtcConnectionId)); + } + createClientEventName(rtcConnectionId) { + return `ice-client-${rtcConnectionId}`; + } + createProviderEventName(rtcConnectionId) { + return `ice-provider-${rtcConnectionId}`; + } + createRouteString(name) { + return `channel/${name}`; + } + createRtcPeer() { + return this.wire.environment.getRtcPeer(); + } + async startClientOffer() { + // TODO replace with real guid. + const rtcConnectionId = Math.random().toString(); + const rtcClient = this.createRtcPeer(); + rtcClient.addEventListener('icecandidate', async (e) => { + if (e.candidate) { + await this.raiseClientIce(rtcConnectionId, { candidate: e.candidate?.toJSON() }); + } + }); + await this.listenForProviderIce(rtcConnectionId, async (payload) => { + await rtcClient.addIceCandidate(payload.candidate); + }); + const channels = { + request: rtcClient.createDataChannel('request'), + response: rtcClient.createDataChannel('response') + }; + const offer = await rtcClient.createOffer(); + await rtcClient.setLocalDescription(offer); + const channelsOpened = Promise.all([channels.request, channels.response].map(this.ensureChannelOpened)).then(() => undefined); + return { rtcClient, channels, offer, rtcConnectionId, channelsOpened }; + } + async finishClientOffer(rtcClient, answer, providerReady) { + await rtcClient.setRemoteDescription(answer); + await providerReady; + return true; + } + async createProviderAnswer(rtcConnectionId, offer) { + const rtcClient = this.createRtcPeer(); + const requestChannelPromise = RTCICEManager.createDataChannelPromise('request', rtcClient); + const responseChannelPromise = RTCICEManager.createDataChannelPromise('response', rtcClient); + rtcClient.addEventListener('icecandidate', async (e) => { + if (e.candidate) { + await this.raiseProviderIce(rtcConnectionId, { candidate: e.candidate?.toJSON() }); + } + }); + await this.listenForClientIce(rtcConnectionId, async (payload) => { + await rtcClient.addIceCandidate(payload.candidate); + }); + await rtcClient.setRemoteDescription(offer); + const answer = await rtcClient.createAnswer(); + await rtcClient.setLocalDescription(answer); + const channels = Promise.all([requestChannelPromise, responseChannelPromise]).then(([request, response]) => { + // Clean up ice events. + this.cleanupIceListeners(rtcConnectionId); + return { request, response }; + }); + return { + rtcClient, + answer, + channels + }; + } +} +iceManager.RTCICEManager = RTCICEManager; + +var provider = {}; + +var runtimeVersioning = {}; + +Object.defineProperty(runtimeVersioning, "__esModule", { value: true }); +runtimeVersioning.runtimeUuidMeetsMinimumRuntimeVersion = runtimeVersioning.parseRuntimeUuid = runtimeVersioning.meetsMinimumRuntimeVersion = void 0; +function vNum(x) { + return [...x.split('.').reverse().entries()].reduce((p, [i, v]) => p + +v * 10000 ** i, 0); +} +/* + Compares runtime versions to see if the current runtime meets your desired minimum. +*/ +function meetsMinimumRuntimeVersion(currentVersion, minVersion) { + const currentVersionParsed = vNum(currentVersion); + const minVersionParsed = vNum(minVersion); + return currentVersionParsed >= minVersionParsed; +} +runtimeVersioning.meetsMinimumRuntimeVersion = meetsMinimumRuntimeVersion; +// Strips the port info from the runtimeUuid, leaving just the runtime version. +function parseRuntimeUuid(runtimeUuid) { + return runtimeUuid.split('/')[0]; +} +runtimeVersioning.parseRuntimeUuid = parseRuntimeUuid; +function runtimeUuidMeetsMinimumRuntimeVersion(runtimeUuid, minVersion) { + const runtimeVersion = parseRuntimeUuid(runtimeUuid); + return meetsMinimumRuntimeVersion(runtimeVersion, minVersion); +} +runtimeVersioning.runtimeUuidMeetsMinimumRuntimeVersion = runtimeUuidMeetsMinimumRuntimeVersion; + +var __classPrivateFieldGet$8 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet$6 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var _ChannelProvider_connections, _ChannelProvider_protectedObj, _ChannelProvider_strategy, _ChannelProvider_removeEndpoint, _ChannelProvider_close; +Object.defineProperty(provider, "__esModule", { value: true }); +provider.ChannelProvider = void 0; +const channel_1 = channel; +const runtimeVersioning_1 = runtimeVersioning; +/** + * Instance created to enable use of a channel as a provider. Allows for communication with the {@link ChannelClient ChannelClients} by invoking an action on + * a single client via {@link ChannelProvider#dispatch dispatch} or all clients via {@link ChannelProvider#publish publish} + * and to listen for communication from clients by registering an action via {@link ChannelProvider#register register}. + * + * ### Synchronous Methods: + * * {@link ChannelProvider#onConnection onConnection(listener)} + * * {@link ChannelProvider#onDisconnection onDisconnection(listener)} + * * {@link ChannelProvider#publish publish(action, payload)} + * * {@link ChannelProvider#register register(action, listener)} + * * {@link ChannelProvider#remove remove(action)} + * + * ### Asynchronous Methods: + * * {@link ChannelProvider#destroy destroy()} + * * {@link ChannelProvider#dispatch dispatch(to, action, payload)} + * * {@link ChannelProvider#getAllClientInfo getAllClientInfo()} + * + * ### Middleware: + * Middleware functions receive the following arguments: (action, payload, senderId). + * The return value of the middleware function will be passed on as the payload from beforeAction, to the action listener, to afterAction + * unless it is undefined, in which case the most recently defined payload is used. Middleware can be used for side effects. + * * {@link ChannelProvider#setDefaultAction setDefaultAction(middleware)} + * * {@link ChannelProvider#onError onError(middleware)} + * * {@link ChannelProvider#beforeAction beforeAction(middleware)} + * * {@link ChannelProvider#afterAction afterAction(middleware)} + */ +class ChannelProvider extends channel_1.ChannelBase { + /** + * a read-only array containing all the identities of connecting clients. + */ + get connections() { + return [...__classPrivateFieldGet$8(this, _ChannelProvider_connections, "f")]; + } + static handleClientDisconnection(channel, payload) { + const removeById = channel.connections.find((identity) => identity.endpointId === payload.endpointId); + if (removeById) { + __classPrivateFieldGet$8(channel, _ChannelProvider_removeEndpoint, "f").call(channel, removeById); + } + else { + const multipleRemoves = channel.connections.filter((identity) => { + return identity.uuid === payload.uuid && identity.name === payload.name; + }); + multipleRemoves.forEach(__classPrivateFieldGet$8(channel, _ChannelProvider_removeEndpoint, "f")); + } + channel.disconnectListener(payload); + } + static setProviderRemoval(provider, remove) { + ChannelProvider.removalMap.set(provider, remove); + } + /** + * @internal + */ + constructor(providerIdentity, close, strategy) { + super(); + _ChannelProvider_connections.set(this, void 0); + _ChannelProvider_protectedObj.set(this, void 0); + _ChannelProvider_strategy.set(this, void 0); + _ChannelProvider_removeEndpoint.set(this, (identity) => { + const remainingConnections = this.connections.filter((clientIdentity) => clientIdentity.endpointId !== identity.endpointId); + __classPrivateFieldGet$8(this, _ChannelProvider_strategy, "f").closeEndpoint(identity.endpointId); + __classPrivateFieldSet$6(this, _ChannelProvider_connections, remainingConnections, "f"); + }); + // Must be bound. + this.processAction = async (action, payload, senderIdentity) => { + if (ChannelProvider.clientIsMultiRuntime(senderIdentity) && + !(0, runtimeVersioning_1.runtimeUuidMeetsMinimumRuntimeVersion)(senderIdentity.runtimeUuid, '18.87.56.0')) { + this.handleMultiRuntimeLegacyClient(senderIdentity); + } + else { + this.checkForClientConnection(senderIdentity); + } + return super.processAction(action, payload, senderIdentity); + }; + _ChannelProvider_close.set(this, () => { + __classPrivateFieldGet$8(this, _ChannelProvider_strategy, "f").close(); + const remove = ChannelProvider.removalMap.get(this); + if (remove) { + remove(); + } + }); + __classPrivateFieldSet$6(this, _ChannelProvider_protectedObj, new channel_1.ProtectedItems(providerIdentity, close), "f"); + this.connectListener = () => undefined; + this.disconnectListener = () => undefined; + __classPrivateFieldSet$6(this, _ChannelProvider_connections, [], "f"); + __classPrivateFieldSet$6(this, _ChannelProvider_strategy, strategy, "f"); + strategy.receive(this.processAction); + } + /** + * Dispatch an action to a specified client. Returns a promise for the result of executing that action on the client side. + * + * @param to - Identity of the target client. + * @param action - Name of the action to be invoked by the client. + * @param payload - Payload to be sent along with the action. + * + * @remarks + * + * Because multiple clients can share the same `name` and `uuid`, when dispatching from a provider to a client, + * the `identity` you provide must include the client's unique `endpointId` property. This `endpointId` is + * passed to the provider in both the `Provider.onConnection` callback and in any registered action callbacks. + * + * @example + * + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.register('provider-action', async (payload, identity) => { + * console.log(payload, identity); + * return await provider.dispatch(identity, 'client-action', 'Hello, World!'); + * }); + * })(); + * ``` + */ + dispatch(to, action, payload) { + const endpointId = to.endpointId ?? this.getEndpointIdForOpenFinId(to, action); + if (endpointId && __classPrivateFieldGet$8(this, _ChannelProvider_strategy, "f").isEndpointConnected(endpointId)) { + return __classPrivateFieldGet$8(this, _ChannelProvider_strategy, "f").send(endpointId, action, payload); + } + return Promise.reject(new Error(`Client connection with identity uuid: ${to.uuid} / name: ${to.name} / endpointId: ${endpointId} no longer connected.`)); + } + async processConnection(senderId, payload) { + __classPrivateFieldGet$8(this, _ChannelProvider_connections, "f").push(senderId); + return this.connectListener(senderId, payload); + } + /** + * Publish an action and payload to every connected client. + * Synchronously returns an array of promises for each action (see dispatch). + * + * @param action + * @param payload + * + * @example + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.register('provider-action', async (payload, identity) => { + * console.log(payload, identity); + * return await Promise.all(provider.publish('client-action', { message: 'Broadcast from provider'})); + * }); + * })(); + * ``` + */ + publish(action, payload) { + return this.connections.map((to) => __classPrivateFieldGet$8(this, _ChannelProvider_strategy, "f").send(to.endpointId, action, payload)); + } + /** + * Register a listener that is called on every new client connection. + * + * @remarks It is passed the identity of the connecting client and a payload if it was provided to Channel.connect. + * If you wish to reject the connection, throw an error. Be sure to synchronously provide an onConnection upon receipt of + * the channelProvider to ensure all potential client connections are caught by the listener. + * + * Because multiple clients can exist at the same `name` and `uuid`, in order to distinguish between individual clients, + * the `identity` argument in a provider's `onConnection` callback contains an `endpointId` property. When dispatching from a + * provider to a client, the `endpointId` property must be provided in order to send an action to a specific client. + * + * @example + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * provider.onConnection(identity => { + * console.log('Client connected', identity); + * }); + * })(); + * ``` + * + * Reject connection: + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * provider.onConnection(identity => { + * throw new Error('Connection Rejected'); + * }); + * })(); + * ``` + * @param listener + */ + onConnection(listener) { + this.connectListener = listener; + } + /** + * Register a listener that is called on client disconnection. It is passed the disconnection event of the disconnecting + * client. + * + * @param listener + * + * @example + * + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.onDisconnection(evt => { + * console.log('Client disconnected', `uuid: ${evt.uuid}, name: ${evt.name}`); + * }); + * })(); + * ``` + */ + onDisconnection(listener) { + this.disconnectListener = listener; + } + /** + * Destroy the channel, raises `disconnected` events on all connected channel clients. + * + * @example + * + * ```js + * (async ()=> { + * const provider = await fin.InterApplicationBus.Channel.create('channelName'); + * + * await provider.destroy(); + * })(); + * ``` + */ + async destroy() { + const protectedObj = __classPrivateFieldGet$8(this, _ChannelProvider_protectedObj, "f"); + protectedObj.providerIdentity; + __classPrivateFieldSet$6(this, _ChannelProvider_connections, [], "f"); + await protectedObj.close(); + __classPrivateFieldGet$8(this, _ChannelProvider_close, "f").call(this); + } + /** + * Returns an array with info on every Client connected to the Provider + * + * @example + * + * ```js + * const provider = await fin.InterApplicationBus.Channel.create('openfin'); + * const client = await fin.InterApplicationBus.Channel.connect('openfin'); + * const clientInfo = await provider.getAllClientInfo(); + * + * console.log(clientInfo); + * + * // [ + * // { + * // "uuid": "openfin", + * // "name": "openfin-view", + * // "endpointId": "6d4c7ca8-4a74-4634-87f8-760558229613", + * // "entityType": "view", + * // "url": "https://openfin.co" + * // }, + * // { + * // "uuid": "openfin2", + * // "name": "openfin-view2", + * // "endpointId": "4z5d8ab9-2b81-3691-91ex-142179382511", + * // "entityType": "view", + * // "url": "https://example.com" + * // } + * //] + * ``` + */ + async getAllClientInfo() { + return this.connections.map((clientInfo) => { + const { uuid, name, endpointId, entityType, connectionUrl } = clientInfo; + return { uuid, name, endpointId, entityType, connectionUrl }; + }); + } + checkForClientConnection(clientIdentity) { + if (!this.isClientConnected(clientIdentity)) { + throw new Error(`This action was sent from a client that is not connected to the provider. + Client Identity: {uuid: ${clientIdentity.uuid}, name: ${clientIdentity.name}, endpointId: ${clientIdentity.endpointId}}`); + } + } + isClientConnected(clientIdentity) { + if (ChannelProvider.clientIdentityIncludesEndpointId(clientIdentity)) { + return this.connections.some((identity) => { + return ( + // Might be redundant to check for uuid and name here after we get an endpointId match, but just in case + identity.endpointId === clientIdentity.endpointId && + identity.uuid === clientIdentity.uuid && + identity.name === clientIdentity.name); + }); + } + return this.isLegacyClientConnected(clientIdentity); + } + isLegacyClientConnected(clientIdentity) { + return this.connections.some((identity) => { + return identity.uuid === clientIdentity.uuid && identity.name === clientIdentity.name; + }); + } + handleMultiRuntimeLegacyClient(senderIdentity) { + if (!this.isLegacyClientConnected(senderIdentity)) { + throw new Error(`This action was sent from a client that is not connected to the provider. Client Identity: + {uuid: ${senderIdentity.uuid}, name: ${senderIdentity.name}, endpointId: ${senderIdentity.endpointId}}`); + } + } + getEndpointIdForOpenFinId(clientIdentity, action) { + const matchingConnections = this.connections.filter((c) => c.name === clientIdentity.name && c.uuid === clientIdentity.uuid); + if (matchingConnections.length >= 2) { + const protectedObj = __classPrivateFieldGet$8(this, _ChannelProvider_protectedObj, "f"); + const { uuid, name } = clientIdentity; + const providerUuid = protectedObj?.providerIdentity.uuid; + const providerName = protectedObj?.providerIdentity.name; + // eslint-disable-next-line no-console + console.warn(`WARNING: Dispatch call may have unintended results. The "to" argument of your dispatch call is missing the + "endpointId" parameter. The identity you are dispatching to ({uuid: ${uuid}, name: ${name}}) + has multiple channelClients for this channel. Your dispatched action: (${action}) from the provider: + ({uuid: ${providerUuid}, name: ${providerName}}) will only be processed by the most recently-created client.`); + } + // Pop to return the most recently created endpointId. + return matchingConnections.pop()?.endpointId; + } + // eslint-disable-next-line class-methods-use-this + static clientIdentityIncludesEndpointId(subscriptionIdentity) { + return subscriptionIdentity.endpointId !== undefined; + } + // eslint-disable-next-line class-methods-use-this + static clientIsMultiRuntime(subscriptionIdentity) { + return subscriptionIdentity.runtimeUuid !== undefined; + } + static async wireClose(wire, channelName) { + await wire.sendAction('destroy-channel', { channelName }); + } +} +provider.ChannelProvider = ChannelProvider; +_ChannelProvider_connections = new WeakMap(), _ChannelProvider_protectedObj = new WeakMap(), _ChannelProvider_strategy = new WeakMap(), _ChannelProvider_removeEndpoint = new WeakMap(), _ChannelProvider_close = new WeakMap(); +// The following line should be changed following a typescript update. +// static #removalMap = new WeakMap(); +ChannelProvider.removalMap = new WeakMap(); + +var messageReceiver = {}; + +Object.defineProperty(messageReceiver, "__esModule", { value: true }); +messageReceiver.MessageReceiver = void 0; +const client_1$1 = client; +const base_1$g = base; +/* +This is a singleton (per fin object) tasked with routing messages coming off the ipc to the correct endpoint. +It needs to be a singleton because there can only be one per wire. It tracks both clients and providers' processAction passed in via the strategy. +If functionality is not about receiving messages, it does not belong here. +*/ +class MessageReceiver extends base_1$g.Base { + constructor(wire) { + super(wire); + this.onmessage = (msg) => { + if (msg.action === 'process-channel-message') { + this.processChannelMessage(msg); + return true; + } + return false; + }; + this.endpointMap = new Map(); + this.latestEndpointIdByChannelId = new Map(); + wire.registerMessageHandler(this.onmessage.bind(this)); + } + async processChannelMessage(msg) { + const { senderIdentity, providerIdentity, action, ackToSender, payload, intendedTargetIdentity } = msg.payload; + const key = intendedTargetIdentity.channelId ?? // The recipient is a provider + intendedTargetIdentity.endpointId ?? // The recipient is a client + this.latestEndpointIdByChannelId.get(providerIdentity.channelId); // No endpointId was passed, make best attempt + const handler = this.endpointMap.get(key); + if (!handler) { + ackToSender.payload.success = false; + ackToSender.payload.reason = `Client connection with identity uuid: ${this.wire.me.uuid} / name: ${this.wire.me.name} / endpointId: ${key} no longer connected.`; + return this.wire.sendRaw(ackToSender); + } + try { + const res = await handler(action, payload, senderIdentity); + ackToSender.payload.payload = ackToSender.payload.payload || {}; + ackToSender.payload.payload.result = res; + return this.wire.sendRaw(ackToSender); + } + catch (e) { + ackToSender.payload.success = false; + ackToSender.payload.reason = e.message; + return this.wire.sendRaw(ackToSender); + } + } + addEndpoint(handler, channelId, endpointId) { + this.endpointMap.set(endpointId, handler); + // Providers have the same endpointId and channelId. + // This is only used when clients are receiving messages from providers, so we shouldn't save provider endpointId here. + if (channelId !== endpointId) { + this.latestEndpointIdByChannelId.set(channelId, endpointId); + } + } + removeEndpoint(channelId, endpointId) { + this.endpointMap.delete(endpointId); + if (this.latestEndpointIdByChannelId.get(channelId) === endpointId) { + this.latestEndpointIdByChannelId.delete(channelId); + } + } + checkForPreviousClientConnection(channelId) { + const endpointIdFromPreviousConnection = this.latestEndpointIdByChannelId.get(channelId); + if (endpointIdFromPreviousConnection) { + // Not convinced by this way of doing things, but pushing up for now. + client_1$1.ChannelClient.closeChannelByEndpointId(endpointIdFromPreviousConnection); + // eslint-disable-next-line no-console + console.warn('You have created a second connection to an older provider. First connection has been removed from the clientMap'); + // eslint-disable-next-line no-console + console.warn('If the provider calls publish(), you may receive multiple messages.'); + } + } +} +messageReceiver.MessageReceiver = MessageReceiver; + +var protocolManager = {}; + +Object.defineProperty(protocolManager, "__esModule", { value: true }); +protocolManager.ProtocolManager = void 0; +/* +This should be agnostic of any actual openfin code to be unit testable. +Dependencies on the actual srategies should be handled in ConnectionManager +*/ +class ProtocolManager { + // eslint-disable-next-line no-useless-constructor + constructor(ProtocolsInPreferenceOrder) { + this.ProtocolsInPreferenceOrder = ProtocolsInPreferenceOrder; + this.DefaultClientProtocols = ['classic']; + this.DefaultProviderProtocols = ['classic']; + this.getClientProtocols = (protocols) => { + const supported = protocols + ? this.ProtocolsInPreferenceOrder.filter((x) => protocols.includes(x)) + : this.DefaultClientProtocols; + if (!supported.length) { + throw new Error(`No valid protocols were passed in. Accepted values are: ${this.ProtocolsInPreferenceOrder.join(', ')}.`); + } + return supported; + }; + this.getProviderProtocols = (protocols) => { + const supported = protocols + ? this.ProtocolsInPreferenceOrder.filter((x) => protocols.includes(x)) + : this.DefaultProviderProtocols; + if (!supported.length) { + throw new Error(`No valid protocols were passed in. Accepted values are: ${this.ProtocolsInPreferenceOrder.join(', ')}.`); + } + return supported; + }; + this.getCompatibleProtocols = (providerProtocols, clientOffer) => { + const supported = clientOffer.supportedProtocols.filter((clientProtocol) => providerProtocols.some((providerProtocol) => providerProtocol.type === clientProtocol.type && + clientProtocol.version >= providerProtocol.minimumVersion && + providerProtocol.version >= (clientProtocol.minimumVersion ?? 0))); + return supported.slice(0, clientOffer.maxProtocols); + }; + } +} +protocolManager.ProtocolManager = ProtocolManager; + +var strategy = {}; + +Object.defineProperty(strategy, "__esModule", { value: true }); +class CombinedStrategy { + // Making this a static method because the constructor can't be typed. + // Otherwise it will error when calling addEndpoint but I'd rather the whole instance be typed as never. + static combine(a, b) { + return new CombinedStrategy(a, b); + } + // eslint-disable-next-line no-useless-constructor + constructor(primary, secondary) { + this.primary = primary; + this.secondary = secondary; + } + onEndpointDisconnect(endpointId, listener) { + this.primary.onEndpointDisconnect(endpointId, () => { + if (!this.secondary.isEndpointConnected(endpointId)) { + listener(); + } + }); + this.secondary.onEndpointDisconnect(endpointId, () => { + if (!this.primary.isEndpointConnected(endpointId)) { + listener(); + } + }); + } + isValidEndpointPayload(payload) { + return this.primary.isValidEndpointPayload(payload) || this.secondary.isValidEndpointPayload(payload); + } + async closeEndpoint(endpointId) { + await this.primary.closeEndpoint(endpointId); + await this.secondary.closeEndpoint(endpointId); + } + isEndpointConnected(endpoint) { + return this.primary.isEndpointConnected(endpoint) || this.secondary.isEndpointConnected(endpoint); + } + async addEndpoint(endpoint, payload) { + if (this.primary.isValidEndpointPayload(payload)) { + await this.primary.addEndpoint(endpoint, payload); + } + if (this.secondary.isValidEndpointPayload(payload)) { + await this.secondary.addEndpoint(endpoint, payload); + } + } + receive(listener) { + this.primary.receive(listener); + this.secondary.receive(listener); + } + send(endpointId, action, payload) { + if (this.primary.isEndpointConnected(endpointId)) { + return this.primary.send(endpointId, action, payload); + } + return this.secondary.send(endpointId, action, payload); + } + async close() { + await Promise.all([this.primary.close(), this.secondary.close()]); + } +} +strategy.default = CombinedStrategy; + +var __classPrivateFieldSet$5 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$7 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __importDefault$1 = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +var _ConnectionManager_messageReceiver, _ConnectionManager_rtcConnectionManager; +Object.defineProperty(connectionManager, "__esModule", { value: true }); +connectionManager.ConnectionManager = void 0; +const exhaustive_1 = exhaustive; +const base_1$f = base; +const strategy_1 = strategy$3; +const strategy_2 = strategy$2; +const ice_manager_1 = iceManager; +const provider_1$1 = provider; +const message_receiver_1 = messageReceiver; +const protocol_manager_1 = protocolManager; +const strategy_3 = __importDefault$1(strategy); +class ConnectionManager extends base_1$f.Base { + static getProtocolOptionsFromStrings(protocols) { + return protocols.map((protocol) => { + switch (protocol) { + case 'rtc': + return strategy_2.RTCInfo; + case 'classic': + return strategy_1.ClassicInfo; + default: + return (0, exhaustive_1.exhaustiveCheck)(protocol, ['rtc', 'classic']); + } + }); + } + constructor(wire) { + super(wire); + _ConnectionManager_messageReceiver.set(this, void 0); + _ConnectionManager_rtcConnectionManager.set(this, void 0); + this.removeChannelFromProviderMap = (channelId) => { + this.providerMap.delete(channelId); + }; + this.onmessage = (msg) => { + if (msg.action === 'process-channel-connection') { + this.processChannelConnection(msg); + return true; + } + return false; + }; + this.providerMap = new Map(); + this.protocolManager = new protocol_manager_1.ProtocolManager(this.wire.environment.type === 'node' ? ['classic'] : ['rtc', 'classic']); + __classPrivateFieldSet$5(this, _ConnectionManager_messageReceiver, new message_receiver_1.MessageReceiver(wire), "f"); + __classPrivateFieldSet$5(this, _ConnectionManager_rtcConnectionManager, new ice_manager_1.RTCICEManager(wire), "f"); + wire.registerMessageHandler(this.onmessage.bind(this)); + } + createProvider(options, providerIdentity) { + const opts = Object.assign(this.wire.environment.getDefaultChannelOptions().create, options || {}); + const protocols = this.protocolManager.getProviderProtocols(opts?.protocols); + const createSingleStrategy = (stratType) => { + switch (stratType) { + case 'rtc': + return new strategy_2.RTCStrategy(); + case 'classic': + return new strategy_1.ClassicStrategy(this.wire, __classPrivateFieldGet$7(this, _ConnectionManager_messageReceiver, "f"), + // Providers do not have an endpointId, use channelId as endpointId in the strategy. + providerIdentity.channelId, providerIdentity); + default: + return (0, exhaustive_1.exhaustiveCheck)(stratType, ['rtc', 'classic']); + } + }; + const strategies = protocols.map(createSingleStrategy); + let strategy; + if (strategies.length === 2) { + const [a, b] = strategies; + strategy = strategy_3.default.combine(a, b); + } + else if (strategies.length === 1) { + [strategy] = strategies; + } + else { + // Should be impossible. + throw new Error('failed to combine strategies'); + } + const channel = new provider_1$1.ChannelProvider(providerIdentity, () => provider_1$1.ChannelProvider.wireClose(this.wire, providerIdentity.channelName), strategy); + const key = providerIdentity.channelId; + this.providerMap.set(key, { + provider: channel, + strategy, + supportedProtocols: ConnectionManager.getProtocolOptionsFromStrings(protocols) + }); + provider_1$1.ChannelProvider.setProviderRemoval(channel, this.removeChannelFromProviderMap.bind(this)); + return channel; + } + async createClientOffer(options) { + const protocols = this.protocolManager.getClientProtocols(options?.protocols); + let rtcPacket; + const supportedProtocols = await Promise.all(protocols.map(async (type) => { + switch (type) { + case 'rtc': { + const { rtcClient, channels, offer, rtcConnectionId, channelsOpened } = await __classPrivateFieldGet$7(this, _ConnectionManager_rtcConnectionManager, "f").startClientOffer(); + rtcPacket = { rtcClient, channels, channelsOpened }; + return { + type: 'rtc', + version: strategy_2.RTCInfo.version, + payload: { offer, rtcConnectionId } + }; + } + case 'classic': + return { type: 'classic', version: strategy_1.ClassicInfo.version }; + default: + return (0, exhaustive_1.exhaustiveCheck)(type, ['rtc', 'classic']); + } + })); + return { + offer: { + supportedProtocols, + maxProtocols: 2 + }, + rtc: rtcPacket + }; + } + async createClientStrategy(rtcPacket, routingInfo) { + if (!routingInfo.endpointId) { + routingInfo.endpointId = this.wire.environment.getNextMessageId(); + // For New Clients connecting to Old Providers. To prevent multi-dispatching and publishing, we delete previously-connected + // clients that are in the same context as the newly-connected client. + __classPrivateFieldGet$7(this, _ConnectionManager_messageReceiver, "f").checkForPreviousClientConnection(routingInfo.channelId); + } + const answer = routingInfo.answer ?? { + supportedProtocols: [{ type: 'classic', version: 1 }] + }; + const createStrategyFromAnswer = async (protocol) => { + if (protocol.type === 'rtc' && rtcPacket) { + await __classPrivateFieldGet$7(this, _ConnectionManager_rtcConnectionManager, "f").finishClientOffer(rtcPacket.rtcClient, protocol.payload.answer, rtcPacket.channelsOpened); + return new strategy_2.RTCStrategy(); + } + if (protocol.type === 'classic') { + return new strategy_1.ClassicStrategy(this.wire, __classPrivateFieldGet$7(this, _ConnectionManager_messageReceiver, "f"), routingInfo.endpointId, routingInfo); + } + return null; + }; + const allProtocols = (await Promise.all(answer.supportedProtocols.map(createStrategyFromAnswer))).filter((x) => x !== null); + // Clean up logic if provider didn't support rtc. + if (rtcPacket && !allProtocols.some((x) => x instanceof strategy_2.RTCStrategy)) { + if (rtcPacket) { + rtcPacket.rtcClient.close(); + } + } + let strategy; + if (allProtocols.length >= 2) { + strategy = strategy_3.default.combine(allProtocols[0], allProtocols[1]); + } + else if (allProtocols.length) { + [strategy] = allProtocols; + } + else { + // Should be impossible. + throw new Error('No compatible protocols'); + } + // as casting rtcPacket because we won't have an rtcStrategy if rtcPacket is undefined; + const endpointPayload = { endpointIdentity: routingInfo, rtc: rtcPacket }; + strategy.addEndpoint(routingInfo.channelId, endpointPayload); + return strategy; + } + async processChannelConnection(msg) { + const { clientIdentity, providerIdentity, ackToSender, payload, offer: clientOffer } = msg.payload; + if (!clientIdentity.endpointId) { + // Should be polyfilled by core but not in cases of node connecting to an old runtime. + clientIdentity.endpointId = this.wire.environment.getNextMessageId(); + clientIdentity.isLocalEndpointId = true; + } + else { + clientIdentity.isLocalEndpointId = false; + } + const key = providerIdentity.channelId; + const bus = this.providerMap.get(key); + if (!bus) { + ackToSender.payload.success = false; + ackToSender.payload.reason = `Channel "${providerIdentity.channelName}" has been destroyed.`; + return this.wire.sendRaw(ackToSender); + } + const { provider, strategy, supportedProtocols } = bus; + try { + if (!(provider instanceof provider_1$1.ChannelProvider)) { + throw Error('Cannot connect to a channel client'); + } + const offer = clientOffer ?? { + supportedProtocols: [{ type: 'classic', version: 1 }], + maxProtocols: 1 + }; + const overlappingProtocols = this.protocolManager.getCompatibleProtocols(supportedProtocols, offer); + if (!overlappingProtocols.length) { + throw new Error('This provider does not support any of the offered protocols.'); + } + const res = await provider.processConnection(clientIdentity, payload); + ackToSender.payload.payload = ackToSender.payload.payload || {}; + // Loop through all supported protocols and accumulate them into the answer + // addEndpoint is tricky but we need to wait for channel resolution before adding the endpoint. + let clientAnswer = { + supportedProtocols: [], + endpointPayloadPromise: Promise.resolve({ endpointIdentity: clientIdentity }) + }; + clientAnswer = await overlappingProtocols.reduce(async (accumP, protocolToUse) => { + const answer = await accumP; + if (protocolToUse.type === 'rtc') { + const { answer: rtcAnswer, rtcClient, channels } = await __classPrivateFieldGet$7(this, _ConnectionManager_rtcConnectionManager, "f").createProviderAnswer(protocolToUse.payload.rtcConnectionId, protocolToUse.payload.offer); + answer.supportedProtocols.push({ + type: 'rtc', + version: strategy_2.RTCInfo.version, + payload: { + answer: rtcAnswer + } + }); + answer.endpointPayloadPromise = answer.endpointPayloadPromise.then((endpointPayload) => channels.then((resolvedChannels) => { + return { + ...endpointPayload, + rtc: { + rtcClient, + channels: resolvedChannels + } + }; + })); + } + else { + answer.supportedProtocols.push({ type: 'classic', version: strategy_1.ClassicInfo.version }); + } + return answer; + }, Promise.resolve(clientAnswer)); + // Need to as cast here. + clientAnswer.endpointPayloadPromise.then((endpointPayload) => strategy.addEndpoint(clientIdentity.endpointId, endpointPayload)); + ackToSender.payload.payload.result = res; + ackToSender.payload.payload.answer = clientAnswer; + return this.wire.sendRaw(ackToSender); + } + catch (e) { + ackToSender.payload.success = false; + ackToSender.payload.reason = e.message; + return this.wire.sendRaw(ackToSender); + } + } +} +connectionManager.ConnectionManager = ConnectionManager; +_ConnectionManager_messageReceiver = new WeakMap(), _ConnectionManager_rtcConnectionManager = new WeakMap(); + +/** + * Entry points for the `Channel` subset of the `InterApplicationBus` API (`fin.InterApplicationBus.Channel`). + * + * * {@link Channel} contains static members of the `Channel` API, accessible through `fin.InterApplicationBus.Channel`. + * * {@link OpenFin.ChannelClient} describes a client of a channel, e.g. as returned by `fin.InterApplicationBus.Channel.connect`. + * * {@link OpenFin.ChannelProvider} describes a provider of a channel, e.g. as returned by `fin.InterApplicationBus.Channel.create`. + * + * @packageDocumentation + */ +var __classPrivateFieldSet$4 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$6 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _Channel_connectionManager, _Channel_internalEmitter, _Channel_readyToConnect; +Object.defineProperty(channel$1, "__esModule", { value: true }); +channel$1.Channel = void 0; +/* eslint-disable no-console */ +const events_1$5 = require$$0; +const lazy_1$1 = lazy; +const base_1$e = base; +const client_1 = client; +const connection_manager_1 = connectionManager; +const provider_1 = provider; +function retryDelay(count) { + const interval = 500; // base delay + const steps = 10; // How many retries to do before incrementing the delay + const base = 2; // How much to multiply the previous delay by + const max = 30000; // max delay + const step = Math.floor(count / steps); + const delay = Math.min(max, interval * base ** step); + return new Promise((resolve) => { + setTimeout(() => { + resolve(false); + }, delay); + }); +} +/** + * The Channel API allows an OpenFin application to create a channel as a {@link ChannelProvider ChannelProvider}, + * or connect to a channel as a {@link ChannelClient ChannelClient}. + * @remarks The "handshake" between the communication partners is + * simplified when using a channel. A request to connect to a channel as a client will return a promise that resolves if/when the channel has been created. Both the + * provider and client can dispatch actions that have been registered on their opposites, and dispatch returns a promise that resolves with a payload from the other + * communication participant. There can be only one provider per channel, but many clients. Version `9.61.35.*` or later is required for both communication partners. + * + * Asynchronous Methods: + * * {@link Channel.create create(channelName, options)} + * * {@link Channel.connect connect(channelName, options)} + * * {@link Channel.onChannelConnect onChannelConnect(listener)} + * * {@link Channel.onChannelDisconnect onChannelDisconnect(listener)} + */ +class Channel extends base_1$e.EmitterBase { + /** + * @internal + */ + constructor(wire) { + super(wire, 'channel'); + _Channel_connectionManager.set(this, void 0); + _Channel_internalEmitter.set(this, new events_1$5.EventEmitter()); + // OpenFin API has not been injected at construction time, *must* wait for API to be ready. + _Channel_readyToConnect.set(this, new lazy_1$1.AsyncRetryableLazy(async () => { + await Promise.all([ + this.on('disconnected', (eventPayload) => { + client_1.ChannelClient.handleProviderDisconnect(eventPayload); + }), + this.on('connected', (...args) => { + __classPrivateFieldGet$6(this, _Channel_internalEmitter, "f").emit('connected', ...args); + }) + ]).catch(() => new Error('error setting up channel connection listeners')); + })); + __classPrivateFieldSet$4(this, _Channel_connectionManager, new connection_manager_1.ConnectionManager(wire), "f"); + } + /** + * + * @internal + */ + async getAllChannels() { + return this.wire.sendAction('get-all-channels').then(({ payload }) => payload.data); + } + /** + * Listens for channel connections. + * + * @param listener - callback to execute. + * + * @example + * + * ```js + * const listener = (channelPayload) => console.log(channelPayload); // see return value below + * + * fin.InterApplicationBus.Channel.onChannelConnect(listener); + * + * // example shape + * { + * "topic": "channel", + * "type": "connected", + * "uuid": "OpenfinPOC", + * "name": "OpenfinPOC", + * "channelName": "counter", + * "channelId": "OpenfinPOC/OpenfinPOC/counter" + * } + * + * ``` + */ + async onChannelConnect(listener) { + await this.on('connected', listener); + } + /** + * Listen for channel disconnections. + * + * @param listener - callback to execute. + * + * @example + * + * ```js + * const listener = (channelPayload) => console.log(channelPayload); // see return value below + * + * fin.InterApplicationBus.Channel.onChannelDisconnect(listener); + * + * // example shape + * { + * "topic": "channel", + * "type": "disconnected", + * "uuid": "OpenfinPOC", + * "name": "OpenfinPOC", + * "channelName": "counter", + * "channelId": "OpenfinPOC/OpenfinPOC/counter" + * } + * + * ``` + */ + async onChannelDisconnect(listener) { + await this.on('disconnected', listener); + } + async safeConnect(channelName, shouldWait, connectPayload) { + const retryInfo = { count: 0 }; + /* eslint-disable no-await-in-loop, no-constant-condition */ + do { + // setup a listener and a connected promise to await in case we connect before the channel is ready + let connectedListener = () => undefined; + const connectedPromise = new Promise((resolve) => { + connectedListener = (payload) => { + if (channelName === payload.channelName) { + resolve(true); + } + }; + __classPrivateFieldGet$6(this, _Channel_internalEmitter, "f").on('connected', connectedListener); + }); + try { + if (retryInfo.count > 0) { + // Wait before retrying + // Delay returns false connectedPromise returns true so we can know if a retry is due to connected event + retryInfo.gotConnectedEvent = await Promise.race([retryDelay(retryInfo.count), connectedPromise]); + const result = await this.wire.sendAction('connect-to-channel', { ...connectPayload, retryInfo }); + // log only if there was a retry + console.log(`Successfully connected to channelName: ${channelName}`); + return result.payload.data; + } + // Send retryInfo to the core for debug log inclusion + const sentMessagePromise = this.wire.sendAction('connect-to-channel', connectPayload); + // Save messageId from the first connection attempt + retryInfo.originalMessageId = sentMessagePromise.messageId; + const result = await sentMessagePromise; + return result.payload.data; + } + catch (error) { + if (!error.message.includes('internal-nack')) { + // Not an internal nack, break the loop + throw error; + } + if (shouldWait && retryInfo.count === 0) { + // start waiting on the next iteration, warn the user + console.warn(`No channel found for channelName: ${channelName}. Waiting for connection...`); + } + } + finally { + retryInfo.count += 1; + // in case of other errors, remove our listener + __classPrivateFieldGet$6(this, _Channel_internalEmitter, "f").removeListener('connected', connectedListener); + } + } while (shouldWait); // If we're waiting we retry the above loop + // Should wait was false, no channel was found. + throw new Error(`No channel found for channelName: ${channelName}.`); + /* eslint-enable no-await-in-loop, no-constant-condition */ + } + /** + * Connect to a channel. If you wish to send a payload to the provider, add a payload property to the options argument. + * EXPERIMENTAL: pass { protocols: ['rtc'] } as options to opt-in to High Throughput Channels. + * + * @param channelName - Name of the target channel. + * @param options - Connection options. + * @returns Returns a promise that resolves with an instance of {@link ChannelClient ChannelClient}. + * + * @remarks The connection request will be routed to the channelProvider if/when the channel is created. If the connect + * request is sent prior to creation, the promise will not resolve or reject until the channel is created by a channelProvider + * (whether or not to wait for creation is configurable in the connectOptions). + * + * The connect call returns a promise that will resolve with a channelClient bus if accepted by the channelProvider, or reject if + * the channelProvider throws an error to reject the connection. This bus can communicate with the Provider, but not to other + * clients on the channel. Using the bus, the channelClient can register actions and middleware. Channel lifecycle can also be + * handled with an onDisconnection listener. + * + * @example + * + * ```js + * async function makeClient(channelName) { + * // A payload can be sent along with channel connection requests to help with authentication + * const connectPayload = { payload: 'token' }; + * + * // If the channel has been created this request will be sent to the provider. If not, the + * // promise will not be resolved or rejected until the channel has been created. + * const clientBus = await fin.InterApplicationBus.Channel.connect(channelName, connectPayload); + * + * clientBus.onDisconnection(channelInfo => { + * // handle the channel lifecycle here - we can connect again which will return a promise + * // that will resolve if/when the channel is re-created. + * makeClient(channelInfo.channelName); + * }) + * + * clientBus.register('topic', (payload, identity) => { + * // register a callback for a topic to which the channel provider can dispatch an action + * console.log('Action dispatched by provider: ', JSON.stringify(identity)); + * console.log('Payload sent in dispatch: ', JSON.stringify(payload)); + * return { + * echo: payload + * }; + * }); + * } + * + * makeClient('channelName') + * .then(() => console.log('Connected')) + * .catch(console.error); + * ``` + */ + async connect(channelName, options = {}) { + // Make sure we don't connect before listeners are set up + // This also errors if we're not in OpenFin, ensuring we don't run unnecessary code + await __classPrivateFieldGet$6(this, _Channel_readyToConnect, "f").getValue(); + if (!channelName || typeof channelName !== 'string') { + throw new Error('Please provide a channelName string to connect to a channel.'); + } + const opts = { wait: true, ...this.wire.environment.getDefaultChannelOptions().connect, ...options }; + const { offer, rtc: rtcPacket } = await __classPrivateFieldGet$6(this, _Channel_connectionManager, "f").createClientOffer(opts); + let connectionUrl; + if (this.fin.me.isFrame || this.fin.me.isView || this.fin.me.isWindow) { + connectionUrl = (await this.fin.me.getInfo()).url; + } + const connectPayload = { + channelName, + ...opts, + offer, + connectionUrl + }; + const routingInfo = await this.safeConnect(channelName, opts.wait, connectPayload); + const strategy = await __classPrivateFieldGet$6(this, _Channel_connectionManager, "f").createClientStrategy(rtcPacket, routingInfo); + const channel = new client_1.ChannelClient(routingInfo, () => client_1.ChannelClient.wireClose(this.wire, routingInfo, routingInfo.endpointId), strategy); + // It is the client's responsibility to handle endpoint disconnection to the provider. + // If the endpoint dies, the client will force a disconnection through the core. + // The provider does not care about endpoint disconnection. + strategy.onEndpointDisconnect(routingInfo.channelId, async () => { + try { + await channel.sendDisconnectAction(); + } + catch (error) { + console.warn(`Something went wrong during disconnect for client with uuid: ${routingInfo.uuid} / name: ${routingInfo.name} / endpointId: ${routingInfo.endpointId}.`); + } + finally { + client_1.ChannelClient.handleProviderDisconnect(routingInfo); + } + }); + return channel; + } + /** + * Create a new channel. + * You must provide a unique channelName. If a channelName is not provided, or it is not unique, the creation will fail. + * EXPERIMENTAL: pass { protocols: ['rtc'] } as options to opt-in to High Throughput Channels. + * + * @param channelName - Name of the channel to be created. + * @param options - Creation options. + * @returns Returns a promise that resolves with an instance of {@link ChannelProvider ChannelProvider}. + * + * @remarks If successful, the create method returns a promise that resolves to an instance of the channelProvider bus. The caller + * then becomes the “channel provider” and can use the channelProvider bus to register actions and middleware. + * + * The caller can also set an onConnection and/or onDisconnection listener that will execute on any new channel + * connection/disconnection attempt from a channel client. To reject a connection, simply throw an error in the + * onConnection listener. The default behavior is to accept all new connections. + * + * A map of client connections is updated automatically on client connection and disconnection and saved in the + * [read-only] `connections` property on the channelProvider bus. The channel will exist until the provider + * destroys it or disconnects by closing or destroying the context (navigating or reloading). To setup a channel + * as a channelProvider, call `Channel.create` with a unique channel name. A map of client connections is updated + * automatically on client connection and disconnection. + * + * @example + * + * ```js + * (async ()=> { + * // entity creates a channel and becomes the channelProvider + * const providerBus = await fin.InterApplicationBus.Channel.create('channelName'); + * + * providerBus.onConnection((identity, payload) => { + * // can reject a connection here by throwing an error + * console.log('Client connection request identity: ', JSON.stringify(identity)); + * console.log('Client connection request payload: ', JSON.stringify(payload)); + * }); + * + * providerBus.register('topic', (payload, identity) => { + * // register a callback for a 'topic' to which clients can dispatch an action + * console.log('Action dispatched by client: ', JSON.stringify(identity)); + * console.log('Payload sent in dispatch: ', JSON.stringify(payload)); + * return { + * echo: payload + * }; + * }); + * })(); + * ``` + */ + async create(channelName, options) { + if (!channelName) { + throw new Error('Please provide a channelName to create a channel'); + } + const { payload: { data: providerIdentity } } = await this.wire.sendAction('create-channel', { channelName }); + const channel = __classPrivateFieldGet$6(this, _Channel_connectionManager, "f").createProvider(options, providerIdentity); + // TODO: fix typing (internal) + // @ts-expect-error + this.on('client-disconnected', (eventPayload) => { + if (eventPayload.channelName === channelName) { + provider_1.ChannelProvider.handleClientDisconnection(channel, eventPayload); + } + }); + return channel; + } +} +channel$1.Channel = Channel; +_Channel_connectionManager = new WeakMap(), _Channel_internalEmitter = new WeakMap(), _Channel_readyToConnect = new WeakMap(); + +Object.defineProperty(interappbus, "__esModule", { value: true }); +interappbus.InterAppPayload = interappbus.InterApplicationBus = void 0; +/** + * Entry point for the OpenFin `InterApplicationBus` API (`fin.InterApplicationBus`). + * + * * {@link InterApplicationBus} contains static members of the `InterApplicationBus` API, accessible through `fin.InterApplicationBus`. + * + * @packageDocumentation + */ +const events_1$4 = require$$0; +const base_1$d = base; +const ref_counter_1 = refCounter; +const index_1$2 = channel$1; +const validate_1$3 = validate; +/** + * A messaging bus that allows for pub/sub messaging between different applications. + * + */ +class InterApplicationBus extends base_1$d.Base { + /** + * @internal + */ + constructor(wire) { + super(wire); + this.events = { + subscriberAdded: 'subscriber-added', + subscriberRemoved: 'subscriber-removed' + }; + this.refCounter = new ref_counter_1.RefCounter(); + this.Channel = new index_1$2.Channel(wire); + this.emitter = new events_1$4.EventEmitter(); + wire.registerMessageHandler(this.onmessage.bind(this)); + this.on = this.emitter.on.bind(this.emitter); + this.removeAllListeners = this.emitter.removeAllListeners.bind(this.emitter); + } + /** + * Publishes a message to all applications running on OpenFin Runtime that + * are subscribed to the specified topic. + * @param topic The topic on which the message is sent + * @param message The message to be published. Can be either a primitive + * data type (string, number, or boolean) or composite data type (object, array) + * that is composed of other primitive or composite data types + * + * @example + * ```js + * fin.InterApplicationBus.publish('topic', 'hello').then(() => console.log('Published')).catch(err => console.log(err)); + * ``` + */ + async publish(topic, message) { + await this.wire.sendAction('publish-message', { + topic, + message, + sourceWindowName: this.me.name + }); + } + /** + * Sends a message to a specific application on a specific topic. + * @param destination The identity of the application to which the message is sent + * @param topic The topic on which the message is sent + * @param message The message to be sent. Can be either a primitive data + * type (string, number, or boolean) or composite data type (object, array) that + * is composed of other primitive or composite data types + * + * @example + * ```js + * fin.InterApplicationBus.send(fin.me, 'topic', 'Hello there!').then(() => console.log('Message sent')).catch(err => console.log(err)); + * ``` + */ + async send(destination, topic, message) { + const errorMsg = (0, validate_1$3.validateIdentity)(destination); + if (errorMsg) { + throw new Error(errorMsg); + } + await this.wire.sendAction('send-message', { + destinationUuid: destination.uuid, + destinationWindowName: destination.name, + topic, + message, + sourceWindowName: this.me.name + }); + } + /** + * Subscribes to messages from the specified application on the specified topic. + * @param source This object is described in the Identity in the typedef + * @param topic The topic on which the message is sent + * @param listener A function that is called when a message has + * been received. It is passed the message, uuid and name of the sending application. + * The message can be either a primitive data type (string, number, or boolean) or + * composite data type (object, array) that is composed of other primitive or composite + * data types + * + * @example + * ```js + * // subscribe to a specified application + * fin.InterApplicationBus.subscribe(fin.me, 'topic', sub_msg => console.log(sub_msg)).then(() => console.log('Subscribed to the specified application')).catch(err => console.log(err)); + * + * // subscribe to wildcard + * fin.InterApplicationBus.subscribe({ uuid: '*' }, 'topic', sub_msg => console.log(sub_msg)).then(() => console.log('Subscribed to *')).catch(err => console.log(err)); + * ``` + */ + subscribe(source, topic, listener) { + const subKey = this.createSubscriptionKey(source.uuid, source.name || '*', topic); + const sendSubscription = async () => { + await this.wire.sendAction('subscribe', { + sourceUuid: source.uuid, + sourceWindowName: source.name || '*', + topic, + destinationWindowName: this.me.name + }); + }; + const alreadySubscribed = () => { + return Promise.resolve(); + }; + this.emitter.on(subKey, listener); + return this.refCounter.actOnFirst(subKey, sendSubscription, alreadySubscribed); + } + /** + * Unsubscribes to messages from the specified application on the specified topic. + * + * @remarks If you are listening to all apps on a topic, (i.e you passed `{ uuid:'*' }` to the subscribe function) + * then you need to pass `{ uuid:'*' }` to unsubscribe as well. If you are listening to a specific application, + * (i.e you passed `{ uuid:'some_app' }` to the subscribe function) then you need to provide the same identifier to + * unsubscribe, unsubscribing to `*` on that same topic will not unhook your initial listener otherwise. + * + * @param source This object is described in the Identity in the typedef + * @param topic The topic on which the message is sent + * @param listener A callback previously registered with subscribe() + * + * @example + * ```js + * const listener = console.log; + * + * // If any application publishes a message on topic `foo`, our listener will be called. + * await fin.InterApplicationBus.subscribe({ uuid:'*' }, 'foo', listener) + * + * // When you want to unsubscribe, you need to specify the uuid of the app you'd like to + * // unsubscribe from (or `*`) and provide the same function you gave the subscribe function + * await fin.InterApplicationBus.unsubscribe({ uuid:'*' }, 'foo', listener) + * ``` + */ + unsubscribe(source, topic, listener) { + const sourceWindowName = source.name || '*'; + const subKey = this.createSubscriptionKey(source.uuid, sourceWindowName, topic); + const sendUnsubscription = async () => { + await this.wire.sendAction('unsubscribe', { + sourceUuid: source.uuid, + sourceWindowName, + topic, + destinationWindowName: this.me.name + }); + }; + const dontSendUnsubscription = () => { + return new Promise((r) => r).then(() => undefined); + }; + this.emitter.removeListener(subKey, listener); + return this.refCounter.actOnLast(subKey, sendUnsubscription, dontSendUnsubscription); + } + processMessage(message) { + const { payload: { message: payloadMessage, sourceWindowName, sourceUuid, topic } } = message; + const keys = [ + this.createSubscriptionKey(sourceUuid, sourceWindowName, topic), + this.createSubscriptionKey(sourceUuid, '*', topic), + this.createSubscriptionKey('*', '*', topic) + ]; + const idOfSender = { uuid: sourceUuid, name: sourceWindowName }; + keys.forEach((key) => { + this.emitter.emit(key, payloadMessage, idOfSender); + }); + } + emitSubscriverEvent(type, message) { + const { payload: { targetName: name, uuid, topic } } = message; + const payload = { name, uuid, topic }; + this.emitter.emit(type, payload); + } + // eslint-disable-next-line class-methods-use-this + createSubscriptionKey(uuid, name, topic) { + const n = name || '*'; + if (!(uuid && n && topic)) { + throw new Error('Missing uuid, name, or topic string'); + } + return createKey(uuid, n, topic); + } + onmessage(message) { + const { action } = message; + switch (action) { + case 'process-message': + this.processMessage(message); + break; + case this.events.subscriberAdded: + this.emitSubscriverEvent(this.events.subscriberAdded, message); + break; + case this.events.subscriberRemoved: + this.emitSubscriverEvent(this.events.subscriberRemoved, message); + break; + } + return true; + } +} +interappbus.InterApplicationBus = InterApplicationBus; +/** + * @internal + */ +class InterAppPayload { +} +interappbus.InterAppPayload = InterAppPayload; +function createKey(...toHash) { + return toHash + .map((item) => { + return Buffer.from(`${item}`).toString('base64'); + }) + .join('/'); +} + +var clipboard = {}; + +/** + * Entry point for the OpenFin `Clipboard` API (`fin.Clipboard`). + * + * * {@link Clipboard} contains static members of the `Clipboard` API, accessible through `fin.Clipboard`. + * + * @packageDocumentation + */ +Object.defineProperty(clipboard, "__esModule", { value: true }); +clipboard.Clipboard = void 0; +const base_1$c = base; +/** + * The Clipboard API allows reading and writing to the clipboard in multiple formats. + * + */ +class Clipboard extends base_1$c.Base { + /** + * Writes data into the clipboard as plain text + * @param writeObj The object for writing data into the clipboard + * + * @example + * ```js + * fin.Clipboard.writeText({ + * data: 'hello, world' + * }).then(() => console.log('Text On clipboard')).catch(err => console.log(err)); + * ``` + */ + async writeText(writeObj) { + await this.wire.sendAction('clipboard-write-text', writeObj); + } + /** + * Read the content of the clipboard as plain text + * @param type Clipboard Type defaults to 'clipboard', use 'selection' for linux + * + * @example + * ```js + * fin.Clipboard.readText().then(text => console.log(text)).catch(err => console.log(err)); + * ``` + */ + async readText(type) { + // NOTE: When we start supporting linux, we could detect the OS and choose 'selection' automatically for the user + const { payload } = await this.wire.sendAction('clipboard-read-text', { type }); + return payload.data; + } + /** + * Writes data into the clipboard as an Image + * @param writeRequest The object to write an image to the clipboard + * + * @example + * ```js + * fin.Clipboard.writeImage({ + * // raw base64 string, or dataURL of either data:image/png or data:image/jpeg type + * image: '...' + * }).then(() => console.log('Image written to clipboard')).catch(err => console.log(err)); + * ``` + */ + async writeImage(writeRequest) { + await this.wire.sendAction('clipboard-write-image', writeRequest); + } + /** + * Read the content of the clipboard as a base64 string or a dataURL based on the input parameter 'format', defaults to 'dataURL' + * @param readRequest Clipboard Read Image request with formatting options + * + * @example + * ```js + * // see TS type: OpenFin.ImageFormatOptions + * + * const pngOrDataURLOrBmpOptions = { + * format: 'png', // can be: 'png' | 'dataURL' | 'bmp' + * }; + * + * const jpgOptions = { + * format: 'jpg', + * quality: 80 // optional, if omitted defaults to 100 + * }; + * + * fin.Clipboard.readImage(pngOrDataURLOrBmpOptions) + * .then(image => console.log('Image read from clipboard as PNG, DataURL or BMP', image)) + * .catch(err => console.log(err)); + * + * fin.Clipboard.readImage(jpgOptions) + * .then(image => console.log('Image read from clipboard as JPG', image)) + * .catch(err => console.log(err)); + * + * // defaults to {format: 'dataURL'} + * fin.Clipboard.readImage() + * .then(image => console.log('Image read from clipboard as DataURL', image)) + * .catch(err => console.log(err)); + * + * ``` + */ + async readImage(readRequest = { format: 'dataURL' }) { + const { payload } = await this.wire.sendAction('clipboard-read-image', readRequest); + return payload.data; + } + /** + * Writes data into the clipboard as Html + * @param writeObj The object for writing data into the clipboard + * + * @example + * ```js + * fin.Clipboard.writeHtml({ + * data: '

Hello, World!

' + * }).then(() => console.log('HTML On clipboard')).catch(err => console.log(err)); + * ``` + */ + async writeHtml(writeObj) { + await this.wire.sendAction('clipboard-write-html', writeObj); + } + /** + * Read the content of the clipboard as Html + * @param type Clipboard Type defaults to 'clipboard', use 'selection' for linux + * + * @example + * ```js + * fin.Clipboard.readHtml().then(html => console.log(html)).catch(err => console.log(err)); + * ``` + */ + async readHtml(type) { + const { payload } = await this.wire.sendAction('clipboard-read-html', { type }); + return payload.data; + } + /** + * Writes data into the clipboard as Rtf + * @param writeObj The object for writing data into the clipboard + * + * @example + * ```js + * fin.Clipboard.writeRtf({ + * data: 'some text goes here' + * }).then(() => console.log('RTF On clipboard')).catch(err => console.log(err)); + * ``` + */ + async writeRtf(writeObj) { + await this.wire.sendAction('clipboard-write-rtf', writeObj); + } + /** + * Read the content of the clipboard as Rtf + * @param type Clipboard Type defaults to 'clipboard', use 'selection' for linux + * + * @example + * + * ```js + * const writeObj = { + * data: 'some text goes here' + * }; + * async function readRtf() { + * await fin.Clipboard.writeRtf(writeObj); + * return await fin.Clipboard.readRtf(); + * } + * readRtf().then(rtf => console.log(rtf)).catch(err => console.log(err)); + * ``` + */ + async readRtf(type) { + const { payload } = await this.wire.sendAction('clipboard-read-rtf', { type }); + return payload.data; + } + /** + * Writes data into the clipboard + * @param writeObj The object for writing data into the clipboard + * + * @example + * ```js + * fin.Clipboard.write({ + * data: { + * text: 'a', + * html: 'b', + * rtf: 'c', + * // Can be either a base64 string, or a DataURL string. If using DataURL, the + * // supported formats are `data:image/png[;base64],` and `data:image/jpeg[;base64],`. + * // Using other image/ DataURLs will throw an Error. + * image: '...' + * } + * }).then(() => console.log('write data into clipboard')).catch(err => console.log(err)); + * ``` + */ + async write(writeObj) { + await this.wire.sendAction('clipboard-write', writeObj); + } + /** + * Reads available formats for the clipboard type + * @param type Clipboard Type defaults to 'clipboard', use 'selection' for linux + * + * @example + * ```js + * fin.Clipboard.getAvailableFormats().then(formats => console.log(formats)).catch(err => console.log(err)); + * ``` + */ + async getAvailableFormats(type) { + const { payload } = await this.wire.sendAction('clipboard-read-formats', { type }); + return payload.data; + } +} +clipboard.Clipboard = Clipboard; + +var externalApplication = {}; + +var Factory$5 = {}; + +var Instance$4 = {}; + +Object.defineProperty(Instance$4, "__esModule", { value: true }); +Instance$4.ExternalApplication = void 0; +/* eslint-disable import/prefer-default-export */ +const base_1$b = base; +/** + * An ExternalApplication object representing native language adapter connections to the runtime. Allows + * the developer to listen to {@link OpenFin.ExternalApplicationEvents external application events}. + * Discovery of connections is provided by {@link System.System.getAllExternalApplications getAllExternalApplications}. + * + * Processes that can be wrapped as `ExternalApplication`s include the following: + * - Processes which have connected to an OpenFin runtime via an adapter + * - Processes started via `System.launchExternalApplication` + * - Processes monitored via `System.monitorExternalProcess` + */ +class ExternalApplication extends base_1$b.EmitterBase { + /** + * @internal + */ + constructor(wire, identity) { + super(wire, 'external-application', identity.uuid); + this.identity = identity; + } + /** + * Retrieves information about the external application. + * + * @example + * ```js + * async function getInfo() { + * const extApp = await fin.ExternalApplication.wrap('javaApp-uuid'); + * return await extApp.getInfo(); + * } + * getInfo().then(info => console.log(info)).catch(err => console.log(err)); + * ``` + */ + getInfo() { + return this.wire.sendAction('get-external-application-info', this.identity).then(({ payload }) => payload.data); + } +} +Instance$4.ExternalApplication = ExternalApplication; + +Object.defineProperty(Factory$5, "__esModule", { value: true }); +Factory$5.ExternalApplicationModule = void 0; +const base_1$a = base; +const Instance_1$4 = Instance$4; +/** + * Static namespace for OpenFin API methods that interact with the {@link ExternalApplication} class, available under `fin.ExternalApplication`. + */ +class ExternalApplicationModule extends base_1$a.Base { + /** + * Asynchronously returns an External Application object that represents an external application. + *
It is possible to wrap a process that does not yet exist, (for example, to listen for startup-related events) + * provided its uuid is already known. + * @param uuid The UUID of the external application to be wrapped + * + * @example + * ```js + * fin.ExternalApplication.wrap('javaApp-uuid'); + * .then(extApp => console.log('wrapped external application')) + * .catch(err => console.log(err)); + * ``` + */ + wrap(uuid) { + this.wire.sendAction('external-application-wrap').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return Promise.resolve(new Instance_1$4.ExternalApplication(this.wire, { uuid })); + } + /** + * Synchronously returns an External Application object that represents an external application. + *
It is possible to wrap a process that does not yet exist, (for example, to listen for startup-related events) + * provided its uuid is already known. + * @param uuid The UUID of the external application to be wrapped + * + * @example + * ```js + * const extApp = fin.ExternalApplication.wrapSync('javaApp-uuid'); + * const info = await extApp.getInfo(); + * console.log(info); + * ``` + */ + wrapSync(uuid) { + this.wire.sendAction('external-application-wrap-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return new Instance_1$4.ExternalApplication(this.wire, { uuid }); + } +} +Factory$5.ExternalApplicationModule = ExternalApplicationModule; + +(function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + /** + * Entry points for the OpenFin `ExternalApplication` API (`fin.ExternalApplication`). + * + * * {@link ExternalApplicationModule} contains static members of the `ExternalApplication` type, accessible through `fin.ExternalApplication`. + * * {@link ExternalApplication} describes an instance of an OpenFin ExternalApplication, e.g. as returned by `fin.ExternalApplication.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * @packageDocumentation + */ + __exportStar(Factory$5, exports); + __exportStar(Instance$4, exports); +} (externalApplication)); + +var frame = {}; + +var Factory$4 = {}; + +var Instance$3 = {}; + +Object.defineProperty(Instance$3, "__esModule", { value: true }); +Instance$3._Frame = void 0; +/* eslint-disable import/prefer-default-export */ +const base_1$9 = base; +/** + * An iframe represents an embedded HTML page within a parent HTML page. Because this embedded page + * has its own DOM and global JS context (which may or may not be linked to that of the parent depending + * on if it is considered out of the root domain or not), it represents a unique endpoint as an OpenFin + * connection. Iframes may be generated dynamically, or be present on initial page load and each non-CORS + * iframe has the OpenFin API injected by default. It is possible to opt into cross-origin iframes having + * the API by setting api.iframe.crossOriginInjection to true in a window's options. To block all iframes + * from getting the API injected you can set api.frame.sameOriginInjection + * to false ({@link OpenFin.WindowCreationOptions see Window Options}). + * + * To be able to directly address this context for eventing and messaging purposes, it needs a + * unique uuid name pairing. For OpenFin applications and windows this is provided via a configuration + * object in the form of a manifest URL or options object, but there is no configuration object for iframes. + * Just as a call to window.open outside of our Window API returns a new window with a random GUID assigned + * for the name, each iframe that has the API injected will be assigned a GUID as its name, the UUID will be + * the same as the parent window's. + * + * The fin.Frame namespace represents a way to interact with `iframes` and facilitates the discovery of current context + * (iframe or main window) as well as the ability to listen for {@link OpenFin.FrameEvents frame-specific events}. + */ +class _Frame extends base_1$9.EmitterBase { + /** + * @internal + */ + constructor(wire, identity) { + super(wire, 'frame', identity.uuid, identity.name); + this.identity = identity; + } + /** + * Returns a frame info object for the represented frame. + * + * @example + * ```js + * async function getInfo() { + * const frm = await fin.Frame.getCurrent(); + * return await frm.getInfo(); + * } + * getInfo().then(info => console.log(info)).catch(err => console.log(err)); + * ``` + */ + getInfo() { + return this.wire.sendAction('get-frame-info', this.identity).then(({ payload }) => payload.data); + } + /** + * Returns a frame info object representing the window that the referenced iframe is + * currently embedded in. + * + * @remarks If the frame is embedded in a view, this will return an invalid stub with empty fields. + * + * @example + * ```js + * async function getParentWindow() { + * const frm = await fin.Frame.getCurrent(); + * return await frm.getParentWindow(); + * } + * getParentWindow().then(winInfo => console.log(winInfo)).catch(err => console.log(err)); + * ``` + */ + getParentWindow() { + return this.wire.sendAction('get-parent-window', this.identity).then(({ payload }) => payload.data); + } +} +Instance$3._Frame = _Frame; + +Object.defineProperty(Factory$4, "__esModule", { value: true }); +Factory$4._FrameModule = void 0; +const base_1$8 = base; +const validate_1$2 = validate; +const Instance_1$3 = Instance$3; +/** + * Static namespace for OpenFin API methods that interact with the {@link _Frame} class, available under `fin.Frame`. + */ +class _FrameModule extends base_1$8.Base { + /** + * Asynchronously returns an API handle for the given Frame identity. + * + * @remarks Wrapping a Frame identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for a Frame throughout its entire lifecycle. + * + * @example + * ```js + * fin.Frame.wrap({ uuid: 'testFrame', name: 'testFrame' }) + * .then(frm => console.log('wrapped frame')) + * .catch(err => console.log(err)); + * ``` + */ + async wrap(identity) { + this.wire.sendAction('frame-wrap').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1$2.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new Instance_1$3._Frame(this.wire, identity); + } + /** + * Synchronously returns an API handle for the given Frame identity. + * + * @remarks Wrapping a Frame identity that does not yet exist will *not* throw an error, and instead + * returns a stub object that cannot yet perform rendering tasks. This can be useful for plumbing eventing + * for a Frame throughout its entire lifecycle. + * + * @example + * ```js + * const frm = fin.Frame.wrapSync({ uuid: 'testFrame', name: 'testFrame' }); + * const info = await frm.getInfo(); + * console.log(info); + * ``` + */ + wrapSync(identity) { + this.wire.sendAction('frame-wrap-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const errorMsg = (0, validate_1$2.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + return new Instance_1$3._Frame(this.wire, identity); + } + /** + * Asynchronously returns a reference to the current frame + * + * @example + * ```js + * fin.Frame.getCurrent() + * .then(frm => console.log('current frame')) + * .catch(err => console.log(err)); + * ``` + */ + getCurrent() { + this.wire.sendAction('frame-get-current').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return Promise.resolve(new Instance_1$3._Frame(this.wire, this.wire.environment.getCurrentEntityIdentity())); + } + /** + * Synchronously returns a reference to the current frame + * + * @example + * ```js + * const frm = fin.Frame.getCurrentSync(); + * const info = await frm.getInfo(); + * console.log(info); + * ``` + */ + getCurrentSync() { + this.wire.sendAction('frame-get-current-sync').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return new Instance_1$3._Frame(this.wire, this.wire.environment.getCurrentEntityIdentity()); + } +} +Factory$4._FrameModule = _FrameModule; + +(function (exports) { + /** + * Entry points for the OpenFin `Frame` API (`fin.Frame`). + * + * * {@link _FrameModule} contains static members of the `Frame` API, accessible through `fin.Frame`. + * * {@link _Frame} describes an instance of an OpenFin Frame, e.g. as returned by `fin.Frame.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * Underscore prefixing of OpenFin types that alias DOM entities will be fixed in a future version. + * + * @packageDocumentation + */ + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(Factory$4, exports); + __exportStar(Instance$3, exports); +} (frame)); + +var globalHotkey = {}; + +Object.defineProperty(globalHotkey, "__esModule", { value: true }); +globalHotkey.GlobalHotkey = void 0; +const base_1$7 = base; +/** + * The GlobalHotkey module can register/unregister a global hotkeys. + * + */ +class GlobalHotkey extends base_1$7.EmitterBase { + /** + * @internal + */ + constructor(wire) { + super(wire, 'global-hotkey'); + } + /** + * Registers a global hotkey with the operating system. + * @param hotkey a hotkey string + * @param listener called when the registered hotkey is pressed by the user. + * @throws If the `hotkey` is reserved, see list below. + * @throws if the `hotkey` is already registered by another application. + * + * @remarks The `hotkey` parameter expects an electron compatible [accelerator](https://github.com/electron/electron/blob/master/docs/api/accelerator.md) and the `listener` will be called if the `hotkey` is pressed by the user. + * If successfull, the hotkey will be 'claimed' by the application, meaning that this register call can be called multiple times from within the same application but will fail if another application has registered the hotkey. + *
The register call will fail if given any of these reserved Hotkeys: + * * `CommandOrControl+0` + * * `CommandOrControl+=` + * * `CommandOrControl+Plus` + * * `CommandOrControl+-` + * * `CommandOrControl+_` + * * `CommandOrControl+Shift+I` + * * `F5` + * * `CommandOrControl+R` + * * `Shift+F5` + * * `CommandOrControl+Shift+R` + * + * Raises the `registered` event. + * + * @example + * ```js + * const hotkey = 'CommandOrControl+X'; + * + * fin.GlobalHotkey.register(hotkey, () => { + * console.log(`${hotkey} pressed`); + * }) + * .then(() => { + * console.log('Success'); + * }) + * .catch(err => { + * console.log('Error registering the hotkey', err); + * }); + * ``` + */ + async register(hotkey, listener) { + // TODO: fix typing (hotkey events are not typed) + // @ts-expect-error + await this.on(hotkey, listener); + await this.wire.sendAction('global-hotkey-register', { hotkey }); + return undefined; + } + /** + * Unregisters a global hotkey with the operating system. + * @param hotkey a hotkey string + * + * @remarks This method will unregister all existing registrations of the hotkey within the application. + * Raises the `unregistered` event. + * + * @example + * ```js + * const hotkey = 'CommandOrControl+X'; + * + * fin.GlobalHotkey.unregister(hotkey) + * .then(() => { + * console.log('Success'); + * }) + * .catch(err => { + * console.log('Error unregistering the hotkey', err); + * }); + * ``` + */ + async unregister(hotkey) { + // TODO: fix typing (hotkey events are not typed) + // @ts-expect-error + await this.removeAllListeners(hotkey); + await this.wire.sendAction('global-hotkey-unregister', { hotkey }); + return undefined; + } + /** + * Unregisters all global hotkeys for the current application. + * + * @remarks Raises the `unregistered` event for each hotkey unregistered. + * + * @example + * ```js + * fin.GlobalHotkey.unregisterAll() + * .then(() => { + * console.log('Success'); + * }) + * .catch(err => { + * console.log('Error unregistering all hotkeys for this application', err); + * }); + * ``` + */ + async unregisterAll() { + await Promise.all(this.eventNames() + .filter((name) => !(name === 'registered' || name === 'unregistered')) + // TODO: fix typing (hotkey events are not typed) + // @ts-expect-error + .map((name) => this.removeAllListeners(name))); + await this.wire.sendAction('global-hotkey-unregister-all', {}); + return undefined; + } + /** + * Checks if a given hotkey has been registered by an application within the current runtime. + * @param hotkey a hotkey string + * + * @example + * ```js + * const hotkey = 'CommandOrControl+X'; + * + * fin.GlobalHotkey.isRegistered(hotkey) + * .then((registered) => { + * console.log(`hotkey ${hotkey} is registered ? ${registered}`); + * }) + * .catch(err => { + * console.log('Error unregistering the hotkey', err); + * }); + * ``` + */ + async isRegistered(hotkey) { + const { payload: { data } } = await this.wire.sendAction('global-hotkey-is-registered', { hotkey }); + return data; + } +} +globalHotkey.GlobalHotkey = GlobalHotkey; + +var platform = {}; + +var Factory$3 = {}; + +var Instance$2 = {}; + +var __classPrivateFieldGet$5 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _Platform_connectToProvider; +Object.defineProperty(Instance$2, "__esModule", { value: true }); +Instance$2.Platform = void 0; +/* eslint-disable import/prefer-default-export, no-undef */ +const base_1$6 = base; +const validate_1$1 = validate; +// Reuse clients to avoid overwriting already-registered client in provider +const clientMap = new Map(); +/** Manages the life cycle of windows and views in the application. + * + * Enables taking snapshots of itself and applying them to restore a previous configuration + * as well as listen to {@link OpenFin.PlatformEvents platform events}. + */ +class Platform extends base_1$6.EmitterBase { + /** + * @internal + */ + // eslint-disable-next-line no-shadow + constructor(identity, channel) { + // we piggyback off of application event emitter because from the core's perspective platform is just an app. + super(channel.wire, 'application', identity.uuid); + this.getClient = (identity) => { + this.wire.sendAction('platform-get-client', this.identity).catch((e) => { + // don't expose + }); + const target = identity || this.identity; + const { uuid } = target; + if (!clientMap.has(uuid)) { + const clientPromise = __classPrivateFieldGet$5(this, _Platform_connectToProvider, "f").call(this, uuid); + clientMap.set(uuid, clientPromise); + } + // we set it above + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return clientMap.get(uuid); + }; + _Platform_connectToProvider.set(this, async (uuid) => { + try { + const channelName = `custom-frame-${uuid}`; + const client = await this._channel.connect(channelName, { wait: false }); + client.onDisconnection(() => { + clientMap.delete(uuid); + }); + return client; + } + catch (e) { + clientMap.delete(uuid); + throw new Error('The targeted Platform is not currently running. Listen for application-started event for the given Uuid.'); + } + }); + /** + * @deprecated (renamed) + * @ignore + */ + this.launchLegacyManifest = this.launchContentManifest; + const errorMsg = (0, validate_1$1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + this._channel = channel; + this.identity = { uuid: identity.uuid }; + this.Layout = this.fin.Platform.Layout; + this.Application = this.fin.Application.wrapSync(this.identity); + } + /** + * Creates a new view and attaches it to a specified target window. + * @param viewOptions View creation options + * @param target The window to which the new view is to be attached. If no target, create a view in a new window. + * @param targetView If provided, the new view will be added to the same tabstrip as targetView. + * + * @remarks If the view already exists, will reparent the view to the new target. You do not need to set a name for a View. + * Views that are not passed a name get a randomly generated one. + * + * @example + * ```js + * let windowIdentity; + * if (fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const platform = fin.Platform.getCurrentSync(); + * + * platform.createView({ + * name: 'test_view', + * url: 'https://developers.openfin.co/docs/platform-api' + * }, windowIdentity).then(console.log); + * ``` + * + * Reparenting a view: + * ```js + * let windowIdentity; + * if (fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * let platform = fin.Platform.getCurrentSync(); + * let viewOptions = { + * name: 'example_view', + * url: 'https://example.com' + * }; + * // a new view will now show in the current window + * await platform.createView(viewOptions, windowIdentity); + * + * const view = fin.View.wrapSync({ uuid: windowIdentity.uuid, name: 'yahoo_view' }); + * // reparent `example_view` when a view in the new window is shown + * view.on('shown', async () => { + * let viewIdentity = { uuid: windowIdentity.uuid, name: 'example_view'}; + * let target = {uuid: windowIdentity.uuid, name: 'test_win'}; + * platform.createView(viewOptions, target); + * }); + * + * // create a new window + * await platform.createWindow({ + * name: "test_win", + * layout: { + * content: [ + * { + * type: 'stack', + * content: [ + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'yahoo_view', + * url: 'https://yahoo.com' + * } + * } + * ] + * } + * ] + * } + * }).then(console.log); + * ``` + */ + async createView(viewOptions, target, targetView) { + this.wire.sendAction('platform-create-view', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + const response = await client.dispatch('create-view', { + target, + opts: viewOptions, + targetView + }); + if (!response || (0, validate_1$1.validateIdentity)(response.identity)) { + throw new Error(`When overwriting the createView call, please return an object that has a valid 'identity' property: ${JSON.stringify(response)}`); + } + return this.fin.View.wrapSync(response.identity); + } + /** + * Creates a new Window. + * @param options Window creation options + * + * @remarks There are two Window types at your disposal while using OpenFin Platforms - Default Window and Custom Window. + * + * The Default Window uses the standard OpenFin Window UI. It contains the standard close, maximize and minimize buttons, + * and will automatically render the Window's layout if one is specified. + * + * For deeper customization, you can bring your own Window code into a Platform. This is called a Custom Window. + * + * @example + * + * + * The example below will create a Default Window which uses OpenFin default Window UI.
+ * The Window contains two Views in a stack Layout: + * + * ```js + * const platform = fin.Platform.getCurrentSync(); + * platform.createWindow({ + * layout: { + * content: [ + * { + * type: 'stack', + * content: [ + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'test_view_1', + * url: 'https://cdn.openfin.co/docs/javascript/canary/Platform.html' + * } + * }, + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'test_view_2', + * url: 'https://cdn.openfin.co/docs/javascript/canary/Platform.html' + * } + * } + * ] + * } + * ] + * } + * }).then(console.log); + * ``` + * The Default Window's design can be customized by specifying the `stylesheetUrl` property in the manifest: + * + * ```json + * { + * platform: { + * defaultWindowOptions: { + * stylesheetUrl: 'some-url.css', + * ... + * } + * } + * } + * ``` + * For a list of common Layout CSS classes you can override in your custom stylesheet, see Useful Layout CSS Classes + ** + * To specify a Platform Custom Window, provide a `url` property when creating a Window. + * If you intend to render a Layout in your Custom Window, you must also specify an `HTMLElement` that the Layout will inject into and set its `id` property to `"layout-container"`. + * + * The example below will create a Platform Custom Window: + * + * ```js + * // in an OpenFin app: + * const platform = fin.Platform.getCurrentSync(); + * const windowConfig = + * { + * url: "https://www.my-domain.com/my-custom-window.html", // here we point to where the Custom Frame is hosted. + * layout: { + * content: [ + * { + * type: "stack", + * content: [ + * { + * type: "component", + * componentName: "view", + * componentState: { + * name: "app #1", + * url: "https://cdn.openfin.co/docs/javascript/canary/Platform.html" + * } + * }, + * { + * type: "component", + * componentName: "view", + * componentState: { + * name: "app #2", + * url: "https://cdn.openfin.co/docs/javascript/canary/Platform.html" + * } + * } + * ] + * } + * ] + * } + * }; + * platform.createWindow(windowConfig); + * ``` + * + * Here's an example of a minimalist Custom Platform Window implementation: + * ```html + * + * + * + * + * + * + * + *
+ *
+ *
+ *
This is a custom frame!
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * + *
+ * + * + * ``` + * Your Custom Window can use in-domain resources for further customization (such as CSS, scripts, etc.).
+ * For a list of common Layout CSS classes you can override in your stylesheet, see Useful Layout CSS Classes + * + * The example above will require the `body` element to have `height: 100%;` set in order to render the layout correctly. + */ + async createWindow(options) { + this.wire.sendAction('platform-create-window', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + if (!options.reason) { + options.reason = 'api-call'; + } + const response = await client.dispatch('create-view-container', options); + if (!response || (0, validate_1$1.validateIdentity)(response.identity)) { + throw new Error(`When overwriting the createWindow call, please return an object that has a valid 'identity' property: ${JSON.stringify(response)}`); + } + const { identity } = response; + const res = this.fin.Window.wrapSync(identity); + // we add the identity at the top level for backwards compatibility. + res.name = identity.name; + res.uuid = identity.uuid; + return res; + } + /** + * Closes current platform, all its windows, and their views. + * + * @example + * ```js + * const platform = await fin.Platform.getCurrent(); + * platform.quit(); + * // All windows/views in current layout platform will close and platform will shut down + * ``` + */ + async quit() { + this.wire.sendAction('platform-quit', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + return client.dispatch('quit'); + } + /** + * Closes a specified view in a target window. + * @param viewIdentity View identity + * + * @example + * ```js + * let windowIdentity; + * if (fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const viewOptions = { + * name: 'test_view', + * url: 'https://example.com' + * }; + * + * function sleep(ms) { + * return new Promise(resolve => setTimeout(resolve, ms)); + * } + * + * const platform = await fin.Platform.getCurrent(); + * + * await platform.createView(viewOptions, windowIdentity); + * // a new view will now show in the current window + * + * await sleep(5000); + * + * const viewIdentity = { uuid: windowIdentity.uuid, name: 'test_view'}; + * platform.closeView(viewIdentity); + * // the view will now close + * ``` + */ + async closeView(viewIdentity) { + this.wire.sendAction('platform-close-view', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + await client.dispatch('close-view', { + view: viewIdentity + }); + } + /** + * ***DEPRECATED - please use {@link Platform.createView Platform.createView}.*** + * Reparents a specified view in a new target window. + * @param viewIdentity View identity + * @param target new owner window identity + * + */ + async reparentView(viewIdentity, target) { + // eslint-disable-next-line no-console + console.warn('Platform.reparentView has been deprecated, please use Platform.createView'); + this.wire.sendAction('platform-reparent-view', this.identity).catch((e) => { + // don't expose + }); + const normalizedViewIdentity = { + ...viewIdentity, + uuid: viewIdentity.uuid ?? this.identity.uuid + }; + const view = await this.fin.View.wrap(normalizedViewIdentity); + const viewOptions = await view.getOptions(); + return this.createView(viewOptions, target); + } + /** + * Returns a snapshot of the platform in its current state. You can pass the returning object to + * [Platform.applySnapshot]{@link Platform#applySnapshot} to launch it. + * + * @remarks The snapshot will include details such as an [ISO format](https://en.wikipedia.org/wiki/ISO_8601) + * timestamp of when the snapshot was taken, OpenFin runtime version the platform is running on, monitor information + * and the list of currently running windows. + * + * @example + * ```js + * const platform = await fin.Platform.getCurrent(); + * const snapshot = await platform.getSnapshot(); + * ``` + */ + async getSnapshot() { + this.wire.sendAction('platform-get-snapshot', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + return client.dispatch('get-snapshot'); + } + /** + * **NOTE**: Internal use only. It is not recommended to manage the state of individual views. + * + * Returns a snapshot of a single view's options in its current state. + * + * Can be used to restore a view to a previous state. + * + * @param viewIdentity View identity + * + * @internal + * @experimental + * @remarks This slice of snapshot state is equivalent to what is stored as `componentState` for views + * when capturing platform state using [Platform.getSnapshot]{@link Platform#getSnapshot}. + * + * @example + * ```js + * const platform = await fin.Platform.getCurrent(); + * const url = 'https://google.com'; + * const view = await fin.View.create({ name: 'my-view', target: fin.me.identity, url }); + * + * await view.navigate(url); + * + * const viewState = await platform.getViewSnapshot(view.identity); + * + * console.log(viewState); + * ``` + */ + async getViewSnapshot(viewIdentity) { + const client = await this.getClient(); + return client.dispatch('get-view-snapshot', { viewIdentity }); + } + /** + * Adds a snapshot to a running Platform. + * Requested snapshot must be a valid Snapshot object, or a url or filepath to such an object. + * + * Can optionally close existing windows and overwrite current platform state with that of a snapshot. + * + * The function accepts either a snapshot taken using {@link Platform#getSnapshot getSnapshot}, + * or a url or filepath to a snapshot JSON object. + * @param requestedSnapshot Snapshot to apply, or a url or filepath. + * @param options Optional parameters to specify whether existing windows should be closed. + * + * @remarks Will create any windows and views that are not running but are passed in the snapshot object. Any View + * specified in the snapshot is assigned a randomly generated name to avoid collisions. + * + * @example + * ```js + * // Get a wrapped layout platform instance + * const platform = await fin.Platform.getCurrent(); + * + * const snapshot = { + * windows: [ + * { + * layout: { + * content: [ + * { + * type: 'stack', + * content: [ + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'component_X', + * url: 'https://www.openfin.co' + * } + * }, + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'component_Y', + * url: 'https://cdn.openfin.co/embed-web/chart.html' + * } + * } + * ] + * } + * ] + * } + * } + * ] + * } + * + * platform.applySnapshot(snapshot); + * ``` + * + * In place of a snapshot object, `applySnapshot` can take a url or filepath and to retrieve a JSON snapshot. + * + * ```js + * const platform = await fin.Platform.getCurrent(); + * platform.applySnapshot('https://api.jsonbin.io/b/5e6f903ef4331e681fc1231d/1'); + * ``` + * + * Optionally, `applySnapshot` can close existing windows and restore a Platform to a previously saved state. + * This is accomplished by providing `{ closeExistingWindows: true }` as an option. + * + * ```js + * // Get a wrapped layout platform instance + * const platform = await fin.Platform.getCurrent(); + * + * async function addViewToWindow(winId) { + * return await platform.createView({ + * name: 'test_view_3', + * url: 'https://openfin.co' + * }, winId); + * } + * + * async function createWindowWithTwoViews() { + * const platform = await fin.Platform.getCurrent(); + * + * return platform.createWindow({ + * layout: { + * content: [ + * { + * type: 'stack', + * content: [ + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'test_view_1', + * url: 'https://example.com' + * } + * }, + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'test_view_2', + * url: 'https://yahoo.com' + * } + * } + * ] + * } + * ] + * } + * }); + * } + * + * const win = await createWindowWithTwoViews(); + * // ... you will now see a new window with two views in it + * + * // we take a snapshot of the current state of the app, before changing it + * const snapshotOfInitialAppState = await platform.getSnapshot(); + * + * // now let's change the state of the app: + * await addViewToWindow(win.identity); + * // ... the window now has three views in it + * + * await platform.applySnapshot(snapshotOfInitialAppState, { closeExistingWindows: true }); + * // ... the window will revert to previous state, with just two views + * + * ``` + */ + async applySnapshot(requestedSnapshot, options) { + this.wire.sendAction('platform-apply-snapshot', this.identity).catch((e) => { + // don't expose + }); + const errMsg = 'Requested snapshot must be a valid Snapshot object, or a url or filepath to such an object.'; + let snapshot; + if (typeof requestedSnapshot === 'string') { + // Fetch and parse snapshot + try { + const response = await this._channel.wire.sendAction('get-application-manifest', { + manifestUrl: requestedSnapshot + }); + snapshot = response.payload.data; + } + catch (err) { + throw new Error(`${errMsg}: ${err}`); + } + } + else { + snapshot = requestedSnapshot; + } + if (!snapshot.windows) { + throw new Error(errMsg); + } + const client = await this.getClient(); + await client.dispatch('apply-snapshot', { + snapshot, + options + }); + return this; + } + /** + * Fetches a JSON manifest using the browser process and returns a Javascript object. + * Can be overwritten using {@link Platform.PlatformModule.init Platform.init}. + * @param manifestUrl The URL of the manifest to fetch. + * + * @remarks Can be overwritten using {@link Platform#init Platform.init}. + * + * @example + * + * ```js + * const platform = fin.Platform.getCurrentSync(); + * const manifest = await platform.fetchManifest('https://www.path-to-manifest.com/app.json'); + * console.log(manifest); + * ``` + */ + async fetchManifest(manifestUrl) { + const client = await this.getClient(); + return client.dispatch('platform-fetch-manifest', { manifestUrl }); + } + /** + * Retrieves a manifest by url and launches a legacy application manifest or snapshot into the platform. Returns a promise that + * resolves to the wrapped Platform. + * @param manifestUrl - The URL of the manifest that will be launched into the platform. If this app manifest + * contains a snapshot, that will be launched into the platform. If not, the application described in startup_app options + * will be launched into the platform. The applicable startup_app options will become {@link OpenFin.ViewCreationOptions View Options}. + * + * @remarks If the app manifest contains a snapshot, that will be launched into the platform. If not, the + * application described in startup_app options will be launched into the platform as a window with a single view. + * The applicable startup_app options will become View Options. + * + * @example + * ```js + * try { + * const platform = fin.Platform.getCurrentSync(); + * await platform.launchContentManifest('http://localhost:5555/app.json'); + * console.log(`content launched successfully into platform`); + * } catch(e) { + * console.error(e); + * } + * // For a local manifest file: + * try { + * const platform = fin.Platform.getCurrentSync(); + * platform.launchContentManifest('file:///C:/somefolder/app.json'); + * console.log(`content launched successfully into platform`); + * } catch(e) { + * console.error(e); + * } + * ``` + * @experimental + */ + async launchContentManifest(manifestUrl) { + this.wire.sendAction('platform-launch-content-manifest', this.identity).catch(() => { + // don't expose + }); + const client = await this.getClient(); + const manifest = await this.fetchManifest(manifestUrl); + client.dispatch('launch-into-platform', { manifest, manifestUrl }); + return this; + } + /** + * Set the context of a host window. The context will be available to the window itself, and to its child Views. It will be saved in any platform snapshots. + * It can be retrieved using {@link Platform#getWindowContext getWindowContext}. + * @param context - A field where serializable context data can be stored to be saved in platform snapshots. + * @param target - A target window or view may optionally be provided. If no target is provided, the update will be applied + * to the current window (if called from a Window) or the current host window (if called from a View). + * + * @remarks The context data must be serializable. This can only be called from a window or view that has been launched into a + * platform. + * This method can be called from the window itself, or from any child view. Context data is shared by all + * entities within a window. + * + * @example + * Setting own context: + * ```js + * const platform = fin.Platform.getCurrentSync(); + * const contextData = { + * security: 'STOCK', + * currentView: 'detailed' + * } + * + * await platform.setWindowContext(contextData); + * // Context of current window is now set to `contextData` + * ``` + * + * Setting the context of another window or view: + * ```js + * const platform = fin.Platform.getCurrentSync(); + * const contextData = { + * security: 'STOCK', + * currentView: 'detailed' + * } + * + * const windowOrViewIdentity = { uuid: fin.me.uuid, name: 'nameOfWindowOrView' }; + * await platform.setWindowContext(contextData, windowOrViewIdentity); + * // Context of the target window or view is now set to `contextData` + * ``` + * + * A view can listen to changes to its host window's context by listening to the `host-context-changed` event. + * This event will fire when a host window's context is updated or when the view is reparented to a new window: + * + * ```js + * // From a view + * const contextChangeHandler = ({ context }) => { + * console.log('Host window\'s context has changed. New context data:', context); + * // react to new context data here + * } + * await fin.me.on('host-context-changed', contextChangeHandler); + * + * const platform = await fin.Platform.getCurrentSync(); + * const contextData = { + * security: 'STOCK', + * currentView: 'detailed' + * } + * platform.setWindowContext(contextData) // contextChangeHandler will log the new context + * ``` + * + * To listen to a window's context updates, use the `context-changed` event: + * ```js + * // From a window + * const contextChangeHandler = ({ context }) => { + * console.log('This window\'s context has changed. New context data:', context); + * // react to new context data here + * } + * await fin.me.on('context-changed', contextChangeHandler); + * + * const platform = await fin.Platform.getCurrentSync(); + * const contextData = { + * security: 'STOCK', + * currentView: 'detailed' + * } + * platform.setWindowContext(contextData) // contextChangeHandler will log the new context + * ``` + * @experimental + */ + async setWindowContext(context = {}, target) { + this.wire.sendAction('platform-set-window-context', this.identity).catch((e) => { + // don't expose + }); + if (!context) { + throw new Error('Please provide a serializable object or string to set the context.'); + } + const client = await this.getClient(); + const { entityType } = target ? await this.fin.System.getEntityInfo(target.uuid, target.name) : this.fin.me; + await client.dispatch('set-window-context', { + context, + entityType, + target: target || { uuid: this.fin.me.uuid, name: this.fin.me.name } + }); + } + /** + * Get the context context of a host window that was previously set using {@link Platform#setWindowContext setWindowContext}. + * The context will be saved in any platform snapshots. Returns a promise that resolves to the context. + * @param target - A target window or view may optionally be provided. If no target is provided, target will be + * the current window (if called from a Window) or the current host window (if called from a View). + * + * @remarks This method can be called from the window itself, or from any child view. Context data is shared + * by all entities within a window. + * + * @example + * + * Retrieving context from current window: + * ```js + * const platform = fin.Platform.getCurrentSync(); + * const customContext = { answer: 42 }; + * await platform.setWindowContext(customContext); + * + * const myContext = await platform.getWindowContext(); + * console.log(myContext); // { answer: 42 } + * ``` + * + * Retrieving the context of another window or view: + * ```js + * const platform = fin.Platform.getCurrentSync(); + * + * const windowOrViewIdentity = { uuid: fin.me.uuid, name: 'nameOfWindowOrView' }; + * + * const targetWindowContext = await platform.getWindowContext(windowOrViewIdentity); + * console.log(targetWindowContext); // context of target window + * ``` + * @experimental + */ + async getWindowContext(target) { + this.wire.sendAction('platform-get-window-context', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + const { entityType } = target ? await this.fin.System.getEntityInfo(target.uuid, target.name) : this.fin.me; + return client.dispatch('get-window-context', { + target: target || { uuid: this.fin.me.uuid, name: this.fin.me.name }, + entityType + }); + } + /** + * Closes a window. If enableBeforeUnload is enabled in the Platform options, any beforeunload handler set on Views will fire + * This behavior can be disabled by setting skipBeforeUnload to false in the options parameter. + * @param winId + * @param options + * + * @remarks This method works by setting a `close-requested` handler on the Platform Window. If you have your own `close-requested` handler set on the Platform Window as well, + * it is recommended to move that logic over to the [PlatformProvider.closeWindow]{@link PlatformProvider#closeWindow} override to ensure it runs when the Window closes. + * + * @example + * + * ```js + * // Close the current Window inside a Window context + * const platform = await fin.Platform.getCurrent(); + * platform.closeWindow(fin.me.identity); + * + * // Close the Window from inside a View context + * const platform = await fin.Platform.getCurrent(); + * const parentWindow = await fin.me.getCurrentWindow(); + * platform.closeWindow(parentWindow.identity); + * + * // Close the Window and do not fire the before unload handler on Views + * const platform = await fin.Platform.getCurrent(); + * platform.closeWindow(fin.me.identity, { skipBeforeUnload: true }); + * ``` + * @experimental + */ + async closeWindow(windowId, options = { skipBeforeUnload: false }) { + this.wire.sendAction('platform-close-window', this.identity).catch((e) => { + // don't expose + }); + const client = await this.getClient(); + return client.dispatch('close-window', { windowId, options }); + } +} +Instance$2.Platform = Platform; +_Platform_connectToProvider = new WeakMap(); + +var layout = {}; + +var Factory$2 = {}; + +var Instance$1 = {}; + +var commonUtils = {}; + +Object.defineProperty(commonUtils, "__esModule", { value: true }); +commonUtils.overrideFromComposables = commonUtils.isValidPresetType = void 0; +function isValidPresetType(type) { + switch (type) { + case 'columns': + case 'grid': + case 'rows': + case 'tabs': + return true; + default: + return false; + } +} +commonUtils.isValidPresetType = isValidPresetType; +function overrideFromComposables(...overrides) { + return (base) => overrides.reduceRight((p, c) => (b) => c(p(b)), (x) => x)(base); +} +commonUtils.overrideFromComposables = overrideFromComposables; +commonUtils.default = { isValidPresetType }; + +var __classPrivateFieldGet$4 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _Layout_layoutClient; +Object.defineProperty(Instance$1, "__esModule", { value: true }); +Instance$1.Layout = void 0; +const lazy_1 = lazy; +const validate_1 = validate; +const base_1$5 = base; +const common_utils_1 = commonUtils; +const layout_entities_1 = layoutEntities; +const layout_constants_1$1 = layout_constants; +/** + * + * Layouts give app providers the ability to embed multiple views in a single window. The Layout namespace + * enables the initialization and manipulation of a window's Layout. A Layout will + * emit events locally on the DOM element representing the layout-container. + * + * + * ### Layout.DOMEvents + * + * When a Layout is created, it emits events onto the DOM element representing the Layout container. + * This Layout container is the DOM element referenced by containerId in {@link Layout.LayoutModule#init Layout.init}. + * You can use the built-in event emitter to listen to these events using [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). + * The events are emitted synchronously and only in the process where the Layout exists. + * Any values returned by the called listeners are ignored and will be discarded. + * If the target DOM element is destroyed, any events that have been set up on that element will be destroyed. + * + * @remarks The built-in event emitter is not an OpenFin event emitter so it doesn't share propagation semantics. + * + * #### {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener addEventListener(type, listener [, options]);} + * Adds a listener to the end of the listeners array for the specified event. + * @example + * ```js + * const myLayoutContainer = document.getElementById('layout-container'); + * + * myLayoutContainer.addEventListener('tab-created', function(event) { + * const { tabSelector } = event.detail; + * const tabElement = document.getElementById(tabSelector); + * const existingColor = tabElement.style.backgroundColor; + * tabElement.style.backgroundColor = "red"; + * setTimeout(() => { + * tabElement.style.backgroundColor = existingColor; + * }, 2000); + * }); + * ``` + * + * #### {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener removeEventListener(type, listener [, options]);} + * Adds a listener to the end of the listeners array for the specified event. + * @example + * ```js + * const myLayoutContainer = document.getElementById('layout-container'); + * + * const listener = function(event) { + * console.log(event.detail); + * console.log('container-created event fired once, removing listener'); + * myLayoutContainer.removeEventListener('container-created', listener); + * }; + * + * myLayoutContainer.addEventListener('container-created', listener); + * ``` + * + * ### Supported event types are: + * + * * tab-created + * * container-created + * * layout-state-changed + * * tab-closed + * * tab-dropped + * + * ### Layout DOM Node Events + * + * #### tab-created + * Generated when a tab is created. As a user drags and drops tabs within window, new tabs are created. A single view may have multiple tabs created and destroyed during its lifetime attached to a single window. + * ```js + * // The response has the following shape in event.detail: + * { + * containerSelector: "container-component_A", + * name: "component_A", + * tabSelector: "tab-component_A", + * topic: "openfin-DOM-event", + * type: "tab-created", + * uuid: "OpenFin POC" + * } + * ``` + * + * #### container-created + * Generated when a container is created. A single view will have only one container during its lifetime attached to a single window and the container's lifecycle is tied to the view. To discover when the container is destroyed, please listen to view-detached event. + * ```js + * // The response has the following shape in event.detail: + * { + * containerSelector: "container-component_A", + * name: "component_A", + * tabSelector: "tab-component_A", + * topic: "openfin-DOM-event", + * type: "container-created", + * uuid: "OpenFin POC" + * } + * ``` + * + * ### layout-state-changed + * Generated when the state of the layout changes in any way, such as a view added/removed/replaced. Note that this event can fire frequently as the underlying layout can change multiple components from all kinds of changes (resizing for example). Given this, it is recommended to debounce this event and then you can use the {@link Layout#getConfig Layout.getConfig} API to retrieve the most up-to-date state. + * ```js + * // The response has the following shape in event.detail + * { + * containerSelector: "container-component_A", + * name: "component_A", + * tabSelector: "tab-component_A", + * topic: "openfin-DOM-event", + * type: "layout-state-changed", + * uuid: "OpenFin POC" + * } + * ``` + * + * #### tab-closed + * Generated when a tab is closed. + * ```js + * // The response has the following shape in event.detail: + * { + * containerSelector: "container-component_A", + * name: "component_A", + * tabSelector: "tab-component_A", + * topic: "openfin-DOM-event", + * type: "tab-closed", + * uuid: "OpenFin POC", + * url: "http://openfin.co" // The url of the view that was closed. + * } + * ``` + * + * #### tab-dropped + * Generated when a tab is dropped. + * ```js + * // The response has the following shape in event.detail: + * { + * containerSelector: "container-component_A", + * name: "component_A", + * tabSelector: "tab-component_A", + * topic: "openfin-DOM-event", + * type: "tab-dropped", + * uuid: "OpenFin POC", + * url: "http://openfin.co" // The url of the view linked to the dropped tab. + * } + * ``` + */ +class Layout extends base_1$5.Base { + /** + * @internal + */ + // eslint-disable-next-line no-shadow + constructor(identity, wire) { + super(wire); + /** + * @internal + * Lazily constructed {@link LayoutEntitiesClient} bound to this platform's client and identity + * The client is for {@link LayoutEntitiesController} + */ + _Layout_layoutClient.set(this, new lazy_1.Lazy(async () => layout_entities_1.LayoutNode.newLayoutEntitiesClient(await this.platform.getClient(), layout_constants_1$1.LAYOUT_CONTROLLER_ID, this.identity))); + /** + * Replaces a Platform window's layout with a new layout. + * + * @remarks Any views that were in the old layout but not the new layout will be destroyed. Views will be assigned a randomly generated name to avoid collisions. + * @example + * ```js + * let windowIdentity; + * if (fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const layout = fin.Platform.Layout.wrapSync(windowIdentity); + * + * const newLayout = { + * content: [ + * { + * type: 'stack', + * content: [ + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'new_component_A1', + * processAffinity: 'ps_1', + * url: 'https://www.example.com' + * } + * }, + * { + * type: 'component', + * componentName: 'view', + * componentState: { + * name: 'new_component_A2', + * url: 'https://cdn.openfin.co/embed-web/chart.html' + * } + * } + * ] + * } + * ] + * }; + * + * layout.replace(newLayout); + * ``` + */ + this.replace = async (layout) => { + this.wire.sendAction('layout-replace').catch((e) => { + // don't expose + }); + const client = await this.platform.getClient(); + await client.dispatch('replace-layout', { + target: this.identity, + opts: { layout } + }); + }; + /** + * Replaces the specified view with a view with the provided configuration. + * + * @remarks The old view is stripped of its listeners and either closed or attached to the provider window + * depending on `detachOnClose` view option. + * + * @param viewToReplace Identity of the view to be replaced + * @param newView Creation options of the new view. + * + * @example + * ```js + * let currentWindow; + * if (fin.me.isWindow) { + * currentWindow = fin.me; + * } else if (fin.me.isView) { + * currentWindow = await fin.me.getCurrentWindow(); + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const layout = fin.Platform.Layout.wrapSync(currentWindow.identity); + * const viewToReplace = (await currentWindow.getCurrentViews())[0]; + * const newViewConfig = {url: 'https://example.com'}; + * await layout.replaceView(viewToReplace.identity, newViewConfig); + * ``` + */ + this.replaceView = async (viewToReplace, newView) => { + this.wire.sendAction('layout-replace-view').catch((e) => { + // don't expose + }); + const client = await this.platform.getClient(); + await client.dispatch('replace-view', { + target: this.identity, + opts: { viewToReplace, newView } + }); + }; + /** + * Replaces a Platform window's layout with a preset layout arrangement using the existing Views attached to the window. + * The preset options are `columns`, `grid`, `rows`, and `tabs`. + * @param options Mandatory object with `presetType` property that sets which preset layout arrangement to use. + * The preset options are `columns`, `grid`, `rows`, and `tabs`. + * + * @example + * ```js + * let windowIdentity; + * if (fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const layout = fin.Platform.Layout.wrapSync(windowIdentity); + * await layout.applyPreset({ presetType: 'grid' }); + * + * // wait 5 seconds until you change the layout from grid to tabs + * await new Promise (res => setTimeout(res, 5000)); + * await layout.applyPreset({ presetType: 'tabs' }); + * ``` + */ + this.applyPreset = async (options) => { + this.wire.sendAction('layout-apply-preset').catch((e) => { + // don't expose + }); + const client = await this.platform.getClient(); + const { presetType } = options; + if (!presetType || !(0, common_utils_1.isValidPresetType)(presetType)) { + throw new Error('Cannot apply preset layout, please include an applicable presetType property in the PresetLayoutOptions.'); + } + await client.dispatch('apply-preset-layout', { + target: this.identity, + opts: { presetType } + }); + }; + const errorMsg = (0, validate_1.validateIdentity)(identity); + if (errorMsg) { + throw new Error(errorMsg); + } + this.identity = identity; + this.platform = this.fin.Platform.wrapSync({ uuid: identity.uuid }); + if (identity.uuid === this.fin.me.uuid && identity.name === this.fin.me.name) { + this.init = this.fin.Platform.Layout.init; + } + } + /** + * Returns the configuration of the window's layout. Returns the same information that is returned for all windows in getSnapshot. + * + * @remarks Cannot be called from a View. + * + * + * @example + * ```js + * const layout = fin.Platform.Layout.getCurrentSync(); + * // Use wrapped instance to get the layout configuration of the current window's Layout: + * const layoutConfig = await layout.getConfig(); + * ``` + */ + async getConfig() { + this.wire.sendAction('layout-get-config').catch((e) => { + // don't expose + }); + const client = await this.platform.getClient(); + return client.dispatch('get-frame-snapshot', { + target: this.identity + }); + } + /** + * Retrieves the attached views in current window layout. + * + * @example + * ```js + * const layout = fin.Platform.Layout.getCurrentSync(); + * const views = await layout.getCurrentViews(); + * ``` + */ + async getCurrentViews() { + this.wire.sendAction('layout-get-views').catch((e) => { + // don't expose + }); + const client = await this.platform.getClient(); + const viewIdentities = await client.dispatch('get-layout-views', { + target: this.identity + }); + return viewIdentities.map((identity) => this.fin.View.wrapSync(identity)); + } + /** + * Retrieves the top level content item of the layout. + * + * @remarks Cannot be called from a view. + * + * + * + * @example + * ```js + * if (!fin.me.isWindow) { + * throw new Error('Not running in a platform View.'); + * } + * + * // From the layout window + * const layout = fin.Platform.Layout.getCurrentSync(); + * // Retrieves the ColumnOrRow instance + * const rootItem = await layout.getRootItem(); + * const content = await rootItem.getContent(); + * console.log(`The root ColumnOrRow instance has ${content.length} item(s)`); + * ``` + */ + async getRootItem() { + this.wire.sendAction('layout-get-root-item').catch(() => { + // don't expose + }); + const client = await __classPrivateFieldGet$4(this, _Layout_layoutClient, "f").getValue(); + const root = await client.getRoot('layoutName' in this.identity ? this.identity : undefined); + return layout_entities_1.LayoutNode.getEntity(root, client); + } +} +Instance$1.Layout = Layout; +_Layout_layoutClient = new WeakMap(); + +var __classPrivateFieldGet$3 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet$3 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var _LayoutModule_instances, _LayoutModule_layoutInitializationAttempted, _LayoutModule_layoutManager, _LayoutModule_getLayoutManagerSpy, _LayoutModule_getSafeLayoutManager; +Object.defineProperty(Factory$2, "__esModule", { value: true }); +Factory$2.LayoutModule = void 0; +const base_1$4 = base; +const Instance_1$2 = Instance$1; +const layout_constants_1 = layout_constants; +/** + * Static namespace for OpenFin API methods that interact with the {@link Layout} class, available under `fin.Platform.Layout`. + */ +class LayoutModule extends base_1$4.Base { + constructor() { + super(...arguments); + _LayoutModule_instances.add(this); + _LayoutModule_layoutInitializationAttempted.set(this, false); + _LayoutModule_layoutManager.set(this, null); + /** + * Initialize the window's Layout. + * + * @remarks Must be called from a custom window that has a 'layout' option set upon creation of that window. + * If a containerId is not provided, this method attempts to find an element with the id `layout-container`. + * A Layout will emit events locally on the DOM element representing the layout-container. + * In order to capture the relevant events during Layout initiation, set up the listeners on the DOM element prior to calling `init`. + * @param options - Layout init options. + * + * @experimental + * + * @example + * ```js + * // If no options are included, the layout in the window options is initialized in an element with the id `layout-container` + * const layout = await fin.Platform.Layout.init(); + * ``` + *
+ * + * ```js + * const containerId = 'my-custom-container-id'; + * + * const myLayoutContainer = document.getElementById(containerId); + * + * myLayoutContainer.addEventListener('tab-created', function(event) { + * const { tabSelector } = event.detail; + * const tabElement = document.getElementById(tabSelector); + * const existingColor = tabElement.style.backgroundColor; + * tabElement.style.backgroundColor = "red"; + * setTimeout(() => { + * tabElement.style.backgroundColor = existingColor; + * }, 2000); + * }); + * + * // initialize the layout into an existing HTML element with the div `my-custom-container-id` + * // the window must have been created with a layout in its window options + * const layout = await fin.Platform.Layout.init({ containerId }); + * ``` + */ + this.init = async (options = {}) => { + this.wire.sendAction('layout-init').catch((e) => { + // don't expose + }); + if (!this.wire.environment.layoutAllowedInContext(this.fin)) { + throw new Error('Layout.init can only be called from a Window context.'); + } + if (__classPrivateFieldGet$3(this, _LayoutModule_layoutInitializationAttempted, "f")) { + throw new Error('Layout.init was already called, please use Layout.create to add additional layouts.'); + } + if (this.wire.environment.type === 'openfin') { + // preload the client + await this.fin.Platform.getCurrentSync().getClient(); + } + __classPrivateFieldSet$3(this, _LayoutModule_layoutInitializationAttempted, true, "f"); + // TODO: rename to createLayoutManager + __classPrivateFieldSet$3(this, _LayoutModule_layoutManager, await this.wire.environment.initLayoutManager(this.fin, this.wire, options), "f"); + await this.wire.environment.applyLayoutSnapshot(this.fin, __classPrivateFieldGet$3(this, _LayoutModule_layoutManager, "f"), options); + const meIdentity = { name: this.fin.me.name, uuid: this.fin.me.uuid }; + if (!options.layoutManagerOverride) { + // CORE-1081 to be removed when we actually delete the `layoutManager` prop + // in single-layout case, we return the undocumented layoutManager type + const layoutIdentity = { layoutName: layout_constants_1.DEFAULT_LAYOUT_KEY, ...meIdentity }; + return __classPrivateFieldGet$3(this, _LayoutModule_getLayoutManagerSpy, "f").call(this, layoutIdentity); + } + return this.wrapSync(meIdentity); + }; + _LayoutModule_getLayoutManagerSpy.set(this, (layoutIdentity) => { + const msg = '[Layout] You are using a deprecated property `layoutManager` - it will throw if you access it starting in v37.'; + const managerProxy = new Proxy({}, { + get(target, key) { + console.warn(`[Layout-mgr-proxy] accessing ${key.toString()}`); + throw new Error(msg); + } + }); + const layout = Object.assign(this.wrapSync(layoutIdentity), { layoutManager: managerProxy }); + const layoutProxy = new Proxy(layout, { + get(target, key) { + if (key === 'layoutManager') { + console.warn(`[Layout-proxy] accessing ${key.toString()}`); + throw new Error(msg); + } + return target[key]; + } + }); + return layoutProxy; + }); + /** + * Returns the layout manager for the current window + * @returns + */ + this.getCurrentLayoutManagerSync = () => { + return __classPrivateFieldGet$3(this, _LayoutModule_instances, "m", _LayoutModule_getSafeLayoutManager).call(this, `fin.Platform.Layout.getCurrentLayoutManagerSync()`); + }; + this.create = async (options) => { + return this.wire.environment.createLayout(__classPrivateFieldGet$3(this, _LayoutModule_instances, "m", _LayoutModule_getSafeLayoutManager).call(this, `fin.Platform.Layout.create()`), options); + }; + this.destroy = async (layoutIdentity) => { + return this.wire.environment.destroyLayout(__classPrivateFieldGet$3(this, _LayoutModule_instances, "m", _LayoutModule_getSafeLayoutManager).call(this, `fin.Platform.Layout.destroy()`), layoutIdentity); + }; + } + /** + * Asynchronously returns a Layout object that represents a Window's layout. + * + * @example + * ```js + * let windowIdentity; + * if (!fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const layout = await fin.Platform.Layout.wrap(windowIdentity); + * // Use wrapped instance to control layout, e.g.: + * const layoutConfig = await layout.getConfig(); + * ``` + */ + async wrap(identity) { + this.wire.sendAction('layout-wrap').catch((e) => { + // don't expose + }); + return new Instance_1$2.Layout(identity, this.wire); + } + /** + * Synchronously returns a Layout object that represents a Window's layout. + * + * @example + * ```js + * let windowIdentity; + * if (!fin.me.isWindow) { + * windowIdentity = fin.me.identity; + * } else if (fin.me.isView) { + * windowIdentity = (await fin.me.getCurrentWindow()).identity; + * } else { + * throw new Error('Not running in a platform View or Window'); + * } + * + * const layout = fin.Platform.Layout.wrapSync(windowIdentity); + * // Use wrapped instance to control layout, e.g.: + * const layoutConfig = await layout.getConfig(); + * ``` + */ + wrapSync(identity) { + this.wire.sendAction('layout-wrap-sync').catch((e) => { + // don't expose + }); + return new Instance_1$2.Layout(identity, this.wire); + } + /** + * Asynchronously returns a Layout object that represents a Window's layout. + * + * @example + * ```js + * const layout = await fin.Platform.Layout.getCurrent(); + * // Use wrapped instance to control layout, e.g.: + * const layoutConfig = await layout.getConfig(); + * ``` + */ + async getCurrent() { + this.wire.sendAction('layout-get-current').catch((e) => { + // don't expose + }); + if (!this.fin.me.isWindow) { + throw new Error('You are not in a Window context. Only Windows can have a Layout.'); + } + const { uuid, name } = this.fin.me; + return this.wrap({ uuid, name }); + } + /** + * Synchronously returns a Layout object that represents a Window's layout. + * + * @remarks Cannot be called from a view. + * + * + * @example + * ```js + * const layout = fin.Platform.Layout.getCurrentSync(); + * // Use wrapped instance to control layout, e.g.: + * const layoutConfig = await layout.getConfig(); + * ``` + */ + getCurrentSync() { + this.wire.sendAction('layout-get-current-sync').catch((e) => { + // don't expose + }); + if (!this.fin.me.isWindow) { + throw new Error('You are not in a Window context. Only Windows can have a Layout.'); + } + const { uuid, name } = this.fin.me; + return this.wrapSync({ uuid, name }); + } +} +Factory$2.LayoutModule = LayoutModule; +_LayoutModule_layoutInitializationAttempted = new WeakMap(), _LayoutModule_layoutManager = new WeakMap(), _LayoutModule_getLayoutManagerSpy = new WeakMap(), _LayoutModule_instances = new WeakSet(), _LayoutModule_getSafeLayoutManager = function _LayoutModule_getSafeLayoutManager(method) { + if (!__classPrivateFieldGet$3(this, _LayoutModule_layoutManager, "f")) { + throw new Error(`You must call init before using the API ${method}`); + } + return __classPrivateFieldGet$3(this, _LayoutModule_layoutManager, "f"); +}; + +(function (exports) { + /** + * Entry point for the OpenFin `Layout` subset of the `Platform` API (`fin.Platform.Layout`). + * + * * {@link LayoutModule} contains static members of the `Layout` API, accessible through `fin.Platform.Layout`. + * * {@link Layout} describes an instance of an OpenFin Layout, e.g. as returned by `fin.Platform.Layout.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * @packageDocumentation + * + */ + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(Factory$2, exports); + __exportStar(Instance$1, exports); +} (layout)); + +Object.defineProperty(Factory$3, "__esModule", { value: true }); +Factory$3.PlatformModule = void 0; +const base_1$3 = base; +const Instance_1$1 = Instance$2; +const index_1$1 = layout; +/** + * Static namespace for OpenFin API methods that interact with the {@link Platform} class, available under `fin.Platform`. + */ +class PlatformModule extends base_1$3.Base { + /** + * @internal + */ + constructor(wire, channel) { + super(wire); + this._channel = channel; + /** + * + * @desc Layouts give app providers the ability to embed multiple views in a single window. The Layout namespace + * enables the initialization and manipulation of a window's Layout. A Layout will + * emit events locally on the DOM element representing the layout-container. + */ + this.Layout = new index_1$1.LayoutModule(this.wire); + } + /** + * Initializes a Platform. Must be called from the Provider when using a custom provider. + * @param options - platform options including a callback function that can be used to extend or replace + * default Provider behavior. + * + * @remarks Must be called from the Provider when using a custom provider. + * + * @example + * + * ```js + * // From Provider context + * await fin.Platform.init(); + * // Platform API is now hooked up and windows contained in the manifest snapshot are open. + * ``` + * + * `Platform.init` accepts an options object that can contain a callback function which can be used to extend or + * replace default Provider behavior. As an argument, this function will receive the `Provider` class, which is + * used to handle Platform actions. The function must return an object with methods to handle Platform API actions. + * The recommended approach is to extend the `Provider` class, overriding the methods you wish to alter, and return an + * instance of your subclass: + * + * ```js + * const overrideCallback = async (PlatformProvider) => { + * // Actions can be performed before initialization. + * // e.g. we might authenticate a user, set up a Channel, etc before initializing the Platform. + * const { manifestUrl } = await fin.Application.getCurrentSync().getInfo(); + * + * // Extend or replace default PlatformProvider behavior by extending the PlatformProvider class. + * class MyOverride extends PlatformProvider { + * // Default behavior can be changed by implementing methods with the same names as those used by the default PlatformProvider. + * async getSnapshot() { + * // Since we are extending the class, we can call `super` methods to access default behavior. + * const snapshot = await super.getSnapshot(); + * // But we can modify return values. + * return { ...snapshot, answer: 42, manifestUrl }; + * } + * async replaceLayout({ opts, target }) { + * // To disable an API method, overwrite with a noop function. + * return; + * } + * } + * // Return instance with methods to be consumed by Platform. + * // The returned object must implement all methods of the PlatformProvider class. + * // By extending the class, we can simply inherit methods we do not wish to alter. + * return new MyOverride(); + * }; + * + * fin.Platform.init({overrideCallback}); + * ``` + * @experimental + */ + async init(options) { + if (!fin.__internal_.isPlatform || fin.me.name !== fin.me.uuid) { + throw new Error('fin.Platform.init should only be called from a custom platform provider running in the main window of the application.'); + } + return this.wire.environment.initPlatform(this.fin, options); + } + /** + * Asynchronously returns a Platform object that represents an existing platform. + * + * @example + * ```js + * const { identity } = fin.me; + * const platform = await fin.Platform.wrap(identity); + * // Use wrapped instance to control layout, e.g.: + * const snapshot = await platform.getSnapshot(); + * ``` + */ + async wrap(identity) { + this.wire.sendAction('platform-wrap').catch((e) => { + // don't expose + }); + return new Instance_1$1.Platform({ uuid: identity.uuid }, this._channel); + } + /** + * Synchronously returns a Platform object that represents an existing platform. + * + * @example + * ```js + * const { identity } = fin.me; + * const platform = fin.Platform.wrapSync(identity); + * // Use wrapped instance to control layout, e.g.: + * const snapshot = await platform.getSnapshot(); + * ``` + */ + wrapSync(identity) { + this.wire.sendAction('platform-wrap-sync').catch((e) => { + // don't expose + }); + return new Instance_1$1.Platform({ uuid: identity.uuid }, this._channel); + } + /** + * Asynchronously returns a Platform object that represents the current platform. + * + * @example + * ```js + * const platform = await fin.Platform.getCurrent(); + * // Use wrapped instance to control layout, e.g.: + * const snapshot = await platform.getSnapshot(); + * ``` + */ + async getCurrent() { + this.wire.sendAction('platform-get-current').catch((e) => { + // don't expose + }); + return this.wrap({ uuid: this.wire.me.uuid }); + } + /** + * Synchronously returns a Platform object that represents the current platform. + * + * @example + * ```js + * const platform = fin.Platform.getCurrentSync(); + * // Use wrapped instance to control layout, e.g.: + * const snapshot = await platform.getSnapshot(); + * ``` + */ + getCurrentSync() { + this.wire.sendAction('platform-get-current-sync').catch((e) => { + // don't expose + }); + return this.wrapSync({ uuid: this.wire.me.uuid }); + } + /** + * Creates and starts a Platform and returns a wrapped and running Platform instance. The wrapped Platform methods can + * be used to launch content into the platform. Promise will reject if the platform is already running. + * + * @example + * ```js + * try { + * const platform = await fin.Platform.start({ + * uuid: 'platform-1', + * autoShow: false, + * defaultWindowOptions: { + * stylesheetUrl: 'css-sheet-url', + * cornerRounding: { + * height: 10, + * width: 10 + * } + * } + * }); + * console.log('Platform is running', platform); + * } catch(e) { + * console.error(e); + * } + * ``` + */ + start(platformOptions) { + this.wire.sendAction('platform-start').catch((e) => { + // don't expose + }); + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { + try { + const { uuid } = platformOptions; + // @ts-expect-error using private variable. + const app = await this.fin.Application._create({ ...platformOptions, isPlatformController: true }); + // TODO: fix typing (internal) + // @ts-expect-error + app.once('platform-api-ready', () => resolve(this.wrapSync({ uuid }))); + // @ts-expect-error using private variable. + app._run({ uuid }); + } + catch (e) { + reject(e); + } + }); + } + /** + * Retrieves platforms's manifest and returns a wrapped and running Platform. If there is a snapshot in the manifest, + * it will be launched into the platform. + * @param manifestUrl - The URL of platform's manifest. + * @param opts - Parameters that the RVM will use. + * + * @example + * ```js + * try { + * const platform = await fin.Platform.startFromManifest('https://openfin.github.io/golden-prototype/public.json'); + * console.log('Platform is running, wrapped platform: ', platform); + * } catch(e) { + * console.error(e); + * } + * // For a local manifest file: + * try { + * const platform = await fin.Platform.startFromManifest('file:///C:/somefolder/app.json'); + * console.log('Platform is running, wrapped platform: ', platform); + * } catch(e) { + * console.error(e); + * } + * ``` + */ + startFromManifest(manifestUrl, opts) { + this.wire.sendAction('platform-start-from-manifest').catch((e) => { + // don't expose + }); + // eslint-disable-next-line no-async-promise-executor + return new Promise(async (resolve, reject) => { + try { + // @ts-expect-error using private variable. + const app = await this.fin.Application._createFromManifest(manifestUrl); + // TODO: fix typing (internal) + // @ts-expect-error + app.once('platform-api-ready', () => resolve(this.wrapSync({ uuid: app.identity.uuid }))); + // @ts-expect-error using private method without warning. + app._run(opts); + } + catch (e) { + reject(e); + } + }); + } +} +Factory$3.PlatformModule = PlatformModule; + +(function (exports) { + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + /** + * Entry points for the OpenFin `Platform` API (`fin.Platform`) + * + * * {@link PlatformModule} contains static members of the `Platform` API, accessible through `fin.Platform`. + * * {@link Platform} describes an instance of an OpenFin Platform, e.g. as returned by `fin.Platform.getCurrent`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * @packageDocumentation + */ + __exportStar(Factory$3, exports); + __exportStar(Instance$2, exports); +} (platform)); + +var me = {}; + +(function (exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.getMe = exports.getBaseMe = exports.environmentUnsupportedMessage = void 0; + const view_1 = requireView(); + const frame_1 = frame; + const window_1 = requireWindow(); + const external_application_1 = externalApplication; + exports.environmentUnsupportedMessage = 'You are not running in OpenFin.'; + function getBaseMe(entityType, uuid, name) { + const entityTypeHelpers = { + isView: entityType === 'view', + isWindow: entityType === 'window', + isFrame: entityType === 'iframe', + isExternal: entityType === 'external connection' + }; + return { ...entityTypeHelpers, uuid, name, entityType }; + } + exports.getBaseMe = getBaseMe; + // We need to do a lot of casting as unknown here because the compiler get's confused about matching types. What matters is that it works on the outside + function getMe(wire) { + const { uuid, name, entityType } = wire.me; + const unsupportedInterop = { + setContext() { + throw new Error(exports.environmentUnsupportedMessage); + }, + addContextHandler() { + throw new Error(exports.environmentUnsupportedMessage); + }, + getContextGroups() { + throw new Error(exports.environmentUnsupportedMessage); + }, + joinContextGroup() { + throw new Error(exports.environmentUnsupportedMessage); + }, + removeFromContextGroup() { + throw new Error(exports.environmentUnsupportedMessage); + }, + getAllClientsInContextGroup() { + throw new Error(exports.environmentUnsupportedMessage); + }, + getInfoForContextGroup() { + throw new Error(exports.environmentUnsupportedMessage); + } + }; + const fallbackErrorMessage = 'Interop API has not been instantiated. Either connection has failed or you have not declared interop in your config.'; + const fallbackInterop = { + setContext() { + throw new Error(fallbackErrorMessage); + }, + addContextHandler() { + throw new Error(fallbackErrorMessage); + }, + getContextGroups() { + throw new Error(fallbackErrorMessage); + }, + joinContextGroup() { + throw new Error(fallbackErrorMessage); + }, + removeFromContextGroup() { + throw new Error(fallbackErrorMessage); + }, + getAllClientsInContextGroup() { + throw new Error(fallbackErrorMessage); + }, + getInfoForContextGroup() { + throw new Error(fallbackErrorMessage); + } + }; + const unsupportedEventBase = { + eventNames: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + emit: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + listeners: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + listenerCount: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + on: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + addListener: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + once: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + prependListener: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + prependOnceListener: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + removeListener: () => { + throw new Error(exports.environmentUnsupportedMessage); + }, + removeAllListeners: () => { + throw new Error(exports.environmentUnsupportedMessage); + } + }; + switch (entityType) { + case 'view': + return Object.assign(new view_1.View(wire, { uuid, name }), getBaseMe(entityType, uuid, name), { + interop: fallbackInterop, + isOpenFin: true + }); + case 'window': + return Object.assign(new window_1._Window(wire, { uuid, name }), getBaseMe(entityType, uuid, name), { + interop: fallbackInterop, + isOpenFin: true + }); + case 'iframe': + return Object.assign(new frame_1._Frame(wire, { uuid, name }), getBaseMe(entityType, uuid, name), { + interop: fallbackInterop, + isOpenFin: true + }); + case 'external connection': + return Object.assign(new external_application_1.ExternalApplication(wire, { uuid }), getBaseMe(entityType, uuid, name), { + interop: fallbackInterop, + isOpenFin: false + }); + default: + return { + ...getBaseMe(entityType, uuid, name), + ...unsupportedEventBase, + interop: unsupportedInterop, + isOpenFin: false + }; + } + } + exports.getMe = getMe; +} (me)); + +var interop = {}; + +var Factory$1 = {}; + +var inaccessibleObject = {}; + +Object.defineProperty(inaccessibleObject, "__esModule", { value: true }); +inaccessibleObject.createWarningObject = inaccessibleObject.createUnusableObject = void 0; +function createUnusableObject(message) { + const handle = () => { + throw new Error(message); + }; + return new Proxy({}, { + apply: handle, + construct: handle, + defineProperty: handle, + deleteProperty: handle, + get: handle, + getOwnPropertyDescriptor: handle, + getPrototypeOf: handle, + has: handle, + isExtensible: handle, + ownKeys: handle, + preventExtensions: handle, + set: handle, + setPrototypeOf: handle + }); +} +inaccessibleObject.createUnusableObject = createUnusableObject; +function createWarningObject(message, obj) { + return new Proxy(obj, { + get: (...args) => { + // eslint-disable-next-line no-console + console.warn(message); + return Reflect.get(...args); + }, + set: (...args) => { + // eslint-disable-next-line no-console + console.warn(message); + return Reflect.set(...args); + }, + getOwnPropertyDescriptor: (...args) => { + // eslint-disable-next-line no-console + console.warn(message); + return Reflect.getOwnPropertyDescriptor(...args); + }, + ownKeys: (...args) => { + // eslint-disable-next-line no-console + console.warn(message); + return Reflect.ownKeys(...args); + } + }); +} +inaccessibleObject.createWarningObject = createWarningObject; + +var InteropBroker = {}; + +var SessionContextGroupBroker = {}; + +var hasRequiredSessionContextGroupBroker; + +function requireSessionContextGroupBroker () { + if (hasRequiredSessionContextGroupBroker) return SessionContextGroupBroker; + hasRequiredSessionContextGroupBroker = 1; + Object.defineProperty(SessionContextGroupBroker, "__esModule", { value: true }); + const _1 = requireInterop(); + let SessionContextGroupBroker$1 = class SessionContextGroupBroker { + constructor(provider, id) { + this.provider = provider; + this.id = id; + this.lastContext = undefined; + this.contextGroupMap = new Map(); + this.clients = new Map(); + this.registerListeners(); + } + registerListeners() { + this.provider.register(`sessionContextGroup:getContext-${this.id}`, this.getCurrentContext.bind(this)); + this.provider.register(`sessionContextGroup:setContext-${this.id}`, this.setContext.bind(this)); + this.provider.register(`sessionContextGroup:handlerAdded-${this.id}`, this.handlerAdded.bind(this)); + this.provider.register(`sessionContextGroup:handlerRemoved-${this.id}`, this.handlerRemoved.bind(this)); + } + getCurrentContext(payload) { + return payload.type ? this.contextGroupMap.get(payload.type) : this.lastContext; + } + setContext(payload, clientIdentity) { + const { context } = payload; + const contextIntegrityCheckResult = _1.InteropBroker.checkContextIntegrity(context); + if (contextIntegrityCheckResult.isValid === false) { + throw new Error(`Failed to set Context - bad Context. Reason: ${contextIntegrityCheckResult.reason}. Context: ${JSON.stringify(context)}`); + } + const clientState = this.getClientState(clientIdentity); + if (!clientState) { + // This shouldn't get hit. + throw new Error(`Client with Identity: ${clientIdentity.uuid} ${clientIdentity.name} not in Session Client State Map`); + } + // set the context + this.contextGroupMap.set(context.type, context); + this.lastContext = context; + const clientSubscriptionStates = Array.from(this.clients.values()); + clientSubscriptionStates.forEach((client) => { + // eslint-disable-next-line no-unused-expressions + client.contextHandlers.get(context.type)?.forEach((handlerId) => { + this.provider.dispatch(client.clientIdentity, handlerId, context); + }); + if (client.globalHandler) { + this.provider.dispatch(client.clientIdentity, client.globalHandler, context); + } + }); + } + getClientState(id) { + return this.clients.get(id.endpointId); + } + async handlerAdded(payload, clientIdentity) { + const { handlerId, contextType } = payload; + const clientSubscriptionState = this.getClientState(clientIdentity); + if (!clientSubscriptionState) { + throw new Error(`Client with Identity: ${clientIdentity.uuid} ${clientIdentity.name} not in Client State Map`); + } + if (contextType) { + const currentHandlerList = clientSubscriptionState.contextHandlers.get(contextType) || []; + clientSubscriptionState.contextHandlers.set(contextType, [...currentHandlerList, handlerId]); + const currentContext = this.contextGroupMap.get(contextType); + if (currentContext) { + await this.provider.dispatch(clientIdentity, handlerId, currentContext); + } + } + else { + clientSubscriptionState.globalHandler = handlerId; + const globalDispatchPromises = [...this.contextGroupMap.keys()].map(async (currentContextType) => { + const currentContext = this.contextGroupMap.get(currentContextType); + if (currentContext) { + await this.provider.dispatch(clientIdentity, handlerId, currentContext); + } + }); + await Promise.all(globalDispatchPromises); + } + } + handlerRemoved(payload, clientIdentity) { + const { handlerId } = payload; + const client = this.clients.get(clientIdentity.endpointId); + if (client) { + Array.from(client.contextHandlers).forEach(([, handlers]) => { + const index = handlers.indexOf(handlerId); + if (index > -1) { + handlers.splice(index, 1); + } + }); + if (client.globalHandler === handlerId) { + client.globalHandler = undefined; + } + } + else { + console.warn(`Trying to remove a handler from a client that isn't mapped. handlerId: ${handlerId}. clientIdentity: ${clientIdentity}`); + } + } + registerNewClient(clientIdentity) { + if (!this.clients.has(clientIdentity.endpointId)) { + const clientSubscriptionState = { + contextHandlers: new Map(), + clientIdentity, + globalHandler: undefined + }; + this.clients.set(clientIdentity.endpointId, clientSubscriptionState); + } + } + onDisconnection(clientIdentity) { + this.clients.delete(clientIdentity.endpointId); + } + }; + SessionContextGroupBroker.default = SessionContextGroupBroker$1; + return SessionContextGroupBroker; +} + +var utils$3 = {}; + +(function (exports) { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.wrapIntentHandler = exports.BROKER_ERRORS = exports.generateOverrideWarning = exports.generateOverrideError = exports.wrapContextHandler = exports.wrapInTryCatch = exports.generateId = void 0; + const generateId = () => `${Math.random()}${Date.now()}`; + exports.generateId = generateId; + const wrapInTryCatch = (f, prefix) => (...args) => { + try { + return f(...args); + } + catch (e) { + throw new Error((prefix || '') + e); + } + }; + exports.wrapInTryCatch = wrapInTryCatch; + const wrapContextHandler = (handler, handlerId) => { + return async (context) => { + try { + await handler(context); + } + catch (error) { + console.error(`Error thrown by handler ${handlerId} for context type ${context.type}: ${error}`); + throw error; + } + }; + }; + exports.wrapContextHandler = wrapContextHandler; + const generateOverrideError = (clientApi, brokerApi) => { + return `You have tried to to use ${clientApi} but ${brokerApi} has not been overridden in the Interop Broker. Please override this function. Refer to our documentation for more info.`; + }; + exports.generateOverrideError = generateOverrideError; + const generateOverrideWarning = (fdc3ClientApi, brokerApi, identity, interopClientApi) => { + const { uuid, name } = identity; + const message = interopClientApi + ? `Entity with identity: ${uuid}/${name} has called ${interopClientApi} or ${fdc3ClientApi} but ${brokerApi} has not been overridden.` + : `Entity with identity: ${uuid}/${name} has called ${fdc3ClientApi} but ${brokerApi} has not been overridden.`; + return message; + }; + exports.generateOverrideWarning = generateOverrideWarning; + exports.BROKER_ERRORS = { + fireIntent: (0, exports.generateOverrideError)('fireIntent', 'handleFiredIntent'), + fireIntentForContext: (0, exports.generateOverrideError)('fireIntentForContext', 'handleFiredIntentForContext'), + getInfoForIntent: (0, exports.generateOverrideError)('getInfoForIntent', 'handleInfoForIntent'), + getInfoForIntentsByContext: (0, exports.generateOverrideError)('getInfoForIntentsByContext', 'handleInfoForIntentsByContext'), + joinSessionContextGroupWithJoinContextGroup: 'The Context Group you have tried to join is a Session Context Group. Custom Context Groups can only be defined by the Interop Broker through code or manifest configuration. Please use joinSessionContextGroup.', + fdc3Open: (0, exports.generateOverrideError)('fdc3.open', 'fdc3HandleOpen'), + fdc3FindInstances: (0, exports.generateOverrideError)('fdc3.findInstances', 'fdc3HandleFindInstances'), + fdc3GetAppMetadata: (0, exports.generateOverrideError)('fdc3.getAppMetadata', 'fdc3HandleGetAppMetadata'), + fdc3GetInfo: (0, exports.generateOverrideError)('fdc3.getInfo', 'fdc3HandleGetInfo') + }; + const wrapIntentHandler = (handler, handlerId) => { + return async (intent) => { + try { + return handler(intent); + } + catch (error) { + console.error(`Error thrown by handler ${handlerId}: ${error}`); + throw error; + } + }; + }; + exports.wrapIntentHandler = wrapIntentHandler; +} (utils$3)); + +var PrivateChannelProvider = {}; + +var hasRequiredPrivateChannelProvider; + +function requirePrivateChannelProvider () { + if (hasRequiredPrivateChannelProvider) return PrivateChannelProvider; + hasRequiredPrivateChannelProvider = 1; + Object.defineProperty(PrivateChannelProvider, "__esModule", { value: true }); + PrivateChannelProvider.PrivateChannelProvider = void 0; + const InteropBroker_1 = requireInteropBroker(); + let PrivateChannelProvider$1 = class PrivateChannelProvider { + constructor(provider, id) { + this.provider = provider; + this.id = id; + this.clients = new Map(); + this.registerListeners(); + this.contextByContextType = new Map(); + this.lastContext = undefined; + this.provider.onConnection((clientIdentity) => this.registerNewClient(clientIdentity)); + this.provider.onDisconnection(async (clientIdentity) => { + const { endpointId } = clientIdentity; + if (this.clients.has(endpointId)) { + await this.handleClientDisconnecting(clientIdentity); + } + if ((await this.provider.getAllClientInfo()).length === 0) { + this.provider.destroy(); + } + }); + } + getClientState(id) { + return this.clients.get(id.endpointId); + } + registerListeners() { + this.provider.register('broadcast', this.broadcast.bind(this)); + this.provider.register('getCurrentContext', this.getCurrentContext.bind(this)); + this.provider.register('contextHandlerAdded', this.contextHandlerAdded.bind(this)); + this.provider.register('contextHandlerRemoved', this.contextHandlerRemoved.bind(this)); + this.provider.register('nonStandardHandlerRemoved', this.nonStandardHandlerRemoved.bind(this)); + this.provider.register('onAddContextHandlerAdded', this.onAddContextHandlerAdded.bind(this)); + this.provider.register('onDisconnectHandlerAdded', this.onDisconnectHandlerAdded.bind(this)); + this.provider.register('onUnsubscribeHandlerAdded', this.onUnsubscribeHandlerAdded.bind(this)); + this.provider.register('clientDisconnecting', (payload, clientIdentity) => { + this.handleClientDisconnecting(clientIdentity); + }); + } + broadcast(payload, broadcasterClientIdentity) { + const { context } = payload; + const broadcasterClientState = this.getClientState(broadcasterClientIdentity); + if (!broadcasterClientState) { + throw new Error(`Client with Identity: ${broadcasterClientIdentity.uuid} ${broadcasterClientIdentity.name}, tried to call broadcast, is not connected to this Private Channel`); + } + const contextIntegrityCheckResult = InteropBroker_1.InteropBroker.checkContextIntegrity(context); + if (contextIntegrityCheckResult.isValid === false) { + throw new Error(`Failed to broadcast - bad Context. Reason: ${contextIntegrityCheckResult.reason}. Context: ${JSON.stringify(context)}`); + } + this.contextByContextType.set(context.type, context); + this.lastContext = context; + Array.from(this.clients.values()).forEach((currClientState) => { + const handlerIdsForContextType = currClientState.handlerIdsByContextTypes.get(context.type); + if (handlerIdsForContextType) { + handlerIdsForContextType.forEach((handlerId) => { + this.provider.dispatch(currClientState.clientIdentity, handlerId, context); + }); + } + if (currClientState.globalHandler) { + this.provider.dispatch(currClientState.clientIdentity, currClientState.globalHandler, context); + } + }); + } + getCurrentContext(payload, senderClientIdentity) { + const { contextType } = payload; + const clientState = this.getClientState(senderClientIdentity); + if (!clientState) { + throw new Error(`Client with Identity: ${senderClientIdentity.uuid} ${senderClientIdentity.name}, tried to call getCurrentContext, is not connected to this Private Channel`); + } + if (contextType !== undefined) { + const currentContext = this.contextByContextType.get(contextType); + if (currentContext) + return currentContext; + return null; + } + return this.lastContext ? this.lastContext : null; + } + contextHandlerAdded(payload, senderClientIdentity) { + const { handlerId, contextType } = payload; + const senderClientState = this.getClientState(senderClientIdentity); + if (!senderClientState) { + throw new Error(`Client with Identity: ${senderClientIdentity.uuid} ${senderClientIdentity.name}, tried to call addContextListener, is not connected to this Private Channel`); + } + if (contextType) { + const currentHandlersList = senderClientState.handlerIdsByContextTypes.get(contextType) || []; + senderClientState.handlerIdsByContextTypes.set(contextType, [...currentHandlersList, handlerId]); + } + else { + senderClientState.globalHandler = handlerId; + } + Array.from(this.clients.values()).forEach((currClientState) => { + if (currClientState.clientIdentity.endpointId !== senderClientIdentity.endpointId && + currClientState.onAddContextListenerHandlerId) { + this.provider.dispatch(currClientState.clientIdentity, currClientState.onAddContextListenerHandlerId, contextType); + } + }); + } + async contextHandlerRemoved(payload, removingClientIdentity) { + // MC: Made this removal async to ensure that onUnsubscribe handlers are hit before anything else happens. + const { handlerId } = payload; + const removingClientState = this.getClientState(removingClientIdentity); + if (removingClientState) { + let contextType; + if (removingClientState.globalHandler === handlerId) { + removingClientState.globalHandler = undefined; + } + else { + for (const [currContextType, handlersIds] of removingClientState.handlerIdsByContextTypes) { + const index = handlersIds.indexOf(handlerId); + if (index > -1) { + handlersIds.splice(index, 1); + contextType = currContextType; + } + } + } + // getting only valid client connections here, it is possible we haven't removed a disconnected client from the map yet + // so we need to ensure we don't dispatch to any disconnected client + // TODO: Take a look at our client disconnection logic and see if we can handle client disconnection cleanly + const clientsToDispatchTo = await this.getConnectedClients(); + const dispatchPromises = clientsToDispatchTo.map(async (otherClientState) => { + const { clientIdentity, clientIdentity: { endpointId }, onUnsubscribeHandlerId } = otherClientState; + if (endpointId !== removingClientIdentity.endpointId && onUnsubscribeHandlerId) { + await this.provider.dispatch(clientIdentity, onUnsubscribeHandlerId, contextType); + } + }); + try { + await Promise.all(dispatchPromises); + } + catch (error) { + console.error(`Problem when attempting to dispatch to onUnsubscribeHandlers. Error: ${error} Removing Client: ${handlerId}. uuid: ${removingClientIdentity.uuid}. name: ${removingClientIdentity.name}. endpointId: ${removingClientIdentity.endpointId}`); + throw new Error(error); + } + } + else { + console.warn(`Trying to remove a handler from a client that isn't mapped. handlerId: ${handlerId}. uuid: ${removingClientIdentity.uuid}. name: ${removingClientIdentity.name}. endpointId: ${removingClientIdentity.endpointId}.`); + } + } + nonStandardHandlerRemoved(payload, id) { + const { handlerId } = payload; + const clientState = this.getClientState(id); + if (clientState) { + if (clientState.onDisconnectHandlerId === handlerId) { + clientState.onDisconnectHandlerId = undefined; + } + else if (clientState.onAddContextListenerHandlerId === handlerId) { + clientState.onAddContextListenerHandlerId = undefined; + } + else if (clientState.onUnsubscribeHandlerId === handlerId) { + clientState.onUnsubscribeHandlerId = undefined; + } + } + else { + console.warn(`Trying to remove a handler from a client that isn't mapped. handlerId: ${handlerId}. clientIdentity: ${id}`); + } + } + onAddContextHandlerAdded(payload, senderClientIdentity) { + const clientState = this.getClientState(senderClientIdentity); + const { handlerId } = payload; + if (!clientState) { + throw new Error(`Client with Identity: ${senderClientIdentity.uuid} ${senderClientIdentity.name}, tried to call onAddContextListener, is not connected to this Private Channel`); + } + clientState.onAddContextListenerHandlerId = handlerId; + // FDC3 Spec says that the added listener should fire for all previously-registered addContextListeners from the other client + Array.from(this.clients.values()).forEach((otherClientState) => { + if (otherClientState.clientIdentity.endpointId !== senderClientIdentity.endpointId) { + Array.from(otherClientState.handlerIdsByContextTypes.keys()).forEach((subscribedContextType) => { + this.provider.dispatch(senderClientIdentity, handlerId, subscribedContextType); + }); + } + }); + } + onDisconnectHandlerAdded(payload, id) { + const clientState = this.getClientState(id); + const { handlerId } = payload; + if (!clientState) { + throw new Error(`Client with Identity: ${id.uuid} ${id.name}, tried to call onDisconnect, is not connected to this Private Channel`); + } + clientState.onDisconnectHandlerId = handlerId; + } + onUnsubscribeHandlerAdded(payload, id) { + const clientState = this.getClientState(id); + const { handlerId } = payload; + if (!clientState) { + throw new Error(`Client with Identity: ${id.uuid} ${id.name}, tried to call onUnsubscribe, is not connected to this Private Channel`); + } + clientState.onUnsubscribeHandlerId = handlerId; + } + removeClient(disconnectingClientIdentity) { + const disconnectingClientState = this.getClientState(disconnectingClientIdentity); + if (!disconnectingClientState) { + throw new Error(`Client with Identity: ${disconnectingClientIdentity.uuid} ${disconnectingClientIdentity.name}, tried to call disconnect, is not connected to this Private Channel`); + } + disconnectingClientState.handlerIdsByContextTypes.clear(); + this.clients.delete(disconnectingClientIdentity.endpointId); + } + async fireOnDisconnectForOtherClients(disconnectingClientIdentity) { + // TODO: call onDisconnect Handler of the other client only. + // CURRENTLY, just calling the onDisconnect handler for all the other clients. Once we limit it to just one other client, we can eliminate all the iteration code. + const { endpointId } = disconnectingClientIdentity; + // getting only valid client connections here, it is possible we haven't removed a disconnected client from the map yet + // so we need to ensure we don't dispatch to any disconnected client + // TODO: Take a look at our client disconnection logic and see if we can handle client disconnection cleanly + const clientsToDispatchTo = await this.getConnectedClients(); + const dispatchPromises = clientsToDispatchTo.map(async (otherClientState) => { + const { clientIdentity: { endpointId: otherClientEndpointId }, onDisconnectHandlerId } = otherClientState; + if (otherClientEndpointId !== endpointId && onDisconnectHandlerId) { + await this.provider.dispatch(otherClientState.clientIdentity, onDisconnectHandlerId); + } + }); + try { + await Promise.all(dispatchPromises); + } + catch (error) { + console.error(`Problem when attempting to dispatch to onDisconnectHandlers. Error: ${error} Disconnecting Client: uuid: ${disconnectingClientIdentity.uuid}. name: ${disconnectingClientIdentity.name}. endpointId: ${disconnectingClientIdentity.endpointId}`); + throw new Error(error); + } + } + async unsubscribeAll(clientIdentity) { + const { endpointId } = clientIdentity; + const state = this.clients.get(endpointId); + if (state) { + const contextTypeHandlerIds = Array.from(state.handlerIdsByContextTypes.values()).flat(); + const globalHandlerId = state.globalHandler; + if (contextTypeHandlerIds.length > 0) { + const unsubPromises = contextTypeHandlerIds.map(async (handlerId) => { + return this.contextHandlerRemoved({ handlerId }, clientIdentity); + }); + try { + await Promise.all(unsubPromises); + } + catch (error) { + console.error(error.message); + } + } + if (globalHandlerId) { + try { + await this.contextHandlerRemoved({ handlerId: globalHandlerId }, clientIdentity); + } + catch (error) { + console.error(error.message); + } + } + } + } + async handleClientDisconnecting(disconnectingClientIdentity) { + await this.unsubscribeAll(disconnectingClientIdentity); + this.removeClient(disconnectingClientIdentity); + await this.fireOnDisconnectForOtherClients(disconnectingClientIdentity); + } + registerNewClient(clientIdentity) { + if (!this.clients.has(clientIdentity.endpointId)) { + const clientSubscriptionState = { + clientIdentity, + handlerIdsByContextTypes: new Map(), + globalHandler: undefined, + onAddContextListenerHandlerId: undefined, + onUnsubscribeHandlerId: undefined, + onDisconnectHandlerId: undefined + }; + this.clients.set(clientIdentity.endpointId, clientSubscriptionState); + } + } + async getConnectedClients() { + const allClientInfo = await this.provider.getAllClientInfo(); + return Array.from(this.clients.values()).filter((clientState) => { + const { uuid, name } = clientState.clientIdentity; + return allClientInfo.some((clientInfo) => { + return name === clientInfo.name && uuid === clientInfo.uuid; + }); + }); + } + static init(channelProvider, id) { + return new PrivateChannelProvider(channelProvider, id); + } + }; + PrivateChannelProvider.PrivateChannelProvider = PrivateChannelProvider$1; + return PrivateChannelProvider; +} + +var hasRequiredInteropBroker; + +function requireInteropBroker () { + if (hasRequiredInteropBroker) return InteropBroker; + hasRequiredInteropBroker = 1; + var __classPrivateFieldSet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + }; + var __classPrivateFieldGet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + var _InteropBroker_fdc3Info, _InteropBroker_contextGroups, _InteropBroker_providerPromise; + Object.defineProperty(InteropBroker, "__esModule", { value: true }); + InteropBroker.InteropBroker = void 0; + const base_1 = base; + const SessionContextGroupBroker_1 = __importDefault(requireSessionContextGroupBroker()); + const utils_1 = utils$3; + const isEqual_1 = __importDefault(require$$3); + const PrivateChannelProvider_1 = requirePrivateChannelProvider(); + const lazy_1 = lazy; + const defaultContextGroups = [ + { + id: 'green', + displayMetadata: { + color: '#00CC88', + name: 'green' + } + }, + { + id: 'purple', + displayMetadata: { + color: '#8C61FF', + name: 'purple' + } + }, + { + id: 'orange', + displayMetadata: { + color: '#FF8C4C', + name: 'orange' + } + }, + { + id: 'red', + displayMetadata: { + color: '#FF5E60', + name: 'red' + } + }, + { + id: 'pink', + displayMetadata: { + color: '#FF8FB8', + name: 'pink' + } + }, + { + id: 'yellow', + displayMetadata: { + color: '#E9FF8F', + name: 'yellow' + } + } + ]; + /** + * {@link https://developers.openfin.co/of-docs/docs/enable-color-linking} + * + * The Interop Broker is responsible for keeping track of the Interop state of the Platform, and for directing messages to the proper locations. + * + * @remarks This class contains some types related to FDC3 that are specific to OpenFin. {@link https://developers.openfin.co/of-docs/docs/fdc3-support-in-openfin OpenFin's FDC3 support} is forward- and backward-compatible. + * Standard types for {@link https://fdc3.finos.org/ FDC3} do not appear in OpenFin’s API documentation, to avoid duplication. + * + * --- + * + * There are 2 ways to inject custom functionality into the Interop Broker: + * + * **1. Configuration** + * + * At the moment, you can configure the default context groups for the Interop Broker without having to override it. To do so, include the `interopBrokerConfiguration` `contextGroups` option in your `platform` options in your manifest. This is the preferred method. + * ```js + * { + * "runtime": { + * "arguments": "--v=1 --inspect", + * "version": "alpha-v19" + * }, + * "platform": { + * "uuid": "platform_customization_local", + * "applicationIcon": "https://openfin.github.io/golden-prototype/favicon.ico", + * "autoShow": false, + * "providerUrl": "http://localhost:5555/provider.html", + * "interopBrokerConfiguration": { + * "contextGroups": [ + * { + * "id": "green", + * "displayMetadata": { + * "color": "#00CC88", + * "name": "green" + * } + * }, + * { + * "id": "purple", + * "displayMetadata": { + * "color": "#8C61FF", + * "name": "purple" + * } + * }, + * ] + * } + * } + * } + * ``` + * + * By default the Interop Broker logs all actions to the console. You can disable this by using the logging option in `interopBrokerConfiguration`: + * ```js + * { + * "runtime": { + * "arguments": "--v=1 --inspect", + * "version": "alpha-v19" + * }, + * "platform": { + * "uuid": "platform_customization_local", + * "applicationIcon": "https://openfin.github.io/golden-prototype/favicon.ico", + * "autoShow": false, + * "providerUrl": "http://localhost:5555/provider.html", + * "interopBrokerConfiguration": { + * "logging": { + * "beforeAction": { + * "enabled": false + * }, + * "afterAction": { + * "enabled": false + * } + * } + * } + * } + * } + * ``` + * + * --- + * **2. Overriding** + * + * Similarly to how {@link https://developers.openfin.co/docs/platform-customization#section-customizing-platform-behavior Platform Overriding} works, you can override functions in the Interop Broker in `fin.Platform.init`. An example of that is shown below. Overriding `isConnectionAuthorized` and `isActionAuthorized` will allow you to control allowed connections and allowed actions. + * + * However, if there is custom functionality you wish to include in the Interop Broker, please let us know. We would like to provide better configuration options so that you don't have to continually maintain your own override code. + * + * ```js + * fin.Platform.init({ + * overrideCallback: async (Provider) => { + * class Override extends Provider { + * async getSnapshot() { + * console.log('before getSnapshot') + * const snapshot = await super.getSnapshot(); + * console.log('after getSnapshot') + * return snapshot; + * } + * + * async applySnapshot({ snapshot, options }) { + * console.log('before applySnapshot') + * const originalPromise = super.applySnapshot({ snapshot, options }); + * console.log('after applySnapshot') + * + * return originalPromise; + * } + * }; + * return new Override(); + * }, + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async joinContextGroup(channelName = 'default', target) { + * console.log('before super joinContextGroup') + * super.joinContextGroup(channelName, target); + * console.log('after super joinContextGroup') + * } + * } + * + * return new Override(); + * } + * }); + * ``` + * + * --- + * + */ + let InteropBroker$1 = class InteropBroker extends base_1.Base { + /** + * @internal + */ + constructor(wire, createProvider, options) { + // Tip from Pierre and Michael from the overrideCheck work: Don't use bound methods for overrideable InteropBroker functions. + super(wire); + _InteropBroker_fdc3Info.set(this, void 0); + _InteropBroker_contextGroups.set(this, void 0); + _InteropBroker_providerPromise.set(this, void 0); + this.getProvider = () => { + return __classPrivateFieldGet(this, _InteropBroker_providerPromise, "f").getValue(); + }; + this.interopClients = new Map(); + this.contextGroupsById = new Map(); + __classPrivateFieldSet(this, _InteropBroker_contextGroups, options.contextGroups ?? [...defaultContextGroups], "f"); + __classPrivateFieldSet(this, _InteropBroker_fdc3Info, options.fdc3Info, "f"); + if (options?.logging) { + this.logging = options.logging; + } + this.intentClientMap = new Map(); + this.lastContextMap = new Map(); + this.sessionContextGroupMap = new Map(); + __classPrivateFieldSet(this, _InteropBroker_providerPromise, new lazy_1.Lazy(createProvider), "f"); + this.setContextGroupMap(); + this.setupChannelProvider(); + } + static createClosedConstructor(...args) { + return class OverrideableBroker extends InteropBroker { + constructor(...unused) { + if (unused.length) { + const [_ignore1, ignore2, opts] = unused; + if (opts && typeof opts === 'object' && !(0, isEqual_1.default)(opts, args[2])) { + // eslint-disable-next-line no-console + console.warn('You have modified the parameters of the InteropOverride constructor. This behavior is deprecated and will be removed in a future version. You can modify these options in your manifest. Please consult our Interop docs for guidance on migrating to the new override scheme.'); + super(args[0], args[1], opts); + return; + } + // eslint-disable-next-line no-console + console.warn('You are attempting to pass arguments to the InteropOverride constructor. This is not necessary, and these passed arguments will be ignored. You are likely using an older InteropBroker override scheme. Please consult our Interop docs for guidance on migrating to the new override scheme.'); + } + super(...args); + } + }; + } + /* + Client API + */ + /** + * Sets a context for the context group of the incoming current entity. + * @param setContextOptions - New context to set. + * @param clientIdentity - Identity of the client sender. + * + */ + setContext({ context }, clientIdentity) { + this.wire.sendAction('interop-broker-set-context').catch((e) => { + // don't expose, analytics-only call + }); + const clientState = this.getClientState(clientIdentity); + if (clientState && clientState.contextGroupId) { + const { contextGroupId } = clientState; + this.setContextForGroup({ context }, contextGroupId); + } + else if (clientState) { + // Client has not joined any context group behavior. + throw new Error('You must join a context group before you can set context.'); + } + else { + // This shouldn't get hit. + throw new Error(`Client with Identity: ${clientIdentity.uuid} ${clientIdentity.name} not in Client State Map`); + } + } + /** + * Sets a context for the context group. + * @param setContextOptions - New context to set. + * @param contextGroupId - Context group id. + * + */ + setContextForGroup({ context }, contextGroupId) { + this.wire.sendAction('interop-broker-set-context-for-group').catch((e) => { + // don't expose, analytics-only call + }); + const contextGroupState = this.contextGroupsById.get(contextGroupId); + if (!contextGroupState) { + throw new Error(`Unable to set context for context group that isn't in the context group mapping: ${contextGroupId}.`); + } + const contextIntegrityCheckResult = InteropBroker.checkContextIntegrity(context); + if (contextIntegrityCheckResult.isValid === false) { + throw new Error(`Failed to set Context - bad Context. Reason: ${contextIntegrityCheckResult.reason}. Context: ${JSON.stringify(context)}`); + } + const broadcastedContextType = context.type; + contextGroupState.set(broadcastedContextType, context); + this.lastContextMap.set(contextGroupId, broadcastedContextType); + const clientsInSameContextGroup = Array.from(this.interopClients.values()).filter((connectedClient) => connectedClient.contextGroupId === contextGroupId); + clientsInSameContextGroup.forEach((client) => { + for (const [, handlerInfo] of client.contextHandlers) { + if (InteropBroker.isContextTypeCompatible(broadcastedContextType, handlerInfo.contextType)) { + this.invokeContextHandler(client.clientIdentity, handlerInfo.handlerId, context); + } + } + }); + } + /** + * Get current context for a client subscribed to a Context Group. + * + * @remarks It takes an optional Context Type argument and returns the last context of that type. + * + * @param getContextOptions - Options for getting context + * @param clientIdentity - Identity of the client sender. + * + */ + getCurrentContext(getCurrentContextOptions, clientIdentity) { + this.wire.sendAction('interop-broker-get-current-context').catch((e) => { + // don't expose, analytics-only call + }); + const clientState = this.getClientState(clientIdentity); + if (!clientState?.contextGroupId) { + throw new Error('You must be a member of a context group to call getCurrentContext'); + } + const { contextGroupId } = clientState; + const contextGroupState = this.contextGroupsById.get(contextGroupId); + const lastContextType = this.lastContextMap.get(contextGroupId); + const contextType = getCurrentContextOptions?.contextType ?? lastContextType; + return contextGroupState && contextType ? contextGroupState.get(contextType) : undefined; + } + /* + Platform Window APIs + */ + // joinContextGroup and addClientToContextGroup are separate functions here, for easier overrides and separation of concerns. + // joinContextGroup checks all connections for matching identities, in case we have multiple connection from an entity. + /** + * Join all connections at the given identity (or just one if endpointId provided) to context group `contextGroupId`. + * If no target is specified, it adds the sender to the context group. + * joinContextGroup is responsible for checking connections at the incoming identity. It calls {@link InteropBroker#addClientToContextGroup InteropBroker.addClientToContextGroup} to actually group the client. + * Used by Platform Windows. + * + * @param joinContextGroupOptions - Id of the Context Group and identity of the entity to join to the group. + * @param senderIdentity - Identity of the client sender. + */ + async joinContextGroup({ contextGroupId, target }, senderIdentity) { + this.wire.sendAction('interop-broker-join-context-group').catch((e) => { + // don't expose, analytics-only call + }); + if (this.sessionContextGroupMap.has(contextGroupId)) { + throw new Error(utils_1.BROKER_ERRORS.joinSessionContextGroupWithJoinContextGroup); + } + if (target) { + // If an endpointId is provided, use that. This will likely be used by external adapters. + if (InteropBroker.hasEndpointId(target)) { + await this.addClientToContextGroup({ contextGroupId }, target); + } + // Sanity check here in case a single app has multiple connections + try { + const allConnections = this.channel.connections.filter((x) => x.uuid === target.uuid && x.name === target.name); + if (!allConnections.length) { + throw new Error(`Given Identity ${target.uuid} ${target.name} is not connected to the Interop Broker.`); + } + if (allConnections.length > 1) { + // Should figure out how we want to handle this situation. In the meantime, just change context group for all connections. + console.warn(`More than one connection found for identity ${target.uuid} ${target.name}`); + } + const promises = []; + for (const connection of allConnections) { + promises.push(this.addClientToContextGroup({ contextGroupId }, connection)); + } + await Promise.all(promises); + } + catch (error) { + throw new Error(error); + } + } + else { + // No target provided, add the sender to the context group. + await this.addClientToContextGroup({ contextGroupId }, senderIdentity); + } + } + // addClientToContextGroup does the actual addition of the client to the Context Group + /** + * Helper function for {@link InteropBroker#joinContextGroup InteropBroker.joinContextGroup}. Does the work of actually adding the client to the Context Group. + * Used by Platform Windows. + * + * @param addClientToContextGroupOptions - Contains the contextGroupId + * @param clientIdentity - Identity of the client sender. + */ + async addClientToContextGroup({ contextGroupId }, clientIdentity) { + this.wire.sendAction('interop-broker-add-client-to-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const clientSubscriptionState = this.getClientState(clientIdentity); + if (!clientSubscriptionState) { + throw new Error(`Client with Identity: ${clientIdentity.uuid} ${clientIdentity.name} not in Client State Map`); + } + if (!this.getContextGroups().find((contextGroupInfo) => contextGroupInfo.id === contextGroupId)) { + throw new Error(`Attempting to join a context group that does not exist: ${contextGroupId}. You may only join existing context groups.`); + } + const oldContextGroupId = clientSubscriptionState.contextGroupId; + if (oldContextGroupId !== contextGroupId) { + clientSubscriptionState.contextGroupId = contextGroupId; + await this.setCurrentContextGroupInClientOptions(clientIdentity, contextGroupId); + const contextGroupMap = this.contextGroupsById.get(contextGroupId); + for (const [, handlerInfo] of clientSubscriptionState.contextHandlers) { + const { contextType, handlerId } = handlerInfo; + if (contextType === undefined) { + // Send this single handler all of the context, because it accepts all. + contextGroupMap.forEach((context, _) => { + this.invokeContextHandler(clientIdentity, handlerId, context); + }); + } + else if (contextGroupMap.has(contextType)) { + const contextForType = contextGroupMap.get(contextType); + if (contextForType) { + this.invokeContextHandler(clientIdentity, handlerId, contextForType); + } + } + } + } + } + // Removes the target from its context group. Similar structure to joinContextGroup. + /** + * Removes the specified target from a context group. + * If no target is specified, it removes the sender from their context group. + * removeFromContextGroup is responsible for checking connections at the incoming identity. + * + * @remarks It calls {@link InteropBroker#removeClientFromContextGroup InteropBroker.removeClientFromContextGroup} to actually ungroup + * the client. Used by Platform Windows. + * + * @param removeFromContextGroupOptions - Contains the target identity to remove. + * @param senderIdentity - Identity of the client sender. + */ + async removeFromContextGroup({ target }, senderIdentity) { + this.wire.sendAction('interop-broker-remove-from-context-group').catch((e) => { + // don't expose, analytics-only call + }); + if (target) { + // If an endpointId is provided, use that. This will likely be used by external adapters. + if (InteropBroker.hasEndpointId(target)) { + await this.removeClientFromContextGroup(target); + } + try { + // Sanity check here in case a single app has multiple connections + const allConnections = this.channel.connections.filter((x) => x.uuid === target.uuid && x.name === target.name); + if (!allConnections.length) { + throw new Error(`No connection found for given Identity ${target.uuid} ${target.name}`); + } + if (allConnections.length > 1) { + console.warn(`More than one connection found for identity ${target.uuid} ${target.name}`); + } + const promises = []; + for (const connection of allConnections) { + promises.push(this.removeClientFromContextGroup(connection)); + } + await Promise.all(promises); + } + catch (error) { + throw new Error(error); + } + } + else { + // No target provided, remove the sender from the context group. + await this.removeClientFromContextGroup(senderIdentity); + } + } + // removeClientFromContextGroup does the actual remove of the client from the Context Group + /** + * Helper function for {@link InteropBroker#removeFromContextGroup InteropBroker.removeFromContextGroup}. Does the work of actually removing the client from the Context Group. + * Used by Platform Windows. + * + * @property { ClientIdentity } clientIdentity - Identity of the client sender. + */ + async removeClientFromContextGroup(clientIdentity) { + this.wire.sendAction('interop-broker-remove-client-from-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const clientState = this.getClientState(clientIdentity); + if (clientState) { + clientState.contextGroupId = undefined; + } + await this.setCurrentContextGroupInClientOptions(clientIdentity, null); + } + // Used by platform windows to know what client groups the provider has declared. Also used internally to access context groups. Overrideable so that the platform developer can modify it. + /** + * Returns the Interop-Broker-defined context groups available for an entity to join. Because this function is used in the rest of the Interop Broker to fetch the Context Groups, overriding this allows you to customize the Context Groups for the Interop Broker. However, we recommend customizing the context groups through configuration instead. + * Used by Platform Windows. + * + */ + // eslint-disable-next-line class-methods-use-this + getContextGroups() { + this.wire.sendAction('interop-broker-get-context-groups').catch((e) => { + // don't expose, analytics-only call + }); + // Create copy for immutability + return __classPrivateFieldGet(this, _InteropBroker_contextGroups, "f").map((contextGroup) => { + return { ...contextGroup }; + }); + } + // Used to by platform windows to get display metadata for a context group. + /** + * Gets display info for a context group + * + * @remarks Used by Platform Windows. + * + * @param getInfoForContextGroupOptions - Contains contextGroupId, the context group you wish to get display info for. + * + */ + getInfoForContextGroup({ contextGroupId }) { + this.wire.sendAction('interop-broker-get-info-for-context-group').catch((e) => { + // don't expose, analytics-only call + }); + return this.getContextGroups().find((contextGroup) => contextGroup.id === contextGroupId); + } + // Used by platform windows to get all clients for a context group. + /** + * Gets all clients for a context group. + * + * @remarks **This is primarily used for platform windows. Views within a platform should not have to use this API.** + * Returns the Interop-Broker-defined context groups available for an entity to join. + * + * @param getAllClientsInContextGroupOptions - Contains contextGroupId, the context group you wish to get clients for. + * + */ + getAllClientsInContextGroup({ contextGroupId }) { + this.wire.sendAction('interop-broker-get-all-clients-in-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const clientsInContextGroup = Array.from(this.interopClients.values()) + .filter((connectedClient) => connectedClient.contextGroupId === contextGroupId) + .map((subscriptionState) => { + return subscriptionState.clientIdentity; + }); + return clientsInContextGroup; + } + /** + * Responsible for launching of applications that can handle a given intent, and delegation of intents to those applications. + * Must be overridden. + * + * @remarks To make this call FDC3-Compliant it would need to return an IntentResolution. + * + * ```js + * interface IntentResolution { + * source: TargetApp; + * // deprecated, not assignable from intent listeners + * data?: object; + * version: string; + * } + * ``` + * + * More information on the IntentResolution type can be found in the [FDC3 documentation](https://fdc3.finos.org/docs/api/ref/IntentResolution). + * + * @param intent The combination of an action and a context that is passed to an application for resolution. + * @param clientIdentity Identity of the Client making the request. + * + * @example + * ```js + * // override call so we set intent target and create view that will handle it + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async handleFiredIntent(intent) { + * super.setIntentTarget(intent, { uuid: 'platform-uuid', name: 'intent-view' }); + * const platform = fin.Platform.getCurrentSync(); + * const win = fin.Window.wrapSync({ name: 'foo', uuid: 'platform-uuid' }); + * const createdView = await platform.createView({ url: 'http://openfin.co', name: 'intent-view' }, win.identity); + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + // eslint-disable-next-line class-methods-use-this + async handleFiredIntent(intent, clientIdentity // TODO(CORE-811): remove inline intersected type + ) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.raiseIntent', 'InteropBroker.handleFiredIntent', clientIdentity, 'interopClient.fireIntent'); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.fireIntent); + } + /** + * Should be called in {@link InteropBroker#handleFiredIntent InteropBroker.handleFiredIntent}. + * While handleFiredIntent is responsible for launching applications, setIntentTarget is used to tell the InteropBroker which application should receive the intent when it is ready. + * @param intent The combination of an action and a context that is passed to an application for resolution. + * @param target - Identity of the target that will handle the intent. + * + */ + async setIntentTarget(intent, target) { + this.wire.sendAction('interop-broker-set-intent-target').catch((e) => { + // don't expose, this is only for api analytics purposes + }); + const targetInfo = this.intentClientMap.get(target.name); + const handlerId = `intent-handler-${intent.name}`; + if (!targetInfo) { + this.intentClientMap.set(target.name, new Map()); + const newHandlerInfoMap = this.intentClientMap.get(target.name); + if (newHandlerInfoMap) { + newHandlerInfoMap.set(handlerId, { isReady: false, pendingIntents: [intent] }); + } + } + else { + const handlerInfo = targetInfo.get(handlerId); + if (!handlerInfo) { + targetInfo.set(handlerId, { isReady: false, pendingIntents: [intent] }); + } + else { + handlerInfo.pendingIntents.push(intent); + if (handlerInfo.clientIdentity && handlerInfo.isReady) { + const { clientIdentity, pendingIntents } = handlerInfo; + try { + const intentToSend = pendingIntents[pendingIntents.length - 1]; + await this.invokeIntentHandler(clientIdentity, handlerId, intentToSend); + handlerInfo.pendingIntents = []; + } + catch (error) { + console.error(`Error invoking intent handler for client ${clientIdentity.uuid}/${clientIdentity.name}/${clientIdentity.endpointId}`); + handlerInfo.isReady = false; + } + } + } + } + } + /** + * Responsible for returning information on a particular Intent. + * + * @remarks Whenever InteropClient.getInfoForIntent is called this function will fire. The options argument gives you + * access to the intent name and any optional context that was passed and clientIdentity is the identity of the client + * that made the call. Ideally here you would fetch the info for the intent and return it with the shape that the + * InteropClient.getInfoForIntent call is expecting. + * + * To make this call FDC3-Compliant it would need to return an App Intent: + * + * ```js + * // { + * // intent: { name: "StartChat", displayName: "Chat" }, + * // apps: [{ name: "Skype" }, { name: "Symphony" }, { name: "Slack" }] + * // } + * ``` + * + * More information on the AppIntent type can be found in the [FDC3 documentation](https://fdc3.finos.org/docs/api/ref/AppIntent). + * + * @param options + * @param clientIdentity Identity of the Client making the request. + * + * @example + * ```js + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async handleInfoForIntent(options, clientIdentity) { + * // Your code goes here. + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + // eslint-disable-next-line class-methods-use-this + async handleInfoForIntent(options, clientIdentity // TODO(CORE-811): remove inline intersected type + ) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.findIntent', 'InteropBroker.handleInfoForIntent', clientIdentity, 'interopClient.getInfoForIntent'); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.getInfoForIntent); + } + /** + * Responsible for returning information on which Intents are meant to handle a specific Context. + * Must be overridden. + * + * @remarks Responsible for returning information on which Intents are meant to handle a specific Context. Must be overridden. + * + * Whenever InteropClient.getInfoForIntentsByContext is called this function will fire. The context argument gives you access to the context that the client wants information on and clientIdentity is the identity of the client that made the call. Ideally here you would fetch the info for any intent that can handle and return it with the shape that the InteropClient.getInfoForIntentsByContext call is expecting. + * + * To make this call FDC3-Compliant it would need to return an array of AppIntents: + * + * ```js + * // [{ + * // intent: { name: "StartCall", displayName: "Call" }, + * // apps: [{ name: "Skype" }] + * // }, + * // { + * // intent: { name: "StartChat", displayName: "Chat" }, + * // apps: [{ name: "Skype" }, { name: "Symphony" }, { name: "Slack" }] + * // }]; + * ``` + * + * More information on the AppIntent type can be found in the [FDC3 documentation](https://fdc3.finos.org/docs/api/ref/AppIntent). + * + * @param context Data passed between entities and applications. + * @param clientIdentity Identity of the Client making the request. + * + * @example + * ```js + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async handleInfoForIntentsByContext(context, clientIdentity) { + * // Your code goes here. + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + // eslint-disable-next-line class-methods-use-this + async handleInfoForIntentsByContext(context, clientIdentity // TODO(CORE-811): remove inline intersected type + ) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.findIntentsByContext', 'InteropBroker.handleInfoForIntentsByContext', clientIdentity, 'interopClient.getInfoForIntentsByContext'); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.getInfoForIntentsByContext); + } + /** + * Responsible for resolving an Intent based on a specific Context. + * Must be overridden. + * + * @remarks Whenever InteropClient.fireIntentForContext is called this function will fire. The contextForIntent argument + * gives you access to the context that will be resolved to an intent. It also can optionally contain any metadata relevant + * to resolving it, like a specific app the client wants the context to be handled by. The clientIdentity is the identity + * of the client that made the call. + * + * To make this call FDC3-Compliant it would need to return an IntentResolution: + * + * ```js + * // { + * // intent: { name: "StartChat", displayName: "Chat" }, + * // apps: [{ name: "Skype" }, { name: "Symphony" }, { name: "Slack" }] + * // } + * ``` + * + * More information on the IntentResolution type can be found in the [FDC3 documentation](https://fdc3.finos.org/docs/api/ref/Metadata#intentresolution). + * + * @param contextForIntent Data passed between entities and applications. + * @param clientIdentity Identity of the Client making the request. + * + * @example + * ```js + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async handleFiredIntentForContext(contextForIntent, clientIdentity) { + * // Your code goes here. + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + // eslint-disable-next-line class-methods-use-this + async handleFiredIntentForContext(contextForIntent, clientIdentity) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.raiseIntentForContext', 'InteropBroker.handleFiredIntentForContext', clientIdentity, 'interopClient.fireIntentForContext'); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.fireIntentForContext); + } + /** + * Provides the identity of any Interop Client that disconnects from the Interop Broker. It is meant to be overriden. + * @param clientIdentity + * + * @example + * ```js + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async clientDisconnected(clientIdentity) { + * const { uuid, name } = clientIdentity; + * console.log(`Client with identity ${uuid}/${name} has been disconnected`); + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + // eslint-disable-next-line class-methods-use-this + async clientDisconnected(clientIdentity) { + // This function is called in channel.onDisconnection. + // It is meant to be overridden to inform when an Interop Client has been disconnected. + } + /** + * Responsible for resolving an fdc3.open call. + * Must be overridden. + * @param fdc3OpenOptions fdc3.open options + * @param clientIdentity Identity of the Client making the request. + */ + // eslint-disable-next-line class-methods-use-this + async fdc3HandleOpen({ app, context }, clientIdentity) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.open', 'InteropBroker.fdc3HandleOpen', clientIdentity); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.fdc3Open); + } + /** + * Responsible for resolving the fdc3.findInstances call. + * Must be overridden + * @param app AppIdentifier that was passed to fdc3.findInstances + * @param clientIdentity Identity of the Client making the request. + */ + // eslint-disable-next-line class-methods-use-this + async fdc3HandleFindInstances(app, clientIdentity) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.open', 'InteropBroker.fdc3HandleFindInstances', clientIdentity); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.fdc3FindInstances); + } + /** + * Responsible for resolving the fdc3.getAppMetadata call. + * Must be overridden + * @param app AppIdentifier that was passed to fdc3.getAppMetadata + * @param clientIdentity Identity of the Client making the request. + */ + // eslint-disable-next-line class-methods-use-this + async fdc3HandleGetAppMetadata(app, clientIdentity) { + const warning = (0, utils_1.generateOverrideWarning)('fdc3.getAppMetadata', 'InteropBroker.fdc3HandleGetAppMetadata', clientIdentity); + console.warn(warning); + throw new Error(utils_1.BROKER_ERRORS.fdc3GetAppMetadata); + } + /** + * This function is called by the Interop Broker whenever a Context handler would fire. + * For FDC3 2.0 you would need to override this function and add the contextMetadata as + * part of the Context object. Then would you need to call + * super.invokeContextHandler passing it this new Context object along with the clientIdentity and handlerId + * @param clientIdentity + * @param handlerId + * @param context + * + * @example + * ```js + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async invokeContextHandler(clientIdentity, handlerId, context) { + * return super.invokeContextHandler(clientIdentity, handlerId, { + * ...context, + * contextMetadata: { + * source: { + * appId: 'openfin-app', + * instanceId: '3D54D456D9HT0' + * } + * } + * }); + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + async invokeContextHandler(clientIdentity, handlerId, context) { + const provider = await this.getProvider(); + try { + await provider.dispatch(clientIdentity, handlerId, context); + } + catch (error) { + console.error(`Error invoking context handler ${handlerId} for context type ${context.type} in client ${clientIdentity.uuid}/${clientIdentity.name}/${clientIdentity.endpointId}`, error); + } + } + /** + * This function is called by the Interop Broker whenever an Intent handler would fire. + * For FDC3 2.0 you would need to override this function and add the contextMetadata as + * part of the Context object inside the Intent object. Then would you need to call + * super.invokeIntentHandler passing it this new Intent object along with the clientIdentity and handlerId + * @param ClientIdentity + * @param handlerId + * @param context + * + * @example + * ```js + * fin.Platform.init({ + * interopOverride: async (InteropBroker) => { + * class Override extends InteropBroker { + * async invokeIntentHandler(clientIdentity, handlerId, context) { + * const { context } = intent; + * return super.invokeIntentHandler(clientIdentity, handlerId, { + * ...intent, + * context: { + * ...context, + * contextMetadata: { + * source: { + * appId: 'openfin-app', + * instanceId: '3D54D456D9HT0' + * } + * } + * } + * }); + * } + * } + * return new Override(); + * } + * }); + * ``` + */ + async invokeIntentHandler(clientIdentity, handlerId, intent) { + const provider = await this.getProvider(); + await provider.dispatch(clientIdentity, handlerId, intent); + } + /** + * Responsible for resolving fdc3.getInfo for FDC3 2.0 + * Would need to return the optionalFeatures and appMetadata for the {@link https://fdc3.finos.org/docs/api/ref/Metadata#implementationmetadata ImplementationMetadata}. + * Must be overridden. + * @param clientIdentity + * + */ + // eslint-disable-next-line class-methods-use-this + async fdc3HandleGetInfo(payload, clientIdentity) { + const { fdc3Version } = payload; + return { + fdc3Version, + ...__classPrivateFieldGet(this, _InteropBroker_fdc3Info, "f"), + optionalFeatures: { + OriginatingAppMetadata: false, + UserChannelMembershipAPIs: true + }, + appMetadata: { + appId: '', + instanceId: '' + } + }; + } + /** + * Returns an array of info for each Interop Client connected to the Interop Broker. + * + * FDC3 2.0: Use the endpointId in the ClientInfo as the instanceId when generating + * an AppIdentifier. + * + * @remarks FDC3 2.0 Note: When needing an instanceId to generate an AppIdentifier use this call to + * get the endpointId and use it as the instanceId. In the Example below we override handleFiredIntent + * and then call super.getAllClientInfo to generate the AppIdentifier for the IntentResolution. + * + * + * @example + * ```js + * // FDC3 2.0 Example: + * fin.Platform.init({ + * interopOverride: async (InteropBroker, ...args) => { + * class Override extends InteropBroker { + * async handleFiredIntent(intent) { + * super.setIntentTarget(intent, { uuid: 'platform-uuid', name: 'intent-view' }); + * const platform = fin.Platform.getCurrentSync(); + * const win = fin.Window.wrapSync({ name: 'foo', uuid: 'platform-uuid' }); + * const createdView = await platform.createView({ url: 'http://openfin.co', name: 'intent-view' }, win.identity); + * + * const allClientInfo = await super.getAllClientInfo(); + * + * const infoForTarget = allClientInfo.find((clientInfo) => { + * return clientInfo.uuid === 'platform-uuid' && clientInfo.name === 'intent-view'; + * }); + * + * const source = { + * appId: 'intent-view', + * instanceId: infoForTarget.endpointId + * } + * + * return { + * source, + * intent: intent.name + * } + * + * } + * } + * return new Override(...args); + * } + * }); + * ``` + */ + async getAllClientInfo() { + const provider = await this.getProvider(); + return provider.getAllClientInfo(); + } + /* + Snapshot APIs + */ + // Used to save interop broker state in snapshots + decorateSnapshot(snapshot) { + return { ...snapshot, interopSnapshotDetails: { contextGroupStates: this.getContextGroupStates() } }; + } + // Used to restore interop broker state in snapshots. + applySnapshot(snapshot, options) { + const contextGroupStates = snapshot?.interopSnapshotDetails?.contextGroupStates; + if (contextGroupStates) { + if (!options?.closeExistingWindows) { + this.updateExistingClients(contextGroupStates); + } + this.rehydrateContextGroupStates(contextGroupStates); + } + } + updateExistingClients(contextGroupStates) { + const clients = this.interopClients; + clients.forEach((subState) => { + const { clientIdentity, contextGroupId, contextHandlers } = subState; + if (contextGroupId) { + const groupContexts = contextGroupStates[contextGroupId]; + for (const [, context] of Object.entries(groupContexts)) { + contextHandlers.forEach((contextHandler) => { + const { handlerId, contextType } = contextHandler; + if (InteropBroker.isContextTypeCompatible(context.type, contextType)) { + this.invokeContextHandler(clientIdentity, handlerId, context); + } + }); + } + } + }); + } + // Used to store context group state in snapshots + getContextGroupStates() { + return InteropBroker.toObject(this.contextGroupsById); + } + // Used to rehydrate the context state from a snapshot + rehydrateContextGroupStates(incomingContextGroupStates) { + const contextGroupStates = Object.entries(incomingContextGroupStates); + for (const [contextGroupId, contexts] of contextGroupStates) { + const contextObjects = Object.entries(contexts); + for (const [contextType, context] of contextObjects) { + if (this.contextGroupsById.has(contextGroupId)) { + const currentContextGroupState = this.contextGroupsById.get(contextGroupId); + currentContextGroupState.set(contextType, context); + } + else { + // This logic will change when dynamic context group creation comes in. + console.warn(`Attempting to set a context group that isn't in the context group mapping. Skipping context group rehydration for: ${contextGroupId}`); + } + } + } + } + /* + Internal Context Handler APIs + */ + // Used to give context to a client that has registered their context handler + contextHandlerRegistered({ contextType, handlerId }, clientIdentity) { + const handlerInfo = { contextType, handlerId }; + const clientState = this.getClientState(clientIdentity); + clientState?.contextHandlers.set(handlerId, handlerInfo); + if (clientState && clientState.contextGroupId) { + const { contextGroupId } = clientState; + const contextGroupMap = this.contextGroupsById.get(contextGroupId); + if (contextType === undefined) { + // Send this single handler all of the context, because it accepts all. + contextGroupMap.forEach((context, _) => { + this.invokeContextHandler(clientIdentity, handlerId, context); + }); + } + else if (contextGroupMap.has(contextType)) { + const contextForType = contextGroupMap.get(contextType); + if (contextForType) { + this.invokeContextHandler(clientIdentity, handlerId, contextForType); + } + } + } + } + // eslint-disable-next-line class-methods-use-this + async intentHandlerRegistered(payload, clientIdentity) { + const { handlerId } = payload; + const clientIntentInfo = this.intentClientMap.get(clientIdentity.name); + const handlerInfo = clientIntentInfo?.get(handlerId); + if (!clientIntentInfo) { + this.intentClientMap.set(clientIdentity.name, new Map()); + const newHandlerInfoMap = this.intentClientMap.get(clientIdentity.name); + if (newHandlerInfoMap) { + newHandlerInfoMap.set(handlerId, { isReady: true, pendingIntents: [], clientIdentity }); + } + } + else if (!handlerInfo) { + clientIntentInfo.set(handlerId, { isReady: true, pendingIntents: [], clientIdentity }); + } + else { + const { pendingIntents } = handlerInfo; + handlerInfo.clientIdentity = clientIdentity; + handlerInfo.isReady = true; + try { + if (pendingIntents.length > 0) { + const intentToSend = pendingIntents[pendingIntents.length - 1]; + await this.invokeIntentHandler(clientIdentity, handlerId, intentToSend); + handlerInfo.pendingIntents = []; + } + } + catch (error) { + console.error(`Error invoking intent handler: ${handlerId} for client ${clientIdentity.uuid}/${clientIdentity.name}/${clientIdentity.endpointId}`); + } + } + } + // Used to remove a context handler for a client + removeContextHandler({ handlerId }, clientIdentity) { + const clientState = this.getClientState(clientIdentity); + if (clientState) { + clientState.contextHandlers.delete(handlerId); + } + } + handleJoinSessionContextGroup({ sessionContextGroupId }, clientIdentity) { + try { + if (!sessionContextGroupId) { + throw new Error('Failed to join session context group: must specify group id.'); + } + const sessionContextGroup = this.sessionContextGroupMap.get(sessionContextGroupId); + if (sessionContextGroup) { + sessionContextGroup.registerNewClient(clientIdentity); + } + else { + const newSessionContextGroupBroker = new SessionContextGroupBroker_1.default(this.channel, sessionContextGroupId); + newSessionContextGroupBroker.registerNewClient(clientIdentity); + this.sessionContextGroupMap.set(sessionContextGroupId, newSessionContextGroupBroker); + } + return { hasConflict: this.contextGroupsById.has(sessionContextGroupId) }; + } + catch (error) { + throw new Error(error); + } + } + /* + Internal Utilties + */ + // Getter for interop info for a client. + getClientState(id) { + return this.interopClients.get(id.endpointId); + } + // Util for getContextGroupStates. Serializes the contextGroupStates object so we can store it. + static toObject(map) { + const objectFromMap = Object.fromEntries(map); + const newObject = {}; + Object.entries(objectFromMap).forEach(([contextGroupId, contextMap]) => { + const newContextObject = Object.fromEntries(contextMap); + newObject[contextGroupId] = newContextObject; + }); + return newObject; + } + static checkContextIntegrity(context) { + if (!context) { + return { isValid: false, reason: 'No context supplied' }; + } + if (typeof context !== 'object') { + return { isValid: false, reason: 'Context must be an Object' }; + } + if (!context.type) { + return { isValid: false, reason: 'Context must have a type property' }; + } + if (context.id && typeof context.id !== 'object') { + return { + isValid: false, + reason: 'Context id must be an Object populated with key-value identifiers (if set)' + }; + } + if (context.id) { + const { id } = context; + const keys = Object.keys(id); + let foundBadIdentifier = false; + if (!keys.length) { + return { isValid: false, reason: 'Context id must have at least one key-value identifier' }; + } + keys.forEach((key) => { + if (typeof key !== 'string' || typeof id[key] !== 'string') { + foundBadIdentifier = true; + } + }); + if (foundBadIdentifier) { + return { isValid: false, reason: 'Context id key-value identifiers must be of type string' }; + } + } + if (context.name && typeof context.name !== 'string') { + return { isValid: false, reason: 'Context name must be of string type (if set)' }; + } + return { isValid: true }; + } + // Util to check a client identity. + static hasEndpointId(target) { + return target.endpointId !== undefined; + } + // Util to check if we should send a context to a handler. + static isContextTypeCompatible(contextType, registeredContextType) { + return typeof registeredContextType === 'undefined' || contextType === registeredContextType; + } + // Setup function for state mapping + setContextGroupMap() { + // This way, if a user overrides this.getContextGroups, it's reflected in the contextGroupMapping. + for (const contextGroupInfo of this.getContextGroups()) { + this.contextGroupsById.set(contextGroupInfo.id, new Map()); + } + } + async setCurrentContextGroupInClientOptions(clientIdentity, contextGroupId) { + try { + const entityInfo = await this.fin.System.getEntityInfo(clientIdentity.uuid, clientIdentity.name); + let entity; + if (entityInfo.entityType === 'view') { + entity = await this.fin.View.wrap(clientIdentity); + } + else if (entityInfo.entityType === 'window') { + entity = await this.fin.Window.wrap(clientIdentity); + } + if (entity) { + await entity.updateOptions({ + interop: { + currentContextGroup: contextGroupId + } + }); + } + } + catch (error) { + // May file in interop + } + } + async setupChannelProvider() { + try { + const channel = await this.getProvider(); + this.channel = channel; + this.wireChannel(channel); + } + catch (error) { + throw new Error(`Error setting up Interop Broker Channel Provider: ${error}`); + } + } + // Setup Channel Connection Logic + wireChannel(channel) { + channel.onConnection(async (clientIdentity, // TODO(CORE-811): remove inline intersected type + payload) => { + if (!(await this.isConnectionAuthorized(clientIdentity, payload))) { + throw new Error(`Connection not authorized for ${clientIdentity.uuid}, ${clientIdentity.name}`); + } + if (!clientIdentity.endpointId) { + throw new Error('Version too old to be compatible with Interop. Please upgrade your runtime to a more recent version.'); + } + const clientSubscriptionState = { + contextGroupId: undefined, + contextHandlers: new Map(), + clientIdentity + }; + // Only allow the client to join a contextGroup that actually exists. + if (payload?.currentContextGroup && this.contextGroupsById.has(payload.currentContextGroup)) { + clientSubscriptionState.contextGroupId = payload?.currentContextGroup; + } + this.interopClients.set(clientIdentity.endpointId, clientSubscriptionState); + }); + channel.onDisconnection((clientIdentity) => { + this.interopClients.delete(clientIdentity.endpointId); + const targetInfo = this.intentClientMap.get(clientIdentity.name); + if (targetInfo && clientIdentity.uuid === this.fin.me.uuid) { + targetInfo.forEach((handler) => { + handler.isReady = false; + }); + } + this.sessionContextGroupMap.forEach((sessionContextGroup) => { + sessionContextGroup.onDisconnection(clientIdentity); + }); + this.clientDisconnected(clientIdentity); + }); + channel.beforeAction(async (action, payload, clientIdentity) => { + if (!(await this.isActionAuthorized(action, payload, clientIdentity))) { + throw new Error(`Action (${action}) not authorized for ${clientIdentity.uuid}, ${clientIdentity.name}`); + } + if (this.logging?.beforeAction?.enabled) { + console.log(action, payload, clientIdentity); + } + }); + channel.afterAction((action, payload, clientIdentity) => { + if (this.logging?.afterAction?.enabled) { + console.log(action, payload, clientIdentity); + } + }); + // Client functions + channel.register('setContext', this.setContext.bind(this)); + channel.register('fireIntent', this.handleFiredIntent.bind(this)); + channel.register('getCurrentContext', this.getCurrentContext.bind(this)); + channel.register('getInfoForIntent', this.handleInfoForIntent.bind(this)); + channel.register('getInfoForIntentsByContext', this.handleInfoForIntentsByContext.bind(this)); + channel.register('fireIntentForContext', this.handleFiredIntentForContext.bind(this)); + // Platform window functions + channel.register('getContextGroups', this.getContextGroups.bind(this)); + channel.register('joinContextGroup', this.joinContextGroup.bind(this)); + channel.register('removeFromContextGroup', this.removeFromContextGroup.bind(this)); + channel.register('getAllClientsInContextGroup', this.getAllClientsInContextGroup.bind(this)); + channel.register('getInfoForContextGroup', this.getInfoForContextGroup.bind(this)); + // Internal methods + channel.register('contextHandlerRegistered', this.contextHandlerRegistered.bind(this)); + channel.register('intentHandlerRegistered', this.intentHandlerRegistered.bind(this)); + channel.register('removeContextHandler', this.removeContextHandler.bind(this)); + channel.register('sessionContextGroup:createIfNeeded', this.handleJoinSessionContextGroup.bind(this)); + // fdc3 only methods + channel.register('fdc3Open', this.fdc3HandleOpen.bind(this)); + channel.register('fdc3v2FindIntentsByContext', this.handleInfoForIntentsByContext.bind(this)); + channel.register('fdc3FindInstances', this.fdc3HandleFindInstances.bind(this)); + channel.register('fdc3GetAppMetadata', this.fdc3HandleGetAppMetadata.bind(this)); + channel.register('fdc3v2GetInfo', async (payload, clientIdentity) => { + return this.fdc3HandleGetInfo.bind(this)(payload, clientIdentity); + }); + channel.register('createPrivateChannelProvider', async (payload) => { + const { channelId } = payload; + const channelProvider = await this.fin.InterApplicationBus.Channel.create(channelId); + PrivateChannelProvider_1.PrivateChannelProvider.init(channelProvider, channelId); + }); + } + /** + * Can be used to completely prevent a connection. Return false to prevent connections. Allows all connections by default. + * @param _id the identity tryinc to connect + * @param _connectionPayload optional payload to use in custom implementations, will be undefined by default + */ + isConnectionAuthorized(_id, _connectionPayload) { + this.wire.sendAction('interop-broker-is-connection-authorized').catch((e) => { + // don't expose, analytics-only call + }); + return Promise.resolve(true); + } + /** + * Called before every action to check if this entity should be allowed to take the action. + * Return false to prevent the action + * @param _action the string action to authorize in camel case + * @param _payload the data being sent for this action + * @param _identity the connection attempting to dispatch this action + */ + isActionAuthorized(_action, _payload, _identity) { + this.wire.sendAction('interop-broker-is-action-authorized').catch((e) => { + // don't expose, analytics-only call + }); + return Promise.resolve(true); + } + }; + InteropBroker.InteropBroker = InteropBroker$1; + _InteropBroker_fdc3Info = new WeakMap(), _InteropBroker_contextGroups = new WeakMap(), _InteropBroker_providerPromise = new WeakMap(); + return InteropBroker; +} + +var InteropClient = {}; + +var SessionContextGroupClient$1 = {}; + +var __classPrivateFieldSet$2 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$2 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _SessionContextGroupClient_clientPromise; +Object.defineProperty(SessionContextGroupClient$1, "__esModule", { value: true }); +const base_1$2 = base; +const utils_1$2 = utils$3; +class SessionContextGroupClient extends base_1$2.Base { + constructor(wire, client, id) { + super(wire); + _SessionContextGroupClient_clientPromise.set(this, void 0); + this.id = id; + __classPrivateFieldSet$2(this, _SessionContextGroupClient_clientPromise, client, "f"); + } + /** + * Sets a context for the session context group. + * @param context - New context to set. + * + * @tutorial interop.setContext + */ + async setContext(context) { + this.wire.sendAction('interop-session-context-group-set-context').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet$2(this, _SessionContextGroupClient_clientPromise, "f"); + return client.dispatch(`sessionContextGroup:setContext-${this.id}`, { + sessionContextGroupId: this.id, + context + }); + } + async getCurrentContext(type) { + this.wire.sendAction('interop-session-context-group-get-context').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet$2(this, _SessionContextGroupClient_clientPromise, "f"); + return client.dispatch(`sessionContextGroup:getContext-${this.id}`, { + sessionContextGroupId: this.id, + type + }); + } + async addContextHandler(contextHandler, contextType) { + this.wire.sendAction('interop-session-context-group-add-handler').catch((e) => { + // don't expose, analytics-only call + }); + if (typeof contextHandler !== 'function') { + throw new Error("Non-function argument passed to the first parameter 'handler'. Be aware that the argument order does not match the FDC3 standard."); + } + const client = await __classPrivateFieldGet$2(this, _SessionContextGroupClient_clientPromise, "f"); + let handlerId; + if (contextType) { + handlerId = `sessionContextHandler:invoke-${this.id}-${contextType}-${(0, utils_1$2.generateId)()}`; + } + else { + handlerId = `sessionContextHandler:invoke-${this.id}`; + } + client.register(handlerId, (0, utils_1$2.wrapContextHandler)(contextHandler, handlerId)); + await client.dispatch(`sessionContextGroup:handlerAdded-${this.id}`, { handlerId, contextType }); + return { unsubscribe: await this.createUnsubscribeCb(handlerId) }; + } + async createUnsubscribeCb(handlerId) { + const client = await __classPrivateFieldGet$2(this, _SessionContextGroupClient_clientPromise, "f"); + return async () => { + client.remove(handlerId); + await client.dispatch(`sessionContextGroup:handlerRemoved-${this.id}`, { handlerId }); + }; + } + getUserInstance() { + return { + id: this.id, + setContext: (0, utils_1$2.wrapInTryCatch)(this.setContext.bind(this), 'Failed to set context: '), + getCurrentContext: (0, utils_1$2.wrapInTryCatch)(this.getCurrentContext.bind(this), 'Failed to get context: '), + addContextHandler: (0, utils_1$2.wrapInTryCatch)(this.addContextHandler.bind(this), 'Failed to add context handler: ') + }; + } +} +SessionContextGroupClient$1.default = SessionContextGroupClient; +_SessionContextGroupClient_clientPromise = new WeakMap(); + +var fdc31_2 = {}; + +var fdc3Common = {}; + +var utils$2 = {}; + +var PrivateChannelClient$1 = {}; + +var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(PrivateChannelClient$1, "__esModule", { value: true }); +PrivateChannelClient$1.PrivateChannelClient = void 0; +const utils$1 = __importStar(utils$3); +class PrivateChannelClient { + constructor(client, id) { + this.id = id; + this.client = client; + this.listeners = new Map(); + } + async broadcast(context) { + return this.client.dispatch('broadcast', { context }); + } + async getCurrentContext(contextType) { + return this.client.dispatch('getCurrentContext', { contextType }); + } + async addContextListener(contextType, handler) { + if (typeof handler !== 'function') { + throw new Error("Non-function argument passed to the second parameter 'handler'. Be aware that the argument order does not match the FDC3 standard."); + } + let handlerId; + if (contextType) { + handlerId = `contextHandler:invoke-${this.id}-${contextType}-${utils$1.generateId()}`; + } + else { + handlerId = `contextHandler:invoke-${this.id}-${utils$1.generateId()}`; + } + this.client.register(handlerId, utils$1.wrapContextHandler(handler, handlerId)); + const listener = { unsubscribe: await this.createContextUnsubscribeCb(handlerId) }; + this.listeners.set(handlerId, listener); + await this.client.dispatch(`contextHandlerAdded`, { handlerId, contextType }); + return listener; + } + createNonStandardUnsubscribeCb(handlerId) { + return async () => { + this.client.remove(handlerId); + this.listeners.delete(handlerId); + await this.client.dispatch('nonStandardHandlerRemoved', { handlerId }); + }; + } + createContextUnsubscribeCb(handlerId) { + return async () => { + this.client.remove(handlerId); + this.listeners.delete(handlerId); + await this.client.dispatch('contextHandlerRemoved', { handlerId }); + }; + } + onAddContextListener(handler) { + const handlerId = `onContextHandlerAdded:invoke-${this.id}-${utils$1.generateId()}`; + this.client.register(handlerId, handler); + const listener = { unsubscribe: this.createNonStandardUnsubscribeCb(handlerId) }; + this.listeners.set(handlerId, listener); + this.client.dispatch(`onAddContextHandlerAdded`, { handlerId }); + return listener; + } + onDisconnect(handler) { + const handlerId = `onDisconnect:invoke-${this.id}-${utils$1.generateId()}`; + this.client.register(handlerId, handler); + const listener = { unsubscribe: this.createNonStandardUnsubscribeCb(handlerId) }; + this.listeners.set(handlerId, listener); + this.client.dispatch(`onDisconnectHandlerAdded`, { handlerId }); + return listener; + } + onUnsubscribe(handler) { + const handlerId = `onUnsubscribe:invoke-${this.id}-${utils$1.generateId()}`; + this.client.register(handlerId, handler); + const listener = { unsubscribe: this.createNonStandardUnsubscribeCb(handlerId) }; + this.listeners.set(handlerId, listener); + this.client.dispatch(`onUnsubscribeHandlerAdded`, { handlerId }); + return listener; + } + async cleanUpAllSubs() { + const listenerUnsubscribers = Array.from(this.listeners.keys()); + listenerUnsubscribers.forEach((handlerId) => { + this.client.remove(handlerId); + this.listeners.delete(handlerId); + }); + } + async disconnect() { + try { + await this.client.dispatch('clientDisconnecting'); + await this.cleanUpAllSubs(); + await this.client.disconnect(); + } + catch (error) { + throw new Error(error.message); + } + } +} +PrivateChannelClient$1.PrivateChannelClient = PrivateChannelClient; + +(function (exports) { + var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.getIntentResolution = exports.isChannel = exports.isContext = exports.connectPrivateChannel = exports.buildAppChannelObject = exports.buildPrivateChannelObject = exports.ChannelError = exports.ResultError = exports.UnsupportedChannelApiError = exports.getUnsupportedChannelApis = void 0; + const utils_1 = utils$3; + const PrivateChannelClient_1 = PrivateChannelClient$1; + const isEqual_1 = __importDefault(require$$3); + const getUnsupportedChannelApis = (channelType) => { + return { + addContextListener: () => { + throw new UnsupportedChannelApiError('Channel.addContextListener', channelType); + }, + broadcast: () => { + throw new UnsupportedChannelApiError('Channel.broadcast', channelType); + }, + getCurrentContext: () => { + throw new UnsupportedChannelApiError('Channel.getCurrentContext', channelType); + } + }; + }; + exports.getUnsupportedChannelApis = getUnsupportedChannelApis; + class UnsupportedChannelApiError extends Error { + constructor(apiName, channelType = 'System') { + super(apiName); + this.message = `Calling ${apiName} on an instance of a ${channelType} Channel returned by fdc3.get${channelType}Channels is not supported. If you would like to use a ${channelType} Channel, please use fdc3.joinChannel, fdc3.addContextListener, and fdc3.broadcast instead.`; + } + } + exports.UnsupportedChannelApiError = UnsupportedChannelApiError; + var ResultError; + (function (ResultError) { + /** Returned if the `IntentHandler` exited without returning a Promise or that + * Promise was not resolved with a Context or Channel object. + */ + ResultError["NoResultReturned"] = "NoResultReturned"; + /** Returned if the `IntentHandler` function processing the raised intent + * throws an error or rejects the Promise it returned. + */ + ResultError["IntentHandlerRejected"] = "IntentHandlerRejected"; + })(ResultError = exports.ResultError || (exports.ResultError = {})); + (function (ChannelError) { + /** Returned if the specified channel is not found when attempting to join a + * channel via the `joinUserChannel` function of the DesktopAgent (`fdc3`). + */ + ChannelError["NoChannelFound"] = "NoChannelFound"; + /** SHOULD be returned when a request to join a user channel or to a retrieve + * a Channel object via the `joinUserChannel` or `getOrCreateChannel` methods + * of the DesktopAgent (`fdc3`) object is denied. + */ + ChannelError["AccessDenied"] = "AccessDenied"; + /** SHOULD be returned when a channel cannot be created or retrieved via the + * `getOrCreateChannel` method of the DesktopAgent (`fdc3`). + */ + ChannelError["CreationFailed"] = "CreationFailed"; + })(exports.ChannelError || (exports.ChannelError = {})); + const buildPrivateChannelObject = (privateChannelClient) => { + let clientDisconnected = false; + const checkIfClientDisconnected = () => { + if (clientDisconnected) { + throw new Error('Private Channel Client has been disconnected from the Private Channel'); + } + }; + return { + id: privateChannelClient.id, + type: 'private', + broadcast: async (context) => { + checkIfClientDisconnected(); + return privateChannelClient.broadcast(context); + }, + getCurrentContext: async (contextType) => { + checkIfClientDisconnected(); + return privateChannelClient.getCurrentContext(contextType); + }, + // @ts-expect-error TODO [CORE-1524] + addContextListener: async (contextType, handler) => { + checkIfClientDisconnected(); + let handlerInUse = handler; + let contextTypeInUse = contextType; + if (typeof contextType === 'function') { + console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)'); + handlerInUse = contextType; + contextTypeInUse = null; + } + const listener = privateChannelClient.addContextListener(contextTypeInUse, handlerInUse); + return listener; + }, + onAddContextListener: (handler) => { + checkIfClientDisconnected(); + return privateChannelClient.onAddContextListener(handler); + }, + disconnect: async () => { + checkIfClientDisconnected(); + clientDisconnected = true; + return privateChannelClient.disconnect(); + }, + onDisconnect: (handler) => { + checkIfClientDisconnected(); + return privateChannelClient.onDisconnect(handler); + }, + onUnsubscribe: (handler) => { + checkIfClientDisconnected(); + return privateChannelClient.onUnsubscribe(handler); + } + }; + }; + exports.buildPrivateChannelObject = buildPrivateChannelObject; + const buildAppChannelObject = (sessionContextGroup) => { + return { + id: sessionContextGroup.id, + type: 'app', + broadcast: sessionContextGroup.setContext, + getCurrentContext: async (contextType) => { + const context = await sessionContextGroup.getCurrentContext(contextType); + return context === undefined ? null : context; + }, + // @ts-expect-error TODO [CORE-1524] + addContextListener: (contextType, handler) => { + let realHandler; + let realType; + if (typeof contextType === 'function') { + console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)'); + realHandler = contextType; + } + else { + realHandler = handler; + if (typeof contextType === 'string') { + realType = contextType; + } + } + const listener = (async () => { + let first = true; + const currentContext = await sessionContextGroup.getCurrentContext(realType); + const wrappedHandler = (context, contextMetadata) => { + if (first) { + first = false; + if ((0, isEqual_1.default)(currentContext, context)) { + return; + } + } + // eslint-disable-next-line consistent-return + return realHandler(context, contextMetadata); + }; + return sessionContextGroup.addContextHandler(wrappedHandler, realType); + })(); + return { + ...listener, + unsubscribe: () => listener.then((l) => l.unsubscribe()) + }; + } + }; + }; + exports.buildAppChannelObject = buildAppChannelObject; + const connectPrivateChannel = async (channelId) => { + try { + const channelClient = await fin.InterApplicationBus.Channel.connect(channelId); + const privateChannelClient = new PrivateChannelClient_1.PrivateChannelClient(channelClient, channelId); + return (0, exports.buildPrivateChannelObject)(privateChannelClient); + } + catch (error) { + throw new Error(`Private Channel with id: ${channelId} doesn't exist`); + } + }; + exports.connectPrivateChannel = connectPrivateChannel; + const isContext = (context) => { + if (context && typeof context === 'object' && 'type' in context) { + const { type } = context; + return typeof type === 'string'; + } + return false; + }; + exports.isContext = isContext; + const isChannel = (channel) => { + if (channel && typeof channel === 'object' && 'type' in channel && 'id' in channel) { + const { type, id } = channel; + return typeof type === 'string' && typeof id === 'string' && (type === 'app' || type === 'private'); + } + return false; + }; + exports.isChannel = isChannel; + const getIntentResolution = async (interopModule, context, app, intent) => { + // Generate an ID to make a session context group with. We will pass that ID to the Broker. + // The broker will then setContext on that session context group later with our Intent Result, + const guid = (0, utils_1.generateId)(); // TODO make this undefined in web + // Promise we'll use in getResult + const getResultPromise = new Promise((resolve, reject) => { + fin.InterApplicationBus.subscribe({ uuid: '*' }, guid, (intentResult) => { + resolve(intentResult); + }).catch(() => reject(new Error('getResult is not supported in this environment'))); + }); + // Adding the intentResolutionResultId to the intentObj. Because fireIntent only accepts a single arg, we have to slap it in here. + const metadata = app ? { target: app, intentResolutionResultId: guid } : { intentResolutionResultId: guid }; + const intentObj = intent ? { name: intent, context, metadata } : { ...context, metadata }; + // Set up the getResult call. + const getResult = async () => { + let intentResult = await getResultPromise; + if (!intentResult || typeof intentResult !== 'object') { + throw new Error(ResultError.NoResultReturned); + } + const { error } = intentResult; + if (error) { + throw new Error(ResultError.IntentHandlerRejected); + } + if ((0, exports.isChannel)(intentResult)) { + const { id, type } = intentResult; + switch (type) { + case 'private': { + intentResult = await (0, exports.connectPrivateChannel)(id); + break; + } + case 'app': { + const sessionContextGroup = await interopModule.joinSessionContextGroup(id); + intentResult = (0, exports.buildAppChannelObject)(sessionContextGroup); + break; + } + } + } + else if (!(0, exports.isContext)(intentResult)) { + throw new Error(ResultError.NoResultReturned); + } + return intentResult; + }; + // Finally fire the intent. + const intentResolutionInfoFromBroker = intent + ? await interopModule.fireIntent(intentObj) + : await interopModule.fireIntentForContext(intentObj); + if (typeof intentResolutionInfoFromBroker !== 'object') { + return { + source: { + appId: '', + instanceId: '' + }, + intent: '', + version: '2.0', + getResult + }; + } + return { ...intentResolutionInfoFromBroker, getResult }; + }; + exports.getIntentResolution = getIntentResolution; +} (utils$2)); + +var hasRequiredFdc3Common; + +function requireFdc3Common () { + if (hasRequiredFdc3Common) return fdc3Common; + hasRequiredFdc3Common = 1; + var __classPrivateFieldGet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + var __classPrivateFieldSet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + }; + var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + var _FDC3ModuleBase_producer; + Object.defineProperty(fdc3Common, "__esModule", { value: true }); + fdc3Common.FDC3ModuleBase = void 0; + const utils_1 = utils$2; + const utils_2 = utils$3; + const InteropClient_1 = requireInteropClient(); + const isEqual_1 = __importDefault(require$$3); + class FDC3ModuleBase { + get client() { + return __classPrivateFieldGet(this, _FDC3ModuleBase_producer, "f").call(this); + } + get fin() { + return this.wire.getFin(); + } + // eslint-disable-next-line no-useless-constructor + constructor(producer, wire) { + this.wire = wire; + _FDC3ModuleBase_producer.set(this, void 0); + __classPrivateFieldSet(this, _FDC3ModuleBase_producer, producer, "f"); + } + /** + * Broadcasts a context for the channel of the current entity. + * @param context - New context to set. + * + * @tutorial fdc3.broadcast + * @static + */ + async broadcast(context) { + this.wire.sendAction('fdc3-broadcast').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this.client.setContext(context); + } + /** + * Launches an app with target information, which can either be a string or an AppMetadata object. + * @param app + * @param context + * + * @tutorial fdc3.open + */ + async _open(app, context) { + this.wire.sendAction('fdc3-open').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await InteropClient_1.InteropClient.ferryFdc3Call(this.client, 'fdc3Open', { app, context }); + } + catch (error) { + const errorToThrow = error.message === utils_2.BROKER_ERRORS.fdc3Open ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + async _getChannels() { + const channels = await this.client.getContextGroups(); + // fdc3 implementation of getSystemChannels returns an array of channels, have to decorate over + // this so people know that these APIs are not supported + return channels.map((channel) => { + return { ...channel, type: 'system', ...(0, utils_1.getUnsupportedChannelApis)() }; + }); + } + /** + * Returns a Channel object for the specified channel, creating it as an App Channel if it does not exist. + * @param channelId + * + * @tutorial fdc3.getOrCreateChannel + */ + async getOrCreateChannel(channelId) { + this.wire.sendAction('fdc3-get-or-create-channel').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const systemChannels = await this._getChannels(); + const userChannel = systemChannels.find((channel) => channel.id === channelId); + if (userChannel) { + return { ...userChannel, type: 'system', ...(0, utils_1.getUnsupportedChannelApis)() }; + } + try { + const sessionContextGroup = await this.client.joinSessionContextGroup(channelId); + return (0, utils_1.buildAppChannelObject)(sessionContextGroup); + } + catch (error) { + console.error(error.message); + throw new Error(utils_1.ChannelError.CreationFailed); + } + } + /** + * Returns the Interop-Broker-defined context groups available for an entity to join. + * + * @tutorial fdc3.getSystemChannels + * @static + */ + async getSystemChannels() { + this.wire.sendAction('fdc3-get-system-channels').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this._getChannels(); + } + /** + * Join all Interop Clients at the given identity to context group `contextGroupId`. + * If no target is specified, it adds the sender to the context group. + * Because multiple Channel connections/Interop Clients can potentially exist at a `uuid`/`name` combo, we currently join all Channel connections/Interop Clients at the given identity to the context group. + * If an `endpointId` is provided (which is unlikely, unless the call is coming from an external adapter), then we only join that single connection to the context group. + * For all intents and purposes, there will only be 1 connection present in Platform and Browser implementations, so this point is more-or-less moot. + * @param channelId - Id of the context group. + * + * @tutorial fdc3.joinChannel + * @static + */ + async joinChannel(channelId) { + this.wire.sendAction('fdc3-join-channel').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await this.client.joinContextGroup(channelId); + } + catch (error) { + if (error.message === utils_2.BROKER_ERRORS.joinSessionContextGroupWithJoinContextGroup) { + console.error('The Channel you have tried to join is an App Channel. Custom Channels can only be defined by the Interop Broker through code or manifest configuration. Please use getOrCreateChannel.'); + } + else { + console.error(error.message); + } + if (error.message.startsWith('Attempting to join a context group that does not exist')) { + throw new Error(utils_1.ChannelError.NoChannelFound); + } + throw new Error(utils_1.ChannelError.AccessDenied); + } + } + /** + * Returns the Channel that the entity is subscribed to. Returns null if not joined to a channel. + * + * @tutorial fdc3.getCurrentChannel + */ + async getCurrentChannel() { + this.wire.sendAction('fdc3-get-current-channel').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const currentContextGroupInfo = await this.getCurrentContextGroupInfo(); + if (!currentContextGroupInfo) { + return null; + } + return this.buildChannelObject(currentContextGroupInfo); + } + /** + * Removes the specified target from a context group. + * If no target is specified, it removes the sender from their context group. + * + * @tutorial fdc3.leaveCurrentChannel + * @static + */ + async leaveCurrentChannel() { + this.wire.sendAction('fdc3-leave-current-channel').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + return this.client.removeFromContextGroup(); + } + // utils + // eslint-disable-next-line class-methods-use-this + async getCurrentContextGroupInfo() { + const contextGroups = await this.client.getContextGroups(); + const clientsInCtxGroupsPromise = contextGroups.map(async (ctxGroup) => { + return this.client.getAllClientsInContextGroup(ctxGroup.id); + }); + const clientsInCtxGroups = await Promise.all(clientsInCtxGroupsPromise); + const clientIdx = clientsInCtxGroups.findIndex((clientIdentityArr) => { + return clientIdentityArr.some((clientIdentity) => { + const { uuid, name } = clientIdentity; + return this.wire.me.uuid === uuid && this.wire.me.name === name; + }); + }); + return contextGroups[clientIdx]; + } + async buildChannelObject(currentContextGroupInfo) { + // @ts-expect-error + return { + ...currentContextGroupInfo, + type: 'system', + addContextListener: (...[contextType, handler]) => { + let realHandler; + let realType; + if (typeof contextType === 'function') { + console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)'); + realHandler = contextType; + } + else { + realHandler = handler; + if (typeof contextType === 'string') { + realType = contextType; + } + } + const listener = (async () => { + let first = true; + const currentContext = await this.client.getCurrentContext(realType); + const wrappedHandler = (context, contextMetadata) => { + if (first) { + first = false; + if ((0, isEqual_1.default)(currentContext, context)) { + return; + } + } + // eslint-disable-next-line consistent-return + return realHandler(context, contextMetadata); + }; + return this.client.addContextHandler(wrappedHandler, realType); + })(); + // @ts-expect-error TODO [CORE-1524] + return { + ...listener, + unsubscribe: () => listener.then((l) => l.unsubscribe()) + }; + }, + broadcast: this.broadcast.bind(this), + // @ts-expect-error Typescript fails to infer the returntype is a Promise + getCurrentContext: async (contextType) => { + const context = await this.client.getCurrentContext(contextType); + // @ts-expect-error Typescript fails to infer the returntype is a Promise + return context === undefined ? null : context; + } + }; + } + } + fdc3Common.FDC3ModuleBase = FDC3ModuleBase; + _FDC3ModuleBase_producer = new WeakMap(); + return fdc3Common; +} + +var hasRequiredFdc31_2; + +function requireFdc31_2 () { + if (hasRequiredFdc31_2) return fdc31_2; + hasRequiredFdc31_2 = 1; + Object.defineProperty(fdc31_2, "__esModule", { value: true }); + fdc31_2.Fdc3Module = void 0; + const utils_1 = utils$3; + const fdc3_common_1 = requireFdc3Common(); + /** + * @version 1.2 + * The FDC3 Client Library provides a set APIs to be used for FDC3 compliance, + * while using our Interop API under the hood. In order to use this set of APIs + * you will need to set up your own {@link InteropBroker InteropBroker} or use a Platform application, which does the setup for you. Refer to our documentation on + * our {@link https://developers.openfin.co/of-docs/docs/enable-color-linking Interop API}. + * + * To enable the FDC3 APIs in a {@link Window Window} or {@link View View}, add the fdc3InteropApi + * property to its options: + * + * ```js + * { + * autoShow: false, + * saveWindowState: true, + * url: 'https://openfin.co', + * fdc3InteropApi: '1.2' + * } + * ``` + * + * If using a {@link Platform Platform } application, you can set this property in defaultWindowOptions and defaultViewOptions. + * + * In order to ensure that the FDC3 Api is ready before use, you can use the 'fdc3Ready' event fired on the DOM Window object: + * + * ```js + * function fdc3Action() { + * // Make some fdc3 API calls here + * } + * + * if (window.fdc3) { + * fdc3Action(); + * } else { + * window.addEventListener('fdc3Ready', fdc3Action); + * } + * ``` + */ + class Fdc3Module extends fdc3_common_1.FDC3ModuleBase { + async open(app, context) { + // eslint-disable-next-line no-underscore-dangle + await super._open(app, context); + } + /** + * Add a context handler for incoming context. If an entity is part of a context group, and then sets its context handler, it will receive all of its declared contexts. If you wish to listen for all incoming contexts, pass `null` for the contextType argument. + * @param contextType - The type of context you wish to handle. + * @param handler - Handler for incoming context. + * + * @tutorial fdc3.addContextListener + * @static + */ + // @ts-expect-error TODO [CORE-1524] + addContextListener(contextType, handler) { + this.wire.sendAction('fdc3-add-context-listener').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + let listener; + if (typeof contextType === 'function') { + console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)'); + listener = this.client.addContextHandler(contextType); + } + else { + listener = this.client.addContextHandler(handler, contextType === null ? undefined : contextType); + } + return { + ...listener, + unsubscribe: () => listener.then((l) => l.unsubscribe()) + }; + } + /** + * Adds a listener for incoming Intents. + * @param intent - Name of the Intent + * @param handler - Handler for incoming Intent + * + * @tutorial fdc3.addIntentListener + * @static + */ + addIntentListener(intent, handler) { + this.wire.sendAction('fdc3-add-intent-listener').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const contextHandler = (raisedIntent) => { + const { context, metadata: intentMetadata } = raisedIntent; + const { metadata } = context; + const intentResolutionResultId = intentMetadata?.intentResolutionResultId || metadata?.intentResolutionResultId; + if (intentResolutionResultId) { + this.fin.InterApplicationBus.publish(intentResolutionResultId, null).catch(() => null); + } + handler(raisedIntent.context); + }; + const listener = this.client.registerIntentHandler(contextHandler, intent, { + fdc3Version: '1.2' + }); + return { + ...listener, + unsubscribe: () => listener.then((l) => l.unsubscribe()) + }; + } + /** + * Raises a specific intent. + * @param intent Name of the Intent. + * @param context Context associated with the Intent. + * @param app App that will resolve the Intent. This is added as metadata to the Intent. Can be accessed by the app provider in {@link InteropBroker#handleFiredIntent InteropBroker.handleFiredIntent}. + * + * @tutorial fdc3.raiseIntent + * @static + */ + async raiseIntent(intent, context, app) { + this.wire.sendAction('fdc3-raise-intent').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const intentObj = app + ? { name: intent, context, metadata: { target: app } } + : { name: intent, context }; + try { + return await this.client.fireIntent(intentObj); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.fireIntent ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Find out more information about a particular intent by passing its name, and optionally its context. + * @param intent Name of the Intent + * @param context + * + * @tutorial fdc3.findIntent + */ + async findIntent(intent, context) { + this.wire.sendAction('fdc3-find-intent').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await this.client.getInfoForIntent({ name: intent, context }); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.getInfoForIntent ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Find all the available intents for a particular context. + * @param context + * + * @tutorial fdc3.findIntentsByContext + */ + async findIntentsByContext(context) { + this.wire.sendAction('fdc3-find-intents-by-context').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await this.client.getInfoForIntentsByContext(context); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.getInfoForIntentsByContext ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Finds and raises an intent against a target app based purely on context data. + * @param context + * @param app + * + * @tutorial fdc3.raiseIntentForContext + */ + async raiseIntentForContext(context, app) { + this.wire.sendAction('fdc3-raise-intent-for-context').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await this.client.fireIntentForContext({ ...context, metadata: { target: app } }); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.fireIntentForContext ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Returns a Channel object for the specified channel, creating it as an App Channel if it does not exist. + * @param channelId + * + * @tutorial fdc3.getOrCreateChannel + */ + async getOrCreateChannel(channelId) { + return super.getOrCreateChannel(channelId); + } + /** + * Returns metadata relating to the FDC3 object and its provider, including the supported version of the FDC3 specification and the name of the provider of the implementation. + * + * @tutorial fdc3.getInfo + */ + getInfo() { + this.wire.sendAction('fdc3-get-info').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const version = this.wire.environment.getAdapterVersionSync(); + return { + providerVersion: version, + provider: `openfin-${this.wire.me.uuid}`, + fdc3Version: '1.2' + }; + } + } + fdc31_2.Fdc3Module = Fdc3Module; + return fdc31_2; +} + +var fdc32_0 = {}; + +var hasRequiredFdc32_0; + +function requireFdc32_0 () { + if (hasRequiredFdc32_0) return fdc32_0; + hasRequiredFdc32_0 = 1; + Object.defineProperty(fdc32_0, "__esModule", { value: true }); + fdc32_0.Fdc3Module2 = void 0; + const fdc3_common_1 = requireFdc3Common(); + const utils_1 = utils$3; + const InteropClient_1 = requireInteropClient(); + const utils_2 = utils$2; + const PrivateChannelClient_1 = PrivateChannelClient$1; + /** + * @version 2.0 + * The FDC3 Client Library provides a set APIs to be used for FDC3 compliance, + * while using our Interop API under the hood. In order to use this set of APIs + * you will need to set up your own {@link InteropBroker InteropBroker} or use a Platform application, which does the setup for you. Refer to our documentation on + * our {@link https://developers.openfin.co/of-docs/docs/enable-context-sharing Interop API}. + * + * To enable the FDC3 APIs in a {@link Window Window} or {@link View View}, add the fdc3InteropApi + * property to its options: + * + * ```js + * { + * autoShow: false, + * saveWindowState: true, + * url: 'https://openfin.co', + * fdc3InteropApi: '2.0' + * } + * ``` + * + * If using a {@link Platform Platform } application, you can set this property in defaultWindowOptions and defaultViewOptions. + * + * In order to ensure that the FDC3 Api is ready before use, you can use the 'fdc3Ready' event fired on the DOM Window object: + * + * ```js + * function fdc3Action() { + * // Make some fdc3 API calls here + * } + * + * if (window.fdc3) { + * fdc3Action(); + * } else { + * window.addEventListener('fdc3Ready', fdc3Action); + * } + * ``` + */ + class Fdc3Module2 extends fdc3_common_1.FDC3ModuleBase { + /** + * Launches an app, specified via an AppIdentifier object. + * @param app + * @param context + * + * @tutorial fdc3.open + */ + async open(app, context) { + if (typeof app === 'string') { + console.warn('Passing a string as the app parameter is deprecated, please use an AppIdentifier ({ appId: string; instanceId?: string }).'); + } + // eslint-disable-next-line no-underscore-dangle + return super._open(app, context); + } + /** + * Find all the available instances for a particular application. + * @param app + * + * @tutorial fdc3v2.findInstances + */ + async findInstances(app) { + this.wire.sendAction('fdc3-find-instances').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await InteropClient_1.InteropClient.ferryFdc3Call(this.client, 'fdc3FindInstances', app); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.fdc3FindInstances ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Retrieves the AppMetadata for an AppIdentifier, which provides additional metadata (such as icons, a title and description) from the App Directory record for the application, that may be used for display purposes. + * @param app + * + * @tutorial fdc3v2.getAppMetadata + */ + async getAppMetadata(app) { + this.wire.sendAction('fdc3-get-app-metadata').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await InteropClient_1.InteropClient.ferryFdc3Call(this.client, 'fdc3GetAppMetadata', app); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.fdc3GetAppMetadata ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Add a context handler for incoming context. If an entity is part of a context group, and then sets its context handler, it will receive all of its declared contexts. If you wish to listen for all incoming contexts, pass `null` for the contextType argument. + * @param contextType + * @param handler + * + * @tutorial fdc3.addContextListener + */ + // @ts-expect-error TODO [CORE-1524] + async addContextListener(contextType, handler) { + this.wire.sendAction('fdc3-add-context-listener').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + // The FDC3 ContextHandler only expects the context and optional ContextMetadata, so we wrap the handler + // here so it only gets passed these parameters + const getWrappedHandler = (handlerToWrap) => { + return (context) => { + const { contextMetadata, ...rest } = context; + const args = contextMetadata ? [{ ...rest }, contextMetadata] : [context, null]; + handlerToWrap(...args); + }; + }; + let actualHandler = handler; + let wrappedHandler = getWrappedHandler(actualHandler); + if (typeof contextType === 'function') { + console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)'); + actualHandler = contextType; + wrappedHandler = getWrappedHandler(actualHandler); + return this.client.addContextHandler(wrappedHandler); + } + return this.client.addContextHandler(wrappedHandler, contextType === null ? undefined : contextType); + } + /** + * Find out more information about a particular intent by passing its name, and optionally its context and resultType. + * @param intent Name of the Intent + * @param context Context + * @param resultType The type of result returned for any intent specified during resolution. + * + * @tutorial fdc3.findIntent + */ + async findIntent(intent, context, resultType) { + this.wire.sendAction('fdc3-find-intent').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + return await this.client.getInfoForIntent({ name: intent, context, metadata: { resultType } }); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.getInfoForIntent ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Find all the available intents for a particular context. + * @param context + * @param resultType The type of result returned for any intent specified during resolution. + * + * @tutorial fdc3v2.findIntentsByContext + */ + async findIntentsByContext(context, resultType) { + this.wire.sendAction('fdc3-find-intents-by-context').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + const payload = resultType ? { context, metadata: { resultType } } : context; + try { + return await InteropClient_1.InteropClient.ferryFdc3Call(this.client, 'fdc3v2FindIntentsByContext', payload); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.getInfoForIntentsByContext ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Raises a specific intent for resolution against apps registered with the desktop agent. + * @param intent Name of the Intent + * @param context Context associated with the Intent + * @param app + * + * @tutorial fdc3v2.raiseIntent + */ + async raiseIntent(intent, context, app) { + this.wire.sendAction('fdc3-raise-intent').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + if (typeof app === 'string') { + console.warn('Passing a string as the app parameter is deprecated, please use an AppIdentifier ({ appId: string; instanceId?: string }).'); + } + return (0, utils_2.getIntentResolution)(this.client, context, app, intent); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.fireIntent ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Finds and raises an intent against apps registered with the desktop agent based purely on the type of the context data. + * @param context Context associated with the Intent + * @param app + * + * @tutorial fdc3v2.raiseIntentForContext + */ + async raiseIntentForContext(context, app) { + // TODO: We have to do the same thing we do for raiseIntent here as well. + this.wire.sendAction('fdc3-raise-intent-for-context').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + try { + if (typeof app === 'string') { + console.warn('Passing a string as the app parameter is deprecated, please use an AppIdentifier ({ appId: string; instanceId?: string }).'); + } + return (0, utils_2.getIntentResolution)(this.client, context, app); + } + catch (error) { + const errorToThrow = error.message === utils_1.BROKER_ERRORS.fireIntent ? 'ResolverUnavailable' : error.message; + throw new Error(errorToThrow); + } + } + /** + * Adds a listener for incoming intents. + * @param intent Name of the Intent + * @param handler A callback that handles a context event and may return a promise of a Context or Channel object to be returned to the application that raised the intent. + * + * @tutorial fdc3.addIntentListener + */ + async addIntentListener(intent, handler) { + this.wire.sendAction('fdc3-add-intent-listener').catch((e) => { + // we do not want to expose this error, just continue if this analytics-only call fails + }); + if (typeof intent !== 'string') { + throw new Error('First argument must be an Intent name'); + } + // The FDC3 Intenter handler only expects the context and contextMetadata to be passed to the handler, + // so we wrap it here and only pass those paramaters. + const contextHandler = async (raisedIntent) => { + let intentResult; + let intentResultToSend; + const { context, metadata: intentMetadata } = raisedIntent; + const { contextMetadata, metadata, ...rest } = context; + const intentResolutionResultId = intentMetadata?.intentResolutionResultId || metadata?.intentResolutionResultId; + try { + const newContext = metadata ? { metadata, ...rest } : { ...rest }; + intentResult = await handler(newContext, contextMetadata); + intentResultToSend = intentResult; + } + catch (error) { + intentResult = error; + intentResultToSend = { error: true }; + } + if (intentResolutionResultId) { + this.fin.InterApplicationBus.publish(intentResolutionResultId, intentResultToSend).catch(() => null); + } + if (intentResult instanceof Error) { + throw new Error(intentResult.message); + } + return intentResult; + }; + return this.client.registerIntentHandler(contextHandler, intent, { fdc3Version: '2.0' }); + } + /** + * Returns a Channel object for the specified channel, creating it as an App Channel if it does not exist. + * @param channelId + * + * @tutorial fdc3.getOrCreateChannel + */ + async getOrCreateChannel(channelId) { + return super.getOrCreateChannel(channelId); + } + /** + * Returns a Channel with an auto-generated identity that is intended for private communication between applications. Primarily used to create channels that will be returned to other applications via an IntentResolution for a raised intent. + * + * @tutorial fdc3v2.createPrivateChannel + */ + async createPrivateChannel() { + const channelId = (0, utils_1.generateId)(); + await InteropClient_1.InteropClient.ferryFdc3Call(this.client, 'createPrivateChannelProvider', { channelId }); + const channelClient = await this.fin.InterApplicationBus.Channel.connect(channelId); + const newPrivateChannelClient = new PrivateChannelClient_1.PrivateChannelClient(channelClient, channelId); + return (0, utils_2.buildPrivateChannelObject)(newPrivateChannelClient); + } + /** + * Retrieves a list of the User Channels available for the app to join. + * + * @tutorial fdc3v2.getUserChannels + */ + async getUserChannels() { + const channels = await this.client.getContextGroups(); + // fdc3 implementation of getUserChannels returns on array of channels, have to decorate over + // this so people know that these APIs are not supported + return channels.map((channel) => { + // @ts-expect-error TODO [CORE-1524] + return { ...channel, type: 'user', ...(0, utils_2.getUnsupportedChannelApis)('User') }; + }); + } + /** + * Retrieves a list of the User Channels available for the app to join. + * + * @deprecated Please use {@link fdc3.getUserChannels fdc3.getUserChannels} instead + * @tutorial fdc3.getSystemChannels + */ + async getSystemChannels() { + console.warn('This API has been deprecated. Please use fdc3.getUserChannels instead.'); + return super.getSystemChannels(); + } + /** + * Join an app to a specified User channel. + * @param channelId Channel name + * + * @tutorial fdc3v2.joinUserChannel + */ + async joinUserChannel(channelId) { + return super.joinChannel(channelId); + } + /** + * Join an app to a specified User channel. + * @param channelId Channel name + * @deprecated Please use {@link fdc3.joinUserChannel fdc3.joinUserChannel} instead + * + * @tutorial fdc3.joinChannel + */ + async joinChannel(channelId) { + console.warn('This API has been deprecated. Please use fdc3.joinUserChannel instead.'); + return super.joinChannel(channelId); + } + /** + * Returns the Channel object for the current User channel membership + * + * @tutorial fdc3.getCurrentChannel + */ + async getCurrentChannel() { + const currentChannel = await super.getCurrentChannel(); + if (!currentChannel) { + return null; + } + return { + ...currentChannel, + type: 'user', + broadcast: this.broadcast.bind(this) + }; + } + /** + * Retrieves information about the FDC3 implementation, including the supported version of the FDC3 specification, the name of the provider of the implementation, its own version number, details of whether optional API features are implemented and the metadata of the calling application according to the desktop agent. + * fdc3HandleGetInfo must be overridden in the InteropBroker so that the ImplementationMetadata will have the appMetadata info. + * + * @tutorial fdc3v2.getInfo + */ + async getInfo() { + return InteropClient_1.InteropClient.ferryFdc3Call(this.client, 'fdc3v2GetInfo', { fdc3Version: '2.0' }); + } + } + fdc32_0.Fdc3Module2 = Fdc3Module2; + return fdc32_0; +} + +var hasRequiredInteropClient; + +function requireInteropClient () { + if (hasRequiredInteropClient) return InteropClient; + hasRequiredInteropClient = 1; + var __classPrivateFieldSet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; + }; + var __classPrivateFieldGet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + }; + var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + var _InteropClient_clientPromise, _InteropClient_sessionContextGroups; + Object.defineProperty(InteropClient, "__esModule", { value: true }); + InteropClient.InteropClient = void 0; + const base_1 = base; + const SessionContextGroupClient_1 = __importDefault(SessionContextGroupClient$1); + const fdc3_1_2_1 = requireFdc31_2(); + const fdc3_2_0_1 = requireFdc32_0(); + const utils_1 = utils$3; + /** + * The Interop Client API is broken up into two groups: + * + * **Content Facing APIs** - For Application Developers putting Views into a Platform Window, who care about Context. These are APIs that send out and receive the Context data that flows between applications. Think of this as the Water in the Interop Pipes. + * + * **Context Grouping APIs** - For Platform Developers, to add and remove Views to and from Context Groups. These APIs are utilized under-the-hood in Platforms, so they don't need to be used to participate in Interop. These are the APIs that decide which entities the context data flows between. Think of these as the valves or pipes that control the flow of Context Data for Interop. + * + * --- + * + * All APIs are available at the `fin.me.interop` namespace. + * + * --- + * + * **You only need 2 things to participate in Interop Context Grouping:** + * * A Context Handler for incoming context: {@link InteropClient#addContextHandler addContextHandler(handler, contextType?)} + * * Call setContext on your context group when you want to share context with other group members: {@link InteropClient#setContext setContext(context)} + * + * --- + * + * ##### Constructor + * Returned by {@link Interop.connectSync Interop.connectSync}. + * + * --- + * + * ##### Interop methods intended for Views + * + * + * **Context Groups API** + * * {@link InteropClient#addContextHandler addContextHandler(handler, contextType?)} + * * {@link InteropClient#setContext setContext(context)} + * * {@link InteropClient#getCurrentContext getCurrentContext(contextType?)} + * * {@link InteropClient#joinSessionContextGroup joinSessionContextGroup(sessionContextGroupId)} + * + * + * **Intents API** + * * {@link InteropClient#fireIntent fireIntent(intent)} + * * {@link InteropClient#registerIntentHandler registerIntentHandler(intentHandler, intentName)} + * * {@link InteropClient#getInfoForIntent getInfoForIntent(infoForIntentOptions)} + * * {@link InteropClient#getInfoForIntentsByContext getInfoForIntentsByContext(context)} + * * {@link InteropClient#fireIntentForContext fireIntentForContext(contextForIntent)} + * + * ##### Interop methods intended for Windows + * * {@link InteropClient#getContextGroups getContextGroups()} + * * {@link InteropClient#joinContextGroup joinContextGroup(contextGroupId, target?)} + * * {@link InteropClient#removeFromContextGroup removeFromContextGroup(target?)} + * * {@link InteropClient#getInfoForContextGroup getInfoForContextGroup(contextGroupId)} + * * {@link InteropClient#getAllClientsInContextGroup getAllClientsInContextGroup(contextGroupId)} + * + */ + let InteropClient$1 = class InteropClient extends base_1.Base { + /** + * @internal + */ + constructor(wire, clientPromise) { + super(wire); + _InteropClient_clientPromise.set(this, void 0); + _InteropClient_sessionContextGroups.set(this, void 0); + __classPrivateFieldSet(this, _InteropClient_sessionContextGroups, new Map(), "f"); + __classPrivateFieldSet(this, _InteropClient_clientPromise, clientPromise, "f"); + } + /* + Client APIs + */ + /** + * Sets a context for the context group of the current entity. + * + * @remarks The entity must be part of a context group in order set a context. + * + * @param context - New context to set. + * + * @example + * ```js + * setInstrumentContext = async (ticker) => { + * fin.me.interop.setContext({type: 'instrument', id: {ticker}}) + * } + * + * // The user clicks an instrument of interest. We want to set that Instrument context so that the rest of our workflow updates with information for that instrument + * instrumentElement.on('click', (evt) => { + * setInstrumentContext(evt.ticker) + * }) + * ``` + */ + async setContext(context) { + this.wire.sendAction('interop-client-set-context').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('setContext', { context }); + } + /** + * Add a context handler for incoming context. If an entity is part of a context group, and then sets its context handler, + * it will receive all of its declared contexts. + * + * @param handler - Handler for incoming context. + * @param contextType - The type of context you wish to handle. + * + * @example + * ```js + * function handleIncomingContext(contextInfo) { + * const { type, id } = contextInfo; + * switch (type) { + * case 'instrument': + * handleInstrumentContext(contextInfo); + * break; + * case 'country': + * handleCountryContext(contextInfo); + * break; + * + * default: + * break; + * } + * } + * + * + * function handleInstrumentContext(contextInfo) { + * const { type, id } = contextInfo; + * console.log('contextInfo for instrument', contextInfo) + * } + * + * function handleCountryContext(contextInfo) { + * const { type, id } = contextInfo; + * console.log('contextInfo for country', contextInfo) + * } + * + * fin.me.interop.addContextHandler(handleIncomingContext); + * ``` + * + * + * Passing in a context type as the second parameter will cause the handler to only be invoked with that context type. + * + * ```js + * function handleInstrumentContext(contextInfo) { + * const { type, id } = contextInfo; + * console.log('contextInfo for instrument', contextInfo) + * } + * + * function handleCountryContext(contextInfo) { + * const { type, id } = contextInfo; + * console.log('contextInfo for country', contextInfo) + * } + * + * + * fin.me.interop.addContextHandler(handleInstrumentContext, 'instrument') + * fin.me.interop.addContextHandler(handleCountryContext, 'country') + * ``` + */ + async addContextHandler(handler, contextType) { + this.wire.sendAction('interop-client-add-context-handler').catch((e) => { + // don't expose, analytics-only call + }); + if (typeof handler !== 'function') { + throw new Error("Non-function argument passed to the first parameter 'handler'. Be aware that the argument order does not match the FDC3 standard."); + } + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + let handlerId; + if (contextType) { + handlerId = `invokeContextHandler-${contextType}-${(0, utils_1.generateId)()}`; + } + else { + handlerId = 'invokeContextHandler'; + } + const wrappedHandler = (0, utils_1.wrapContextHandler)(handler, handlerId); + client.register(handlerId, wrappedHandler); + await client.dispatch('contextHandlerRegistered', { handlerId, contextType }); + return { + unsubscribe: async () => { + client.remove(handlerId); + await client.dispatch('removeContextHandler', { handlerId }); + } + }; + } + /* + Platform Window APIs + */ + /** + * Returns the Interop-Broker-defined context groups available for an entity to join. + * Used by Platform Windows. + * + * @example + * ```js + * fin.me.interop.getContextGroups() + * .then(contextGroups => { + * contextGroups.forEach(contextGroup => { + * console.log(contextGroup.displayMetadata.name) + * console.log(contextGroup.displayMetadata.color) + * }) + * }) + * ``` + */ + async getContextGroups() { + this.wire.sendAction('interop-client-get-context-groups').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('getContextGroups'); + } + /** + * Join all Interop Clients at the given identity to context group `contextGroupId`. + * If no target is specified, it adds the sender to the context group. + * + * @remarks Because multiple Channel connections/Interop Clients can potentially exist at a `uuid`/`name` combo, we currently join all Channel connections/Interop Clients at the given identity to the context group. + * If an `endpointId` is provided (which is unlikely, unless the call is coming from an external adapter), then we only join that single connection to the context group. + * For all intents and purposes, there will only be 1 connection present in Platform and Browser implmentations, so this point is more-or-less moot. + * Used by Platform Windows. + * + * @param contextGroupId - Id of the context group. + * @param target - Identity of the entity you wish to join to a context group. + * + * @example + * ```js + * joinViewToContextGroup = async (contextGroupId, view) => { + * await fin.me.interop.joinContextGroup(contextGroupId, view); + * } + * + * getLastFocusedView() + * .then(lastFocusedViewIdentity => { + * joinViewToContextGroup('red', lastFocusedViewIdentity) + * }) + * ``` + */ + async joinContextGroup(contextGroupId, target) { + this.wire.sendAction('interop-client-join-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + if (!contextGroupId) { + throw new Error('No contextGroupId specified for joinContextGroup.'); + } + return client.dispatch('joinContextGroup', { contextGroupId, target }); + } + /** + * Removes the specified target from a context group. + * If no target is specified, it removes the sender from their context group. + * Used by Platform Windows. + * + * @param target - Identity of the entity you wish to join to a context group. + * + * @example + * ```js + * removeViewFromContextGroup = async (view) => { + * await fin.me.interop.removeFromContextGroup(view); + * } + * + * getLastFocusedView() + * .then(lastFocusedViewIdentity => { + * removeViewFromContextGroup(lastFocusedViewIdentity) + * }) + * ``` + */ + async removeFromContextGroup(target) { + this.wire.sendAction('interop-client-remove-from-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('removeFromContextGroup', { target }); + } + /** + * Gets all clients for a context group. + * + * @remarks **This is primarily used for platform windows. Views within a platform should not have to use this API.** + * + * Returns the Interop-Broker-defined context groups available for an entity to join. + * @param contextGroupId - The id of context group you wish to get clients for. + * + * @example + * ```js + * fin.me.interop.getAllClientsInContextGroup('red') + * .then(clientsInContextGroup => { + * console.log(clientsInContextGroup) + * }) + * ``` + */ + async getAllClientsInContextGroup(contextGroupId) { + this.wire.sendAction('interop-client-get-all-clients-in-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + if (!contextGroupId) { + throw new Error('No contextGroupId specified for getAllClientsInContextGroup.'); + } + return client.dispatch('getAllClientsInContextGroup', { contextGroupId }); + } + /** + * Gets display info for a context group + * + * @remarks Used by Platform Windows. + * @param contextGroupId - The id of context group you wish to get display info for. + * + * @example + * ```js + * fin.me.interop.getInfoForContextGroup('red') + * .then(contextGroupInfo => { + * console.log(contextGroupInfo.displayMetadata.name) + * console.log(contextGroupInfo.displayMetadata.color) + * }) + * ``` + */ + async getInfoForContextGroup(contextGroupId) { + this.wire.sendAction('interop-client-get-info-for-context-group').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + if (!contextGroupId) { + throw new Error('No contextGroupId specified for getInfoForContextGroup.'); + } + return client.dispatch('getInfoForContextGroup', { contextGroupId }); + } + /** + * Sends an intent to the Interop Broker to resolve. + * @param intent - The combination of an action and a context that is passed to an application for resolution. + * + * @example + * ```js + * // View wants to fire an Intent after a user clicks on a ticker + * tickerElement.on('click', (element) => { + * const ticker = element.innerText; + * const intent = { + * name: 'ViewChart', + * context: {type: 'fdc3.instrument', id: { ticker }} + * } + * + * fin.me.interop.fireIntent(intent); + * }) + * ``` + */ + async fireIntent(intent) { + this.wire.sendAction('interop-client-fire-intent').catch((e) => { + // don't expose, this is only for api analytics purposes + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('fireIntent', intent); + } + /** + * Adds an intent handler for incoming intents. The last intent sent of the name subscribed to will be received. + * @param handler - Registered function meant to handle a specific intent type. + * @param intentName - The name of an intent. + * + * @example + * ```js + * const intentHandler = (intent) => { + * const { context } = intent; + * myViewChartHandler(context); + * }; + * + * const subscription = await fin.me.interop.registerIntentHandler(intentHandler, 'ViewChart'); + * + * function myAppCloseSequence() { + * // to unsubscribe the handler, simply call: + * subscription.unsubscribe(); + * } + * ``` + */ + async registerIntentHandler(handler, intentName, options) { + this.wire.sendAction('interop-client-register-intent-handler').catch((e) => { + // don't expose, this is only for api analytics purposes + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + const handlerId = `intent-handler-${intentName}`; + const wrappedHandler = (0, utils_1.wrapIntentHandler)(handler, handlerId); + try { + await client.register(handlerId, wrappedHandler); + await client.dispatch('intentHandlerRegistered', { handlerId, ...options }); + } + catch (error) { + throw new Error('Unable to register intent handler'); + } + return { + unsubscribe: async () => { + client.remove(handlerId); + } + }; + } + /** + * Gets the last context of the Context Group currently subscribed to. It takes an optional Context Type and returns the + * last context of that type. + * @param contextType + * + * @example + * ```js + * await fin.me.interop.joinContextGroup('yellow'); + * await fin.me.interop.setContext({ type: 'instrument', id: { ticker: 'FOO' }}); + * const currentContext = await fin.me.interop.getCurrentContext(); + * + * // with a specific context + * await fin.me.interop.joinContextGroup('yellow'); + * await fin.me.interop.setContext({ type: 'country', id: { ISOALPHA3: 'US' }}); + * await fin.me.interop.setContext({ type: 'instrument', id: { ticker: 'FOO' }}); + * const currentContext = await fin.me.interop.getCurrentContext('country'); + * ``` + */ + async getCurrentContext(contextType) { + this.wire.sendAction('interop-client-get-current-context').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('getCurrentContext', { contextType }); + } + /** + * Get information for a particular Intent from the Interop Broker. + * + * @remarks To resolve this info, the function handleInfoForIntent is meant to be overridden in the Interop Broker. + * The format for the response will be determined by the App Provider overriding the function. + * + * @param options + * + * @example + * ```js + * const intentInfo = await fin.me.interop.getInfoForIntent('ViewChart'); + * ``` + */ + async getInfoForIntent(options) { + this.wire.sendAction('interop-client-get-info-for-intent').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('getInfoForIntent', options); + } + /** + * Get information from the Interop Broker on all Intents that are meant to handle a particular context. + * + * @remarks To resolve this info, the function handleInfoForIntentsByContext is meant to be overridden in the Interop Broker. + * The format for the response will be determined by the App Provider overriding the function. + * + * @param context + * + * @example + * ```js + * tickerElement.on('click', (element) => { + * const ticker = element.innerText; + * + * const context = { + * type: 'fdc3.instrument', + * id: { + * ticker + * } + * } + * + * const intentsInfo = await fin.me.interop.getInfoForIntentByContext(context); + * }) + * ``` + */ + async getInfoForIntentsByContext(context) { + this.wire.sendAction('interop-client-get-info-for-intents-by-context').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('getInfoForIntentsByContext', context); + } + /** + * Sends a Context that will be resolved to an Intent by the Interop Broker. + * This context accepts a metadata property. + * + * @remarks To resolve this info, the function handleFiredIntentByContext is meant to be overridden in the Interop Broker. + * The format for the response will be determined by the App Provider overriding the function. + * + * @param context + * + * @example + * ```js + * tickerElement.on('click', (element) => { + * const ticker = element.innerText; + * + * const context = { + * type: 'fdc3.instrument', + * id: { + * ticker + * } + * } + * + * const intentResolution = await fin.me.interop.fireIntentForContext(context); + * }) + * ``` + */ + async fireIntentForContext(context) { + this.wire.sendAction('interop-client-fire-intent-for-context').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.dispatch('fireIntentForContext', context); + } + /** + * Join the current entity to session context group `sessionContextGroupId` and return a sessionContextGroup instance. + * If the sessionContextGroup doesn't exist, one will get created. + * + * @remarks Session Context Groups do not persist between runs and aren't present on snapshots. + * @param sessionContextGroupId - Id of the context group. + * + * @example + * Say we want to have a Session Context Group that holds UI theme information for all apps to consume: + * + * My color-picker View: + * ```js + * const themeSessionContextGroup = await fin.me.interop.joinSessionContextGroup('theme'); + * + * const myColorPickerElement = document.getElementById('color-palette-picker'); + * myColorPickerElement.addEventListener('change', event => { + * themeSessionContextGroup.setContext({ type: 'color-palette', selection: event.value }); + * }); + * ``` + * + * In other views: + * ```js + * const themeSessionContextGroup = await fin.me.interop.joinSessionContextGroup('theme'); + * + * const changeColorPalette = ({ selection }) => { + * // change the color palette to the selection + * }; + * + * // If the context is already set by the time the handler was set, the handler will get invoked immediately with the current context. + * themeSessionContextGroup.addContextHandler(changeColorPalette, 'color-palette'); + * ``` + */ + async joinSessionContextGroup(sessionContextGroupId) { + try { + const currentSessionContextGroup = __classPrivateFieldGet(this, _InteropClient_sessionContextGroups, "f").get(sessionContextGroupId); + if (currentSessionContextGroup) { + return currentSessionContextGroup.getUserInstance(); + } + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + const { hasConflict } = await client.dispatch('sessionContextGroup:createIfNeeded', { + sessionContextGroupId + }); + if (hasConflict) { + console.warn(`A (non-session) context group with the name "${sessionContextGroupId}" already exists. If you are trying to join a Context Group, call joinContextGroup instead.`); + } + const newSessionContextGroup = new SessionContextGroupClient_1.default(this.wire, __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"), sessionContextGroupId); + __classPrivateFieldGet(this, _InteropClient_sessionContextGroups, "f").set(sessionContextGroupId, newSessionContextGroup); + return newSessionContextGroup.getUserInstance(); + } + catch (error) { + console.error(`Error thrown trying to create Session Context Group with id "${sessionContextGroupId}": ${error}`); + throw error; + } + } + /** + * Register a listener that is called when the Interop Client has been disconnected from the Interop Broker. + * Only one listener per Interop Client can be set. + * @param listener + * + * @example + * ```js + * const listener = (event) => { + * const { type, topic, brokerName} = event; + * console.log(`Disconnected from Interop Broker ${brokerName} `); + * } + * + * await fin.me.interop.onDisconnection(listener); + * ``` + */ + async onDisconnection(listener) { + this.wire.sendAction('interop-client-add-ondisconnection-listener').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet(this, _InteropClient_clientPromise, "f"); + return client.onDisconnection((event) => { + const { uuid } = event; + listener({ type: 'interop-broker', topic: 'disconnected', brokerName: uuid }); + }); + } + getFDC3Sync(version) { + switch (version) { + case '1.2': + return new fdc3_1_2_1.Fdc3Module(() => this, this.wire); + case '2.0': + return new fdc3_2_0_1.Fdc3Module2(() => this, this.wire); + default: + throw new Error(`Invalid FDC3 version provided: ${version}. Must be '1.2' or '2.0'`); + } + } + async getFDC3(version) { + return this.getFDC3Sync(version); + } + /** + * @internal + * + * Used to ferry fdc3-only calls from the fdc3 shim to the Interop Broker + */ + static async ferryFdc3Call(interopClient, action, payload) { + const client = await __classPrivateFieldGet(interopClient, _InteropClient_clientPromise, "f"); + return client.dispatch(action, payload || null); + } + }; + InteropClient.InteropClient = InteropClient$1; + _InteropClient_clientPromise = new WeakMap(), _InteropClient_sessionContextGroups = new WeakMap(); + return InteropClient; +} + +var overrideCheck = {}; + +var hasRequiredOverrideCheck; + +function requireOverrideCheck () { + if (hasRequiredOverrideCheck) return overrideCheck; + hasRequiredOverrideCheck = 1; + Object.defineProperty(overrideCheck, "__esModule", { value: true }); + overrideCheck.overrideCheck = overrideCheck.checkFDC32Overrides = overrideCheck.getDefaultViewFdc3VersionFromAppInfo = void 0; + const InteropBroker_1 = requireInteropBroker(); + function getDefaultViewFdc3VersionFromAppInfo({ manifest, initialOptions }) { + const setVersion = manifest?.platform?.defaultViewOptions?.fdc3InteropApi ?? initialOptions.defaultViewOptions?.fdc3InteropApi; + return ['1.2', '2.0'].includes(setVersion ?? '') ? setVersion : undefined; + } + overrideCheck.getDefaultViewFdc3VersionFromAppInfo = getDefaultViewFdc3VersionFromAppInfo; + function checkFDC32Overrides(overriddenBroker) { + // These are the APIs that must be overridden for FDC3 2.0 compliance + const mustOverrideAPIs = [ + 'fdc3HandleFindInstances', + 'handleInfoForIntent', + 'handleInfoForIntentsByContext', + 'fdc3HandleGetAppMetadata', + 'fdc3HandleGetInfo', + 'fdc3HandleOpen', + 'handleFiredIntent', + 'handleFiredIntentForContext' + ]; + return mustOverrideAPIs.filter((api) => { + return overriddenBroker[api] === InteropBroker_1.InteropBroker.prototype[api]; + }); + } + overrideCheck.checkFDC32Overrides = checkFDC32Overrides; + function overrideCheck$1(overriddenBroker, fdc3InteropApi) { + if (fdc3InteropApi && fdc3InteropApi === '2.0') { + const notOverridden = checkFDC32Overrides(overriddenBroker); + if (notOverridden.length > 0) { + console.warn(`WARNING: FDC3 2.0 has been set as a default option for Views in this Platform, but the required InteropBroker APIs for FDC3 2.0 compliance have not all been overridden.\nThe following APIs need to be overridden:\n${notOverridden.join('\n')}`); + } + } + } + overrideCheck.overrideCheck = overrideCheck$1; + return overrideCheck; +} + +var hasRequiredFactory; + +function requireFactory () { + if (hasRequiredFactory) return Factory$1; + hasRequiredFactory = 1; + var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(Factory$1, "__esModule", { value: true }); + Factory$1.InteropModule = void 0; + const cloneDeep_1 = __importDefault(require$$0$1); + const inaccessibleObject_1 = inaccessibleObject; + const base_1 = base; + const InteropBroker_1 = requireInteropBroker(); + const InteropClient_1 = requireInteropClient(); + const overrideCheck_1 = requireOverrideCheck(); + const common_utils_1 = commonUtils; + const defaultOverride = (Class) => new Class(); + const BrokerParamAccessError = 'You have attempted to use or modify InteropBroker parameters, which is not allowed. You are likely using an older InteropBroker override scheme. Please consult our Interop docs for guidance on migrating to the new override scheme.'; + /** + * Manages creation of Interop Brokers and Interop Clients. These APIs are called under-the-hood in Platforms. + * + */ + class InteropModule extends base_1.Base { + /** + * Initializes an Interop Broker. This is called under-the-hood for Platforms. + * + * @remarks For Platforms, this is set up automatically. We advise to only create your own Interop Broker + * when not using a Platform app. You can override functions in the Interop Broker. More info {@link InteropBroker here}. + * + * @param name - Name of the Interop Broker. + * @param override - A callback function or array of callback functions that can be used to extend or replace default Interop Broker behavior. + * + * @example + * ``` js + * const interopBroker = await fin.Interop.init('openfin'); + * const contextGroups = await interopBroker.getContextGroups(); + * console.log(contextGroups); + * ``` + */ + async init(name, override = defaultOverride) { + this.wire.sendAction('interop-init').catch(() => { + // don't expose, analytics-only call + }); + // Allows for manifest-level configuration, without having to override. (e.g. specifying custom context groups) + const options = await this.wire.environment.getInteropInfo(this.wire.getFin()); + const objectThatThrows = (0, inaccessibleObject_1.createUnusableObject)(BrokerParamAccessError); + const warningOptsClone = (0, inaccessibleObject_1.createWarningObject)(BrokerParamAccessError, (0, cloneDeep_1.default)(options)); + const getProvider = () => { + return this.fin.InterApplicationBus.Channel.create(`interop-broker-${name}`); + }; + const throwingGetProvider = async () => { + // eslint-disable-next-line no-console + throw new Error(BrokerParamAccessError); + }; + const OverrideableBroker = InteropBroker_1.InteropBroker.createClosedConstructor(this.wire, getProvider, options); + let broker; + if (Array.isArray(override)) { + const BrokerConstructor = (0, common_utils_1.overrideFromComposables)(...override)(OverrideableBroker); + // We need to use these objects because removing them entirely would be a breaking change and we want an informative error + // @ts-expect-error + broker = new BrokerConstructor(objectThatThrows, throwingGetProvider, warningOptsClone); + } + else { + // We need to use these objects because removing them entirely would be a breaking change and we want an informative error + // @ts-expect-error + broker = await override(OverrideableBroker, objectThatThrows, throwingGetProvider, warningOptsClone); + } + (0, overrideCheck_1.overrideCheck)(broker, options.fdc3Version); + return broker; + } + /** + * Connects a client to an Interop broker. This is called under-the-hood for Views in a Platform. + * + * @remarks + * @param name - The name of the Interop Broker to connect to. For Platforms, this will default to the uuid of the Platform. + * @param interopConfig - Information relevant to the Interop Broker. Typically a declaration of + * what context(s) the entity wants to subscribe to, and the current Context Group of the entity. + * + * @example + * ```js + * const interopConfig = { + * currentContextGroup: 'green' + * } + * + * const interopBroker = await fin.Interop.init('openfin'); + * const client = await fin.Interop.connectSync('openfin', interopConfig); + * const contextGroupInfo = await client.getInfoForContextGroup(); + * console.log(contextGroupInfo); + * ``` + */ + connectSync(name, interopConfig) { + this.wire.sendAction('interop-connect-sync').catch(() => { + // don't expose, analytics-only call + }); + return new InteropClient_1.InteropClient(this.wire, this.wire.environment.whenReady().then(() => { + return this.fin.InterApplicationBus.Channel.connect(`interop-broker-${name}`, { + payload: interopConfig + }); + })); + } + } + Factory$1.InteropModule = InteropModule; + return Factory$1; +} + +var hasRequiredInterop; + +function requireInterop () { + if (hasRequiredInterop) return interop; + hasRequiredInterop = 1; + (function (exports) { + /** + * Entry point for the OpenFin `Interop` API (`fin.Interop`). + * + * * {@link InteropModule} contains static members of the `Interop` API (available under `fin.Interop`) + * * {@link InteropClient} and {@link InteropBroker} document instances of their respective classes. + * + * @packageDocumentation + */ + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(requireFactory(), exports); + __exportStar(requireInteropClient(), exports); + __exportStar(requireInteropBroker(), exports); + } (interop)); + return interop; +} + +var snapshotSource = {}; + +var Factory = {}; + +var Instance = {}; + +var utils = {}; + +Object.defineProperty(utils, "__esModule", { value: true }); +utils.getSnapshotSourceChannelName = void 0; +const channelPrefix = 'snapshot-source-provider-'; +const getSnapshotSourceChannelName = (id) => `${channelPrefix}${id.uuid}`; +utils.getSnapshotSourceChannelName = getSnapshotSourceChannelName; + +var __classPrivateFieldSet$1 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet$1 = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _SnapshotSource_identity, _SnapshotSource_getConnection, _SnapshotSource_getClient, _SnapshotSource_startConnection, _SnapshotSource_setUpConnectionListener; +Object.defineProperty(Instance, "__esModule", { value: true }); +Instance.SnapshotSource = void 0; +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +const base_1$1 = base; +const utils_1$1 = utils; +const connectionMap = new Map(); +/** + * Enables configuring a SnapshotSource with custom getSnapshot and applySnapshot methods. + * + * @typeParam Snapshot Implementation-defined shape of an application snapshot. Allows + * custom snapshot implementations for legacy applications to define their own snapshot format. + */ +class SnapshotSource extends base_1$1.Base { + /** + * @internal + */ + constructor(wire, id) { + super(wire); + _SnapshotSource_identity.set(this, void 0); + _SnapshotSource_getConnection.set(this, () => { + if (!connectionMap.has(this.identity.uuid)) { + connectionMap.set(this.identity.uuid, { eventFired: null, clientPromise: null }); + } + return connectionMap.get(this.identity.uuid); + }); + _SnapshotSource_getClient.set(this, () => { + if (!__classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).clientPromise) { + __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).clientPromise = __classPrivateFieldGet$1(this, _SnapshotSource_startConnection, "f").call(this); + } + return __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).clientPromise; + }); + _SnapshotSource_startConnection.set(this, async () => { + const channelName = (0, utils_1$1.getSnapshotSourceChannelName)(this.identity); + try { + if (!__classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).eventFired) { + await __classPrivateFieldGet$1(this, _SnapshotSource_setUpConnectionListener, "f").call(this); + } + const client = await this.fin.InterApplicationBus.Channel.connect(channelName, { wait: false }); + client.onDisconnection(() => { + __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).clientPromise = null; + __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).eventFired = null; + }); + return client; + } + catch (e) { + __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).clientPromise = null; + throw new Error("The targeted SnapshotSource is not currently initialized. Await this object's ready() method."); + } + }); + _SnapshotSource_setUpConnectionListener.set(this, async () => { + const channelName = (0, utils_1$1.getSnapshotSourceChannelName)(this.identity); + let resolve; + let reject; + const eventFired = new Promise((y, n) => { + resolve = y; + reject = n; + }); + __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).eventFired = eventFired; + const listener = async (e) => { + try { + if (e.channelName === channelName) { + resolve(); + await this.fin.InterApplicationBus.Channel.removeListener('connected', listener); + } + } + catch (err) { + reject(err); + } + }; + await this.fin.InterApplicationBus.Channel.on('connected', listener); + }); + __classPrivateFieldSet$1(this, _SnapshotSource_identity, id, "f"); + } + get identity() { + return __classPrivateFieldGet$1(this, _SnapshotSource_identity, "f"); + } + /** + * Method to determine if the SnapshotSource has been initialized. + * + * @remarks Use when the parent application is starting up to ensure the SnapshotSource is able to accept and + * apply a snapshot using the {@link SnapshotSource#applySnapshot applySnapshot} method. + * + * @example + * ```js + * let snapshotSource = fin.SnapshotSource.wrapSync(fin.me); + * + * const snapshotProvider = { + * async getSnapshot() { return 'foo' }, + * async applySnapshot(snapshot) { + * console.log(snapshot); + * return undefined; + * } + * } + * await fin.SnapshotSource.init(snapshotProvider); + * + * try { + * await snapshotSource.ready(); + * await snapshotSource.applySnapshot('foo'); + * } catch (err) { + * console.log(err) + * } + * ``` + */ + async ready() { + this.wire.sendAction('snapshot-source-ready').catch((e) => { + // don't expose, analytics-only call + }); + // eslint-disable-next-line no-async-promise-executor + try { + // If getClient was already called before this, do we have a timing issue where the channel might have been created but we missed the event but this still fails? + await __classPrivateFieldGet$1(this, _SnapshotSource_getClient, "f").call(this); + } + catch (e) { + // it was not running. + await __classPrivateFieldGet$1(this, _SnapshotSource_getConnection, "f").call(this).eventFired; + } + } + /** + * Call the SnapshotSource's getSnapshot method defined by {@link SnapshotSource.SnapshotSourceModule#init init}. + * + */ + async getSnapshot() { + this.wire.sendAction('snapshot-source-get-snapshot').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet$1(this, _SnapshotSource_getClient, "f").call(this); + const response = (await client.dispatch('get-snapshot')); + return (await response).snapshot; + } + /** + * Call the SnapshotSource's applySnapshot method defined by {@link SnapshotSource.SnapshotSourceModule#init init}. + * + */ + async applySnapshot(snapshot) { + this.wire.sendAction('snapshot-source-apply-snapshot').catch((e) => { + // don't expose, analytics-only call + }); + const client = await __classPrivateFieldGet$1(this, _SnapshotSource_getClient, "f").call(this); + return client.dispatch('apply-snapshot', { snapshot }); + } +} +Instance.SnapshotSource = SnapshotSource; +_SnapshotSource_identity = new WeakMap(), _SnapshotSource_getConnection = new WeakMap(), _SnapshotSource_getClient = new WeakMap(), _SnapshotSource_startConnection = new WeakMap(), _SnapshotSource_setUpConnectionListener = new WeakMap(); + +Object.defineProperty(Factory, "__esModule", { value: true }); +Factory.SnapshotSourceModule = void 0; +const base_1 = base; +const Instance_1 = Instance; +const utils_1 = utils; +/** + * Static namespace for OpenFin API methods that interact with the {@link SnapshotSource} class, available under `fin.SnapshotSource`. + */ +class SnapshotSourceModule extends base_1.Base { + /** + * Initializes a SnapshotSource with the getSnapshot and applySnapshot methods defined. + * + * @typeParam Snapshot Implementation-defined shape of an application snapshot. Allows + * custom snapshot implementations for legacy applications to define their own snapshot format. + * + * @example + * ```js + * const snapshotProvider = { + * async getSnapshot() { + * const bounds = await fin.me.getBounds(); + * return bounds; + * }, + * async applySnapshot(snapshot) { + * await fin.me.setBounds(snapshot); + * return undefined; + * } + * } + * + * await fin.SnapshotSource.init(snapshotProvider); + * ``` + * + */ + async init(provider) { + this.wire.sendAction('snapshot-source-init').catch((e) => { + // don't expose, analytics-only call + }); + if (typeof provider !== 'object' || + typeof provider.getSnapshot !== 'function' || + typeof provider.applySnapshot !== 'function') { + throw new Error('you must pass in a valid SnapshotProvider'); + } + const channel = await this.fin.InterApplicationBus.Channel.create((0, utils_1.getSnapshotSourceChannelName)(this.fin.me)); + channel.register('get-snapshot', async () => { + const snapshot = await provider.getSnapshot(); + return { snapshot }; + }); + channel.register('apply-snapshot', ({ snapshot }) => provider.applySnapshot(snapshot)); + } + /** + * Synchronously returns a SnapshotSource object that represents the current SnapshotSource. + * + * @example + * ```js + * const snapshotSource = fin.SnapshotSource.wrapSync(fin.me); + * // Use wrapped instance's getSnapshot method, e.g.: + * const snapshot = await snapshotSource.getSnapshot(); + * ``` + */ + wrapSync(identity) { + this.wire.sendAction('snapshot-source-wrap-sync').catch((e) => { + // don't expose, analytics-only call + }); + return new Instance_1.SnapshotSource(this.wire, identity); + } + /** + * Asynchronously returns a SnapshotSource object that represents the current SnapshotSource. + * + * @example + * ```js + * const snapshotSource = await fin.SnapshotSource.wrap(fin.me); + * // Use wrapped instance's getSnapshot method, e.g.: + * const snapshot = await snapshotSource.getSnapshot(); + * ``` + */ + async wrap(identity) { + this.wire.sendAction('snapshot-source-wrap').catch((e) => { + // don't expose, analytics-only call + }); + return this.wrapSync(identity); + } +} +Factory.SnapshotSourceModule = SnapshotSourceModule; + +(function (exports) { + /** + * Entry points for the OpenFin `SnapshotSource` API (`fin.SnapshotSource`). + * + * * {@link SnapshotSourceModule} contains static members of the `SnapshotSource` API, accessible through `fin.SnapshotSource`. + * * {@link SnapshotSource} describes an instance of an OpenFin SnapshotSource, e.g. as returned by `fin.SnapshotSource.wrap`. + * + * These are separate code entities, and are documented separately. In the [previous version of the API documentation](https://cdn.openfin.co/docs/javascript/32.114.76.10/index.html), + * both of these were documented on the same page. + * + * @packageDocumentation + */ + var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); + }) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; + })); + var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + __exportStar(Factory, exports); + __exportStar(Instance, exports); +} (snapshotSource)); + +Object.defineProperty(fin$2, "__esModule", { value: true }); +var Fin_1 = fin$2.Fin = void 0; +const events_1$3 = require$$0; +// Import from the file rather than the directory in case someone consuming types is using module resolution other than "node" +const index_1 = system; +const index_2 = requireWindow(); +const index_3 = requireApplication(); +const index_4 = interappbus; +const index_5 = clipboard; +const index_6 = externalApplication; +const index_7 = frame; +const index_8 = globalHotkey; +const index_9 = requireView(); +const index_10 = platform; +const me_1$2 = me; +const interop_1 = requireInterop(); +const snapshot_source_1 = snapshotSource; +/** + * @internal + */ +class Fin extends events_1$3.EventEmitter { + /** + * @internal + */ + constructor(wire) { + super(); + this.wire = wire; + this.System = new index_1.System(wire); + this.Window = new index_2._WindowModule(wire); + this.Application = new index_3.ApplicationModule(wire); + this.InterApplicationBus = new index_4.InterApplicationBus(wire); + this.Clipboard = new index_5.Clipboard(wire); + this.ExternalApplication = new index_6.ExternalApplicationModule(wire); + this.Frame = new index_7._FrameModule(wire); + this.GlobalHotkey = new index_8.GlobalHotkey(wire); + this.Platform = new index_10.PlatformModule(wire, this.InterApplicationBus.Channel); + this.View = new index_9.ViewModule(wire); + this.Interop = new interop_1.InteropModule(wire); + this.SnapshotSource = new snapshot_source_1.SnapshotSourceModule(wire); + wire.registerFin(this); + this.me = (0, me_1$2.getMe)(wire); + // Handle disconnect events + wire.on('disconnected', () => { + this.emit('disconnected'); + }); + } +} +Fin_1 = fin$2.Fin = Fin; + +var transport = {}; + +var wire = {}; + +Object.defineProperty(wire, "__esModule", { value: true }); +wire.isInternalConnectConfig = wire.isPortDiscoveryConfig = wire.isNewConnectConfig = wire.isConfigWithReceiver = wire.isRemoteConfig = wire.isExistingConnectConfig = wire.isExternalConfig = void 0; +function isExternalConfig(config) { + if (typeof config.manifestUrl === 'string') { + return true; + } + return false; +} +wire.isExternalConfig = isExternalConfig; +function isExistingConnectConfig(config) { + return hasUuid(config) && typeof config.address === 'string'; +} +wire.isExistingConnectConfig = isExistingConnectConfig; +function isRemoteConfig(config) { + return isExistingConnectConfig(config) && typeof config.token === 'string'; +} +wire.isRemoteConfig = isRemoteConfig; +function isConfigWithReceiver(config) { + return typeof config.receiver === 'object' && isRemoteConfig({ ...config, address: '' }); +} +wire.isConfigWithReceiver = isConfigWithReceiver; +function hasUuid(config) { + return typeof config.uuid === 'string'; +} +function hasRuntimeVersion(config) { + return config.runtime && typeof config.runtime.version === 'string'; +} +function isNewConnectConfig(config) { + return hasUuid(config) && hasRuntimeVersion(config); +} +wire.isNewConnectConfig = isNewConnectConfig; +function isPortDiscoveryConfig(config) { + return (isExternalConfig(config) && hasRuntimeVersion(config)) || isNewConnectConfig(config); +} +wire.isPortDiscoveryConfig = isPortDiscoveryConfig; +function isInternalConnectConfig(config) { + return isExistingConnectConfig(config) || isNewConnectConfig(config); +} +wire.isInternalConnectConfig = isInternalConnectConfig; + +var eventAggregator = {}; + +var emitterMap = {}; + +Object.defineProperty(emitterMap, "__esModule", { value: true }); +emitterMap.EmitterMap = void 0; +const events_1$2 = require$$0; +class EmitterMap { + constructor() { + this.storage = new Map(); + } + // eslint-disable-next-line class-methods-use-this + hashKeys(keys) { + const hashed = keys.map(normalizeString); + return hashed.join('/'); + } + getOrCreate(keys) { + const hash = this.hashKeys(keys); + if (!this.storage.has(hash)) { + this.storage.set(hash, new events_1$2.EventEmitter()); + } + // We set it above + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this.storage.get(hash); + } + has(keys) { + return this.storage.has(this.hashKeys(keys)); + } + delete(keys) { + const hash = this.hashKeys(keys); + return this.storage.delete(hash); + } +} +emitterMap.EmitterMap = EmitterMap; +function normalizeString(s) { + const b = Buffer.from(s); + return b.toString('base64'); +} + +Object.defineProperty(eventAggregator, "__esModule", { value: true }); +const emitterMap_1 = emitterMap; +function isEventMessage(message) { + return message.action === 'process-desktop-event'; +} +function mapKeyFromEvent(event) { + const { topic } = event; + if (topic === 'frame' || topic === 'window' || topic === 'view') { + const { uuid, name } = event; + return [topic, uuid, name]; + } + if (topic === 'application') { + const { uuid } = event; + return [topic, uuid]; + } + return [topic]; +} +class EventAggregator extends emitterMap_1.EmitterMap { + constructor() { + super(...arguments); + this.dispatchEvent = (message) => { + if (isEventMessage(message)) { + const { payload } = message; + const accessor = mapKeyFromEvent(payload); + if (this.has(accessor)) { + this.getOrCreate(accessor).emit(payload.type, payload); + return true; + } + } + return false; + }; + } +} +eventAggregator.default = EventAggregator; + +var __classPrivateFieldSet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet = (commonjsGlobal && commonjsGlobal.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +var _Transport_wire, _Transport_fin; +Object.defineProperty(transport, "__esModule", { value: true }); +var Transport_1 = transport.Transport = void 0; +const events_1$1 = require$$0; +const wire_1 = wire; +const transport_errors_1 = transportErrors; +const eventAggregator_1 = __importDefault(eventAggregator); +const me_1$1 = me; +const errors_1 = errors; +class Transport extends events_1$1.EventEmitter { + constructor(WireType, environment, config) { + super(); + this.wireListeners = new Map(); + this.topicRefMap = new Map(); + this.eventAggregator = new eventAggregator_1.default(); + this.messageHandlers = [this.eventAggregator.dispatchEvent]; + _Transport_wire.set(this, void 0); + // Typing as unknown to avoid circular dependency, should not be used directly. + _Transport_fin.set(this, void 0); + this.connectSync = () => { + const wire = __classPrivateFieldGet(this, _Transport_wire, "f"); + wire.connectSync(); + }; + // This function is only used in our tests. + this.getPort = () => { + const wire = __classPrivateFieldGet(this, _Transport_wire, "f"); + return wire.getPort(); + }; + __classPrivateFieldSet(this, _Transport_wire, new WireType(this.onmessage.bind(this)), "f"); + this.environment = environment; + this.sendRaw = __classPrivateFieldGet(this, _Transport_wire, "f").send.bind(__classPrivateFieldGet(this, _Transport_wire, "f")); + this.registerMessageHandler(this.handleMessage.bind(this)); + __classPrivateFieldGet(this, _Transport_wire, "f").on('disconnected', () => { + for (const [, { handleNack }] of this.wireListeners) { + handleNack({ reason: 'Remote connection has closed' }); + } + this.wireListeners.clear(); + this.emit('disconnected'); + }); + const { uuid, name } = config; + const entityType = this.environment.getCurrentEntityType(); + this.me = (0, me_1$1.getBaseMe)(entityType, uuid, name); + } + getFin() { + if (!__classPrivateFieldGet(this, _Transport_fin, "f")) { + throw new Error('No Fin object registered for this transport'); + } + return __classPrivateFieldGet(this, _Transport_fin, "f"); + } + registerFin(_fin) { + if (__classPrivateFieldGet(this, _Transport_fin, "f")) { + throw new Error('Fin object has already been registered for this transport'); + } + __classPrivateFieldSet(this, _Transport_fin, _fin, "f"); + } + shutdown() { + const wire = __classPrivateFieldGet(this, _Transport_wire, "f"); + return wire.shutdown(); + } + async connect(config) { + if ((0, wire_1.isConfigWithReceiver)(config)) { + await __classPrivateFieldGet(this, _Transport_wire, "f").connect(config.receiver); + return this.authorize(config); + } + if ((0, wire_1.isRemoteConfig)(config)) { + return this.connectRemote(config); + } + if ((0, wire_1.isExistingConnectConfig)(config)) { + return this.connectByPort(config); + } + if ((0, wire_1.isNewConnectConfig)(config)) { + const port = await this.environment.retrievePort(config); + return this.connectByPort({ ...config, address: `ws://localhost:${port}` }); + } + return undefined; + } + async connectRemote(config) { + await __classPrivateFieldGet(this, _Transport_wire, "f").connect(new (this.environment.getWsConstructor())(config.address)); + return this.authorize(config); + } + async connectByPort(config) { + const { address, uuid } = config; + const reqAuthPayload = { ...config, type: 'file-token' }; + const wire = __classPrivateFieldGet(this, _Transport_wire, "f"); + await wire.connect(new (this.environment.getWsConstructor())(config.address)); + const requestExtAuthRet = await this.sendAction('request-external-authorization', { + uuid, + type: 'file-token' + }, true); + if (requestExtAuthRet.action !== 'external-authorization-response') { + throw new transport_errors_1.UnexpectedActionError(requestExtAuthRet.action); + } + await this.environment.writeToken(requestExtAuthRet.payload.file, requestExtAuthRet.payload.token); + return this.authorize(reqAuthPayload); + } + async authorize(reqAuthPayload) { + const requestAuthRet = await this.sendAction('request-authorization', reqAuthPayload, true); + if (requestAuthRet.action !== 'authorization-response') { + throw new transport_errors_1.UnexpectedActionError(requestAuthRet.action); + } + else if (requestAuthRet.payload.success !== true) { + throw new transport_errors_1.RuntimeError(requestAuthRet.payload); + } + } + sendAction(action, payload = {}, uncorrelated = false + // specialResponse type is only used for 'requestAuthorization' + ) { + // eslint-disable-next-line @typescript-eslint/no-empty-function + let cancel = () => { }; + // We want the callsite from the caller of this function, not from here. + const callSites = transport_errors_1.RuntimeError.getCallSite(1); + const messageId = this.environment.getNextMessageId(); + const prom = new Promise((resolve, reject) => { + cancel = reject; + const msg = { + action, + payload, + messageId + }; + const wire = __classPrivateFieldGet(this, _Transport_wire, "f"); + this.addWireListener(messageId, resolve, (payload) => this.nackHandler(payload, reject, callSites), uncorrelated); + return wire.send(msg).catch(reject); + }); + return Object.assign(prom, { cancel, messageId }); + } + nackHandler(payloadOrMessage, reject, callSites) { + if (typeof payloadOrMessage === 'string') { + // NOTE: this is for backwards compatibility to support plain string rejections + reject(payloadOrMessage); + } + else { + reject(new transport_errors_1.RuntimeError(payloadOrMessage, callSites)); + } + } + ferryAction(origData) { + return new Promise((resolve, reject) => { + const id = this.environment.getNextMessageId(); + origData.messageId = id; + const resolver = (data) => { + resolve(data.payload); + }; + const wire = __classPrivateFieldGet(this, _Transport_wire, "f"); + return wire + .send(origData) + .then(() => this.addWireListener(id, resolver, (payload) => this.nackHandler(payload, reject), false)) + .catch(reject); + }); + } + registerMessageHandler(handler) { + this.messageHandlers.push(handler); + } + addWireListener(id, resolve, handleNack, uncorrelated) { + if (uncorrelated) { + this.uncorrelatedListener = resolve; + } + else if (this.wireListeners.has(id)) { + handleNack({ + reason: 'Duplicate handler id', + error: (0, errors_1.errorToPOJO)(new transport_errors_1.DuplicateCorrelationError(String(id))) + }); + } + else { + this.wireListeners.set(id, { resolve, handleNack }); + } + // Timeout and reject()? + } + // This method executes message handlers until the _one_ that handles the message (returns truthy) has run + onmessage(data) { + for (const h of this.messageHandlers) { + h.call(null, data); + } + } + handleMessage(data) { + const id = data.correlationId || NaN; + if (!('correlationId' in data)) { + if (this.uncorrelatedListener) { + this.uncorrelatedListener.call(null, data); + } + this.uncorrelatedListener = () => { + // empty block + }; + } + else if (!this.wireListeners.has(id)) { + return false; + } + else { + // We just checked for existence above + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const { resolve, handleNack } = this.wireListeners.get(id); + if (data.action !== 'ack') { + handleNack({ reason: 'Did not receive ack action', error: (0, errors_1.errorToPOJO)(new transport_errors_1.NoAckError(data.action)) }); + } + else if (!('payload' in data)) { + // I'm not sure when this code would actually run, but passing in something that doeesn't have a reason to the runtimeerror constructor will not end well. + // @ts-expect-error + if (typeof data.reason === 'string') { + handleNack(data); + } + else { + console.warn('Received invalid response from core', data); + handleNack({ reason: 'invalid response shape' }); + } + } + else if (!data.payload.success) { + handleNack(data.payload); + } + else { + resolve.call(null, data); + } + this.wireListeners.delete(id); + } + return true; + } +} +Transport_1 = transport.Transport = Transport; +_Transport_wire = new WeakMap(), _Transport_fin = new WeakMap(); + +var mockEnvironment = {}; + +Object.defineProperty(mockEnvironment, "__esModule", { value: true }); +var MockEnvironment_1 = mockEnvironment.MockEnvironment = void 0; +const me_1 = me; +class MockEnvironment { + constructor() { + this.type = 'other'; + this.childViews = true; + } + getAdapterVersionSync() { + throw new Error(me_1.environmentUnsupportedMessage); + } + async getInteropInfo() { + throw new Error(me_1.environmentUnsupportedMessage); + } + getDefaultChannelOptions() { + throw new Error(me_1.environmentUnsupportedMessage); + } + getRtcPeer() { + throw new Error(me_1.environmentUnsupportedMessage); + } + layoutAllowedInContext(_fin) { + throw new Error(me_1.environmentUnsupportedMessage); + } + initLayoutManager() { + throw new Error(me_1.environmentUnsupportedMessage); + } + applyLayoutSnapshot() { + throw new Error(me_1.environmentUnsupportedMessage); + } + async createLayout() { + throw new Error(me_1.environmentUnsupportedMessage); + } + async destroyLayout() { + throw new Error(me_1.environmentUnsupportedMessage); + } + async resolveLayout() { + throw new Error(me_1.environmentUnsupportedMessage); + } + initPlatform() { + throw new Error(me_1.environmentUnsupportedMessage); + } + observeBounds() { + throw new Error(me_1.environmentUnsupportedMessage); + } + writeToken(path, token) { + throw new Error(me_1.environmentUnsupportedMessage); + } + retrievePort(config) { + throw new Error(me_1.environmentUnsupportedMessage); + } + getNextMessageId() { + return `mock-message-id-${Math.random()}`; + } + getRandomId() { + throw new Error(me_1.environmentUnsupportedMessage); + } + createChildContent(options) { + throw new Error(me_1.environmentUnsupportedMessage); + } + getWebWindow(identity) { + throw new Error(me_1.environmentUnsupportedMessage); + } + getCurrentEntityIdentity() { + throw new Error(me_1.environmentUnsupportedMessage); + } + getCurrentEntityType() { + return 'unknown'; + } + raiseEvent(eventName, eventArgs) { + throw new Error(me_1.environmentUnsupportedMessage); + } + getUrl() { + throw new Error(me_1.environmentUnsupportedMessage); + } + whenReady() { + throw new Error(me_1.environmentUnsupportedMessage); + } + getWsConstructor() { + throw new Error('Method not implemented.'); + } +} +MockEnvironment_1 = mockEnvironment.MockEnvironment = MockEnvironment; + +var mockWire = {}; + +Object.defineProperty(mockWire, "__esModule", { value: true }); +var MockWire_1 = mockWire.MockWire = void 0; +/* eslint-disable @typescript-eslint/no-unused-vars */ +const events_1 = require$$0; +class MockWire extends events_1.EventEmitter { + connect() { + throw new Error('You are not running in OpenFin.'); + } + connectSync() { + throw new Error('You are not running in OpenFin.'); + } + send(data) { + throw new Error('You are not running in OpenFin.'); + } + shutdown() { + throw new Error('You are not running in OpenFin.'); + } + getPort() { + throw new Error('This transport has no port'); + } + // eslint-disable-next-line no-useless-constructor + constructor() { + super(); + } +} +MockWire_1 = mockWire.MockWire = MockWire; + +const fin$1 = ((typeof window !== 'undefined' && window?.fin) || + (() => { + const environment = new MockEnvironment_1(); + const transport = new Transport_1(MockWire_1, environment, { + uuid: '', + name: '' + }); + return new Fin_1(transport); + })()); + +exports.OpenFin = OpenFin$1; +exports["default"] = OpenFin$1; +exports.fin = fin$1; + + +/***/ }), + +/***/ "../../node_modules/events/events.js": +/*!*******************************************!*\ + !*** ../../node_modules/events/events.js ***! + \*******************************************/ +/***/ ((module) => { + +"use strict"; +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +var R = typeof Reflect === 'object' ? Reflect : null +var ReflectApply = R && typeof R.apply === 'function' + ? R.apply + : function ReflectApply(target, receiver, args) { + return Function.prototype.apply.call(target, receiver, args); + } + +var ReflectOwnKeys +if (R && typeof R.ownKeys === 'function') { + ReflectOwnKeys = R.ownKeys +} else if (Object.getOwnPropertySymbols) { + ReflectOwnKeys = function ReflectOwnKeys(target) { + return Object.getOwnPropertyNames(target) + .concat(Object.getOwnPropertySymbols(target)); + }; +} else { + ReflectOwnKeys = function ReflectOwnKeys(target) { + return Object.getOwnPropertyNames(target); + }; +} + +function ProcessEmitWarning(warning) { + if (console && console.warn) console.warn(warning); +} + +var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { + return value !== value; +} + +function EventEmitter() { + EventEmitter.init.call(this); +} +module.exports = EventEmitter; +module.exports.once = once; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._eventsCount = 0; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +var defaultMaxListeners = 10; + +function checkListener(listener) { + if (typeof listener !== 'function') { + throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); + } +} + +Object.defineProperty(EventEmitter, 'defaultMaxListeners', { + enumerable: true, + get: function() { + return defaultMaxListeners; + }, + set: function(arg) { + if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { + throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); + } + defaultMaxListeners = arg; + } +}); + +EventEmitter.init = function() { + + if (this._events === undefined || + this._events === Object.getPrototypeOf(this)._events) { + this._events = Object.create(null); + this._eventsCount = 0; + } + + this._maxListeners = this._maxListeners || undefined; +}; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { + if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { + throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); + } + this._maxListeners = n; + return this; +}; + +function _getMaxListeners(that) { + if (that._maxListeners === undefined) + return EventEmitter.defaultMaxListeners; + return that._maxListeners; +} + +EventEmitter.prototype.getMaxListeners = function getMaxListeners() { + return _getMaxListeners(this); +}; + +EventEmitter.prototype.emit = function emit(type) { + var args = []; + for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); + var doError = (type === 'error'); + + var events = this._events; + if (events !== undefined) + doError = (doError && events.error === undefined); + else if (!doError) + return false; + + // If there is no 'error' event listener then throw. + if (doError) { + var er; + if (args.length > 0) + er = args[0]; + if (er instanceof Error) { + // Note: The comments on the `throw` lines are intentional, they show + // up in Node's output if this results in an unhandled exception. + throw er; // Unhandled 'error' event + } + // At least give some kind of context to the user + var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); + err.context = er; + throw err; // Unhandled 'error' event + } + + var handler = events[type]; + + if (handler === undefined) + return false; + + if (typeof handler === 'function') { + ReflectApply(handler, this, args); + } else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + ReflectApply(listeners[i], this, args); + } + + return true; +}; + +function _addListener(target, type, listener, prepend) { + var m; + var events; + var existing; + + checkListener(listener); + + events = target._events; + if (events === undefined) { + events = target._events = Object.create(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener !== undefined) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); + + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } + + if (existing === undefined) { + // Optimize the case of one listener. Don't need the extra array object. + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; + // If we've already got an array, just append. + } else if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + + // Check for listener leak + m = _getMaxListeners(target); + if (m > 0 && existing.length > m && !existing.warned) { + existing.warned = true; + // No error code for this since it is a Warning + // eslint-disable-next-line no-restricted-syntax + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' ' + String(type) + ' listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + ProcessEmitWarning(w); + } + } + + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; + +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + if (arguments.length === 0) + return this.listener.call(this.target); + return this.listener.apply(this.target, arguments); + } +} + +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = onceWrapper.bind(state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} + +EventEmitter.prototype.once = function once(type, listener) { + checkListener(listener); + this.on(type, _onceWrap(this, type, listener)); + return this; +}; + +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + checkListener(listener); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; + +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + checkListener(listener); + + events = this._events; + if (events === undefined) + return this; + + list = events[type]; + if (list === undefined) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = Object.create(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } + + if (position < 0) + return this; + + if (position === 0) + list.shift(); + else { + spliceOne(list, position); + } + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener !== undefined) + this.emit('removeListener', type, originalListener || listener); + } + + return this; + }; + +EventEmitter.prototype.off = EventEmitter.prototype.removeListener; + +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (events === undefined) + return this; + + // not listening for removeListener, no need to emit + if (events.removeListener === undefined) { + if (arguments.length === 0) { + this._events = Object.create(null); + this._eventsCount = 0; + } else if (events[type] !== undefined) { + if (--this._eventsCount === 0) + this._events = Object.create(null); + else + delete events[type]; + } + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = Object.keys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = Object.create(null); + this._eventsCount = 0; + return this; + } + + listeners = events[type]; + + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners !== undefined) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } + + return this; + }; + +function _listeners(target, type, unwrap) { + var events = target._events; + + if (events === undefined) + return []; + + var evlistener = events[type]; + if (evlistener === undefined) + return []; + + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; + + return unwrap ? + unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); +}; + +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); +}; + +EventEmitter.listenerCount = function(emitter, type) { + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } +}; + +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events !== undefined) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener !== undefined) { + return evlistener.length; + } + } + + return 0; +} + +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; +}; + +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; +} + +function spliceOne(list, index) { + for (; index + 1 < list.length; index++) + list[index] = list[index + 1]; + list.pop(); +} + +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function once(emitter, name) { + return new Promise(function (resolve, reject) { + function errorListener(err) { + emitter.removeListener(name, resolver); + reject(err); + } + + function resolver() { + if (typeof emitter.removeListener === 'function') { + emitter.removeListener('error', errorListener); + } + resolve([].slice.call(arguments)); + }; + + eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); + if (name !== 'error') { + addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); + } + }); +} + +function addErrorHandlerIfEventEmitter(emitter, handler, flags) { + if (typeof emitter.on === 'function') { + eventTargetAgnosticAddListener(emitter, 'error', handler, flags); + } +} + +function eventTargetAgnosticAddListener(emitter, name, listener, flags) { + if (typeof emitter.on === 'function') { + if (flags.once) { + emitter.once(name, listener); + } else { + emitter.on(name, listener); + } + } else if (typeof emitter.addEventListener === 'function') { + // EventTarget does not have `error` event semantics like Node + // EventEmitters, we do not listen for `error` events here. + emitter.addEventListener(name, function wrapListener(arg) { + // IE does not have builtin `{ once: true }` support so we + // have to do it manually. + if (flags.once) { + emitter.removeEventListener(name, wrapListener); + } + listener(arg); + }); + } else { + throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); + } +} + + +/***/ }), + +/***/ "../../node_modules/lodash/_DataView.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_DataView.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"), + root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'); + +module.exports = DataView; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Hash.js": +/*!******************************************!*\ + !*** ../../node_modules/lodash/_Hash.js ***! + \******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var hashClear = __webpack_require__(/*! ./_hashClear */ "../../node_modules/lodash/_hashClear.js"), + hashDelete = __webpack_require__(/*! ./_hashDelete */ "../../node_modules/lodash/_hashDelete.js"), + hashGet = __webpack_require__(/*! ./_hashGet */ "../../node_modules/lodash/_hashGet.js"), + hashHas = __webpack_require__(/*! ./_hashHas */ "../../node_modules/lodash/_hashHas.js"), + hashSet = __webpack_require__(/*! ./_hashSet */ "../../node_modules/lodash/_hashSet.js"); + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +module.exports = Hash; + + +/***/ }), + +/***/ "../../node_modules/lodash/_ListCache.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_ListCache.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var listCacheClear = __webpack_require__(/*! ./_listCacheClear */ "../../node_modules/lodash/_listCacheClear.js"), + listCacheDelete = __webpack_require__(/*! ./_listCacheDelete */ "../../node_modules/lodash/_listCacheDelete.js"), + listCacheGet = __webpack_require__(/*! ./_listCacheGet */ "../../node_modules/lodash/_listCacheGet.js"), + listCacheHas = __webpack_require__(/*! ./_listCacheHas */ "../../node_modules/lodash/_listCacheHas.js"), + listCacheSet = __webpack_require__(/*! ./_listCacheSet */ "../../node_modules/lodash/_listCacheSet.js"); + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +module.exports = ListCache; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Map.js": +/*!*****************************************!*\ + !*** ../../node_modules/lodash/_Map.js ***! + \*****************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"), + root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'); + +module.exports = Map; + + +/***/ }), + +/***/ "../../node_modules/lodash/_MapCache.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_MapCache.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var mapCacheClear = __webpack_require__(/*! ./_mapCacheClear */ "../../node_modules/lodash/_mapCacheClear.js"), + mapCacheDelete = __webpack_require__(/*! ./_mapCacheDelete */ "../../node_modules/lodash/_mapCacheDelete.js"), + mapCacheGet = __webpack_require__(/*! ./_mapCacheGet */ "../../node_modules/lodash/_mapCacheGet.js"), + mapCacheHas = __webpack_require__(/*! ./_mapCacheHas */ "../../node_modules/lodash/_mapCacheHas.js"), + mapCacheSet = __webpack_require__(/*! ./_mapCacheSet */ "../../node_modules/lodash/_mapCacheSet.js"); + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +module.exports = MapCache; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Promise.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_Promise.js ***! + \*********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"), + root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/* Built-in method references that are verified to be native. */ +var Promise = getNative(root, 'Promise'); + +module.exports = Promise; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Set.js": +/*!*****************************************!*\ + !*** ../../node_modules/lodash/_Set.js ***! + \*****************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"), + root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/* Built-in method references that are verified to be native. */ +var Set = getNative(root, 'Set'); + +module.exports = Set; + + +/***/ }), + +/***/ "../../node_modules/lodash/_SetCache.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_SetCache.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var MapCache = __webpack_require__(/*! ./_MapCache */ "../../node_modules/lodash/_MapCache.js"), + setCacheAdd = __webpack_require__(/*! ./_setCacheAdd */ "../../node_modules/lodash/_setCacheAdd.js"), + setCacheHas = __webpack_require__(/*! ./_setCacheHas */ "../../node_modules/lodash/_setCacheHas.js"); + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; +SetCache.prototype.has = setCacheHas; + +module.exports = SetCache; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Stack.js": +/*!*******************************************!*\ + !*** ../../node_modules/lodash/_Stack.js ***! + \*******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var ListCache = __webpack_require__(/*! ./_ListCache */ "../../node_modules/lodash/_ListCache.js"), + stackClear = __webpack_require__(/*! ./_stackClear */ "../../node_modules/lodash/_stackClear.js"), + stackDelete = __webpack_require__(/*! ./_stackDelete */ "../../node_modules/lodash/_stackDelete.js"), + stackGet = __webpack_require__(/*! ./_stackGet */ "../../node_modules/lodash/_stackGet.js"), + stackHas = __webpack_require__(/*! ./_stackHas */ "../../node_modules/lodash/_stackHas.js"), + stackSet = __webpack_require__(/*! ./_stackSet */ "../../node_modules/lodash/_stackSet.js"); + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +module.exports = Stack; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Symbol.js": +/*!********************************************!*\ + !*** ../../node_modules/lodash/_Symbol.js ***! + \********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/** Built-in value references. */ +var Symbol = root.Symbol; + +module.exports = Symbol; + + +/***/ }), + +/***/ "../../node_modules/lodash/_Uint8Array.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_Uint8Array.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/** Built-in value references. */ +var Uint8Array = root.Uint8Array; + +module.exports = Uint8Array; + + +/***/ }), + +/***/ "../../node_modules/lodash/_WeakMap.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_WeakMap.js ***! + \*********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"), + root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/* Built-in method references that are verified to be native. */ +var WeakMap = getNative(root, 'WeakMap'); + +module.exports = WeakMap; + + +/***/ }), + +/***/ "../../node_modules/lodash/_arrayEach.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_arrayEach.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +module.exports = arrayEach; + + +/***/ }), + +/***/ "../../node_modules/lodash/_arrayFilter.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_arrayFilter.js ***! + \*************************************************/ +/***/ ((module) => { + +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +module.exports = arrayFilter; + + +/***/ }), + +/***/ "../../node_modules/lodash/_arrayLikeKeys.js": +/*!***************************************************!*\ + !*** ../../node_modules/lodash/_arrayLikeKeys.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseTimes = __webpack_require__(/*! ./_baseTimes */ "../../node_modules/lodash/_baseTimes.js"), + isArguments = __webpack_require__(/*! ./isArguments */ "../../node_modules/lodash/isArguments.js"), + isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"), + isBuffer = __webpack_require__(/*! ./isBuffer */ "../../node_modules/lodash/isBuffer.js"), + isIndex = __webpack_require__(/*! ./_isIndex */ "../../node_modules/lodash/_isIndex.js"), + isTypedArray = __webpack_require__(/*! ./isTypedArray */ "../../node_modules/lodash/isTypedArray.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; +} + +module.exports = arrayLikeKeys; + + +/***/ }), + +/***/ "../../node_modules/lodash/_arrayPush.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_arrayPush.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +module.exports = arrayPush; + + +/***/ }), + +/***/ "../../node_modules/lodash/_arraySome.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_arraySome.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +module.exports = arraySome; + + +/***/ }), + +/***/ "../../node_modules/lodash/_assignValue.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_assignValue.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseAssignValue = __webpack_require__(/*! ./_baseAssignValue */ "../../node_modules/lodash/_baseAssignValue.js"), + eq = __webpack_require__(/*! ./eq */ "../../node_modules/lodash/eq.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } +} + +module.exports = assignValue; + + +/***/ }), + +/***/ "../../node_modules/lodash/_assocIndexOf.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_assocIndexOf.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var eq = __webpack_require__(/*! ./eq */ "../../node_modules/lodash/eq.js"); + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +module.exports = assocIndexOf; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseAssign.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_baseAssign.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var copyObject = __webpack_require__(/*! ./_copyObject */ "../../node_modules/lodash/_copyObject.js"), + keys = __webpack_require__(/*! ./keys */ "../../node_modules/lodash/keys.js"); + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +module.exports = baseAssign; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseAssignIn.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_baseAssignIn.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var copyObject = __webpack_require__(/*! ./_copyObject */ "../../node_modules/lodash/_copyObject.js"), + keysIn = __webpack_require__(/*! ./keysIn */ "../../node_modules/lodash/keysIn.js"); + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); +} + +module.exports = baseAssignIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseAssignValue.js": +/*!*****************************************************!*\ + !*** ../../node_modules/lodash/_baseAssignValue.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var defineProperty = __webpack_require__(/*! ./_defineProperty */ "../../node_modules/lodash/_defineProperty.js"); + +/** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } +} + +module.exports = baseAssignValue; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseClone.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_baseClone.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Stack = __webpack_require__(/*! ./_Stack */ "../../node_modules/lodash/_Stack.js"), + arrayEach = __webpack_require__(/*! ./_arrayEach */ "../../node_modules/lodash/_arrayEach.js"), + assignValue = __webpack_require__(/*! ./_assignValue */ "../../node_modules/lodash/_assignValue.js"), + baseAssign = __webpack_require__(/*! ./_baseAssign */ "../../node_modules/lodash/_baseAssign.js"), + baseAssignIn = __webpack_require__(/*! ./_baseAssignIn */ "../../node_modules/lodash/_baseAssignIn.js"), + cloneBuffer = __webpack_require__(/*! ./_cloneBuffer */ "../../node_modules/lodash/_cloneBuffer.js"), + copyArray = __webpack_require__(/*! ./_copyArray */ "../../node_modules/lodash/_copyArray.js"), + copySymbols = __webpack_require__(/*! ./_copySymbols */ "../../node_modules/lodash/_copySymbols.js"), + copySymbolsIn = __webpack_require__(/*! ./_copySymbolsIn */ "../../node_modules/lodash/_copySymbolsIn.js"), + getAllKeys = __webpack_require__(/*! ./_getAllKeys */ "../../node_modules/lodash/_getAllKeys.js"), + getAllKeysIn = __webpack_require__(/*! ./_getAllKeysIn */ "../../node_modules/lodash/_getAllKeysIn.js"), + getTag = __webpack_require__(/*! ./_getTag */ "../../node_modules/lodash/_getTag.js"), + initCloneArray = __webpack_require__(/*! ./_initCloneArray */ "../../node_modules/lodash/_initCloneArray.js"), + initCloneByTag = __webpack_require__(/*! ./_initCloneByTag */ "../../node_modules/lodash/_initCloneByTag.js"), + initCloneObject = __webpack_require__(/*! ./_initCloneObject */ "../../node_modules/lodash/_initCloneObject.js"), + isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"), + isBuffer = __webpack_require__(/*! ./isBuffer */ "../../node_modules/lodash/isBuffer.js"), + isMap = __webpack_require__(/*! ./isMap */ "../../node_modules/lodash/isMap.js"), + isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"), + isSet = __webpack_require__(/*! ./isSet */ "../../node_modules/lodash/isSet.js"), + keys = __webpack_require__(/*! ./keys */ "../../node_modules/lodash/keys.js"), + keysIn = __webpack_require__(/*! ./keysIn */ "../../node_modules/lodash/keysIn.js"); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +module.exports = baseClone; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseCreate.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_baseCreate.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"); + +/** Built-in value references. */ +var objectCreate = Object.create; + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; +}()); + +module.exports = baseCreate; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseGetAllKeys.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_baseGetAllKeys.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayPush = __webpack_require__(/*! ./_arrayPush */ "../../node_modules/lodash/_arrayPush.js"), + isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"); + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); +} + +module.exports = baseGetAllKeys; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseGetTag.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_baseGetTag.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"), + getRawTag = __webpack_require__(/*! ./_getRawTag */ "../../node_modules/lodash/_getRawTag.js"), + objectToString = __webpack_require__(/*! ./_objectToString */ "../../node_modules/lodash/_objectToString.js"); + +/** `Object#toString` result references. */ +var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); +} + +module.exports = baseGetTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsArguments.js": +/*!*****************************************************!*\ + !*** ../../node_modules/lodash/_baseIsArguments.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetTag = __webpack_require__(/*! ./_baseGetTag */ "../../node_modules/lodash/_baseGetTag.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; + +/** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ +function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; +} + +module.exports = baseIsArguments; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsEqual.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_baseIsEqual.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsEqualDeep = __webpack_require__(/*! ./_baseIsEqualDeep */ "../../node_modules/lodash/_baseIsEqualDeep.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +module.exports = baseIsEqual; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsEqualDeep.js": +/*!*****************************************************!*\ + !*** ../../node_modules/lodash/_baseIsEqualDeep.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Stack = __webpack_require__(/*! ./_Stack */ "../../node_modules/lodash/_Stack.js"), + equalArrays = __webpack_require__(/*! ./_equalArrays */ "../../node_modules/lodash/_equalArrays.js"), + equalByTag = __webpack_require__(/*! ./_equalByTag */ "../../node_modules/lodash/_equalByTag.js"), + equalObjects = __webpack_require__(/*! ./_equalObjects */ "../../node_modules/lodash/_equalObjects.js"), + getTag = __webpack_require__(/*! ./_getTag */ "../../node_modules/lodash/_getTag.js"), + isArray = __webpack_require__(/*! ./isArray */ "../../node_modules/lodash/isArray.js"), + isBuffer = __webpack_require__(/*! ./isBuffer */ "../../node_modules/lodash/isBuffer.js"), + isTypedArray = __webpack_require__(/*! ./isTypedArray */ "../../node_modules/lodash/isTypedArray.js"); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +module.exports = baseIsEqualDeep; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsMap.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_baseIsMap.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getTag = __webpack_require__(/*! ./_getTag */ "../../node_modules/lodash/_getTag.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return isObjectLike(value) && getTag(value) == mapTag; +} + +module.exports = baseIsMap; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsNative.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_baseIsNative.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isFunction = __webpack_require__(/*! ./isFunction */ "../../node_modules/lodash/isFunction.js"), + isMasked = __webpack_require__(/*! ./_isMasked */ "../../node_modules/lodash/_isMasked.js"), + isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"), + toSource = __webpack_require__(/*! ./_toSource */ "../../node_modules/lodash/_toSource.js"); + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +module.exports = baseIsNative; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsSet.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_baseIsSet.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getTag = __webpack_require__(/*! ./_getTag */ "../../node_modules/lodash/_getTag.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** `Object#toString` result references. */ +var setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return isObjectLike(value) && getTag(value) == setTag; +} + +module.exports = baseIsSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseIsTypedArray.js": +/*!******************************************************!*\ + !*** ../../node_modules/lodash/_baseIsTypedArray.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetTag = __webpack_require__(/*! ./_baseGetTag */ "../../node_modules/lodash/_baseGetTag.js"), + isLength = __webpack_require__(/*! ./isLength */ "../../node_modules/lodash/isLength.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; + +/** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; +} + +module.exports = baseIsTypedArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseKeys.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_baseKeys.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isPrototype = __webpack_require__(/*! ./_isPrototype */ "../../node_modules/lodash/_isPrototype.js"), + nativeKeys = __webpack_require__(/*! ./_nativeKeys */ "../../node_modules/lodash/_nativeKeys.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +module.exports = baseKeys; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseKeysIn.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_baseKeysIn.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"), + isPrototype = __webpack_require__(/*! ./_isPrototype */ "../../node_modules/lodash/_isPrototype.js"), + nativeKeysIn = __webpack_require__(/*! ./_nativeKeysIn */ "../../node_modules/lodash/_nativeKeysIn.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = baseKeysIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseTimes.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_baseTimes.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +module.exports = baseTimes; + + +/***/ }), + +/***/ "../../node_modules/lodash/_baseUnary.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_baseUnary.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +module.exports = baseUnary; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cacheHas.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_cacheHas.js ***! + \**********************************************/ +/***/ ((module) => { + +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +module.exports = cacheHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cloneArrayBuffer.js": +/*!******************************************************!*\ + !*** ../../node_modules/lodash/_cloneArrayBuffer.js ***! + \******************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Uint8Array = __webpack_require__(/*! ./_Uint8Array */ "../../node_modules/lodash/_Uint8Array.js"); + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +module.exports = cloneArrayBuffer; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cloneBuffer.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_cloneBuffer.js ***! + \*************************************************/ +/***/ ((module, exports, __webpack_require__) => { + +/* module decorator */ module = __webpack_require__.nmd(module); +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; + +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; +} + +module.exports = cloneBuffer; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cloneDataView.js": +/*!***************************************************!*\ + !*** ../../node_modules/lodash/_cloneDataView.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var cloneArrayBuffer = __webpack_require__(/*! ./_cloneArrayBuffer */ "../../node_modules/lodash/_cloneArrayBuffer.js"); + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +module.exports = cloneDataView; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cloneRegExp.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_cloneRegExp.js ***! + \*************************************************/ +/***/ ((module) => { + +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +module.exports = cloneRegExp; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cloneSymbol.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_cloneSymbol.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +module.exports = cloneSymbol; + + +/***/ }), + +/***/ "../../node_modules/lodash/_cloneTypedArray.js": +/*!*****************************************************!*\ + !*** ../../node_modules/lodash/_cloneTypedArray.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var cloneArrayBuffer = __webpack_require__(/*! ./_cloneArrayBuffer */ "../../node_modules/lodash/_cloneArrayBuffer.js"); + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +module.exports = cloneTypedArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/_copyArray.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_copyArray.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +module.exports = copyArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/_copyObject.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_copyObject.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assignValue = __webpack_require__(/*! ./_assignValue */ "../../node_modules/lodash/_assignValue.js"), + baseAssignValue = __webpack_require__(/*! ./_baseAssignValue */ "../../node_modules/lodash/_baseAssignValue.js"); + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; +} + +module.exports = copyObject; + + +/***/ }), + +/***/ "../../node_modules/lodash/_copySymbols.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_copySymbols.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var copyObject = __webpack_require__(/*! ./_copyObject */ "../../node_modules/lodash/_copyObject.js"), + getSymbols = __webpack_require__(/*! ./_getSymbols */ "../../node_modules/lodash/_getSymbols.js"); + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +module.exports = copySymbols; + + +/***/ }), + +/***/ "../../node_modules/lodash/_copySymbolsIn.js": +/*!***************************************************!*\ + !*** ../../node_modules/lodash/_copySymbolsIn.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var copyObject = __webpack_require__(/*! ./_copyObject */ "../../node_modules/lodash/_copyObject.js"), + getSymbolsIn = __webpack_require__(/*! ./_getSymbolsIn */ "../../node_modules/lodash/_getSymbolsIn.js"); + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(source), object); +} + +module.exports = copySymbolsIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/_coreJsData.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_coreJsData.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"); + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +module.exports = coreJsData; + + +/***/ }), + +/***/ "../../node_modules/lodash/_defineProperty.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_defineProperty.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"); + +var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} +}()); + +module.exports = defineProperty; + + +/***/ }), + +/***/ "../../node_modules/lodash/_equalArrays.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_equalArrays.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var SetCache = __webpack_require__(/*! ./_SetCache */ "../../node_modules/lodash/_SetCache.js"), + arraySome = __webpack_require__(/*! ./_arraySome */ "../../node_modules/lodash/_arraySome.js"), + cacheHas = __webpack_require__(/*! ./_cacheHas */ "../../node_modules/lodash/_cacheHas.js"); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +module.exports = equalArrays; + + +/***/ }), + +/***/ "../../node_modules/lodash/_equalByTag.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_equalByTag.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"), + Uint8Array = __webpack_require__(/*! ./_Uint8Array */ "../../node_modules/lodash/_Uint8Array.js"), + eq = __webpack_require__(/*! ./eq */ "../../node_modules/lodash/eq.js"), + equalArrays = __webpack_require__(/*! ./_equalArrays */ "../../node_modules/lodash/_equalArrays.js"), + mapToArray = __webpack_require__(/*! ./_mapToArray */ "../../node_modules/lodash/_mapToArray.js"), + setToArray = __webpack_require__(/*! ./_setToArray */ "../../node_modules/lodash/_setToArray.js"); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +module.exports = equalByTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_equalObjects.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_equalObjects.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getAllKeys = __webpack_require__(/*! ./_getAllKeys */ "../../node_modules/lodash/_getAllKeys.js"); + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +module.exports = equalObjects; + + +/***/ }), + +/***/ "../../node_modules/lodash/_freeGlobal.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_freeGlobal.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g; + +module.exports = freeGlobal; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getAllKeys.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_getAllKeys.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetAllKeys = __webpack_require__(/*! ./_baseGetAllKeys */ "../../node_modules/lodash/_baseGetAllKeys.js"), + getSymbols = __webpack_require__(/*! ./_getSymbols */ "../../node_modules/lodash/_getSymbols.js"), + keys = __webpack_require__(/*! ./keys */ "../../node_modules/lodash/keys.js"); + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} + +module.exports = getAllKeys; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getAllKeysIn.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_getAllKeysIn.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetAllKeys = __webpack_require__(/*! ./_baseGetAllKeys */ "../../node_modules/lodash/_baseGetAllKeys.js"), + getSymbolsIn = __webpack_require__(/*! ./_getSymbolsIn */ "../../node_modules/lodash/_getSymbolsIn.js"), + keysIn = __webpack_require__(/*! ./keysIn */ "../../node_modules/lodash/keysIn.js"); + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return baseGetAllKeys(object, keysIn, getSymbolsIn); +} + +module.exports = getAllKeysIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getMapData.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_getMapData.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isKeyable = __webpack_require__(/*! ./_isKeyable */ "../../node_modules/lodash/_isKeyable.js"); + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +module.exports = getMapData; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getNative.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_getNative.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsNative = __webpack_require__(/*! ./_baseIsNative */ "../../node_modules/lodash/_baseIsNative.js"), + getValue = __webpack_require__(/*! ./_getValue */ "../../node_modules/lodash/_getValue.js"); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +module.exports = getNative; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getPrototype.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_getPrototype.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var overArg = __webpack_require__(/*! ./_overArg */ "../../node_modules/lodash/_overArg.js"); + +/** Built-in value references. */ +var getPrototype = overArg(Object.getPrototypeOf, Object); + +module.exports = getPrototype; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getRawTag.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_getRawTag.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Symbol = __webpack_require__(/*! ./_Symbol */ "../../node_modules/lodash/_Symbol.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** Built-in value references. */ +var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + +/** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ +function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; +} + +module.exports = getRawTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getSymbols.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_getSymbols.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayFilter = __webpack_require__(/*! ./_arrayFilter */ "../../node_modules/lodash/_arrayFilter.js"), + stubArray = __webpack_require__(/*! ./stubArray */ "../../node_modules/lodash/stubArray.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +module.exports = getSymbols; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getSymbolsIn.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_getSymbolsIn.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayPush = __webpack_require__(/*! ./_arrayPush */ "../../node_modules/lodash/_arrayPush.js"), + getPrototype = __webpack_require__(/*! ./_getPrototype */ "../../node_modules/lodash/_getPrototype.js"), + getSymbols = __webpack_require__(/*! ./_getSymbols */ "../../node_modules/lodash/_getSymbols.js"), + stubArray = __webpack_require__(/*! ./stubArray */ "../../node_modules/lodash/stubArray.js"); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush(result, getSymbols(object)); + object = getPrototype(object); + } + return result; +}; + +module.exports = getSymbolsIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getTag.js": +/*!********************************************!*\ + !*** ../../node_modules/lodash/_getTag.js ***! + \********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var DataView = __webpack_require__(/*! ./_DataView */ "../../node_modules/lodash/_DataView.js"), + Map = __webpack_require__(/*! ./_Map */ "../../node_modules/lodash/_Map.js"), + Promise = __webpack_require__(/*! ./_Promise */ "../../node_modules/lodash/_Promise.js"), + Set = __webpack_require__(/*! ./_Set */ "../../node_modules/lodash/_Set.js"), + WeakMap = __webpack_require__(/*! ./_WeakMap */ "../../node_modules/lodash/_WeakMap.js"), + baseGetTag = __webpack_require__(/*! ./_baseGetTag */ "../../node_modules/lodash/_baseGetTag.js"), + toSource = __webpack_require__(/*! ./_toSource */ "../../node_modules/lodash/_toSource.js"); + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + setTag = '[object Set]', + weakMapTag = '[object WeakMap]'; + +var dataViewTag = '[object DataView]'; + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +module.exports = getTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_getValue.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_getValue.js ***! + \**********************************************/ +/***/ ((module) => { + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +module.exports = getValue; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashClear.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_hashClear.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; +} + +module.exports = hashClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashDelete.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_hashDelete.js ***! + \************************************************/ +/***/ ((module) => { + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; +} + +module.exports = hashDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashGet.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_hashGet.js ***! + \*********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +module.exports = hashGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashHas.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_hashHas.js ***! + \*********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); +} + +module.exports = hashHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_hashSet.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_hashSet.js ***! + \*********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var nativeCreate = __webpack_require__(/*! ./_nativeCreate */ "../../node_modules/lodash/_nativeCreate.js"); + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +module.exports = hashSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_initCloneArray.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_initCloneArray.js ***! + \****************************************************/ +/***/ ((module) => { + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +module.exports = initCloneArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/_initCloneByTag.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_initCloneByTag.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var cloneArrayBuffer = __webpack_require__(/*! ./_cloneArrayBuffer */ "../../node_modules/lodash/_cloneArrayBuffer.js"), + cloneDataView = __webpack_require__(/*! ./_cloneDataView */ "../../node_modules/lodash/_cloneDataView.js"), + cloneRegExp = __webpack_require__(/*! ./_cloneRegExp */ "../../node_modules/lodash/_cloneRegExp.js"), + cloneSymbol = __webpack_require__(/*! ./_cloneSymbol */ "../../node_modules/lodash/_cloneSymbol.js"), + cloneTypedArray = __webpack_require__(/*! ./_cloneTypedArray */ "../../node_modules/lodash/_cloneTypedArray.js"); + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } +} + +module.exports = initCloneByTag; + + +/***/ }), + +/***/ "../../node_modules/lodash/_initCloneObject.js": +/*!*****************************************************!*\ + !*** ../../node_modules/lodash/_initCloneObject.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseCreate = __webpack_require__(/*! ./_baseCreate */ "../../node_modules/lodash/_baseCreate.js"), + getPrototype = __webpack_require__(/*! ./_getPrototype */ "../../node_modules/lodash/_getPrototype.js"), + isPrototype = __webpack_require__(/*! ./_isPrototype */ "../../node_modules/lodash/_isPrototype.js"); + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} + +module.exports = initCloneObject; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isIndex.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_isIndex.js ***! + \*********************************************/ +/***/ ((module) => { + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); +} + +module.exports = isIndex; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isKeyable.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/_isKeyable.js ***! + \***********************************************/ +/***/ ((module) => { + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +module.exports = isKeyable; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isMasked.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_isMasked.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var coreJsData = __webpack_require__(/*! ./_coreJsData */ "../../node_modules/lodash/_coreJsData.js"); + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +module.exports = isMasked; + + +/***/ }), + +/***/ "../../node_modules/lodash/_isPrototype.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_isPrototype.js ***! + \*************************************************/ +/***/ ((module) => { + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +module.exports = isPrototype; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheClear.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_listCacheClear.js ***! + \****************************************************/ +/***/ ((module) => { + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; + this.size = 0; +} + +module.exports = listCacheClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheDelete.js": +/*!*****************************************************!*\ + !*** ../../node_modules/lodash/_listCacheDelete.js ***! + \*****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** Used for built-in method references. */ +var arrayProto = Array.prototype; + +/** Built-in value references. */ +var splice = arrayProto.splice; + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; +} + +module.exports = listCacheDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheGet.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_listCacheGet.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +module.exports = listCacheGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheHas.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_listCacheHas.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +module.exports = listCacheHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_listCacheSet.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_listCacheSet.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var assocIndexOf = __webpack_require__(/*! ./_assocIndexOf */ "../../node_modules/lodash/_assocIndexOf.js"); + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +module.exports = listCacheSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheClear.js": +/*!***************************************************!*\ + !*** ../../node_modules/lodash/_mapCacheClear.js ***! + \***************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var Hash = __webpack_require__(/*! ./_Hash */ "../../node_modules/lodash/_Hash.js"), + ListCache = __webpack_require__(/*! ./_ListCache */ "../../node_modules/lodash/_ListCache.js"), + Map = __webpack_require__(/*! ./_Map */ "../../node_modules/lodash/_Map.js"); + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +module.exports = mapCacheClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheDelete.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_mapCacheDelete.js ***! + \****************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; +} + +module.exports = mapCacheDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheGet.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_mapCacheGet.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +module.exports = mapCacheGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheHas.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_mapCacheHas.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +module.exports = mapCacheHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapCacheSet.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_mapCacheSet.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getMapData = __webpack_require__(/*! ./_getMapData */ "../../node_modules/lodash/_getMapData.js"); + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; +} + +module.exports = mapCacheSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_mapToArray.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_mapToArray.js ***! + \************************************************/ +/***/ ((module) => { + +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +module.exports = mapToArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/_nativeCreate.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_nativeCreate.js ***! + \**************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var getNative = __webpack_require__(/*! ./_getNative */ "../../node_modules/lodash/_getNative.js"); + +/* Built-in method references that are verified to be native. */ +var nativeCreate = getNative(Object, 'create'); + +module.exports = nativeCreate; + + +/***/ }), + +/***/ "../../node_modules/lodash/_nativeKeys.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_nativeKeys.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var overArg = __webpack_require__(/*! ./_overArg */ "../../node_modules/lodash/_overArg.js"); + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object); + +module.exports = nativeKeys; + + +/***/ }), + +/***/ "../../node_modules/lodash/_nativeKeysIn.js": +/*!**************************************************!*\ + !*** ../../node_modules/lodash/_nativeKeysIn.js ***! + \**************************************************/ +/***/ ((module) => { + +/** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; +} + +module.exports = nativeKeysIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/_nodeUtil.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_nodeUtil.js ***! + \**********************************************/ +/***/ ((module, exports, __webpack_require__) => { + +/* module decorator */ module = __webpack_require__.nmd(module); +var freeGlobal = __webpack_require__(/*! ./_freeGlobal */ "../../node_modules/lodash/_freeGlobal.js"); + +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; + +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} +}()); + +module.exports = nodeUtil; + + +/***/ }), + +/***/ "../../node_modules/lodash/_objectToString.js": +/*!****************************************************!*\ + !*** ../../node_modules/lodash/_objectToString.js ***! + \****************************************************/ +/***/ ((module) => { + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var nativeObjectToString = objectProto.toString; + +/** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ +function objectToString(value) { + return nativeObjectToString.call(value); +} + +module.exports = objectToString; + + +/***/ }), + +/***/ "../../node_modules/lodash/_overArg.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/_overArg.js ***! + \*********************************************/ +/***/ ((module) => { + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +module.exports = overArg; + + +/***/ }), + +/***/ "../../node_modules/lodash/_root.js": +/*!******************************************!*\ + !*** ../../node_modules/lodash/_root.js ***! + \******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var freeGlobal = __webpack_require__(/*! ./_freeGlobal */ "../../node_modules/lodash/_freeGlobal.js"); + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +module.exports = root; + + +/***/ }), + +/***/ "../../node_modules/lodash/_setCacheAdd.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_setCacheAdd.js ***! + \*************************************************/ +/***/ ((module) => { + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +module.exports = setCacheAdd; + + +/***/ }), + +/***/ "../../node_modules/lodash/_setCacheHas.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_setCacheHas.js ***! + \*************************************************/ +/***/ ((module) => { + +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +module.exports = setCacheHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_setToArray.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_setToArray.js ***! + \************************************************/ +/***/ ((module) => { + +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +module.exports = setToArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/_stackClear.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/_stackClear.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var ListCache = __webpack_require__(/*! ./_ListCache */ "../../node_modules/lodash/_ListCache.js"); + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; + this.size = 0; +} + +module.exports = stackClear; + + +/***/ }), + +/***/ "../../node_modules/lodash/_stackDelete.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/_stackDelete.js ***! + \*************************************************/ +/***/ ((module) => { + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; +} + +module.exports = stackDelete; + + +/***/ }), + +/***/ "../../node_modules/lodash/_stackGet.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_stackGet.js ***! + \**********************************************/ +/***/ ((module) => { + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +module.exports = stackGet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_stackHas.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_stackHas.js ***! + \**********************************************/ +/***/ ((module) => { + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +module.exports = stackHas; + + +/***/ }), + +/***/ "../../node_modules/lodash/_stackSet.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_stackSet.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var ListCache = __webpack_require__(/*! ./_ListCache */ "../../node_modules/lodash/_ListCache.js"), + Map = __webpack_require__(/*! ./_Map */ "../../node_modules/lodash/_Map.js"), + MapCache = __webpack_require__(/*! ./_MapCache */ "../../node_modules/lodash/_MapCache.js"); + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + return this; +} + +module.exports = stackSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/_toSource.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/_toSource.js ***! + \**********************************************/ +/***/ ((module) => { + +/** Used for built-in method references. */ +var funcProto = Function.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +module.exports = toSource; + + +/***/ }), + +/***/ "../../node_modules/lodash/cloneDeep.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/cloneDeep.js ***! + \**********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseClone = __webpack_require__(/*! ./_baseClone */ "../../node_modules/lodash/_baseClone.js"); + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +module.exports = cloneDeep; + + +/***/ }), + +/***/ "../../node_modules/lodash/eq.js": +/*!***************************************!*\ + !*** ../../node_modules/lodash/eq.js ***! + \***************************************/ +/***/ ((module) => { + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +module.exports = eq; + + +/***/ }), + +/***/ "../../node_modules/lodash/isArguments.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/isArguments.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsArguments = __webpack_require__(/*! ./_baseIsArguments */ "../../node_modules/lodash/_baseIsArguments.js"), + isObjectLike = __webpack_require__(/*! ./isObjectLike */ "../../node_modules/lodash/isObjectLike.js"); + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); +}; + +module.exports = isArguments; + + +/***/ }), + +/***/ "../../node_modules/lodash/isArray.js": +/*!********************************************!*\ + !*** ../../node_modules/lodash/isArray.js ***! + \********************************************/ +/***/ ((module) => { + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +module.exports = isArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/isArrayLike.js": +/*!************************************************!*\ + !*** ../../node_modules/lodash/isArrayLike.js ***! + \************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var isFunction = __webpack_require__(/*! ./isFunction */ "../../node_modules/lodash/isFunction.js"), + isLength = __webpack_require__(/*! ./isLength */ "../../node_modules/lodash/isLength.js"); + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +module.exports = isArrayLike; + + +/***/ }), + +/***/ "../../node_modules/lodash/isBuffer.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/isBuffer.js ***! + \*********************************************/ +/***/ ((module, exports, __webpack_require__) => { + +/* module decorator */ module = __webpack_require__.nmd(module); +var root = __webpack_require__(/*! ./_root */ "../../node_modules/lodash/_root.js"), + stubFalse = __webpack_require__(/*! ./stubFalse */ "../../node_modules/lodash/stubFalse.js"); + +/** Detect free variable `exports`. */ +var freeExports = true && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && "object" == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +module.exports = isBuffer; + + +/***/ }), + +/***/ "../../node_modules/lodash/isEqual.js": +/*!********************************************!*\ + !*** ../../node_modules/lodash/isEqual.js ***! + \********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsEqual = __webpack_require__(/*! ./_baseIsEqual */ "../../node_modules/lodash/_baseIsEqual.js"); + +/** + * Performs a deep comparison between two values to determine if they are + * equivalent. + * + * **Note:** This method supports comparing arrays, array buffers, booleans, + * date objects, error objects, maps, numbers, `Object` objects, regexes, + * sets, strings, symbols, and typed arrays. `Object` objects are compared + * by their own, not inherited, enumerable properties. Functions and DOM + * nodes are compared by strict equality, i.e. `===`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.isEqual(object, other); + * // => true + * + * object === other; + * // => false + */ +function isEqual(value, other) { + return baseIsEqual(value, other); +} + +module.exports = isEqual; + + +/***/ }), + +/***/ "../../node_modules/lodash/isFunction.js": +/*!***********************************************!*\ + !*** ../../node_modules/lodash/isFunction.js ***! + \***********************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseGetTag = __webpack_require__(/*! ./_baseGetTag */ "../../node_modules/lodash/_baseGetTag.js"), + isObject = __webpack_require__(/*! ./isObject */ "../../node_modules/lodash/isObject.js"); + +/** `Object#toString` result references. */ +var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; +} + +module.exports = isFunction; + + +/***/ }), + +/***/ "../../node_modules/lodash/isLength.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/isLength.js ***! + \*********************************************/ +/***/ ((module) => { + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +module.exports = isLength; + + +/***/ }), + +/***/ "../../node_modules/lodash/isMap.js": +/*!******************************************!*\ + !*** ../../node_modules/lodash/isMap.js ***! + \******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsMap = __webpack_require__(/*! ./_baseIsMap */ "../../node_modules/lodash/_baseIsMap.js"), + baseUnary = __webpack_require__(/*! ./_baseUnary */ "../../node_modules/lodash/_baseUnary.js"), + nodeUtil = __webpack_require__(/*! ./_nodeUtil */ "../../node_modules/lodash/_nodeUtil.js"); + +/* Node.js helper references. */ +var nodeIsMap = nodeUtil && nodeUtil.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; + +module.exports = isMap; + + +/***/ }), + +/***/ "../../node_modules/lodash/isObject.js": +/*!*********************************************!*\ + !*** ../../node_modules/lodash/isObject.js ***! + \*********************************************/ +/***/ ((module) => { + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} + +module.exports = isObject; + + +/***/ }), + +/***/ "../../node_modules/lodash/isObjectLike.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/isObjectLike.js ***! + \*************************************************/ +/***/ ((module) => { + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return value != null && typeof value == 'object'; +} + +module.exports = isObjectLike; + + +/***/ }), + +/***/ "../../node_modules/lodash/isSet.js": +/*!******************************************!*\ + !*** ../../node_modules/lodash/isSet.js ***! + \******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsSet = __webpack_require__(/*! ./_baseIsSet */ "../../node_modules/lodash/_baseIsSet.js"), + baseUnary = __webpack_require__(/*! ./_baseUnary */ "../../node_modules/lodash/_baseUnary.js"), + nodeUtil = __webpack_require__(/*! ./_nodeUtil */ "../../node_modules/lodash/_nodeUtil.js"); + +/* Node.js helper references. */ +var nodeIsSet = nodeUtil && nodeUtil.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; + +module.exports = isSet; + + +/***/ }), + +/***/ "../../node_modules/lodash/isTypedArray.js": +/*!*************************************************!*\ + !*** ../../node_modules/lodash/isTypedArray.js ***! + \*************************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var baseIsTypedArray = __webpack_require__(/*! ./_baseIsTypedArray */ "../../node_modules/lodash/_baseIsTypedArray.js"), + baseUnary = __webpack_require__(/*! ./_baseUnary */ "../../node_modules/lodash/_baseUnary.js"), + nodeUtil = __webpack_require__(/*! ./_nodeUtil */ "../../node_modules/lodash/_nodeUtil.js"); + +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + +module.exports = isTypedArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/keys.js": +/*!*****************************************!*\ + !*** ../../node_modules/lodash/keys.js ***! + \*****************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayLikeKeys = __webpack_require__(/*! ./_arrayLikeKeys */ "../../node_modules/lodash/_arrayLikeKeys.js"), + baseKeys = __webpack_require__(/*! ./_baseKeys */ "../../node_modules/lodash/_baseKeys.js"), + isArrayLike = __webpack_require__(/*! ./isArrayLike */ "../../node_modules/lodash/isArrayLike.js"); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +module.exports = keys; + + +/***/ }), + +/***/ "../../node_modules/lodash/keysIn.js": +/*!*******************************************!*\ + !*** ../../node_modules/lodash/keysIn.js ***! + \*******************************************/ +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + +var arrayLikeKeys = __webpack_require__(/*! ./_arrayLikeKeys */ "../../node_modules/lodash/_arrayLikeKeys.js"), + baseKeysIn = __webpack_require__(/*! ./_baseKeysIn */ "../../node_modules/lodash/_baseKeysIn.js"), + isArrayLike = __webpack_require__(/*! ./isArrayLike */ "../../node_modules/lodash/isArrayLike.js"); + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); +} + +module.exports = keysIn; + + +/***/ }), + +/***/ "../../node_modules/lodash/stubArray.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/stubArray.js ***! + \**********************************************/ +/***/ ((module) => { + +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +module.exports = stubArray; + + +/***/ }), + +/***/ "../../node_modules/lodash/stubFalse.js": +/*!**********************************************!*\ + !*** ../../node_modules/lodash/stubFalse.js ***! + \**********************************************/ +/***/ ((module) => { + +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} + +module.exports = stubFalse; + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // 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] = { +/******/ id: moduleId, +/******/ loaded: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* 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 }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/node module decorator */ +/******/ (() => { +/******/ __webpack_require__.nmd = (module) => { +/******/ module.paths = []; +/******/ if (!module.children) module.children = []; +/******/ return module; +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +/*!********************************!*\ + !*** ./client/src/provider.ts ***! + \********************************/ +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _openfin_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @openfin/core */ "../../node_modules/@openfin/core/out/mock.js"); + +let fileName; +let debugLogStr; +let debugLogFile; +let opfsLogFile; +const channelName = `${_openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.identity.uuid}-logger`; +let channelClient; +let channelProvider; +let fileHandle; +window.addEventListener("DOMContentLoaded", async () => { + const platform = _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.Platform.getCurrentSync(); + await platform.once("platform-api-ready", async () => init()); + _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.Platform.init({ + overrideCallback: async (Provider) => { + /** + * Override the provider class. + */ + class Override extends Provider { + } + return new Override(); + } + }).catch(() => { }); +}); +/** + * Populates DOM with the UI elements and adds listeners obtaining selected/submitted options. + */ +async function init() { + const logListElement = document.querySelector("#log-list"); + if (logListElement) { + await createLogDropDown(logListElement); + logListElement.addEventListener("change", async (selectionChangeEvent) => { + fileName = selectionChangeEvent.target.value; + }); + } + const upload = document.querySelector("#upload-form"); + if (upload) { + upload.addEventListener("submit", uploadHandler); + } + const sendAppLogBtn = document.querySelector("#send-app-log"); + if (sendAppLogBtn) { + sendAppLogBtn.addEventListener("click", sendApplicationLogs); + } + const sendOPFSLogBtn = document.querySelector("#send-opfs-log"); + if (sendOPFSLogBtn) { + sendOPFSLogBtn.addEventListener("click", sendOPFSLogs); + } + const consoleLogBtn = document.querySelector("#console-app-log"); + if (consoleLogBtn) { + consoleLogBtn.addEventListener("click", consoleLogMessage); + } + const channelLogBtn = document.querySelector("#channel-app-log"); + if (channelLogBtn) { + channelLogBtn.addEventListener("click", channelLogMessage); + } + const clearPreviewBtn = document.querySelector("#clear-preview"); + if (clearPreviewBtn) { + clearPreviewBtn.addEventListener("click", clearPreview); + } + await setupChannelClientAndService(); +} +/** + * Sets up the Channel Client and Service. + */ +async function setupChannelClientAndService() { + // if your content is coming from the same domain then you would not need to use the Channel API and can consider alternatives + // such as BroadcastChannel API or SharedWorker + if (channelClient === undefined && channelProvider === undefined) { + // set up the file handler for logging for the service + if (fileHandle === undefined) { + const root = await navigator.storage.getDirectory(); + // Create a new file handle. + // The name could be date based if you were going to create a new file each day. + fileHandle = await root.getFileHandle("log.log", { create: true }); + } + channelProvider = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.InterApplicationBus.Channel.create(channelName); + channelProvider.onConnection((identity, payload) => { + if (identity.uuid !== _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.identity.uuid) { + // reject connection + throw new Error("Connection rejected. Only the current application can connect to the channel."); + } + // you can add additional logic to validate the view/window connecting (e.g. to ensure it is only trusted urls that are allowed to log etc) + }); + channelProvider.register("log", async (payload, identity) => { + if (identity.uuid !== _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.identity.uuid) { + // reject request to log (this is optional but you might have multiple actions registered and you might allow a connection to the service but not all actions) + throw new Error("Log request rejected. Only the current application can log."); + } + const logPreview = document.querySelector("#preview"); + try { + // you could make this more complex to support log levels etc. For now we just pass a string to the log function + // utc timestamp + const utcTimestamp = new Date().toISOString(); + const message = `${utcTimestamp}|${identity.name}|${payload}`; + await writeLogToFile(message); + if (logPreview) { + logPreview.textContent += ` +Console Logged the following message through Channel API: +"${message}"`; + } + } + catch (err) { + if (logPreview) { + logPreview.textContent += ` +Error console logging message through Channel API: ${err.message}`; + } + } + }); + channelClient = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.InterApplicationBus.Channel.connect(channelName); + } +} +/** + * Write logs to file. This logic could be done in a worker to avoid blocking the main thread. + * https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system. + * @param logMessage The log message to write to file. + */ +async function writeLogToFile(logMessage) { + try { + if (fileHandle === undefined) { + const root = await navigator.storage.getDirectory(); + // Create a new file handle if it doesn't exist. + // The name could be date based if you were going to create a new file each day. + fileHandle = await root.getFileHandle("log.log", { create: true }); + } + // Create a writable stream + const writableStream = await fileHandle.createWritable({ keepExistingData: true }); + // Move the write position to the end of the file + const fileForSize = await fileHandle.getFile(); + const size = fileForSize.size; + await writableStream.seek(size); + // Write the log message to the file + if (size === 0) { + await writableStream.write(logMessage); + } + else { + await writableStream.write(`\n${logMessage}`); + } + // Close the file + await writableStream.close(); + console.log("Log written to file successfully."); + } + catch (err) { + console.error("Error writing log to file:", err); + } +} +/** + * Handle uploads. + * 1. Creates a FormData object. + * 2. Creates a File object from the string of the Runtime debug log file contents. + * 3. Populates the FormData object with necessary parameters to be read by the server. + * 4. Uploads the created runtime debug log file to a server endpoint. + * @param submitEvent The event to handle. + */ +async function uploadHandler(submitEvent) { + submitEvent.preventDefault(); + if (!fileName) { + fileName = "debug.log"; + } + const formData = new FormData(); + debugLogStr = await getLogFromName(fileName); + debugLogFile = new File([debugLogStr], fileName, { type: "text/plain" }); + formData.append("file", debugLogFile); + formData.append("filename", fileName); + formData.append("uuid", _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.uuid); + const logPreview = document.querySelector("#preview"); + try { + const uploadState = await fetch("https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/uploads", { + method: "POST", + body: formData + }); + const uploadStateJson = await uploadState.json(); + const uploadStateJsonString = JSON.stringify(uploadStateJson, null, 5); + const logs = `${new Date().toLocaleTimeString()}: ${uploadStateJsonString}\n`; + if (logPreview) { + logPreview.textContent += logs; + } + } + catch (err) { + if (logPreview) { + logPreview.textContent += ` +Error uploading Runtime Logs: ${err.message}`; + } + } +} +/** + * Uploads the OPFS log file to the server. + * @returns true if the log file was uploaded successfully, false otherwise. + */ +async function uploadOPFSLogHandler() { + // read the log file from origin private file system + if (fileHandle !== undefined) { + try { + // read the file from fileHanlde + const file = await fileHandle.getFile(); + const logFileName = file.name; + const fileContents = await file.text(); + opfsLogFile = new File([fileContents], logFileName, { type: "text/plain" }); + const opfsFormData = new FormData(); + opfsFormData.append("opfsFile", opfsLogFile); + opfsFormData.append("filename", logFileName); + opfsFormData.append("uuid", _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.me.uuid); + const result = await fetch("https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/opfsuploads", { + method: "POST", + body: opfsFormData + }); + if (result.ok) { + // Clear the log file after uploading + const writableStream = await fileHandle.createWritable(); + await writableStream.truncate(0); + await writableStream.close(); + const logPreview = document.querySelector("#preview"); + const uploadStateJson = await result.json(); + const uploadStateJsonString = JSON.stringify(uploadStateJson, null, 5); + const logs = `${new Date().toLocaleTimeString()}: ${uploadStateJsonString}\n`; + if (logPreview) { + logPreview.textContent += logs; + } + return true; + } + return false; + } + catch (error) { + console.error("Error reading log file:", error); + return false; + } + } + return false; +} +/** + * Clears the preview log. + */ +function clearPreview() { + const logPreview = document.querySelector("#preview"); + if (logPreview) { + logPreview.textContent = ""; + } +} +/** + * Sends a message to the OpenFin RVM to send the application logs. + */ +async function sendApplicationLogs() { + const logPreview = document.querySelector("#preview"); + try { + const appLogResponse = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.Application.getCurrentSync().sendApplicationLog(); + if (logPreview) { + logPreview.textContent += ` +Uploaded App Logs. Log ID: ${appLogResponse.logId}`; + } + } + catch (err) { + if (logPreview) { + logPreview.textContent += ` +Error uploading App Logs: ${err.message}`; + } + } +} +/** + * Sends opfs logs to the server. + */ +async function sendOPFSLogs() { + const logPreview = document.querySelector("#preview"); + try { + const success = await uploadOPFSLogHandler(); + if (logPreview) { + logPreview.textContent += ` +Uploaded OPFS Logs. Success: ${success}`; + } + } + catch (err) { + if (logPreview) { + logPreview.textContent += ` +Error uploading OPFS Logs: ${err.message}`; + } + } +} +/** + * Sends a message to console log. + */ +async function consoleLogMessage() { + const logPreview = document.querySelector("#preview"); + try { + const message = ` +Sending console log message: ${Date.now()}`; + console.log(message); + if (logPreview) { + logPreview.textContent += ` +Console Logged the following message: +"${message}"`; + } + } + catch (err) { + if (logPreview) { + logPreview.textContent += ` +Error console logging message: ${err.message}`; + } + } +} +/** + * Sends a message to console log through the Channel API. + */ +async function channelLogMessage() { + const logPreview = document.querySelector("#preview"); + try { + const message = ` +Sending channel log message: ${Date.now()}`; + if (logPreview) { + logPreview.textContent += ` +Sending the following message through the Channel API: +"${message}"`; + } + await channelClient.dispatch("log", message); + } + catch (err) { + if (logPreview) { + logPreview.textContent += ` +Error sending message through Channel API: ${err.message}`; + } + } +} +/** + * Retrieves the runtime debug log from a filename. + * @param name file name of the runtime debug log to retrieve. + * @returns the log content. + */ +async function getLogFromName(name) { + const log = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.System.getLog({ name }); + return log; +} +/** + * Creates an HTMLOptionElement for each of the Runtime debug logs. + * @param parentElement HTML Element to append the log filename HTMLOptionElement to. + */ +async function createLogDropDown(parentElement) { + const logList = await _openfin_core__WEBPACK_IMPORTED_MODULE_0__.fin.System.getLogList(); + for (const log of logList) { + const logElement = document.createElement("option"); + logElement.id = log.date; + logElement.textContent = log.name; + logElement.value = log.name; + parentElement.append(logElement); + } +} + +})(); + +/******/ })() +; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1FQUFtRTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRTtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELHNCQUFzQjtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELHNCQUFzQjtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELHNCQUFzQjtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0Qsc0JBQXNCO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0Es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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4RUFBOEUsU0FBUztBQUN2RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsU0FBUztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdURBQXVELHlCQUF5QjtBQUNoRjtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9GQUFvRixTQUFTO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QiwwQ0FBMEM7QUFDbkU7QUFDQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLHlDQUF5QztBQUNsRTtBQUNBO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxTQUFTO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0ZBQWtGLFNBQVM7QUFDM0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRkFBZ0YsU0FBUztBQUN6RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsV0FBVztBQUMzRDtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLFdBQVc7QUFDckQ7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLGlDQUFpQztBQUMxRTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUZBQWlGLFNBQVM7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Es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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFLFNBQVM7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0UsU0FBUztBQUN6RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTRELFNBQVM7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxTQUFTO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELFNBQVM7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0RBQXNELGdCQUFnQjtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtEQUErRCxLQUFLO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsNEVBQTRFO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0VBQXNFLE1BQU0sVUFBVSxTQUFTO0FBQy9GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxlQUFlO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixPQUFPO0FBQ3ZCLG1FQUFtRSxNQUFNLFVBQVUsU0FBUztBQUM1RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0VBQXNFLE1BQU0sVUFBVSxTQUFTO0FBQy9GO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLGdCQUFnQixhQUFhO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLGdFQUFn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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLDhFQUE4RSxTQUFTO0FBQ3ZGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsV0FBVyxTQUFTO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDREQUE0RCxrQ0FBa0M7QUFDOUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsVUFBVTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsVUFBVTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxrREFBa0QsYUFBYTtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBLCtDQUErQyxhQUFhO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhEQUE4RCxNQUFNO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQSwrRUFBK0Usa0NBQWtDO0FBQ2pIO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWixRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELDBCQUEwQixpREFBaUQsT0FBTztBQUNySTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELDBCQUEwQixpREFBaUQsT0FBTztBQUN2STtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLHVEQUF1RCxhQUFhO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkZBQTJGLDJDQUEyQztBQUN0STtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkZBQTJGLDJDQUEyQztBQUN0STtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsZ0RBQWdELGFBQWE7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQSx5REFBeUQsYUFBYTtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QywrQ0FBK0M7QUFDdkY7QUFDQTtBQUNBLGdDQUFnQztBQUNoQyx5QkFBeUI7QUFDekI7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLG1JQUFtSSx5QkFBeUI7QUFDNUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQiw0QkFBNEI7QUFDM0QsOEJBQThCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtB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LENBQUM7SUFDOUMsT0FBTyxHQUFHLENBQUM7QUFDWixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsS0FBSyxVQUFVLGlCQUFpQixDQUFDLGFBQWdDO0lBQ2hFLE1BQU0sT0FBTyxHQUFzQixNQUFNLDhDQUFHLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBRWpFLEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDM0IsTUFBTSxVQUFVLEdBQXNCLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkUsVUFBVSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1FBQ3pCLFVBQVUsQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQztRQUNsQyxVQUFVLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDNUIsYUFBYSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsQyxDQUFDO0FBQ0YsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL0BvcGVuZmluL2NvcmUvb3V0L21vY2suanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX0RhdGFWaWV3LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fSGFzaC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX0xpc3RDYWNoZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX01hcC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX01hcENhY2hlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fUHJvbWlzZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX1NldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX1NldENhY2hlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fU3RhY2suanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19TeW1ib2wuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19VaW50OEFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fV2Vha01hcC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2FycmF5RWFjaC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2FycmF5RmlsdGVyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlMaWtlS2V5cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2FycmF5UHVzaC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2FycmF5U29tZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Fzc2lnblZhbHVlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYXNzb2NJbmRleE9mLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VBc3NpZ25Jbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VBc3NpZ25WYWx1ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VDbG9uZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VDcmVhdGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlR2V0QWxsS2V5cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VHZXRUYWcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlSXNBcmd1bWVudHMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlSXNFcXVhbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0VxdWFsRGVlcC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc01hcC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc05hdGl2ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc1NldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc1R5cGVkQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlS2V5cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VLZXlzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlVGltZXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlVW5hcnkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jYWNoZUhhcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lQXJyYXlCdWZmZXIuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jbG9uZUJ1ZmZlci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lRGF0YVZpZXcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19jbG9uZVJlZ0V4cC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nsb25lU3ltYm9sLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY2xvbmVUeXBlZEFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weUFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weU9iamVjdC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2NvcHlTeW1ib2xzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weVN5bWJvbHNJbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2NvcmVKc0RhdGEuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19kZWZpbmVQcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2VxdWFsQXJyYXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxCeVRhZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2VxdWFsT2JqZWN0cy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2ZyZWVHbG9iYWwuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRBbGxLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0QWxsS2V5c0luLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TWFwRGF0YS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldE5hdGl2ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFByb3RvdHlwZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFJhd1RhZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFN5bWJvbHMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRTeW1ib2xzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRUYWcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19nZXRWYWx1ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hDbGVhci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hEZWxldGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19oYXNoR2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaEhhcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hTZXQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19pbml0Q2xvbmVBcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2luaXRDbG9uZUJ5VGFnLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faW5pdENsb25lT2JqZWN0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faXNJbmRleC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzS2V5YWJsZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzTWFza2VkLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9faXNQcm90b3R5cGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19saXN0Q2FjaGVDbGVhci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZURlbGV0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUdldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUhhcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZVNldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlQ2xlYXIuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZURlbGV0ZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlR2V0LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVIYXMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZVNldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcFRvQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19uYXRpdmVDcmVhdGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19uYXRpdmVLZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbmF0aXZlS2V5c0luLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fbm9kZVV0aWwuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19vYmplY3RUb1N0cmluZy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX292ZXJBcmcuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19yb290LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0Q2FjaGVBZGQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zZXRDYWNoZUhhcy5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3NldFRvQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja0NsZWFyLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc3RhY2tEZWxldGUuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja0dldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrSGFzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9fc3RhY2tTZXQuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL190b1NvdXJjZS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvY2xvbmVEZWVwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9lcS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcmd1bWVudHMuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXkuanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXlMaWtlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc0J1ZmZlci5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNFcXVhbC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNGdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNMZW5ndGguanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL2lzTWFwLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc09iamVjdC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNPYmplY3RMaWtlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9pc1NldC5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvaXNUeXBlZEFycmF5LmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9rZXlzLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvLi4vLi4vbm9kZV9tb2R1bGVzL2xvZGFzaC9rZXlzSW4uanMiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uLi8uLi9ub2RlX21vZHVsZXMvbG9kYXNoL3N0dWJBcnJheS5qcyIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzLy4uLy4uL25vZGVfbW9kdWxlcy9sb2Rhc2gvc3R1YkZhbHNlLmpzIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy93ZWJwYWNrL3J1bnRpbWUvZ2xvYmFsIiwid2VicGFjazovL3VzZS1sb2dnaW5nLWFwaXMvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly91c2UtbG9nZ2luZy1hcGlzL3dlYnBhY2svcnVudGltZS9ub2RlIG1vZHVsZSBkZWNvcmF0b3IiLCJ3ZWJwYWNrOi8vdXNlLWxvZ2dpbmctYXBpcy8uL2NsaWVudC9zcmMvcHJvdmlkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgcmVxdWlyZSQkMCA9IHJlcXVpcmUoJ2V2ZW50cycpO1xudmFyIHJlcXVpcmUkJDAkMSA9IHJlcXVpcmUoJ2xvZGFzaC9jbG9uZURlZXAnKTtcbnZhciByZXF1aXJlJCQzID0gcmVxdWlyZSgnbG9kYXNoL2lzRXF1YWwnKTtcblxuZnVuY3Rpb24gX21lcmdlTmFtZXNwYWNlcyhuLCBtKSB7XG5cdG0uZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuXHRcdGUgJiYgdHlwZW9mIGUgIT09ICdzdHJpbmcnICYmICFBcnJheS5pc0FycmF5KGUpICYmIE9iamVjdC5rZXlzKGUpLmZvckVhY2goZnVuY3Rpb24gKGspIHtcblx0XHRcdGlmIChrICE9PSAnZGVmYXVsdCcgJiYgIShrIGluIG4pKSB7XG5cdFx0XHRcdHZhciBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihlLCBrKTtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG4sIGssIGQuZ2V0ID8gZCA6IHtcblx0XHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZVtrXTsgfVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSk7XG5cdHJldHVybiBPYmplY3QuZnJlZXplKG4pO1xufVxuXG52YXIgY29tbW9uanNHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWxUaGlzIDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fTtcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMgKHgpIHtcblx0cmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDtcbn1cblxudmFyIE9wZW5GaW4kMiA9IHt9O1xuXG52YXIgZXZlbnRzID0ge307XG5cbnZhciBhcHBsaWNhdGlvbiQxID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgdGhhdCBjYW4gYmUgZW1pdHRlZCBieSBhbiB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbn0uICBJbmNsdWRlcyBldmVudHNcbiAqIHJlLXByb3BhZ2F0ZWQgZnJvbSB0aGUge0BsaW5rIE9wZW5GaW4uV2luZG93fSAoYW5kLCB0cmFuc2l0aXZlbHksIHtAbGluayBPcGVuRmluLlZpZXd9KSBsZXZlbCwgcHJlZml4ZWQgd2l0aCBgd2luZG93LWAgKGFuZCBhbHNvLCBpZiBhcHBsaWNhYmxlLCBgdmlldy1gKS5cbiAqIEZvciBleGFtcGxlLCBhIHZpZXcncyBcImF0dGFjaGVkXCIgZXZlbnQgd2lsbCBmaXJlIGFzICd3aW5kb3ctdmlldy1hdHRhY2hlZCcgYXQgdGhlIGFwcGxpY2F0aW9uIGxldmVsLlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhpcyBuYW1lc3BhY2UgY29udGFpbnMgb25seSBwYXlsb2FkIHNoYXBlcyBmb3IgZXZlbnRzIHRoYXQgYXJlIHVuaXF1ZSB0byBgQXBwbGljYXRpb25gLiAgRXZlbnRzIHRoYXQgcHJvcGFnYXRlIHRvIGBBcHBsaWNhdGlvbmAgZnJvbVxuICogY2hpbGQge0BsaW5rIE9wZW5GaW4uV2luZG93IHdpbmRvd3N9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3IHZpZXdzfSBhcmUgZGVmaW5lZCBpbiB0aGUge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfSBhbmRcbiAqIHtAbGluayBPcGVuRmluLlZpZXdFdmVudHN9IG5hbWVzcGFjZXMuICBGb3IgYSBsaXN0IG9mIHZhbGlkIHN0cmluZyBrZXlzIGZvciAqYWxsKiBhcHBsaWNhdGlvbiBldmVudHMsIHNlZSB7QGxpbmsgQXBwbGljYXRpb24ub24gQXBwbGljYXRpb24ub259LlxuICpcbiAqIHtAbGluayBBcHBsaWNhdGlvblNvdXJjZWRFdmVudCBBcHBsaWNhdGlvbi1zb3VyY2VkIGV2ZW50c30gKGkuZS4gdGhvc2UgdGhhdCBoYXZlIG5vdCBwcm9wYWdhdGVkIGZyb20ge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3c31cbiAqIG9yIHtAbGluayBPcGVuRmluLldpbmRvd0V2ZW50cyBXaW5kb3dzfSByZS1wcm9wYWdhdGUgdG8ge0BsaW5rIE9wZW5GaW4uU3lzdGVtRXZlbnRzIFN5c3RlbX0gd2l0aCB0aGVpciB0eXBlIHN0cmluZyBwcmVmaXhlZCB3aXRoIGBhcHBsaWNhdGlvbi1gLlxuICoge0BsaW5rIEFwcGxpY2F0aW9uV2luZG93RXZlbnQgQXBwbGljYXRpb24gZXZlbnRzIHRoYXQgYXJlIHRpZWQgdG8gV2luZG93cyBidXQgZG8gbm90IHByb3BhZ2F0ZSBmcm9tIHRoZW19XG4gKiBhcmUgcHJvcGFnYXRlZCB0byBgU3lzdGVtYCB3aXRob3V0IGFueSB0eXBlIHN0cmluZyBwcmVmaXhpbmcuXG4gKlxuICogXCJSZXF1ZXN0ZWRcIiBldmVudHMgKGUuZy4ge0BsaW5rIFJ1blJlcXVlc3RlZEV2ZW50fSkgZG8gbm90IHByb3BhZ2F0ZS5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwcGxpY2F0aW9uJDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgYmFzZSQxID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBzaGFyZWQgZXZlbnQgcGF5bG9hZHMgYW5kIHV0aWxpdHkgdHlwZXMgY29tbW9uIHRvIGFsbCBldmVudCBlbWl0dGVycy5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGJhc2UkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBleHRlcm5hbEFwcGxpY2F0aW9uJDEgPSB7fTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBiZSB0cmFuc21pdHRlZCBieSBhbiB7QGxpbmsgT3BlbkZpbi5FeHRlcm5hbEFwcGxpY2F0aW9ufS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yIGV4dGVybmFsIGFwcGxpY2F0aW9uIGV2ZW50cywgc2VlIHtAbGluayBFeHRlcm5hbEFwcGxpY2F0aW9uLm9uIEV4dGVybmFsQXBwbGljYXRpb24ub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXh0ZXJuYWxBcHBsaWNhdGlvbiQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIGZyYW1lJDEgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGZyYW1lJDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgZ2xvYmFsSG90a2V5JDEgPSB7fTtcblxuLyoqXG4gKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgdGhhdCBjYW4gYmUgdHJhbnNtaXR0ZWQgYnkge0BsaW5rIEdsb2JhbEhvdGtleS5HbG9iYWxIb3RrZXl9LlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogRm9yIGEgbGlzdCBvZiB2YWxpZCBzdHJpbmcga2V5cyBmb3IgZ2xvYmFsIGhvdGtleSBldmVudHMsIHNlZSB7QGxpbmsgR2xvYmFsSG90a2V5Lkdsb2JhbEhvdGtleS5vbiBHbG9iYWxIb3RrZXkub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsSG90a2V5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgcGxhdGZvcm0kMSA9IHt9O1xuXG4vKipcbiAqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBlbWl0dGVkIGJ5IGEge0BsaW5rIE9wZW5GaW4uUGxhdGZvcm19LlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhlIFBsYXRmb3JtIGBFdmVudEVtaXR0ZXJgIGlzIGEgc3VwZXJzZXQgb2YgdGhlIHtAbGluayBPcGVuRmluLkFwcGxpY2F0aW9ufSBgRXZlbnRFbWl0dGVyYCxcbiAqIG1lYW5pbmcgaXQgY2FuIGxpc3RlbiB0byBhbGwge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb25FdmVudHMgQXBwbGljYXRpb24gZXZlbnRzfSBpbiBhZGRpdGlvbiB0byB0aGVcbiAqIFBsYXRmb3JtLXNwZWNpZmljIGV2ZW50cyBsaXN0ZWQgaGVyZS4gIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIHBsYXRmb3JtIGV2ZW50cywgc2VlXG4gKiB7QGxpbmsgUGxhdGZvcm0ub24gUGxhdGZvcm0ub259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkocGxhdGZvcm0kMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cbnZhciBzeXN0ZW0kMSA9IHt9O1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgcnVudGltZS13aWRlIE9wZW5GaW4gZXZlbnRzIGVtaXR0ZWQgYnkge0BsaW5rIFN5c3RlbS5TeXN0ZW19LiAgSW5jbHVkZXMgZXZlbnRzXG4gKiByZS1wcm9wYWdhdGVkIGZyb20ge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259LCB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9LCBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30gKHByZWZpeGVkIHdpdGggYGFwcGxpY2F0aW9uLWAsIGB3aW5kb3ctYCwgYW5kIGB2aWV3LWApLiAgQWxsXG4gKiBldmVudCBwcm9wYWdhdGlvbnMgYXJlIHZpc2libGUgYXQgdGhlIFN5c3RlbSBsZXZlbC4gUHJvcGFnYXRlZCBldmVudHMgZnJvbSBXZWJDb250ZW50cyAod2luZG93cywgdmlld3MsIGZyYW1lcykgdG8gdGhlIEFwcGxpY2F0aW9uIGxldmVsIHdpbGwgKm5vdCpcbiAqIHRyYW5zaXRpdmVseSByZS1wcm9wYWdhdGUgdG8gdGhlIFN5c3RlbSBsZXZlbCwgYmVjYXVzZSB0aGV5IGFyZSBhbHJlYWR5IHZpc2libGUgYXQgdGhlIHN5c3RlbSBsZXZlbCBhbmQgY29udGFpbiB0aGUgaWRlbnRpdHlcbiAqIG9mIHRoZSBhcHBsaWNhdGlvbi4gIEZvciBleGFtcGxlLCBhbiBhcHBsaWNhdGlvbidzIFwiY2xvc2VkXCIgZXZlbnQgd2lsbCBmaXJlIGFzICdhcHBsaWNhdGlvbi1jbG9zZWQnIGF0IHRoZSBzeXN0ZW0gbGV2ZWwuICBBIHZpZXcncyAnc2hvd24nIGV2ZW50XG4gKiB3aWxsIGJlIHZpc2libGUgYXMgJ3ZpZXctc2hvd24nIGF0IHRoZSBzeXN0ZW0gbGV2ZWwsIGJ1dCAqbm90KiBhcyBgYXBwbGljYXRpb24td2luZG93LXZpZXctc2hvd25gLlxuICpcbiAqIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGFzIGludGVyZmFjZXMsIHdoaWxlIGFsZ2VicmFpYyBoZWxwZXIgdHlwZXMgYW5kIGRlcml2ZWQgdHlwZXMgYXJlIGRvY3VtZW50ZWQgYXMgdHlwZSBhbGlhc2VzLlxuICogRXZlbnRzIGdhaW4gbWV0YWRhdGEgYXMgdGhleSBwcm9wYWdhdGUsIHdoaWNoIGlzICpub3QqIHByZXNlbnQgb24gdGhlIGV4cGxpY2l0IHBheWxvYWQgaW50ZXJmYWNlcy4gIFRvIHJlZmVyIHRvIHRoZSBmdWxsIHR5cGVcbiAqIG9mIGFuIGV2ZW50IGFzIGl0IHdvdWxkIGJlIHJhaXNlZCBvbiB0aGlzIGVtaXR0ZXIsIHVzZSB7QGxpbmsgUGF5bG9hZH0uXG4gKlxuICogVGhpcyBuYW1lc3BhY2UgY29udGFpbnMgb25seSBwYXlsb2FkIHNoYXBlcyBmb3IgZXZlbnRzIHRoYXQgYXJlIHVuaXF1ZSB0byBgU3lzdGVtYC4gIEV2ZW50cyB0aGF0IHByb3BhZ2F0ZSB0byBgU3lzdGVtYCBmcm9tXG4gKiBjaGlsZCB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbiBhcHBsaWNhdGlvbnN9LCB7QGxpbmsgT3BlbkZpbi5XaW5kb3cgd2luZG93c30sIGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3IHZpZXdzfSBhcmUgZGVmaW5lZCBpbiB0aGVcbiAqIHtAbGluayBPcGVuRmluLkFwcGxpY2F0aW9uRXZlbnRzfSwge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfSwgYW5kIHtAbGluayBPcGVuRmluLlZpZXdFdmVudHN9IG5hbWVzcGFjZXMuICBGb3IgYSBsaXN0IG9mIHZhbGlkIHN0cmluZyBrZXlzIGZvciAqYWxsKlxuICogc3lzdGVtIGV2ZW50cywgc2VlIHtAbGluayBTeXN0ZW0ub24gU3lzdGVtLm9ufS5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN5c3RlbSQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIHZpZXckMSA9IHt9O1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgZXZlbnRzIHRoYXQgY2FuIGJlIGVtaXR0ZWQgYnkgYSB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIFRoaXMgbmFtZXNwYWNlIGNvbnRhaW5zIG9ubHkgcGF5bG9hZCBzaGFwZXMgZm9yIGV2ZW50cyB0aGF0IGFyZSB1bmlxdWUgdG8gYFZpZXdgLiAgRXZlbnRzIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIGFsbCBgV2ViQ29udGVudHNgXG4gKiAoaS5lLiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9LCB7QGxpbmsgT3BlbkZpbi5WaWV3fSkgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHN9LiAgRm9yIGEgbGlzdFxuICogb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIFZpZXcgZXZlbnRzLCBzZWUge0BsaW5rIFZpZXcub24gVmlldy5vbn0uXG4gKlxuICogVmlldyBldmVudHMgcHJvcGFnYXRlIHRvIHRoZWlyIHBhcmVudCB7QGxpbmsgT3BlbkZpbi5XaW5kb3dFdmVudHMgV2luZG93fSwge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb25FdmVudHMgQXBwbGljYXRpb259LFxuICogYW5kIHtAbGluayBPcGVuRmluLlN5c3RlbUV2ZW50cyBTeXN0ZW19IHdpdGggYW4gYWRkZWQgYHZpZXdJZGVudGl0eWAgcHJvcGVydHkgYW5kIHRoZWlyIGV2ZW50IHR5cGVzIHByZWZpeGVkIHdpdGggYCd2aWV3LSdgLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodmlldyQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxudmFyIHdlYmNvbnRlbnRzID0ge307XG5cbi8qKlxuICogTmFtZXNwYWNlIGZvciBldmVudHMgc2hhcmVkIGJ5IGFsbCBPcGVuRmluIFdlYkNvbnRlbnRzIGVsZW1lbnRzIChpLmUuIHtAbGluayBPcGVuRmluLldpbmRvd30sXG4gKiB7QGxpbmsgT3BlbkZpbi5WaWV3fSkuXG4gKlxuICogV2ViQ29udGVudHMgZXZlbnRzIHdpbGwgcmUtZW1pdCBvbiBwYXJlbnQgZW50aXRpZXMgLSBlLmcuLCBhIHByb3BhZ2F0aW5nIGV2ZW50IGluIGEgdmlldyB3aWxsIGFsc28gYmUgZW1pdHRlZCBvbiB0aGUgdmlldydzXG4gKiBwYXJlbnQgd2luZG93LCBhbmQgcHJvcGFnYXRpbmcgZXZlbnRzIGluIGEgd2luZG93IHdpbGwgYWxzbyBiZSBlbWl0dGVkIG9uIHRoZSB3aW5kb3cncyBwYXJlbnQge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2ViY29udGVudHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG52YXIgd2luZG93JDIgPSB7fTtcblxuLyoqXG4gKiBOYW1lc3BhY2UgZm9yIGV2ZW50cyB0aGF0IGNhbiBiZSBlbWl0dGVkIGJ5IGEge0BsaW5rIE9wZW5GaW4uV2luZG93fS5cbiAqXG4gKiBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqIEV2ZW50cyBnYWluIG1ldGFkYXRhIGFzIHRoZXkgcHJvcGFnYXRlLCB3aGljaCBpcyAqbm90KiBwcmVzZW50IG9uIHRoZSBleHBsaWNpdCBwYXlsb2FkIGludGVyZmFjZXMuICBUbyByZWZlciB0byB0aGUgZnVsbCB0eXBlXG4gKiBvZiBhbiBldmVudCBhcyBpdCB3b3VsZCBiZSByYWlzZWQgb24gdGhpcyBlbWl0dGVyLCB1c2Uge0BsaW5rIFBheWxvYWR9LlxuICpcbiAqIFRoaXMgbmFtZXNwYWNlIGNvbnRhaW5zIG9ubHkgcGF5bG9hZCBzaGFwZXMgZm9yIGV2ZW50cyB0aGF0IGFyZSB1bmlxdWUgdG8gYFdpbmRvd2AuICBFdmVudHMgdGhhdCBhcmUgc2hhcmVkIGJldHdlZW4gYWxsIGBXZWJDb250ZW50c2BcbiAqIChpLmUuIHtAbGluayBPcGVuRmluLldpbmRvd30sIHtAbGluayBPcGVuRmluLlZpZXd9KSBhcmUgZGVmaW5lZCBpbiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50c30uIEV2ZW50cyB0aGF0XG4gKiBwcm9wYWdhdGUgZnJvbSBgVmlld2AgYXJlIGRlZmluZWQgaW4ge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50c30uIEZvciBhIGxpc3Qgb2YgdmFsaWQgc3RyaW5nIGtleXMgZm9yICphbGwqIFdpbmRvdyBldmVudHMsIHNlZVxuICoge0BsaW5rIFdpbmRvdy5vbiBXaW5kb3cub259XG4gKlxuICoge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzLldpbmRvd1NvdXJjZWRFdmVudCBXaW5kb3ctc291cmNlZCBldmVudHN9IChpLmUuIHRob3NlIHRoYXQgYXJlIG5vdCBwcm9wYWdhdGVkIGZyb20gYVxuICoge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3fSkgcHJvcGFnYXRlIHRvIHRoZWlyIHBhcmVudCB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50cyBBcHBsaWNhdGlvbn0gYW5kXG4gKiB7QGxpbmsgT3BlbkZpbi5TeXN0ZW1FdmVudHMgU3lzdGVtfSB3aXRoIHRoZWlyIGV2ZW50IHR5cGVzIHByZWZpeGVkIHdpdGggYCd3aW5kb3ctJ2ApLlxuICpcbiAqIFwiUmVxdWVzdGVkXCIgZXZlbnRzIChlLmcuIHtAbGluayBBdXRoUmVxdWVzdGVkRXZlbnR9KSBkbyBub3QgcHJvcGFnYXRlIHRvIGBTeXN0ZW0uICBUaGUge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzLldpbmRvd0Nsb3NlUmVxdWVzdGVkRXZlbnR9XG4gKiBkb2VzIG5vdCBwcm9wYWdhdGUgYXQgYWxsLlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5PYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXG4vKipcbiAqIE5hbWVzcGFjZSBmb3IgT3BlbkZpbiBldmVudCB0eXBlcy4gRWFjaCBlbnRpdHkgdGhhdCBlbWl0cyBPcGVuRmluIGV2ZW50cyBoYXMgaXRzIG93biBzdWItbmFtZXNwYWNlLiBFdmVudCBwYXlsb2Fkc1xuICogdGhlbXNlbHZlcyBhcmUgZG9jdW1lbnRlZCBhcyBpbnRlcmZhY2VzLCB3aGlsZSBhbGdlYnJhaWMgaGVscGVyIHR5cGVzIGFuZCBkZXJpdmVkIHR5cGVzIGFyZSBkb2N1bWVudGVkIGFzIHR5cGUgYWxpYXNlcy5cbiAqXG4gKiAjIyMjIEV2ZW50IGVtaXR0ZXJzXG4gKlxuICogVGhlIGZvbGxvd2luZyBlbnRpdGllcyBlbWl0IE9wZW5GaW4gZXZlbnRzLCBhbmQgaGF2ZSBjb3JyZXNwb25kaW5nIHN1Yi1uYW1lc3BhY2VzOlxuICpcbiAqICoge0BsaW5rIE9wZW5GaW4uQXBwbGljYXRpb259OiB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbn06IHtAbGluayBPcGVuRmluLkV4dGVybmFsQXBwbGljYXRpb25FdmVudHN9XG4gKiAqIHtAbGluayBPcGVuRmluLkZyYW1lfToge0BsaW5rIE9wZW5GaW4uRnJhbWVFdmVudHN9XG4gKiAqIHtAbGluayBPcGVuRmluLkdsb2JhbEhvdGtleX06IHtAbGluayBPcGVuRmluLkdsb2JhbEhvdGtleUV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uUGxhdGZvcm19OiB7QGxpbmsgT3BlbkZpbi5QbGF0Zm9ybUV2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uU3lzdGVtfToge0BsaW5rIE9wZW5GaW4uU3lzdGVtRXZlbnRzfVxuICogKiB7QGxpbmsgT3BlbkZpbi5WaWV3fToge0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50c31cbiAqICoge0BsaW5rIE9wZW5GaW4uV2luZG93fToge0BsaW5rIE9wZW5GaW4uV2luZG93RXZlbnRzfVxuICpcbiAqIFRoZXNlIGBFdmVudEVtaXR0ZXJgIGVudGl0aWVzIHNoYXJlIGEgY29tbW9uIHNldCBvZiBtZXRob2RzIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBPcGVuRmluIGV2ZW50IGJ1cywgd2hpY2ggY2FuIGJlXG4gKiBzZWVuIG9uIHRoZSBpbmRpdmlkdWFsIGRvY3VtZW50YXRpb24gcGFnZXMgZm9yIGVhY2ggZW50aXR5IHR5cGUuXG4gKlxuICogUmVnaXN0ZXJpbmcgZXZlbnQgaGFuZGxlcnMgaXMgYW4gYXN5bmNocm9ub3VzIG9wZXJhdGlvbi4gSXQgaXMgaW1wb3J0YW50IHRvIGVuc3VyZSB0aGF0IHRoZSByZXR1cm5lZCBQcm9taXNlcyBhcmUgYXdhaXRlZCB0byByZWR1Y2UgdGhlXG4gKiByaXNrIG9mIHJhY2UgY29uZGl0aW9ucy5cbiAqXG4gKiBXaGVuIHRoZSBgRXZlbnRFbWl0dGVyYCByZWNlaXZlcyBhbiBldmVudCBmcm9tIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIGVtaXRzIG9uIHRoZSByZW5kZXJlciwgYWxsIG9mIHRoZSBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhhdFxuICogc3BlY2lmaWMgZXZlbnQgYXJlIGNhbGxlZCBzeW5jaHJvbm91c2x5LiBBbnkgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsZWQgbGlzdGVuZXJzIGFyZSBpZ25vcmVkIGFuZCB3aWxsIGJlIGRpc2NhcmRlZC4gIElmIHRoZSB3aW5kb3cgZG9jdW1lbnRcbiAqIGlzIGRlc3Ryb3llZCBieSBwYWdlIG5hdmlnYXRpb24gb3IgcmVsb2FkLCBpdHMgcmVnaXN0ZXJlZCBldmVudCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICpcbiAqIFdlIHJlY29tbWVuZCB1c2luZyBBcnJvdyBGdW5jdGlvbnMgZm9yIGV2ZW50IGxpc3RlbmVycyB0byBlbnN1cmUgdGhlIHRoaXMgc2NvcGUgaXMgY29uc2lzdGVudCB3aXRoIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBjb250ZXh0LlxuICpcbiAqIEV2ZW50cyByZS1wcm9wYWdhdGUgZnJvbSBzbWFsbGVyL21vcmUtbG9jYWwgc2NvcGVzIHRvIGxhcmdlci9tb3JlLWdsb2JhbCBzY29wZXMuICBGb3IgZXhhbXBsZSwgYW4gZXZlbnQgZW1pdHRlZCBvbiBhIHNwZWNpZmljXG4gKiB2aWV3IHdpbGwgcHJvcGFnYXRlIHRvIHRoZSB3aW5kb3cgaW4gd2hpY2ggdGhlIHZpZXcgaXMgZW1iZWRkZWQsIGFuZCB0aGVuIHRvIHRoZSBhcHBsaWNhdGlvbiBpbiB3aGljaCB0aGUgd2luZG93IGlzIHJ1bm5pbmcsIGFuZFxuICogZmluYWxseSB0byB0aGUgT3BlbkZpbiBydW50aW1lIGl0c2VsZiBhdCB0aGUgXCJzeXN0ZW1cIiBsZXZlbC4gIEZvciBkZXRhaWxzIG9uIHByb3BhZ2F0aW9uIHNlbWFudGljcywgc2VlIHRoZSBuYW1lc3BhY2UgZm9yXG4gKiB0aGUgcHJvcGFnYXRpbmcgKG9yIHByb3BhZ2F0ZWQtdG8pIGVudGl0eS5cbiAqXG4gKiBJZiB5b3UgbmVlZCB0aGUgcGF5bG9hZCB0eXBlIGZvciBhIHNwZWNpZmljIHR5cGUgb2YgZXZlbnQgKGVzcGVjaWFsbHkgcHJvcGFnYXRlZCBldmVudHMpLCB1c2UgdGhlIGVtaXR0aW5nIHRvcGljJ3MgYFBheWxvYWRgIGdlbmVyaWNcbiAqIChlLmcuIHtAbGluayBXaW5kb3dFdmVudHMuUGF5bG9hZH0pIHdpdGggdGhlIGV2ZW50J3MgYHR5cGVgIHN0cmluZy4gIEZvciBleGFtcGxlLCB0aGUgcGF5bG9hZCBvZlxuICogYSB7QGxpbmsgVmlld0V2ZW50cy5DcmVhdGVkRXZlbnR9IGFmdGVyIGl0IGhhcyBwcm9wYWdhdGVkIHRvIGl0cyBwYXJlbnQge0BsaW5rIFdpbmRvd0V2ZW50cyBXaW5kb3d9IGNhbiBiZSBmb3VuZCB3aXRoXG4gKiBgV2luZG93RXZlbnRzLlBheWxvYWQ8J3ZpZXctY3JlYXRlZCc+YC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xudmFyIF9fY3JlYXRlQmluZGluZyQxID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19zZXRNb2R1bGVEZWZhdWx0JDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xufSkgOiBmdW5jdGlvbihvLCB2KSB7XG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xufSk7XG52YXIgX19pbXBvcnRTdGFyJDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnRTdGFyKSB8fCBmdW5jdGlvbiAobW9kKSB7XG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmckMShyZXN1bHQsIG1vZCwgayk7XG4gICAgX19zZXRNb2R1bGVEZWZhdWx0JDEocmVzdWx0LCBtb2QpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV2ZW50cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5ldmVudHMuV2luZG93RXZlbnRzID0gZXZlbnRzLldlYkNvbnRlbnRzRXZlbnRzID0gZXZlbnRzLlZpZXdFdmVudHMgPSBldmVudHMuU3lzdGVtRXZlbnRzID0gZXZlbnRzLlBsYXRmb3JtRXZlbnRzID0gZXZlbnRzLkdsb2JhbEhvdGtleUV2ZW50cyA9IGV2ZW50cy5GcmFtZUV2ZW50cyA9IGV2ZW50cy5FeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzID0gZXZlbnRzLkJhc2VFdmVudHMgPSBldmVudHMuQXBwbGljYXRpb25FdmVudHMgPSB2b2lkIDA7XG5jb25zdCBBcHBsaWNhdGlvbkV2ZW50cyA9IF9faW1wb3J0U3RhciQxKGFwcGxpY2F0aW9uJDEpO1xuZXZlbnRzLkFwcGxpY2F0aW9uRXZlbnRzID0gQXBwbGljYXRpb25FdmVudHM7XG5jb25zdCBCYXNlRXZlbnRzID0gX19pbXBvcnRTdGFyJDEoYmFzZSQxKTtcbmV2ZW50cy5CYXNlRXZlbnRzID0gQmFzZUV2ZW50cztcbmNvbnN0IEV4dGVybmFsQXBwbGljYXRpb25FdmVudHMgPSBfX2ltcG9ydFN0YXIkMShleHRlcm5hbEFwcGxpY2F0aW9uJDEpO1xuZXZlbnRzLkV4dGVybmFsQXBwbGljYXRpb25FdmVudHMgPSBFeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzO1xuY29uc3QgRnJhbWVFdmVudHMgPSBfX2ltcG9ydFN0YXIkMShmcmFtZSQxKTtcbmV2ZW50cy5GcmFtZUV2ZW50cyA9IEZyYW1lRXZlbnRzO1xuY29uc3QgR2xvYmFsSG90a2V5RXZlbnRzID0gX19pbXBvcnRTdGFyJDEoZ2xvYmFsSG90a2V5JDEpO1xuZXZlbnRzLkdsb2JhbEhvdGtleUV2ZW50cyA9IEdsb2JhbEhvdGtleUV2ZW50cztcbmNvbnN0IFBsYXRmb3JtRXZlbnRzID0gX19pbXBvcnRTdGFyJDEocGxhdGZvcm0kMSk7XG5ldmVudHMuUGxhdGZvcm1FdmVudHMgPSBQbGF0Zm9ybUV2ZW50cztcbmNvbnN0IFN5c3RlbUV2ZW50cyA9IF9faW1wb3J0U3RhciQxKHN5c3RlbSQxKTtcbmV2ZW50cy5TeXN0ZW1FdmVudHMgPSBTeXN0ZW1FdmVudHM7XG5jb25zdCBWaWV3RXZlbnRzID0gX19pbXBvcnRTdGFyJDEodmlldyQxKTtcbmV2ZW50cy5WaWV3RXZlbnRzID0gVmlld0V2ZW50cztcbmNvbnN0IFdlYkNvbnRlbnRzRXZlbnRzID0gX19pbXBvcnRTdGFyJDEod2ViY29udGVudHMpO1xuZXZlbnRzLldlYkNvbnRlbnRzRXZlbnRzID0gV2ViQ29udGVudHNFdmVudHM7XG5jb25zdCBXaW5kb3dFdmVudHMgPSBfX2ltcG9ydFN0YXIkMSh3aW5kb3ckMik7XG5ldmVudHMuV2luZG93RXZlbnRzID0gV2luZG93RXZlbnRzO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0LyoqXG5cdCAqIFRvcC1sZXZlbCBuYW1lc3BhY2UgZm9yIHR5cGVzIHJlZmVyZW5jZWQgYnkgdGhlIE9wZW5GaW4gQVBJLiAgQ29udGFpbnM6XG5cdCAqXG5cdCAqICogVGhlIHR5cGUgb2YgdGhlIGdsb2JhbCBgZmluYCBlbnRyeSBwb2ludCAoe0BsaW5rIEZpbkFwaX0pXG5cdCAqICogQ2xhc3NlcyB0aGF0IGFjdCBhcyBzdGF0aWMgbmFtZXNwYWNlcyByZXR1cm5lZCBmcm9tIHRoZSBgZmluYCBnbG9iYWwgKGUuZy4ge0BsaW5rIEFwcGxpY2F0aW9uTW9kdWxlfSwgYWNjZXNzaWJsZSB2aWEgYGZpbi5BcHBsaWNhdGlvbmApXG5cdCAqICogSW5zdGFuY2UgY2xhc3NlcyB0aGF0IGFyZSByZXR1cm5lZCBmcm9tIEFQSSBjYWxscyAoZS5nLiB7QGxpbmsgQXBwbGljYXRpb259LCBhY2Nlc3NpYmxlIHZpYSBgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKClgKVxuXHQgKiAqIFBhcmFtZXRlciBzaGFwZXMgZm9yIEFQSSBtZXRob2RzIChlLmcuIHtAbGluayBBcHBsaWNhdGlvbk9wdGlvbnN9LCB1c2VkIGluIGBmaW4uQXBwbGljYXRpb24uc3RhcnQoKWApXG5cdCAqICogRXZlbnQgbmFtZXNwYWNlcyBhbmQgcGF5bG9hZCB1bmlvbiB0eXBlcyAoZS5nLiB7QGxpbmsgQXBwbGljYXRpb25FdmVudHN9IGFuZCB7QGxpbmsgQXBwbGljYXRpb25FdmVudH0pXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0Ly8gRGVwcmVjYXRlZCBzaGltIHRvIHByZXNlcnZlIHYzMCBuYW1lc3BhY2UgbmFtZXNcblx0X19leHBvcnRTdGFyKGV2ZW50cywgZXhwb3J0cyk7IFxufSAoT3BlbkZpbiQyKSk7XG5cbnZhciBPcGVuRmluID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKE9wZW5GaW4kMik7XG5cbnZhciBPcGVuRmluJDEgPSAvKiNfX1BVUkVfXyovX21lcmdlTmFtZXNwYWNlcyh7XG5cdF9fcHJvdG9fXzogbnVsbCxcblx0ZGVmYXVsdDogT3BlbkZpblxufSwgW09wZW5GaW4kMl0pO1xuXG52YXIgZmluJDIgPSB7fTtcblxudmFyIHN5c3RlbSA9IHt9O1xuXG52YXIgYmFzZSA9IHt9O1xuXG52YXIgcHJvbWlzZXMgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2VzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnByb21pc2VzLnByb21pc2VNYXBTZXJpYWwgPSBwcm9taXNlcy5zZXJpYWwgPSBwcm9taXNlcy5wcm9taXNlTWFwID0gcHJvbWlzZXMucHJvbWlzaWZ5ID0gdm9pZCAwO1xuZnVuY3Rpb24gcHJvbWlzaWZ5KGZ1bmMpIHtcbiAgICByZXR1cm4gKC4uLmFyZ3MpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgZnVuYyguLi5hcmdzLCAoZXJyLCB2YWwpID0+IChlcnIgPyByZWplY3QoZXJyKSA6IHJlc29sdmUodmFsKSkpO1xuICAgIH0pO1xufVxucHJvbWlzZXMucHJvbWlzaWZ5ID0gcHJvbWlzaWZ5O1xuYXN5bmMgZnVuY3Rpb24gcHJvbWlzZU1hcChhcnIsIGFzeW5jRikge1xuICAgIHJldHVybiBQcm9taXNlLmFsbChhcnIubWFwKGFzeW5jRikpO1xufVxucHJvbWlzZXMucHJvbWlzZU1hcCA9IHByb21pc2VNYXA7XG5hc3luYyBmdW5jdGlvbiBzZXJpYWwoYXJyKSB7XG4gICAgY29uc3QgcmV0ID0gW107XG4gICAgZm9yIChjb25zdCBmdW5jIG9mIGFycikge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgICAgICBjb25zdCBuZXh0ID0gYXdhaXQgZnVuYygpO1xuICAgICAgICByZXQucHVzaChuZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbn1cbnByb21pc2VzLnNlcmlhbCA9IHNlcmlhbDtcbmFzeW5jIGZ1bmN0aW9uIHByb21pc2VNYXBTZXJpYWwoYXJyLCBmdW5jKSB7XG4gICAgcmV0dXJuIHNlcmlhbChhcnIubWFwKCh2YWx1ZSwgaW5kZXgsIGFycmF5KSA9PiAoKSA9PiBmdW5jKHZhbHVlLCBpbmRleCwgYXJyYXkpKSk7XG59XG5wcm9taXNlcy5wcm9taXNlTWFwU2VyaWFsID0gcHJvbWlzZU1hcFNlcmlhbDtcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRlID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX0VtaXR0ZXJCYXNlX2VtaXR0ZXJBY2Nlc3Nvcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShiYXNlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmJhc2UuUmVwbHkgPSBiYXNlLkVtaXR0ZXJCYXNlID0gYmFzZS5CYXNlID0gdm9pZCAwO1xuY29uc3QgcHJvbWlzZXNfMSA9IHByb21pc2VzO1xuY2xhc3MgQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEBkZXByZWNhdGVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzTm9kZUVudmlyb25tZW50ID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5lbnZpcm9ubWVudC50eXBlID09PSAnbm9kZSc7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAaW50ZXJuYWxcbiAgICAgICAgICogQGRlcHJlY2F0ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNPcGVuRmluRW52aXJvbm1lbnQgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgPT09ICdvcGVuZmluJztcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc0Jyb3dzZXJFbnZpcm9ubWVudCA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQudHlwZSA9PT0gJ290aGVyJztcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy53aXJlID0gd2lyZTtcbiAgICB9XG4gICAgZ2V0IGZpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5nZXRGaW4oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBPcGVuRmluIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IGNvZGUgY29udGV4dCAodXN1YWxseSBhIGRvY3VtZW50XG4gICAgICogc3VjaCBhcyBhIHtAbGluayBPcGVuRmluLlZpZXd9IG9yIHtAbGluayBPcGVuRmluLldpbmRvd30pLCBhcyB3ZWxsIGFzIHRvIHRoZSBjdXJyZW50IGBJbnRlcm9wYCBjb250ZXh0LlxuICAgICAqXG4gICAgICogVXNlZnVsIGZvciBkZWJ1Z2dpbmcgaW4gdGhlIGRldnRvb2xzIGNvbnNvbGUsIHdoZXJlIHRoaXMgd2lsbCBpbnRlbGxpZ2VudGx5IHR5cGUgaXRzZWxmIGJhc2VkXG4gICAgICogb24gdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlIGRldnRvb2xzIHBhbmVsIHdhcyBvcGVuZWQuXG4gICAgICovXG4gICAgZ2V0IG1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLm1lO1xuICAgIH1cbn1cbmJhc2UuQmFzZSA9IEJhc2U7XG4vKipcbiAqIEFuIGVudGl0eSB0aGF0IGVtaXRzIE9wZW5GaW4gZXZlbnRzLlxuICpcbiAqIEByZW1hcmtzIEV2ZW50LWJpbmRpbmcgbWV0aG9kcyBhcmUgYXN5bmNocm9ub3VzIGFzIHRoZXkgbXVzdCBjcm9zcyBwcm9jZXNzIGJvdW5kYXJpZXNcbiAqIGFuZCBzZXR1cCB0aGUgbGlzdGVuZXIgaW4gdGhlIGJyb3dzZXIgcHJvY2Vzcy4gIFdoZW4gdGhlIGBFdmVudEVtaXR0ZXJgIHJlY2VpdmVzIGFuIGV2ZW50IGZyb20gdGhlIGJyb3dzZXIgcHJvY2Vzc1xuICogYW5kIGVtaXRzIG9uIHRoZSByZW5kZXJlciwgYWxsIG9mIHRoZSBmdW5jdGlvbnMgYXR0YWNoZWQgdG8gdGhhdCBzcGVjaWZpYyBldmVudCBhcmUgY2FsbGVkIHN5bmNocm9ub3VzbHkuICBBbnkgdmFsdWVzXG4gKiByZXR1cm5lZCBieSB0aGUgY2FsbGVkIGxpc3RlbmVycyBhcmUgaWdub3JlZCBhbmQgd2lsbCBiZSBkaXNjYXJkZWQuICBJZiB0aGUgZXhlY3V0aW9uIGNvbnRleHQgb2YgdGhlIHdpbmRvdyBpcyBkZXN0cm95ZWRcbiAqIGJ5IHBhZ2UgbmF2aWdhdGlvbiBvciByZWxvYWQsIGFueSBldmVudHMgdGhhdCBoYXZlIGJlZW4gc2V0dXAgaW4gdGhhdCBjb250ZXh0IHdpbGwgYmUgZGVzdHJveWVkLlxuICpcbiAqIEl0IGlzIGltcG9ydGFudCB0byBrZWVwIGluIG1pbmQgdGhhdCB3aGVuIGFuIG9yZGluYXJ5IGxpc3RlbmVyIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhlIHN0YW5kYXJkIGB0aGlzYCBrZXl3b3JkIGlzIGludGVudGlvbmFsbHlcbiAqIHNldCB0byByZWZlcmVuY2UgdGhlIGBFdmVudEVtaXR0ZXJgIGluc3RhbmNlIHRvIHdoaWNoIHRoZSBsaXN0ZW5lciBpcyBhdHRhY2hlZC4gIEl0IGlzIHBvc3NpYmxlIHRvIHVzZSBFUzYgQXJyb3cgRnVuY3Rpb25zIGFzXG4gKiBsaXN0ZW5lcnMsIGhvd2V2ZXIsIHdoZW4gZG9pbmcgc28sIHRoZSBgdGhpc2Aga2V5d29yZCB3aWxsIG5vIGxvbmdlciByZWZlcmVuY2UgdGhlIGBFdmVudEVtaXR0ZXJgIGluc3RhbmNlLlxuICpcbiAqIEV2ZW50cyByZS1wcm9wYWdhdGUgZnJvbSBzbWFsbGVyL21vcmUtbG9jYWwgc2NvcGVzIHRvIGxhcmdlci9tb3JlLWdsb2JhbCBzY29wZXMuICBGb3IgZXhhbXBsZSwgYW4gZXZlbnQgZW1pdHRlZCBvbiBhIHNwZWNpZmljXG4gKiB2aWV3IHdpbGwgcHJvcGFnYXRlIHRvIHRoZSB3aW5kb3cgaW4gd2hpY2ggdGhlIHZpZXcgaXMgZW1iZWRkZWQsIGFuZCB0aGVuIHRvIHRoZSBhcHBsaWNhdGlvbiBpbiB3aGljaCB0aGUgd2luZG93IGlzIHJ1bm5pbmcsIGFuZFxuICogZmluYWxseSB0byB0aGUgT3BlbkZpbiBydW50aW1lIGl0c2VsZiBhdCB0aGUgXCJzeXN0ZW1cIiBsZXZlbC4gIFJlLXByb3BhZ2F0ZWQgZXZlbnRzIGFyZSBwcmVmaXhlZCB3aXRoIHRoZSBuYW1lIG9mIHRoZSBzY29wZSBpbiB3aGljaFxuICogdGhleSBvcmlnaW5hdGVkIC0gZm9yIGV4YW1wbGUsIGEgXCJzaG93blwiIGV2ZW50IGVtaXR0ZWQgb24gYSB2aWV3IHdpbGwgYmUgcmUtcHJvcGFnYXRlZCBhdCB0aGUgd2luZG93IGxldmVsIGFzIFwidmlldy1zaG93blwiLCBhbmRcbiAqIHRoZW4gdG8gdGhlIGFwcGxpY2F0aW9uIGFzIFwid2luZG93LXZpZXctc2hvd25cIiwgYW5kIGZpbmFsbHkgYXQgdGhlIHN5c3RlbSBsZXZlbCBhcyBcImFwcGxpY2F0aW9uLXdpbmRvdy12aWV3LXNob3duXCIuXG4gKlxuICogQWxsIGV2ZW50IHByb3BhZ2F0aW9ucyBhcmUgdmlzaWJsZSBhdCB0aGUgU3lzdGVtIGxldmVsLCByZWdhcmRsZXNzIG9mIHNvdXJjZSwgc28gdHJhbnNpdGl2ZSByZS1wcm9wYWdhdGlvbnMgKGUuZy4gZnJvbSB2aWV3IHRvIHdpbmRvd1xuICogdG8gYXBwbGljYXRpb24pIGFyZSB2aXNpYmxlIGluIHRoZWlyIGVudGlyZXR5IGF0IHRoZSBzeXN0ZW0gbGV2ZWwuICBTbywgd2UgY2FuIGxpc3RlbiB0byB0aGUgYWJvdmUgZXZlbnQgYXMgXCJzaG93blwiLCBcInZpZXctc2hvd25cIixcbiAqIFwid2luZG93LXZpZXctc2hvd25cIiwgb3IgXCJhcHBsaWNhdGlvbi13aW5kb3ctdmlldy1zaG93bi5cIlxuICovXG5jbGFzcyBFbWl0dGVyQmFzZSBleHRlbmRzIEJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIHRvcGljLCAuLi5hZGRpdGlvbmFsQWNjZXNzb3JzKSB7XG4gICAgICAgIHN1cGVyKHdpcmUpO1xuICAgICAgICB0aGlzLnRvcGljID0gdG9waWM7XG4gICAgICAgIF9FbWl0dGVyQmFzZV9lbWl0dGVyQWNjZXNzb3Iuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIHRoaXMuZXZlbnROYW1lcyA9ICgpID0+ICh0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkuZXZlbnROYW1lcygpIDogW10pO1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVtaXQgPSAoZXZlbnRUeXBlLCBwYXlsb2FkLCAuLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5oYXNFbWl0dGVyKCkgPyB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpLmVtaXQoZXZlbnRUeXBlLCBwYXlsb2FkLCAuLi5hcmdzKSA6IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhc0VtaXR0ZXIgPSAoKSA9PiB0aGlzLndpcmUuZXZlbnRBZ2dyZWdhdG9yLmhhcyhfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGUodGhpcywgX0VtaXR0ZXJCYXNlX2VtaXR0ZXJBY2Nlc3NvciwgXCJmXCIpKTtcbiAgICAgICAgdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIgPSAoKSA9PiB0aGlzLndpcmUuZXZlbnRBZ2dyZWdhdG9yLmdldE9yQ3JlYXRlKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZSh0aGlzLCBfRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yLCBcImZcIikpO1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9ICh0eXBlKSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJzKHR5cGUpIDogW107XG4gICAgICAgIHRoaXMubGlzdGVuZXJDb3VudCA9ICh0eXBlKSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJDb3VudCh0eXBlKSA6IDA7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyID0gYXN5bmMgKGV2ZW50VHlwZSwgb3B0aW9ucyA9IHt9LCBhcHBseVN1YnNjcmlwdGlvbiwgdW5kb1N1YnNjcmlwdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgcnVudGltZUV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIC4uLnRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgdGltZXN0YW1wOiBvcHRpb25zLnRpbWVzdGFtcCB8fCBEYXRlLm5vdygpLFxuICAgICAgICAgICAgICAgIHRvcGljOiB0aGlzLnRvcGljLFxuICAgICAgICAgICAgICAgIHR5cGU6IGV2ZW50VHlwZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpO1xuICAgICAgICAgICAgLy8gV2UgYXBwbHkgdGhlIHN1YnNjcmlwdGlvbiBhbmQgdGhlbiB1bmRvIGlmIHRoZSBhc3luYyBjYWxsIGZhaWxzIHRvIGF2b2lkXG4gICAgICAgICAgICAvLyBpbmRldGVybWluYWN5IGluIHN1YnNjcmlwdGlvbiBhcHBsaWNhdGlvbiBvcmRlciwgd2hpY2ggY2FuIGJyZWFrIHRoaW5ncyBlbHNld2hlcmVcbiAgICAgICAgICAgIGFwcGx5U3Vic2NyaXB0aW9uKGVtaXR0ZXIpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3Vic2NyaWJlLXRvLWRlc2t0b3AtZXZlbnQnLCBydW50aW1lRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB1bmRvU3Vic2NyaXB0aW9uKGVtaXR0ZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsZXRlRW1pdHRlcklmTm90aGluZ1JlZ2lzdGVyZWQoZW1pdHRlcik7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kZXJlZ2lzdGVyRXZlbnRMaXN0ZW5lciA9IGFzeW5jIChldmVudFR5cGUsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcnVudGltZUV2ZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5LFxuICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IG9wdGlvbnMudGltZXN0YW1wIHx8IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIHRvcGljOiB0aGlzLnRvcGljLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBldmVudFR5cGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCd1bnN1YnNjcmliZS10by1kZXNrdG9wLWV2ZW50JywgcnVudGltZUV2ZW50KS5jYXRjaCgoKSA9PiBudWxsKTtcbiAgICAgICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZW1pdHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoaXMgd2lsbCBvbmx5IGJlIHJlYWNoZWQgaWYgdW5zdWJzY3JpYmUgZnJvbSBldmVudCB0aGF0IGRvZXMgbm90IGV4aXN0IGJ1dCBkbyBub3Qgd2FudCB0byBlcnJvciBoZXJlXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYyh0aGlzLCBfRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yLCBbdG9waWMsIC4uLmFkZGl0aW9uYWxBY2Nlc3NvcnNdLCBcImZcIik7XG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gKGV2ZW50KSA9PiB0aGlzLmhhc0VtaXR0ZXIoKSA/IHRoaXMuZ2V0T3JDcmVhdGVFbWl0dGVyKCkubGlzdGVuZXJzKGV2ZW50KSA6IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRXZlbnQgcGF5bG9hZHMgYXJlIGRvY3VtZW50ZWQgaW4gdGhlIHtAbGluayBPcGVuRmluLkV2ZW50c30gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIGFzeW5jIG9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zLCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5vbihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSwgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3RlbmVycyBhcnJheSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKi9cbiAgICBhc3luYyBhZGRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9uKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudC4gVGhlIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGUgZmlyc3QgdGltZSB0aGUgZXZlbnQgaXMgZmlyZWQsIGFmdGVyIHdoaWNoIGl0IGlzIHJlbW92ZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBFdmVudCBwYXlsb2FkcyBhcmUgZG9jdW1lbnRlZCBpbiB0aGUge0BsaW5rIE9wZW5GaW4uRXZlbnRzfSBuYW1lc3BhY2UuXG4gICAgICovXG4gICAgYXN5bmMgb25jZShldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRlcmVnaXN0ZXIgPSAoKSA9PiB0aGlzLmRlcmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgb3B0aW9ucywgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIub25jZShldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5vbmNlKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9LCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRXZlbnQgcGF5bG9hZHMgYXJlIGRvY3VtZW50ZWQgaW4gdGhlIHtAbGluayBPcGVuRmluLkV2ZW50c30gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIGFzeW5jIHByZXBlbmRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgb3B0aW9ucywgKGVtaXR0ZXIpID0+IHtcbiAgICAgICAgICAgIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICB9LCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgb25lIHRpbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudC4gVGhlIGxpc3RlbmVyIGlzIGludm9rZWQgb25seSB0aGUgZmlyc3QgdGltZSB0aGUgZXZlbnQgaXMgZmlyZWQsXG4gICAgICogYWZ0ZXIgd2hpY2ggaXQgaXMgcmVtb3ZlZC4gVGhlIGxpc3RlbmVyIGlzIGFkZGVkIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3RlbmVycyBhcnJheS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEV2ZW50IHBheWxvYWRzIGFyZSBkb2N1bWVudGVkIGluIHRoZSB7QGxpbmsgT3BlbkZpbi5FdmVudHN9IG5hbWVzcGFjZS5cbiAgICAgKi9cbiAgICBhc3luYyBwcmVwZW5kT25jZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZGVyZWdpc3RlciA9ICgpID0+IHRoaXMuZGVyZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zLCAoZW1pdHRlcikgPT4ge1xuICAgICAgICAgICAgZW1pdHRlci5wcmVwZW5kT25jZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5vbmNlKGV2ZW50VHlwZSwgZGVyZWdpc3Rlcik7XG4gICAgICAgIH0sIChlbWl0dGVyKSA9PiB7XG4gICAgICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICAgICAgICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihldmVudFR5cGUsIGRlcmVnaXN0ZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGxpc3RlbmVyIGZyb20gdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2F1dGlvbjogQ2FsbGluZyB0aGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSBhcnJheSBpbmRpY2VzIGluIHRoZSBsaXN0ZW5lciBhcnJheSBiZWhpbmQgdGhlIGxpc3RlbmVyLlxuICAgICAqL1xuICAgIGFzeW5jIHJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IGF3YWl0IHRoaXMuZGVyZWdpc3RlckV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGVtaXR0ZXIpIHtcbiAgICAgICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLmRlbGV0ZUVtaXR0ZXJJZk5vdGhpbmdSZWdpc3RlcmVkKGVtaXR0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBhc3luYyBkZXJlZ2lzdGVyQWxsTGlzdGVuZXJzKGV2ZW50VHlwZSkge1xuICAgICAgICBjb25zdCBydW50aW1lRXZlbnQgPSB7IC4uLnRoaXMuaWRlbnRpdHksIHR5cGU6IGV2ZW50VHlwZSwgdG9waWM6IHRoaXMudG9waWMgfTtcbiAgICAgICAgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICBjb25zdCBlbWl0dGVyID0gdGhpcy5nZXRPckNyZWF0ZUVtaXR0ZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlZkNvdW50ID0gZW1pdHRlci5saXN0ZW5lckNvdW50KHJ1bnRpbWVFdmVudC50eXBlKTtcbiAgICAgICAgICAgIGNvbnN0IHVuc3Vic2NyaWJlUHJvbWlzZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVmQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIHVuc3Vic2NyaWJlUHJvbWlzZXMucHVzaCh0aGlzLndpcmUuc2VuZEFjdGlvbigndW5zdWJzY3JpYmUtdG8tZGVza3RvcC1ldmVudCcsIHJ1bnRpbWVFdmVudCkuY2F0Y2goKCkgPT4gbnVsbCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodW5zdWJzY3JpYmVQcm9taXNlcyk7XG4gICAgICAgICAgICByZXR1cm4gZW1pdHRlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMsIG9yIHRob3NlIG9mIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICpcbiAgICAgKi9cbiAgICBhc3luYyByZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnRUeXBlKSB7XG4gICAgICAgIGNvbnN0IHJlbW92ZUJ5RXZlbnQgPSBhc3luYyAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVtaXR0ZXIgPSBhd2FpdCB0aGlzLmRlcmVnaXN0ZXJBbGxMaXN0ZW5lcnMoZXZlbnQpO1xuICAgICAgICAgICAgaWYgKGVtaXR0ZXIpIHtcbiAgICAgICAgICAgICAgICBlbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycyhldmVudCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxldGVFbWl0dGVySWZOb3RoaW5nUmVnaXN0ZXJlZChlbWl0dGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgYXdhaXQgcmVtb3ZlQnlFdmVudChldmVudFR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuaGFzRW1pdHRlcigpKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmdldE9yQ3JlYXRlRW1pdHRlcigpLmV2ZW50TmFtZXMoKTtcbiAgICAgICAgICAgIGF3YWl0ICgwLCBwcm9taXNlc18xLnByb21pc2VNYXApKGV2ZW50cywgcmVtb3ZlQnlFdmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRlbGV0ZUVtaXR0ZXJJZk5vdGhpbmdSZWdpc3RlcmVkKGVtaXR0ZXIpIHtcbiAgICAgICAgaWYgKGVtaXR0ZXIuZXZlbnROYW1lcygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy53aXJlLmV2ZW50QWdncmVnYXRvci5kZWxldGUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCRlKHRoaXMsIF9FbWl0dGVyQmFzZV9lbWl0dGVyQWNjZXNzb3IsIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5iYXNlLkVtaXR0ZXJCYXNlID0gRW1pdHRlckJhc2U7XG5fRW1pdHRlckJhc2VfZW1pdHRlckFjY2Vzc29yID0gbmV3IFdlYWtNYXAoKTtcbmNsYXNzIFJlcGx5IHtcbn1cbmJhc2UuUmVwbHkgPSBSZXBseTtcblxudmFyIHRyYW5zcG9ydEVycm9ycyA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodHJhbnNwb3J0RXJyb3JzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnRyYW5zcG9ydEVycm9ycy5SdW50aW1lRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuTm90U3VwcG9ydGVkRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuTm90SW1wbGVtZW50ZWRFcnJvciA9IHRyYW5zcG9ydEVycm9ycy5Ob0Fja0Vycm9yID0gdHJhbnNwb3J0RXJyb3JzLkR1cGxpY2F0ZUNvcnJlbGF0aW9uRXJyb3IgPSB0cmFuc3BvcnRFcnJvcnMuVW5leHBlY3RlZEFjdGlvbkVycm9yID0gdHJhbnNwb3J0RXJyb3JzLkRpc2Nvbm5lY3RlZEVycm9yID0gdm9pZCAwO1xuY2xhc3MgRGlzY29ubmVjdGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgY29uc3RydWN0b3IocmVhZHlTdGF0ZSkge1xuICAgICAgICBzdXBlcihgRXhwZWN0ZWQgd2Vic29ja2V0IHN0YXRlIE9QRU4gYnV0IGZvdW5kICR7cmVhZHlTdGF0ZX1gKTtcbiAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gcmVhZHlTdGF0ZTtcbiAgICB9XG59XG50cmFuc3BvcnRFcnJvcnMuRGlzY29ubmVjdGVkRXJyb3IgPSBEaXNjb25uZWN0ZWRFcnJvcjtcbmNsYXNzIFVuZXhwZWN0ZWRBY3Rpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5VbmV4cGVjdGVkQWN0aW9uRXJyb3IgPSBVbmV4cGVjdGVkQWN0aW9uRXJyb3I7XG5jbGFzcyBEdXBsaWNhdGVDb3JyZWxhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxudHJhbnNwb3J0RXJyb3JzLkR1cGxpY2F0ZUNvcnJlbGF0aW9uRXJyb3IgPSBEdXBsaWNhdGVDb3JyZWxhdGlvbkVycm9yO1xuY2xhc3MgTm9BY2tFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5Ob0Fja0Vycm9yID0gTm9BY2tFcnJvcjtcbmNsYXNzIE5vdEltcGxlbWVudGVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG50cmFuc3BvcnRFcnJvcnMuTm90SW1wbGVtZW50ZWRFcnJvciA9IE5vdEltcGxlbWVudGVkRXJyb3I7XG5jbGFzcyBOb3RTdXBwb3J0ZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbnRyYW5zcG9ydEVycm9ycy5Ob3RTdXBwb3J0ZWRFcnJvciA9IE5vdFN1cHBvcnRlZEVycm9yO1xuY2xhc3MgSW50ZXJuYWxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihlcnIpIHtcbiAgICAgICAgY29uc3QgeyBtZXNzYWdlLCBuYW1lLCBzdGFjaywgLi4ucmVzdCB9ID0gZXJyO1xuICAgICAgICBzdXBlcihtZXNzYWdlKTtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZSB8fCAnRXJyb3InO1xuICAgICAgICB0aGlzLnN0YWNrID0gc3RhY2sgPz8gdGhpcy50b1N0cmluZygpO1xuICAgICAgICBPYmplY3Qua2V5cyhyZXN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSByZXN0W2tleV07XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vIEZvciBkb2N1bWVudGF0aW9uIG9mIHRoZSBlcnJvciBtZXRob2RzIGJlaW5nIHVzZWQgc2VlIGhlcmU6IGh0dHBzOi8vdjguZGV2L2RvY3Mvc3RhY2stdHJhY2UtYXBpXG5jbGFzcyBSdW50aW1lRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgc3RhdGljIGdldENhbGxTaXRlKGNhbGxzVG9SZW1vdmUgPSAwKSB7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IEVycm9yLnN0YWNrVHJhY2VMaW1pdDtcbiAgICAgICAgY29uc3QgcmVhbENhbGxzVG9SZW1vdmUgPSBjYWxsc1RvUmVtb3ZlICsgMTsgLy8gcmVtb3ZlIHRoaXMgY2FsbDtcbiAgICAgICAgRXJyb3Iuc3RhY2tUcmFjZUxpbWl0ID0gbGVuZ3RoICsgcmVhbENhbGxzVG9SZW1vdmU7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgICAgICBjb25zdCBfcHJlcGFyZVN0YWNrVHJhY2UgPSBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZTtcbiAgICAgICAgLy8gVGhpcyB3aWxsIGJlIGNhbGxlZCB3aGVuIHdlIGFjY2VzcyB0aGUgYHN0YWNrYCBwcm9wZXJ0eVxuICAgICAgICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IChfLCBzdGFjaykgPT4gc3RhY2s7XG4gICAgICAgIC8vIHN0YWNrIGlzIG9wdGlvbmFsIGluIG5vbiBjaHJvbWl1bSBjb250ZXh0c1xuICAgICAgICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrPy5zbGljZShyZWFsQ2FsbHNUb1JlbW92ZSkgPz8gW107XG4gICAgICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gX3ByZXBhcmVTdGFja1RyYWNlO1xuICAgICAgICBFcnJvci5zdGFja1RyYWNlTGltaXQgPSBsZW5ndGg7XG4gICAgICAgIHJldHVybiBzdGFjaztcbiAgICB9XG4gICAgc3RhdGljIHByZXBhcmVTdGFja1RyYWNlKGVyciwgY2FsbFNpdGVzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZShlcnIsIGNhbGxTaXRlcyk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0cmluZyA9IFwiXCI7XG4gICAgICAgIHN0cmluZyArPSBlcnIubmFtZSB8fCBcIkVycm9yXCI7XG4gICAgICAgIHN0cmluZyArPSBgOiAke2Vyci5tZXNzYWdlIHx8IFwiXCJ9YDtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsU2l0ZSBvZiBjYWxsU2l0ZXMpIHtcbiAgICAgICAgICAgIHN0cmluZyArPSBgXFxuICAgIGF0ICR7Y2FsbFNpdGUudG9TdHJpbmcoKX1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgfVxuICAgIDtcbiAgICBjb25zdHJ1Y3RvcihwYXlsb2FkLCBjYWxsU2l0ZXMpIHtcbiAgICAgICAgY29uc3QgeyByZWFzb24sIGVycm9yIH0gPSBwYXlsb2FkO1xuICAgICAgICBzdXBlcihyZWFzb24pO1xuICAgICAgICB0aGlzLm5hbWUgPSAnUnVudGltZUVycm9yJztcbiAgICAgICAgaWYgKGVycm9yPy5zdGFjaykge1xuICAgICAgICAgICAgdGhpcy5jYXVzZSA9IG5ldyBJbnRlcm5hbEVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsbFNpdGVzKSB7XG4gICAgICAgICAgICB0aGlzLnN0YWNrID0gUnVudGltZUVycm9yLnByZXBhcmVTdGFja1RyYWNlKHRoaXMsIGNhbGxTaXRlcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG50cmFuc3BvcnRFcnJvcnMuUnVudGltZUVycm9yID0gUnVudGltZUVycm9yO1xuXG52YXIgd2luZG93JDEgPSB7fTtcblxudmFyIEZhY3RvcnkkOCA9IHt9O1xuXG52YXIgdmFsaWRhdGUgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkYXRlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhbGlkYXRlLnZhbGlkYXRlSWRlbnRpdHkgPSB2b2lkIDA7XG5mdW5jdGlvbiB2YWxpZGF0ZUlkZW50aXR5KGlkZW50aXR5KSB7XG4gICAgbGV0IGVycm9yTXNnO1xuICAgIGlmICh0eXBlb2YgaWRlbnRpdHkgIT09ICdvYmplY3QnIHx8IHR5cGVvZiBpZGVudGl0eS51dWlkICE9PSAnc3RyaW5nJykge1xuICAgICAgICBlcnJvck1zZyA9ICdOb3QgYSB2YWxpZCBpZGVudGl0eSBvYmplY3QnO1xuICAgIH1cbiAgICByZXR1cm4gZXJyb3JNc2c7XG59XG52YWxpZGF0ZS52YWxpZGF0ZUlkZW50aXR5ID0gdmFsaWRhdGVJZGVudGl0eTtcblxudmFyIEluc3RhbmNlJDcgPSB7fTtcblxudmFyIGFwcGxpY2F0aW9uID0ge307XG5cbnZhciBGYWN0b3J5JDcgPSB7fTtcblxudmFyIEluc3RhbmNlJDYgPSB7fTtcblxudmFyIHZpZXcgPSB7fTtcblxudmFyIEZhY3RvcnkkNiA9IHt9O1xuXG52YXIgd2FybmluZ3MgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHdhcm5pbmdzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbndhcm5pbmdzLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IHZvaWQgMDtcbmNvbnN0IGhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IChvcHRpb25zKSA9PiB7XG4gICAgaWYgKG9wdGlvbnMuY29udGVudE5hdmlnYXRpb24/LndoaXRlbGlzdCB8fFxuICAgICAgICBvcHRpb25zLmNvbnRlbnROYXZpZ2F0aW9uPy5ibGFja2xpc3QgfHxcbiAgICAgICAgb3B0aW9ucy5jb250ZW50UmVkaXJlY3Q/LndoaXRlbGlzdCB8fFxuICAgICAgICBvcHRpb25zLmNvbnRlbnRSZWRpcmVjdD8uYmxhY2tsaXN0KSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgVGhlIHByb3BlcnRpZXMgJ3doaXRlbGlzdCcgYW5kICdibGFja2xpc3QnIGhhdmUgYmVlbiBtYXJrZWQgYXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uIFBsZWFzZSB1c2UgJ2FsbG93bGlzdCcgYW5kICdkZW55bGlzdCcuYCk7XG4gICAgfVxufTtcbndhcm5pbmdzLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncyA9IGhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncztcblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeSQzO1xuXG5mdW5jdGlvbiByZXF1aXJlRmFjdG9yeSQzICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkRmFjdG9yeSQzKSByZXR1cm4gRmFjdG9yeSQ2O1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkkMyA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDYsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDYuVmlld01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgYmFzZV8xID0gYmFzZTtcblx0Y29uc3QgdmFsaWRhdGVfMSA9IHZhbGlkYXRlO1xuXHRjb25zdCBpbmRleF8xID0gcmVxdWlyZVZpZXcoKTtcblx0Y29uc3Qgd2FybmluZ3NfMSA9IHdhcm5pbmdzO1xuXHQvKipcblx0ICogU3RhdGljIG5hbWVzcGFjZSBmb3IgT3BlbkZpbiBBUEkgbWV0aG9kcyB0aGF0IGludGVyYWN0IHdpdGggdGhlIHtAbGluayBWaWV3fSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uVmlld2AuXG5cdCAqL1xuXHRjbGFzcyBWaWV3TW9kdWxlIGV4dGVuZHMgYmFzZV8xLkJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBDcmVhdGVzIGEgbmV3IFZpZXcuXG5cdCAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIFZpZXcgY3JlYXRpb24gb3B0aW9uc1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogbGV0IHZpZXc7XG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICogICAgIGNvbnN0IG1lID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUNyZWF0ZScsXG5cdCAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjcmVhdGVWaWV3KClcblx0ICAgICAqICAgICAudGhlbigoY3JlYXRlZFZpZXcpID0+IHtcblx0ICAgICAqICAgICAgICAgdmlldyA9IGNyZWF0ZWRWaWV3O1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZygnVmlldyBjcmVhdGVkLicsIHZpZXcpO1xuXHQgICAgICogICAgICAgICB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIE5vdGUgdGhhdCBjcmVhdGVkIHZpZXdzIG5lZWRzIHRvIG5hdmlnYXRlIHNvbWV3aGVyZSBmb3IgdGhlbSB0byBhY3R1YWxseSByZW5kZXIgYSB3ZWJzaXRlLlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjcmVhdGUob3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IHsgdXVpZCB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIGlmICghb3B0aW9ucy5uYW1lIHx8IHR5cGVvZiBvcHRpb25zLm5hbWUgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgYSBuYW1lIHByb3BlcnR5IGFzIGEgc3RyaW5nIGluIG9yZGVyIHRvIGNyZWF0ZSBhIFZpZXcuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgICgwLCB3YXJuaW5nc18xLmhhbmRsZURlcHJlY2F0ZWRXYXJuaW5ncykob3B0aW9ucyk7XG5cdCAgICAgICAgaWYgKHRoaXMud2lyZS5lbnZpcm9ubWVudC5jaGlsZFZpZXdzKSB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5jcmVhdGVDaGlsZENvbnRlbnQoe1xuXHQgICAgICAgICAgICAgICAgZW50aXR5VHlwZTogJ3ZpZXcnLFxuXHQgICAgICAgICAgICAgICAgb3B0aW9uczogeyAuLi5vcHRpb25zLCB1dWlkIH1cblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLXZpZXcnLCB7IC4uLm9wdGlvbnMsIHV1aWQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLndyYXBTeW5jKHsgdXVpZCwgbmFtZTogb3B0aW9ucy5uYW1lIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBWaWV3IGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGEgVmlldyBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuXHQgICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuXHQgICAgICogZm9yIGEgVmlldyB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlZpZXcud3JhcCh7IHV1aWQ6ICd0ZXN0Vmlld1V1aWQnLCBuYW1lOiAndGVzdFZpZXdOYW1lJyB9KSlcblx0ICAgICAqICAgICAudGhlbih2aWV3ID0+IGNvbnNvbGUubG9nKCd3cmFwcGVkIHZpZXcnLCB2aWV3KSlcblx0ICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHdyYXAoaWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigndmlldy13cmFwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMS52YWxpZGF0ZUlkZW50aXR5KShpZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGVycm9yTXNnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgaW5kZXhfMS5WaWV3KHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIFZpZXcgaWRlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBWaWV3IGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYSBWaWV3IHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcud3JhcFN5bmMoeyB1dWlkOiAndGVzdFZpZXcnLCBuYW1lOiAndGVzdFZpZXdOYW1lJyB9KTtcblx0ICAgICAqIGF3YWl0IHZpZXcuaGlkZSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMS52YWxpZGF0ZUlkZW50aXR5KShpZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGVycm9yTXNnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBuZXcgaW5kZXhfMS5WaWV3KHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgVmlldyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5WaWV3LmdldEN1cnJlbnQoKVxuXHQgICAgICogICAgIC50aGVuKHZpZXcgPT4gY29uc29sZS5sb2coJ2N1cnJlbnQgdmlldycsIHZpZXcpKVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnQoKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctZ2V0LWN1cnJlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoIXRoaXMud2lyZS5tZS5pc1ZpZXcpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFZpZXcgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwKHsgdXVpZCwgbmFtZSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgVmlldyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogY29uc29sZS5sb2codmlldyk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd2aWV3LWdldC1jdXJyZW50LXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAoIXRoaXMud2lyZS5tZS5pc1ZpZXcpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFZpZXcgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQ2LlZpZXdNb2R1bGUgPSBWaWV3TW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQ2O1xufVxuXG52YXIgSW5zdGFuY2UkNSA9IHt9O1xuXG52YXIgbGF6eSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5sYXp5LkFzeW5jUmV0cnlhYmxlTGF6eSA9IGxhenkuTGF6eSA9IHZvaWQgMDtcbi8qKlxuICogSGFuZHkgY2xhc3MgZm9yIG1hbmFnaW5nIGFzeW5jaHJvbm91cyBkZXBlbmRlbmNpZXMgb2YgY2xhc3Nlcy5cbiAqXG4gKiBXaWxsIGNhbGwgdGhlIHByb2R1Y2VyIGZ1bmN0aW9uIG9uY2UgYW5kIG9ubHkgb25jZSB3aGVuIGdldFZhbHVlIGlzIGNhbGxlZCxcbiAqIHJldHVybmluZyB0aGUgcmVzdWx0YW50IHZhbHVlIGZvciBldmVyeSBzdWJzZXF1ZW50IGNhbGwuXG4gKi9cbmNsYXNzIExhenkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHByb2R1Y2VyRm4pIHtcbiAgICAgICAgdGhpcy5wcm9kdWNlckZuID0gcHJvZHVjZXJGbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF6aWx5IGdldCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIHByb2R1Y2VyLlxuICAgICAqIEByZXR1cm5zIFRoZSB2YWx1ZSByZXR1cm5lZCBmcm9tIHRoZSBwcm9kdWNlciBmdW5jdGlvblxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBpZiAoIXRoaXMudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnByb2R1Y2VyRm4oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG59XG5sYXp5LkxhenkgPSBMYXp5O1xuLyoqXG4gKiBIYW5keSBjbGFzcyBmb3IgbWFuYWdpbmcgYXN5bmNocm9ub3VzIGRlcGVuZGVuY2llcyBvZiBjbGFzc2VzLlxuICpcbiAqIFdpbGwgY2FsbCBhc3luY2hyb25vdXMgcHJvZHVjZXIgb25seSBhZnRlciBgZ2V0VmFsdWVgIGlzIGNhbGxlZC4gIElmIHRoZVxuICogZGVmZXJyZWQgY29kZSBlcnJvcnMsIHdlIGNhbiB0cnkgaXQgYWdhaW4gYnkgcmUtY2FsbGluZyBgZ2V0VmFsdWVgIGFmdGVyXG4gKiB0aGUgcHJvbWlzZSByZWplY3RzLlxuICovXG5jbGFzcyBBc3luY1JldHJ5YWJsZUxhenkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHByb2R1Y2VyRm4pIHtcbiAgICAgICAgdGhpcy5wcm9kdWNlckZuID0gcHJvZHVjZXJGbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF6aWx5IGdldCB0aGUgdmFsdWUgcmV0dXJuZWQgYnkgdGhlIGFzeW5jIHByb2R1Y2VyLlxuICAgICAqXG4gICAgICogQHJldHVybnMgVGhlIHZhbHVlIHJldHVybmVkIGZyb20gdGhlIHByb2R1Y2VyIGZ1bmN0aW9uXG4gICAgICovXG4gICAgYXN5bmMgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9taXNlKSB7XG4gICAgICAgICAgICB0aGlzLnByb21pc2UgPSB0aGlzLnByb2R1Y2VyRm4oKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnByb21pc2U7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XG4gICAgfVxufVxubGF6eS5Bc3luY1JldHJ5YWJsZUxhenkgPSBBc3luY1JldHJ5YWJsZUxhenk7XG5cbnZhciBsYXlvdXRFbnRpdGllcyA9IHt9O1xuXG52YXIgYXBpRXhwb3NlciQxID0ge307XG5cbnZhciBhcGlDb25zdW1lciA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoYXBpQ29uc3VtZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuYXBpQ29uc3VtZXIuQXBpQ29uc3VtZXIgPSB2b2lkIDA7XG4vKipcbiAqIENvbnN1bWVyIGZvciBhcGlzIGV4cG9zZWQgd2l0aCB7QHNlZSBBcGlFeHBvc2VyfS5cbiAqXG4gKiBBIHN0cmF0ZWd5IHRoYXQgbWF0Y2hlcyB0aGUgc3RyYXRlZ3kgdXNlZCB0byBleHBvc2UgYSB0YXJnZXQgQVBJIG11c3QgYmUgcHJvdmlkZWQuXG4gKi9cbmNsYXNzIEFwaUNvbnN1bWVyIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBjb25zdHJ1Y3RvcihzdHJhdGVneSkge1xuICAgICAgICB0aGlzLnN0cmF0ZWd5ID0gc3RyYXRlZ3k7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdW1lcyBhbiBhcGkgZXhwb3NlZCB1c2luZyBhIGdpdmVuIHRyYW5zcG9ydCBzdHJhdGVneSwgYW5kIGdlbmVyYXRlcyBhIGNsaWVudFxuICAgICAgICAgKiBmb3IgZWFzeSwgdHlwZSBzYWZlIGNvbnN1bXB0aW9uIG9mIHRoYXQgY2xpZW50LlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBTdHJhdGVneSBzcGVjaWZpYyBjb25zdW1wdGlvbiBvcHRpb25zLlxuICAgICAgICAgKiBAcmV0dXJucyBBbiBhcGkgY2xpZW50IG1hdGNoaW5nIHRoZSBnaXZlbiB0eXBlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb25zdW1lID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV4cG9zZWRQcm9wZXJ0aWVzID0gYXdhaXQgdGhpcy5zdHJhdGVneS5nZXRFeHBvc2VkRnVuY3Rpb25zKG9wdGlvbnMpO1xuICAgICAgICAgICAgcmV0dXJuIGV4cG9zZWRQcm9wZXJ0aWVzLnJlZHVjZSgoY2xpZW50LCBwcm9wKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLmNsaWVudCxcbiAgICAgICAgICAgICAgICBbcHJvcC5rZXldOiB0aGlzLnN0cmF0ZWd5LmNyZWF0ZUZ1bmN0aW9uKHByb3AsIG9wdGlvbnMpXG4gICAgICAgICAgICB9KSwge30pO1xuICAgICAgICB9O1xuICAgIH1cbn1cbmFwaUNvbnN1bWVyLkFwaUNvbnN1bWVyID0gQXBpQ29uc3VtZXI7XG5cbnZhciBhcGlFeHBvc2VyID0ge307XG5cbnZhciBkZWNvcmF0b3JzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShkZWNvcmF0b3JzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmRlY29yYXRvcnMuZXhwb3NlID0gZGVjb3JhdG9ycy5nZXRFeHBvc2VkUHJvcGVydGllcyA9IHZvaWQgMDtcbmNvbnN0IGV4cG9zZWRQcm9wZXJ0aWVzID0gU3ltYm9sKCdleHBvc2VkUHJvcGVydGllcycpO1xuY29uc3QgZ2V0RXhwb3NlZFByb3BlcnRpZXMgPSAodGFyZ2V0KSA9PiB7XG4gICAgcmV0dXJuIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10gfHwgdGFyZ2V0LnByb3RvdHlwZVtleHBvc2VkUHJvcGVydGllc10gfHwgW107XG59O1xuZGVjb3JhdG9ycy5nZXRFeHBvc2VkUHJvcGVydGllcyA9IGdldEV4cG9zZWRQcm9wZXJ0aWVzO1xuLyoqXG4gKiBJbmRpY2F0ZXMgdGhhdCBhIGNsYXNzIG1lbWJlciBmdW5jdGlvbiBjYW4gYmUgZXhwb3NlZCB1c2luZyB7QGxpbmsgQXBpRXhwb3Nlcn0uXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIHNwZWNpZmljIHRvIHRoZSBzdHJhdGVneSB1c2VkIGluIHtAbGluayBBcGlFeHBvc2VyfVxuICovXG4vLyBSZXR1cm5zIGFueSBhcyBkZWNvcmF0b3IgdHlwaW5nIGlzIHdlaXJkLlxuY29uc3QgZXhwb3NlID0gKG9wdGlvbnMpID0+ICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikgPT4ge1xuICAgIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10gPSB0YXJnZXRbZXhwb3NlZFByb3BlcnRpZXNdIHx8IFtdO1xuICAgIHRhcmdldFtleHBvc2VkUHJvcGVydGllc10ucHVzaCh7IGtleSwgZGVzY3JpcHRvciwgb3B0aW9ucyB9KTtcbn07XG5kZWNvcmF0b3JzLmV4cG9zZSA9IGV4cG9zZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGFwaUV4cG9zZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuYXBpRXhwb3Nlci5BcGlFeHBvc2VyID0gdm9pZCAwO1xuY29uc3QgZGVjb3JhdG9yc18xID0gZGVjb3JhdG9ycztcbi8qKlxuICogRXhwb3NlcyBhcGkgc2VydmljZXMgb24gdGhlIHRyYW5zcG9ydCBvZiBjaG9pY2UuXG4gKi9cbmNsYXNzIEFwaUV4cG9zZXIge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBzdHJhdGVneSBUaGUgZXhwb3NlIHN0cmF0ZWd5IHRvIHVzZSB0byBleHBvc2UgaW5zdGFuY2VzLlxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKHN0cmF0ZWd5KSB7XG4gICAgICAgIHRoaXMuc3RyYXRlZ3kgPSBzdHJhdGVneTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV4cG9zZXMgYW4gaW5zdGFuY2Ugb2YgYSBnaXZlbiBhcGkgb25cbiAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIEluc3RhbmNlIG9mIGEgY2xhc3Mgd2hpY2ggaGFzIGJlZW4gZGVjb3JhdGVkIHRvIGluZGljYXRlIHdoaWNoIGZ1bmN0aW9ucyBjYW4gYmUgZXhwb3NlZC5cbiAgICAgICAgICogQHBhcmFtIGluc3RhbmNlT3B0aW9ucyBUcmFuc3BvcnQgc3RyYXRlZ3kgc3BlY2lmaWMgb3B0aW9ucyB0byB1c2Ugd2hlbiBleHBvc2luZy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXhwb3NlSW5zdGFuY2UgPSBhc3luYyAoaW5zdGFuY2UsIGluc3RhbmNlT3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhwb3NhYmxlUHJvcHMgPSAoMCwgZGVjb3JhdG9yc18xLmdldEV4cG9zZWRQcm9wZXJ0aWVzKShpbnN0YW5jZSk7XG4gICAgICAgICAgICBjb25zdCBleHBvc2VkUHJvcHMgPSBhd2FpdCBQcm9taXNlLmFsbChleHBvc2FibGVQcm9wcy5tYXAoYXN5bmMgKHsga2V5LCBvcHRpb25zIH0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXN0b21Db25zdW1wdGlvbk9wdGlvbnMgPSBhd2FpdCB0aGlzLnN0cmF0ZWd5LmV4cG9zZUZ1bmN0aW9uKGluc3RhbmNlW2tleV0uYmluZChpbnN0YW5jZSksIHtcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBtZXRhOiBpbnN0YW5jZU9wdGlvbnNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IGN1c3RvbUNvbnN1bXB0aW9uT3B0aW9uc1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnN0cmF0ZWd5LmV4cG9zZU1ldGEoaW5zdGFuY2VPcHRpb25zLCBleHBvc2VkUHJvcHMpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICA7XG59XG5hcGlFeHBvc2VyLkFwaUV4cG9zZXIgPSBBcGlFeHBvc2VyO1xuXG52YXIgc3RyYXRlZ2llcyA9IHt9O1xuXG52YXIgb3BlbmZpbkNoYW5uZWxzID0ge307XG5cbnZhciBjaGFubmVsc0NvbnN1bWVyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsc0NvbnN1bWVyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWxzQ29uc3VtZXIuQ2hhbm5lbHNDb25zdW1lciA9IHZvaWQgMDtcbmNsYXNzIENoYW5uZWxzQ29uc3VtZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIGNvbnN0cnVjdG9yKGNoYW5uZWwpIHtcbiAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcbiAgICAgICAgdGhpcy5nZXRFeHBvc2VkRnVuY3Rpb25zID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgaWQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHByb3BzIH0gPSBhd2FpdCB0aGlzLmNoYW5uZWwuZGlzcGF0Y2goYGFwaS1tZXRhOiR7aWR9YCk7XG4gICAgICAgICAgICByZXR1cm4gcHJvcHM7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY3JlYXRlRnVuY3Rpb24gPSAocHJvcCkgPT4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgYWN0aW9uIH0gPSBwcm9wLm9wdGlvbnM7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jaGFubmVsLmRpc3BhdGNoKGFjdGlvbiwgeyBhcmdzIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICA7XG59XG5jaGFubmVsc0NvbnN1bWVyLkNoYW5uZWxzQ29uc3VtZXIgPSBDaGFubmVsc0NvbnN1bWVyO1xuXG52YXIgY2hhbm5lbHNFeHBvc2VyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsc0V4cG9zZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY2hhbm5lbHNFeHBvc2VyLkNoYW5uZWxzRXhwb3NlciA9IHZvaWQgMDtcbmNsYXNzIENoYW5uZWxzRXhwb3NlciB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgY29uc3RydWN0b3IoY2hhbm5lbFByb3ZpZGVyT3JDbGllbnQpIHtcbiAgICAgICAgdGhpcy5jaGFubmVsUHJvdmlkZXJPckNsaWVudCA9IGNoYW5uZWxQcm92aWRlck9yQ2xpZW50O1xuICAgICAgICB0aGlzLmV4cG9zZUZ1bmN0aW9uID0gYXN5bmMgKHRhcmdldCwgY29uZmlnKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGtleSwgb3B0aW9ucywgbWV0YSB9ID0gY29uZmlnO1xuICAgICAgICAgICAgY29uc3QgeyBpZCB9ID0gbWV0YTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGAke2lkfS4ke29wdGlvbnM/LmFjdGlvbiB8fCBrZXl9YDtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2hhbm5lbFByb3ZpZGVyT3JDbGllbnQucmVnaXN0ZXIoYWN0aW9uLCBhc3luYyAoeyBhcmdzIH0pID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0KC4uLmFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4geyBhY3Rpb24gfTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5leHBvc2VNZXRhID0gYXN5bmMgKHsgaWQgfSwgcHJvcHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9IGBhcGktbWV0YToke2lkfWA7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNoYW5uZWxQcm92aWRlck9yQ2xpZW50LnJlZ2lzdGVyKGFjdGlvbiwgKCkgPT4gKHsgcHJvcHMgfSkpO1xuICAgICAgICB9O1xuICAgIH1cbn1cbmNoYW5uZWxzRXhwb3Nlci5DaGFubmVsc0V4cG9zZXIgPSBDaGFubmVsc0V4cG9zZXI7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRfX2V4cG9ydFN0YXIoY2hhbm5lbHNDb25zdW1lciwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihjaGFubmVsc0V4cG9zZXIsIGV4cG9ydHMpOyBcbn0gKG9wZW5maW5DaGFubmVscykpO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKG9wZW5maW5DaGFubmVscywgZXhwb3J0cyk7IFxufSAoc3RyYXRlZ2llcykpO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKGFwaUNvbnN1bWVyLCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKGFwaUV4cG9zZXIsIGV4cG9ydHMpO1xuXHRfX2V4cG9ydFN0YXIoc3RyYXRlZ2llcywgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihkZWNvcmF0b3JzLCBleHBvcnRzKTsgXG59IChhcGlFeHBvc2VyJDEpKTtcblxudmFyIGNoYW5uZWxBcGlSZWxheSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbEFwaVJlbGF5LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWxBcGlSZWxheS5jcmVhdGVSZWxheWVkRGlzcGF0Y2ggPSBjaGFubmVsQXBpUmVsYXkucmVsYXlDaGFubmVsQ2xpZW50QXBpID0gdm9pZCAwO1xuY29uc3QgRVhQRUNURURfRVJST1JTID0gW1xuICAgICdubyBsb25nZXIgY29ubmVjdGVkJyxcbiAgICAnUlRDRGF0YUNoYW5uZWwgY2xvc2VkIHVuZXhwZWN0ZWRseScsXG4gICAgJ1RoZSBjbGllbnQgeW91IGFyZSB0cnlpbmcgdG8gZGlzcGF0Y2ggZnJvbSBpcyBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgdGFyZ2V0IHByb3ZpZGVyJyxcbl07XG4vLyBDaGVja3MgcG9zc2libGUgZXJyb3IgbWVzc2FnZXMgdGhhdCB3ZSB3YW50IHRvIHRyYXAsIGNsaWVudCBlcnJvciBtZXNzYWdlIGNhbiBvcmlnaW5hdGVcbi8vIGZyb20gQ2hhbm5lbFByb3ZpZGVyOjpkaXNwYXRjaCBPUiBDbGFzc2ljU3RyYXRlZ3k6OmNsb3NlRW5kcG9pbnQgT1IgUlRDRW5kUG9pbnQ6OmRhdGFDaGFubmVsOjpvbmNsb3NlXG5jb25zdCBpc0Rpc2Nvbm5lY3RlZEVycm9yID0gKGVycm9yTXNnKSA9PiB7XG4gICAgcmV0dXJuIEVYUEVDVEVEX0VSUk9SUy5zb21lKGUgPT4gZXJyb3JNc2cuaW5jbHVkZXMoZSkpO1xufTtcbi8qKlxuICogQGludGVybmFsXG4gKiBDcmVhdGUgYSBjaGFubmVsIHJlbGF5IGZvciBhIGdpdmVuIGNoYW5uZWwgZXhwb3NpdGlvbiwgYWxsb3dpbmcgYSBzaW5nbGUgcHJvdmlkZXIgdG8gcm91dGVcbiAqIGFjdGlvbnMgdG8gdGhlIGRlc2lnbmF0ZWQgY2xpZW50cy5cbiAqXG4gKiBEZXNpZ25lZCB0byBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggQGV4cG9zZVxuICpcbiAqIEBwYXJhbSBjaGFubmVsUHJvdmlkZXIgVGhlIGNoYW5uZWwgcHJvdmlkZXIgdG8gcmVsYXkgdGhlIGFjdGlvbnMgb24uXG4gKiBAcGFyYW0gY29uZmlnIERldGVybWluZXMgd2hpY2ggYWN0aW9ucyB0byByZWxheS4gUGxlYXNlIGVuc3VyZSBhY3Rpb24gcHJlZml4IG1hdGNoZXMgdGhlIGV4cG9zZWQgYXBpLlxuICovXG5jb25zdCByZWxheUNoYW5uZWxDbGllbnRBcGkgPSBhc3luYyAoY2hhbm5lbFByb3ZpZGVyLCByZWxheUlkKSA9PiB7XG4gICAgY2hhbm5lbFByb3ZpZGVyLnJlZ2lzdGVyKGByZWxheToke3JlbGF5SWR9YCwgKHsgYWN0aW9uLCB0YXJnZXQsIHBheWxvYWQgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY2hhbm5lbFByb3ZpZGVyLmRpc3BhdGNoKHRhcmdldCwgYWN0aW9uLCBwYXlsb2FkKTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5jaGFubmVsQXBpUmVsYXkucmVsYXlDaGFubmVsQ2xpZW50QXBpID0gcmVsYXlDaGFubmVsQ2xpZW50QXBpO1xuY29uc3QgY3JlYXRlUmVsYXllZERpc3BhdGNoID0gKGNsaWVudCwgdGFyZ2V0LCByZWxheUlkLCByZWxheUVycm9yTXNnKSA9PiBhc3luYyAoYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNsaWVudC5kaXNwYXRjaChgcmVsYXk6JHtyZWxheUlkfWAsIHtcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICB0YXJnZXRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc0Rpc2Nvbm5lY3RlZEVycm9yKGUubWVzc2FnZSkgJiYgcmVsYXlFcnJvck1zZykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlbGF5RXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgfVxufTtcbmNoYW5uZWxBcGlSZWxheS5jcmVhdGVSZWxheWVkRGlzcGF0Y2ggPSBjcmVhdGVSZWxheWVkRGlzcGF0Y2g7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JGIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9MYXlvdXROb2RlX2NsaWVudCwgX1RhYlN0YWNrX2NsaWVudCwgX0NvbHVtbk9yUm93X2NsaWVudDtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShsYXlvdXRFbnRpdGllcywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5sYXlvdXRFbnRpdGllcy5Db2x1bW5PclJvdyA9IGxheW91dEVudGl0aWVzLlRhYlN0YWNrID0gbGF5b3V0RW50aXRpZXMuTGF5b3V0Tm9kZSA9IHZvaWQgMDtcbmNvbnN0IGFwaV9leHBvc2VyXzEgPSBhcGlFeHBvc2VyJDE7XG5jb25zdCBjaGFubmVsX2FwaV9yZWxheV8xID0gY2hhbm5lbEFwaVJlbGF5O1xuLypcbiAgICBUaGlzIGZpbGUgaW5jbHVkZXMgTGF5b3V0Tm9kZSwgQ29sdW1uT3JSb3cgYW5kIFRhYlN0YWNrIGNsYXNzZXMsIHdoaWNoIGFyZSBhbGwgY2xvc2VseVxuICAgIGludGVydHdpbmVkLCBhbmQgc2hhcmUgbWVtYmVycyB2aWEgcGFyZW50IGFic3RyYWN0IGNsYXNzIExheW91dE5vZGUuIFRvIHByZXZlbnQgY2lyY3VsYXJcbiAgICByZWZzLCB3ZSBkZWZpbmUgYW5kIGV4cG9ydCBhbGwgdGhlIGNsYXNzZXMgaGVyZS5cbiovXG4vKipcbiAqIEBpZ25vcmVcbiAqIEBpbnRlcm5hbFxuICogU3VwcGxpZXMgYW4gQXBpQ2xpZW50IGZvciB7QGxpbmsgTGF5b3V0RW50aXRpZXNDb250cm9sbGVyfSBhbmQgaGVscGVyIG1ldGhvZHNcbiAqIGZvciB0aGUgZW50aXRpZXMge0BsaW5rIFRhYlN0YWNrfSBBTkQge0BsaW5rIENvbHVtbk9yUm93fSB0byB1c2UuXG4gKi9cbmNsYXNzIExheW91dE5vZGUge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjbGllbnQsIGVudGl0eUlkKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAaWdub3JlXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBBcGlDbGllbnQgZm9yIHtAbGluayBMYXlvdXRFbnRpdGllc0NvbnRyb2xsZXJ9XG4gICAgICAgICAqL1xuICAgICAgICBfTGF5b3V0Tm9kZV9jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgdGhlIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93IGlzIHRoZSByb290IGNvbnRlbnQgaXRlbVxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBpc1Jvb3QgPSBhd2FpdCBzdGFjay5pc1Jvb3QoKTtcbiAgICAgICAgICogLy8gVGhlIFRhYlN0YWNrIGlzIHJvb3Q6IGZhbHNlXG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgVGFiU3RhY2sgaXMgcm9vdDogJHtpc1Jvb3R9YCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIFJldHJpZXZlcyB0aGUgcGFyZW50IENvbHVtbk9yUm93XG4gICAgICAgICAqIGNvbnN0IHBhcmVudCA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBjb25zdCBwYXJlbnRJc1Jvb3QgPSBhd2FpdCBwYXJlbnQuaXNSb290KCk7XG4gICAgICAgICAqIC8vIFRoZSBwYXJlbnQgQ29sdW1uT3JSb3cgaXMgcm9vdDogdHJ1ZVxuICAgICAgICAgKiBjb25zb2xlLmxvZyhgVGhlIHBhcmVudCBDb2x1bW5PclJvdyBpcyByb290OiAke3BhcmVudElzUm9vdH1gKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzUm9vdCA9ICgpID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5pc1Jvb3QodGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDaGVja3MgaWYgdGhlIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93IGV4aXN0c1xuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiAvLyBSZXRyaWV2ZXMgdGhlIHBhcmVudCBDb2x1bW5PclJvd1xuICAgICAgICAgKiBjb25zdCBjb2x1bW5PclJvdyA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBsZXQgZXhpc3RzID0gYXdhaXQgc3RhY2suZXhpc3RzKCk7XG4gICAgICAgICAqIC8vIG9yXG4gICAgICAgICAqIGxldCBleGlzdHMgPSBhd2FpdCBjb2x1bW5PclJvdy5leGlzdHMoKTtcbiAgICAgICAgICogLy8gVGhlIGVudGl0eSBleGlzdHM6IHRydWVcbiAgICAgICAgICogY29uc29sZS5sb2coYFRoZSBlbnRpdHkgZXhpc3RzOiAke2V4aXN0c31gKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmV4aXN0cyA9ICgpID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5leGlzdHModGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIHBhcmVudCBvZiB0aGUgVGFiU3RhY2sgb3IgQ29sdW1uT3JSb3dcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogaWYgKCFmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluIGEgcGxhdGZvcm0gVmlldy4nKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKlxuICAgICAgICAgKiBjb25zdCBzdGFjayA9IGF3YWl0IGZpbi5tZS5nZXRDdXJyZW50U3RhY2soKTtcbiAgICAgICAgICogLy8gUmV0cmlldmVzIHRoZSBwYXJlbnQgQ29sdW1uT3JSb3dcbiAgICAgICAgICogY29uc3QgY29sdW1uT3JSb3cgPSBhd2FpdCBzdGFjay5nZXRQYXJlbnQoKTtcbiAgICAgICAgICpcbiAgICAgICAgICogLy8gdW5kZWZpbmVkIGlmIGVudGl0eSBpcyB0aGUgcm9vdCBpdGVtXG4gICAgICAgICAqIGxldCBwYXJlbnQgPSBhd2FpdCBjb2x1bW5PclJvdy5nZXRQYXJlbnQoKTtcbiAgICAgICAgICogLy8gb3JcbiAgICAgICAgICogbGV0IHBhcmVudCA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0UGFyZW50ID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRkKHRoaXMsIF9MYXlvdXROb2RlX2NsaWVudCwgXCJmXCIpLmdldFBhcmVudCh0aGlzLmVudGl0eUlkKTtcbiAgICAgICAgICAgIGlmICghcGFyZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBMYXlvdXROb2RlLmdldEVudGl0eShwYXJlbnQsIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFRhYlN0YWNrIGFkamFjZW50IHRvIHRoZSBnaXZlbiBUYWJTdGFjayBvciBDb2x1bW5PclJvdy4gSW5wdXRzIGNhbiBiZSBuZXcgdmlld3MgdG8gY3JlYXRlLCBvciBleGlzdGluZyB2aWV3cy5cbiAgICAgICAgICpcbiAgICAgICAgICogS25vd24gSXNzdWU6IElmIHRoZSBudW1iZXIgb2Ygdmlld3MgdG8gYWRkIG92ZXJmbG93cyB0aGUgdGFiLWNvbnRhaW5lciwgdGhlIGFkZGVkIHZpZXdzIHdpbGwgYmUgc2V0IGFzIGFjdGl2ZVxuICAgICAgICAgKiBkdXJpbmcgZWFjaCByZW5kZXIsIGFuZCB0aGVuIHBsYWNlZCBhdCB0aGUgZnJvbnQgb2YgdGhlIHRhYi1zdGFjaywgd2hpbGUgdGhlIHVuZGVybHlpbmcgb3JkZXIgb2YgdGFicyB3aWxsIHJlbWFpbiB1bmNoYW5nZWQuXG4gICAgICAgICAqIFRoaXMgbWVhbnMgdGhlIHZpZXdzIHlvdSBwYXNzIHRvIGNyZWF0ZUFkamFjZW50U3RhY2soKSBtYXkgbm90IHJlbmRlciBpbiB0aGUgb3JkZXIgZ2l2ZW4gYnkgdGhlIGFycmF5LlxuICAgICAgICAgKiBVbnRpbCBmaXhlZCwgdGhpcyBwcm9ibGVtIGNhbiBiZSBhdm9pZGVkIG9ubHkgaWYgeW91ciB3aW5kb3cgaXMgd2lkZSBlbm91Z2ggdG8gZml0IGNyZWF0aW5nIGFsbCB0aGUgdmlld3MgaW4gdGhlIHRhYnN0YWNrLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gdmlld3MgVGhlIHZpZXdzIHRoYXQgd2lsbCBwb3B1bGF0ZSB0aGUgbmV3IFRhYlN0YWNrLlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBBZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBjb250cm9sIG5ldyBUYWJTdGFjayBjcmVhdGlvbi5cbiAgICAgICAgICogQHJldHVybnMgVGhlIG5ld2x5LWNyZWF0ZWQgVGFiU3RhY2suXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIGNvbnN0IGNvbHVtbk9yUm93ID0gYXdhaXQgc3RhY2suZ2V0UGFyZW50KCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIENyZWF0ZSB2aWV3IHJlZmVyZW5jZXMgYnkgc3VwcGx5aW5nIGEgJ25hbWUnIGFuZCAndXJsJ1xuICAgICAgICAgKiBjb25zdCB2aWV3cyA9IFtcbiAgICAgICAgICogICAgIC8vIGlmICduYW1lJyBpcyB1bmRlZmluZWQsIG9uZSB3aWxsIGJlIGdlbmVyYXRlZFxuICAgICAgICAgKiAgICAgLy8gaWYgJ3VybCcgaXMgdW5kZWZpbmVkLCBpdCB3aWxsIGRlZmF1bHQgdGhlIHZpZXcgVVJMIHRvICdhYm91dDpibGFuaydcbiAgICAgICAgICogICAgIHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJ30sXG4gICAgICAgICAqICAgICB7IG5hbWU6ICdvZi1kZXZlbG9wZXJzLXZpZXcnLCB1cmw6ICdodHRwOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvLyd9LFxuICAgICAgICAgKiBdO1xuICAgICAgICAgKlxuICAgICAgICAgKiAvLyBDcmVhdGUgYSB2aWV3IGJlZm9yZWhhbmQgdG8gYmUgaW5jbHVkZWQgaW4gdGhlIG5ldyB0YWIgc3RhY2tcbiAgICAgICAgICogY29uc3Qgb3V0c2lkZVZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuICAgICAgICAgKiAgICAgbmFtZTogJ291dHNpZGUtYmxvb21iZXJnLXZpZXcnLFxuICAgICAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly9ibG9vbWJlcmcuY29tLycsXG4gICAgICAgICAqICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgICAgICogfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIFZpZXdzIHRvIGFkZCBjYW4gYmUgaWRlbnRpdGllcywgb3IgdGhlIHJlZmVyZW5jZSB2aWV3cyBtZW50aW9uZWQgYWJvdmVcbiAgICAgICAgICogY29uc3Qgdmlld3NUb0FkZCA9IFtvdXRzaWRlVmlldy5pZGVudGl0eSwgLi4udmlld3NdO1xuICAgICAgICAgKlxuICAgICAgICAgKiAvLyBQb3NzaWJsZSBwb3NpdGlvbiBpbnB1dHM6ICdyaWdodCcgfCAnbGVmdCcgfCAndG9wJyB8ICdib3R0b20nXG4gICAgICAgICAqIGxldCBzdGFja0Zyb20gPSBhd2FpdCBjb2x1bW5PclJvdy5jcmVhdGVBZGphY2VudFN0YWNrKHZpZXdzVG9BZGQsIHsgcG9zaXRpb246ICdyaWdodCcgfSk7XG4gICAgICAgICAqIC8vIE9yXG4gICAgICAgICAqIGxldCBuZXdTdGFjayA9IGF3YWl0IHN0YWNrLmNyZWF0ZUFkamFjZW50U3RhY2sodmlld3NUb0FkZCwgeyBwb3NpdGlvbjogJ3JpZ2h0JyB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coYEEgbmV3IFRhYlN0YWNrIGNyZWF0ZWQgdG8gdGhlIHJpZ2h0IGhhcyAke25ld1N0YWNrLmxlbmd0aH0gdmlld3MgaW4gaXRgKTtcbiAgICAgICAgICpcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY3JlYXRlQWRqYWNlbnRTdGFjayA9IGFzeW5jICh2aWV3cywgb3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5SWQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikuY3JlYXRlQWRqYWNlbnRTdGFjayh0aGlzLmVudGl0eUlkLCB2aWV3cywgb3B0aW9ucyk7XG4gICAgICAgICAgICByZXR1cm4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoeyBlbnRpdHlJZCwgdHlwZTogJ3N0YWNrJyB9LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikpO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogUmV0cmlldmVzIHRoZSBhZGphY2VudCBUYWJTdGFja3Mgb2YgdGhlIGdpdmVuIFRhYlN0YWNrIG9yIENvbHVtbk9yUm93LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZWRnZSBFZGdlIHdob3NlIGFkamFjZW50IFRhYlN0YWNrcyB3aWxsIGJlIHJldHVybmVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBjb2x1bW5PclJvdyA9IGF3YWl0IHN0YWNrLmdldFBhcmVudCgpO1xuICAgICAgICAgKiAvLyBQb3NzaWJsZSBwb3NpdGlvbiBpbnB1dHM6ICdyaWdodCcgfCAnbGVmdCcgfCAndG9wJyB8ICdib3R0b20nXG4gICAgICAgICAqIGxldCByaWdodFN0YWNrcyA9IGF3YWl0IGNvbHVtbk9yUm93LmdldEFkamFjZW50U3RhY2tzKCdyaWdodCcpO1xuICAgICAgICAgKiBsZXQgbGVmdFN0YWNrcyA9IGF3YWl0IGNvbHVtbk9yUm93LmdldEFkamFjZW50U3RhY2tzKCdsZWZ0Jyk7XG4gICAgICAgICAqIC8vIG9yXG4gICAgICAgICAqIGxldCByaWdodFN0YWNrcyA9IGF3YWl0IHN0YWNrLmdldEFkamFjZW50U3RhY2tzKCdyaWdodCcpO1xuICAgICAgICAgKiBsZXQgbGVmdFN0YWNrcyA9IGF3YWl0IHN0YWNrLmdldEFkamFjZW50U3RhY2tzKCdsZWZ0Jyk7XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgZW50aXR5IGhhcyAke3JpZ2h0U3RhY2tzLmxlbmd0aH0gc3RhY2tzIHRvIHRoZSByaWdodCwgYW5kICR7bGVmdFN0YWNrcy5sZW5ndGh9IHN0YWNrcyB0byB0aGUgbGVmdGApO1xuICAgICAgICAgKlxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5nZXRBZGphY2VudFN0YWNrcyA9IGFzeW5jIChlZGdlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhZGphY2VudFN0YWNrcyA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfTGF5b3V0Tm9kZV9jbGllbnQsIFwiZlwiKS5nZXRBZGphY2VudFN0YWNrcyh7XG4gICAgICAgICAgICAgICAgdGFyZ2V0SWQ6IHRoaXMuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgZWRnZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gYWRqYWNlbnRTdGFja3MubWFwKChzdGFjaykgPT4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdGFjaycsXG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IHN0YWNrLmVudGl0eUlkXG4gICAgICAgICAgICB9LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0xheW91dE5vZGVfY2xpZW50LCBcImZcIikpKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCRiKHRoaXMsIF9MYXlvdXROb2RlX2NsaWVudCwgY2xpZW50LCBcImZcIik7XG4gICAgICAgIHRoaXMuZW50aXR5SWQgPSBlbnRpdHlJZDtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5MYXlvdXROb2RlID0gTGF5b3V0Tm9kZTtcbl9MYXlvdXROb2RlX2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEBpZ25vcmVcbiAqIEBpbnRlcm5hbFxuICogRW5jYXBzdWxhdGVzIEFwaSBjb25zdW1wdGlvbiBvZiB7QGxpbmsgTGF5b3V0RW50aXRpZXNDbGllbnR9IHdpdGggYSByZWxheWVkIGRpc3BhdGNoXG4gKiBAcGFyYW0gY2xpZW50XG4gKiBAcGFyYW0gY29udHJvbGxlcklkXG4gKiBAcGFyYW0gaWRlbnRpdHlcbiAqIEByZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIHtAbGluayBMYXlvdXRFbnRpdGllc0NsaWVudH0gd2l0aCBib3VuZCB0byB0aGUgY29udHJvbGxlcklkXG4gKi9cbkxheW91dE5vZGUubmV3TGF5b3V0RW50aXRpZXNDbGllbnQgPSBhc3luYyAoY2xpZW50LCBjb250cm9sbGVySWQsIGlkZW50aXR5KSA9PiB7XG4gICAgY29uc3QgZGlzcGF0Y2ggPSAoMCwgY2hhbm5lbF9hcGlfcmVsYXlfMS5jcmVhdGVSZWxheWVkRGlzcGF0Y2gpKGNsaWVudCwgaWRlbnRpdHksICdsYXlvdXQtcmVsYXknLCAnWW91IGFyZSB0cnlpbmcgdG8gaW50ZXJhY3Qgd2l0aCBhIGxheW91dCBjb21wb25lbnQgb24gYSB3aW5kb3cgdGhhdCBkb2VzIG5vdCBleGlzdCBvciBoYXMgYmVlbiBkZXN0cm95ZWQuJyk7XG4gICAgY29uc3QgY29uc3VtZXIgPSBuZXcgYXBpX2V4cG9zZXJfMS5BcGlDb25zdW1lcihuZXcgYXBpX2V4cG9zZXJfMS5DaGFubmVsc0NvbnN1bWVyKHsgZGlzcGF0Y2ggfSkpO1xuICAgIHJldHVybiBjb25zdW1lci5jb25zdW1lKHsgaWQ6IGNvbnRyb2xsZXJJZCB9KTtcbn07XG5MYXlvdXROb2RlLmdldEVudGl0eSA9IChkZWZpbml0aW9uLCBjbGllbnQpID0+IHtcbiAgICBjb25zdCB7IGVudGl0eUlkLCB0eXBlIH0gPSBkZWZpbml0aW9uO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdjb2x1bW4nOlxuICAgICAgICBjYXNlICdyb3cnOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBDb2x1bW5PclJvdyhjbGllbnQsIGVudGl0eUlkLCB0eXBlKTtcbiAgICAgICAgY2FzZSAnc3RhY2snOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBUYWJTdGFjayhjbGllbnQsIGVudGl0eUlkKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pc2VkIExheW91dCBFbnRpdHkgZW5jb3VudGVyZWQgKCcke0pTT04uc3RyaW5naWZ5KGRlZmluaXRpb24pfSlgKTtcbiAgICB9XG59O1xuLyoqXG4gKiBBIFRhYlN0YWNrIGlzIHVzZWQgdG8gbWFuYWdlIHRoZSBzdGF0ZSBvZiBhIHN0YWNrIG9mIHRhYnMgd2l0aGluIGFuIE9wZW5GaW4gTGF5b3V0LlxuICovXG5jbGFzcyBUYWJTdGFjayBleHRlbmRzIExheW91dE5vZGUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBjb25zdHJ1Y3RvcihjbGllbnQsIGVudGl0eUlkKSB7XG4gICAgICAgIHN1cGVyKGNsaWVudCwgZW50aXR5SWQpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEFwaUNsaWVudCBmb3Ige0BsaW5rIExheW91dEVudGl0aWVzQ29udHJvbGxlcn1cbiAgICAgICAgICovXG4gICAgICAgIF9UYWJTdGFja19jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUeXBlIG9mIHRoZSBjb250ZW50IGl0ZW0uIEFsd2F5cyBzdGFjaywgYnV0IHVzZWZ1bCBmb3IgZGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBhIHtAbGluayBUYWJTdGFja30gYW5kIHtAbGluayBDb2x1bW5PclJvd30uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnR5cGUgPSAnc3RhY2snO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmV0cmlldmVzIGEgbGlzdCBvZiBhbGwgdmlld3MgYmVsb25naW5nIHRvIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogS25vd24gSXNzdWU6IElmIGFkZGluZyBhIHZpZXcgb3ZlcmZsb3dzIHRoZSB0YWItY29udGFpbmVyIHdpZHRoLCB0aGUgYWRkZWQgdmlldyB3aWxsIGJlIHNldCBhcyBhY3RpdmVcbiAgICAgICAgICogYW5kIHJlbmRlcmVkIGF0IHRoZSBmcm9udCBvZiB0aGUgdGFiLXN0YWNrLCB3aGlsZSB0aGUgdW5kZXJseWluZyBvcmRlciBvZiB0YWJzIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgICAgICogSWYgdGhhdCBoYXBwZW5zIGFuZCB0aGVuIGdldFZpZXdzKCkgaXMgY2FsbGVkLCBpdCB3aWxsIHJldHVybiB0aGUgaWRlbnRpdGllcyBpbiBhIGRpZmZlcmVudCBvcmRlciB0aGFuXG4gICAgICAgICAqIHRoYW4gdGhlIGN1cnJlbnRseSByZW5kZXJlZCB0YWIgb3JkZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHtAbGluayBUYWJTdGFja30gaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiAvLyBBbHRlcm5hdGl2ZWx5LCB5b3UgY2FuIHdyYXAgYW55IHZpZXcgYW5kIGdldCB0aGUgc3RhY2sgZnJvbSB0aGVyZVxuICAgICAgICAgKiAvLyBjb25zdCB2aWV3RnJvbVNvbWV3aGVyZSA9IGZpbi5WaWV3LndyYXBTeW5jKHNvbWVWaWV3LmlkZW50aXR5KTtcbiAgICAgICAgICogLy8gY29uc3Qgc3RhY2sgPSBhd2FpdCB2aWV3RnJvbVNvbWV3aGVyZS5nZXRDdXJyZW50U3RhY2soKTtcbiAgICAgICAgICogY29uc3Qgdmlld3MgPSBhd2FpdCBzdGFjay5nZXRWaWV3cygpO1xuICAgICAgICAgKiBjb25zb2xlLmxvZyhgU3RhY2sgY29udGFpbnMgJHt2aWV3cy5sZW5ndGh9IHZpZXcocylgKTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0Vmlld3MgPSAoKSA9PiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX1RhYlN0YWNrX2NsaWVudCwgXCJmXCIpLmdldFN0YWNrVmlld3ModGhpcy5lbnRpdHlJZCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBZGRzIG9yIGNyZWF0ZXMgYSB2aWV3IGluIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgS25vd24gSXNzdWU6IElmIGFkZGluZyBhIHZpZXcgb3ZlcmZsb3dzIHRoZSB0YWItY29udGFpbmVyLCB0aGUgYWRkZWQgdmlldyB3aWxsIGJlIHNldCBhcyBhY3RpdmVcbiAgICAgICAgICogYW5kIHJlbmRlcmVkIGF0IHRoZSBmcm9udCBvZiB0aGUgdGFiLXN0YWNrLCB3aGlsZSB0aGUgdW5kZXJseWluZyBvcmRlciBvZiB0YWJzIHdpbGwgcmVtYWluIHVuY2hhbmdlZC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHZpZXcgVGhlIGlkZW50aXR5IG9mIGFuIGV4aXN0aW5nIHZpZXcgdG8gYWRkLCBvciBvcHRpb25zIHRvIGNyZWF0ZSBhIHZpZXcuXG4gICAgICAgICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbmFsIHZpZXcgb3B0aW9uczogaW5kZXggbnVtYmVyIHVzZWQgdG8gaW5zZXJ0IHRoZSB2aWV3IGludG8gdGhlIHN0YWNrIGF0IHRoYXQgaW5kZXguIERlZmF1bHRzIHRvIDAgKGZyb250IG9mIHRoZSBzdGFjaylcbiAgICAgICAgICogQHJldHVybnMgUmVzb2x2ZXMgd2l0aCB0aGUge0BsaW5rIE9wZW5GaW4uSWRlbnRpdHkgaWRlbnRpdHl9IG9mIHRoZSBhZGRlZCB2aWV3LlxuICAgICAgICAgKiBAdGhyb3dzIElmIHRoZSB2aWV3IGRvZXMgbm90IGV4aXN0IG9yIGZhaWxzIHRvIGNyZWF0ZS5cbiAgICAgICAgICogQHRocm93cyBJZiB0aGUge0BsaW5rIFRhYlN0YWNrfSBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIC8vIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gd3JhcCBhbnkgdmlldyBhbmQgZ2V0IHRoZSBzdGFjayBmcm9tIHRoZXJlXG4gICAgICAgICAqIC8vIGNvbnN0IHZpZXdGcm9tU29tZXdoZXJlID0gZmluLlZpZXcud3JhcFN5bmMoc29tZVZpZXcuaWRlbnRpdHkpO1xuICAgICAgICAgKiAvLyBjb25zdCBzdGFjayA9IGF3YWl0IHZpZXdGcm9tU29tZXdoZXJlLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBnb29nbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJyB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coJ0lkZW50aXR5IG9mIHRoZSBnb29nbGUgdmlldyBqdXN0IGFkZGVkJywgeyBnb29nbGVWaWV3SWRlbnRpdHkgfSk7XG4gICAgICAgICAqIC8vIHBhc3MgaW4geyBpbmRleDogbnVtYmVyIH0gdG8gc2V0IHRoZSBpbmRleCBpbiB0aGUgc3RhY2suIEhlcmUgMSBtZWFucywgZW5kIG9mIHRoZSBzdGFjayAoZGVmYXVsdHMgdG8gMClcbiAgICAgICAgICogY29uc3QgYXBwbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2FwcGxlLXZpZXcnLCB1cmw6ICdodHRwOi8vYXBwbGUuY29tLycgfSwgeyBpbmRleDogMSB9KTtcbiAgICAgICAgICogY29uc29sZS5sb2coJ0lkZW50aXR5IG9mIHRoZSBhcHBsZSB2aWV3IGp1c3QgYWRkZWQnLCB7IGFwcGxlVmlld0lkZW50aXR5IH0pO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hZGRWaWV3ID0gYXN5bmMgKHZpZXcsIG9wdGlvbnMgPSB7IGluZGV4OiAwIH0pID0+IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkZCh0aGlzLCBfVGFiU3RhY2tfY2xpZW50LCBcImZcIikuYWRkVmlld1RvU3RhY2sodGhpcy5lbnRpdHlJZCwgdmlldywgb3B0aW9ucyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZW1vdmVzIGEgdmlldyBmcm9tIHRoaXMge0BsaW5rIFRhYlN0YWNrfS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgVGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgdmlldyBpZGVudGl0eSBkb2VzIG5vdCBleGlzdCBvciB3YXMgYWxyZWFkeSBkZXN0cm95ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB2aWV3IC0gSWRlbnRpdHkgb2YgdGhlIHZpZXcgdG8gcmVtb3ZlLlxuICAgICAgICAgKiBAdGhyb3dzIElmIHRoZSB2aWV3IGRvZXMgbm90IGV4aXN0IG9yIGRvZXMgbm90IGJlbG9uZyB0byB0aGUgc3RhY2suXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHtAbGluayBUYWJTdGFja30gaGFzIGJlZW4gZGVzdHJveWVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBpZiAoIWZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBjb25zdCBnb29nbGVWaWV3SWRlbnRpdHkgPSBhd2FpdCBzdGFjay5hZGRWaWV3KHsgbmFtZTogJ2dvb2dsZS12aWV3JywgdXJsOiAnaHR0cDovL2dvb2dsZS5jb20vJyB9KTtcbiAgICAgICAgICpcbiAgICAgICAgICogYXdhaXQgc3RhY2sucmVtb3ZlVmlldyhnb29nbGVWaWV3SWRlbnRpdHkpO1xuICAgICAgICAgKlxuICAgICAgICAgKiB0cnkge1xuICAgICAgICAgKiAgICAgYXdhaXQgc3RhY2sucmVtb3ZlVmlldyhnb29nbGVWaWV3SWRlbnRpdHkpO1xuICAgICAgICAgKiB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgKiAgICAgLy8gVHJpZWQgdG8gcmVtb3ZlIGEgdmlldyAoJ2dvb2dsZS12aWV3Jykgd2hpY2ggZG9lcyBub3QgYmVsb25nIHRvIHRoZSBzdGFjay5cbiAgICAgICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVtb3ZlVmlldyA9IGFzeW5jICh2aWV3KSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX1RhYlN0YWNrX2NsaWVudCwgXCJmXCIpLnJlbW92ZVZpZXdGcm9tU3RhY2sodGhpcy5lbnRpdHlJZCwgdmlldyk7XG4gICAgICAgIH07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBhY3RpdmUgdmlldyBvZiB0aGUge0BsaW5rIFRhYlN0YWNrfSB3aXRob3V0IGZvY3VzaW5nIGl0LlxuICAgICAgICAgKiBAcGFyYW0gdmlldyAtIElkZW50aXR5IG9mIHRoZSB2aWV3IHRvIGFjdGl2YXRlLlxuICAgICAgICAgKiBAcmV0dXJucyBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdm9pZCBvbmNlIHRoZSB2aWV3IGhhcyBiZWVuIGFjdGl2YXRlZC5cbiAgICAgICAgICogQHRocm93cyBJZiB0aGUge0BsaW5rIFRhYlN0YWNrfSBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgICAqIEB0aHJvd3MgSWYgdGhlIHZpZXcgZG9lcyBub3QgZXhpc3QuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIENoYW5nZSB0aGUgYWN0aXZlIHRhYiBvZiBhIGtub3duIFZpZXcncyBUYWJTdGFjazpcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogY29uc3QgdGFyZ2V0VmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogJ3V1aWQnLCBuYW1lOiAndmlldy1uYW1lJyB9KTtcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCB0YXJnZXRWaWV3LmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBhd2FpdCBzdGFjay5zZXRBY3RpdmVWaWV3KHRhcmdldFZpZXcuaWRlbnRpdHkpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICpcbiAgICAgICAgICogU2V0IHRoZSBjdXJyZW50IFZpZXcgYXMgYWN0aXZlIHdpdGhpbiBpdHMgVGFiU3RhY2s6XG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuICAgICAgICAgKiBhd2FpdCBzdGFjay5zZXRBY3RpdmVWaWV3KGZpbi5tZS5pZGVudGl0eSk7XG4gICAgICAgICAqIGBgYFxuICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnNldEFjdGl2ZVZpZXcgPSBhc3luYyAodmlldykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRkKHRoaXMsIF9UYWJTdGFja19jbGllbnQsIFwiZlwiKS5zZXRTdGFja0FjdGl2ZVZpZXcodGhpcy5lbnRpdHlJZCwgdmlldyk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYih0aGlzLCBfVGFiU3RhY2tfY2xpZW50LCBjbGllbnQsIFwiZlwiKTtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5UYWJTdGFjayA9IFRhYlN0YWNrO1xuX1RhYlN0YWNrX2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG4vKipcbiAqIEEgQ29sdW1uT3JSb3cgaXMgdXNlZCB0byBtYW5hZ2UgdGhlIHN0YXRlIG9mIENvbHVtbiBhbmQgUm93cyB3aXRoaW4gYW4gT3BlbkZpbiBMYXlvdXQuXG4gKi9cbmNsYXNzIENvbHVtbk9yUm93IGV4dGVuZHMgTGF5b3V0Tm9kZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2xpZW50LCBlbnRpdHlJZCwgdHlwZSkge1xuICAgICAgICBzdXBlcihjbGllbnQsIGVudGl0eUlkKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpZ25vcmVcbiAgICAgICAgICogQGludGVybmFsXG4gICAgICAgICAqIEFwaUNsaWVudCBmb3Ige0BsaW5rIExheW91dEVudGl0aWVzQ29udHJvbGxlcn1cbiAgICAgICAgICovXG4gICAgICAgIF9Db2x1bW5PclJvd19jbGllbnQuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGNvbnRlbnQgYXJyYXkgb2YgdGhlIENvbHVtbk9yUm93XG4gICAgICAgICAqXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGlmICghZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcuJyk7XG4gICAgICAgICAqIH1cbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3Qgc3RhY2sgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFN0YWNrKCk7XG4gICAgICAgICAqIC8vIFJldHJpZXZlcyB0aGUgcGFyZW50IENvbHVtbk9yUm93XG4gICAgICAgICAqIGNvbnN0IGNvbHVtbk9yUm93ID0gYXdhaXQgc3RhY2suZ2V0UGFyZW50KCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIHJldHVybnMgW1RhYlN0YWNrXVxuICAgICAgICAgKiBjb25zdCBjb250ZW50QXJyYXkgPSBhd2FpdCBjb2x1bW5PclJvdy5nZXRDb250ZW50KCk7XG4gICAgICAgICAqIGNvbnNvbGUubG9nKGBUaGUgQ29sdW1uT3JSb3cgaGFzICR7Y29udGVudEFycmF5Lmxlbmd0aH0gaXRlbShzKWApO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0Q29udGVudCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRJdGVtRW50aXRpZXMgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0NvbHVtbk9yUm93X2NsaWVudCwgXCJmXCIpLmdldENvbnRlbnQodGhpcy5lbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gY29udGVudEl0ZW1FbnRpdGllcy5tYXAoKGVudGl0eSkgPT4gTGF5b3V0Tm9kZS5nZXRFbnRpdHkoZW50aXR5LCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGQodGhpcywgX0NvbHVtbk9yUm93X2NsaWVudCwgXCJmXCIpKSk7XG4gICAgICAgIH07XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYih0aGlzLCBfQ29sdW1uT3JSb3dfY2xpZW50LCBjbGllbnQsIFwiZlwiKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG59XG5sYXlvdXRFbnRpdGllcy5Db2x1bW5PclJvdyA9IENvbHVtbk9yUm93O1xuX0NvbHVtbk9yUm93X2NsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBsYXlvdXRfY29uc3RhbnRzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShsYXlvdXRfY29uc3RhbnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmxheW91dF9jb25zdGFudHMuREVGQVVMVF9MQVlPVVRfS0VZID0gbGF5b3V0X2NvbnN0YW50cy5MQVlPVVRfQ09OVFJPTExFUl9JRCA9IHZvaWQgMDtcbmxheW91dF9jb25zdGFudHMuTEFZT1VUX0NPTlRST0xMRVJfSUQgPSAnbGF5b3V0LWVudGl0aWVzJztcbi8vIFRPRE86IGV2ZW50dWFsbHkgZXhwb3J0IHRoaXMgc29tZWhvd1xubGF5b3V0X2NvbnN0YW50cy5ERUZBVUxUX0xBWU9VVF9LRVkgPSAnX19kZWZhdWx0X18nO1xuXG52YXIgbWFpbiA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobWFpbiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5tYWluLldlYkNvbnRlbnRzID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJGogPSBiYXNlO1xuY2xhc3MgV2ViQ29udGVudHMgZXh0ZW5kcyBiYXNlXzEkai5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBpZGVudGl0eSBvZiB0aGUge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgV2ViQ29udGVudHN9LlxuICAgICAqIEBwYXJhbSBlbnRpdHlUeXBlIFRoZSB0eXBlIG9mIHRoZSB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBXZWJDb250ZW50c30uXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHksIGVudGl0eVR5cGUpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgZW50aXR5VHlwZSwgaWRlbnRpdHkudXVpZCwgaWRlbnRpdHkubmFtZSk7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICAgICAgdGhpcy5lbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyBhIGJhc2U2NCBlbmNvZGVkIGltYWdlIG9mIGFsbCBvciBwYXJ0IG9mIHRoZSBXZWJDb250ZW50cy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgY2FwdHVyZVBhZ2UgY2FsbC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiAvLyBQTkcgaW1hZ2Ugb2YgYSBmdWxsIHZpc2libGUgVmlld1xuICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHZpZXcuY2FwdHVyZVBhZ2UoKSk7XG4gICAgICpcbiAgICAgKiAvLyBMb3ctcXVhbGl0eSBKUEVHIGltYWdlIG9mIGEgZGVmaW5lZCB2aXNpYmxlIGFyZWEgb2YgdGhlIHZpZXdcbiAgICAgKiBjb25zdCBvcHRpb25zID0ge1xuICAgICAqICAgICBhcmVhOiB7XG4gICAgICogICAgICAgICBoZWlnaHQ6IDEwMCxcbiAgICAgKiAgICAgICAgIHdpZHRoOiAxMDAsXG4gICAgICogICAgICAgICB4OiAxMCxcbiAgICAgKiAgICAgICAgIHk6IDEwLFxuICAgICAqICAgICB9LFxuICAgICAqICAgICBmb3JtYXQ6ICdqcGcnLFxuICAgICAqICAgICBxdWFsaXR5OiAyMFxuICAgICAqIH1cbiAgICAgKiBjb25zb2xlLmxvZyhhd2FpdCB2aWV3LmNhcHR1cmVQYWdlKG9wdGlvbnMpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHduZCA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogLy8gUE5HIGltYWdlIG9mIGEgZnVsbCB2aXNpYmxlIHdpbmRvd1xuICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHduZC5jYXB0dXJlUGFnZSgpKTtcbiAgICAgKlxuICAgICAqIC8vIExvdy1xdWFsaXR5IEpQRUcgaW1hZ2Ugb2YgYSBkZWZpbmVkIHZpc2libGUgYXJlYSBvZiB0aGUgd2luZG93XG4gICAgICogY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgKiAgICAgYXJlYToge1xuICAgICAqICAgICAgICAgaGVpZ2h0OiAxMDAsXG4gICAgICogICAgICAgICB3aWR0aDogMTAwLFxuICAgICAqICAgICAgICAgeDogMTAsXG4gICAgICogICAgICAgICB5OiAxMCxcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgZm9ybWF0OiAnanBnJyxcbiAgICAgKiAgICAgcXVhbGl0eTogMjBcbiAgICAgKiB9XG4gICAgICogY29uc29sZS5sb2coYXdhaXQgd25kLmNhcHR1cmVQYWdlKG9wdGlvbnMpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBjYXB0dXJlUGFnZShvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignY2FwdHVyZS1wYWdlJywgeyBvcHRpb25zLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBKYXZhc2NyaXB0IG9uIHRoZSBXZWJDb250ZW50cywgcmVzdHJpY3RlZCB0byBjb250ZW50cyB5b3Ugb3duIG9yIGNvbnRlbnRzIG93bmVkIGJ5XG4gICAgICogYXBwbGljYXRpb25zIHlvdSBoYXZlIGNyZWF0ZWQuXG4gICAgICogQHBhcmFtIGNvZGUgSmF2YVNjcmlwdCBjb2RlIHRvIGJlIGV4ZWN1dGVkIG9uIHRoZSB2aWV3LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUphdmFTY3JpcHQoY29kZSkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7dXVpZDogJ3V1aWQnLCBuYW1lOiAndmlldyBuYW1lJ30pO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5leGVjdXRlSmF2YVNjcmlwdChjb2RlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBleGVjdXRlSmF2YVNjcmlwdChgY29uc29sZS5sb2coJ0hlbGxvLCBPcGVuZmluJylgKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdKYXZhc2NyaXB0IGV4Y3V0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZXhlY3V0ZUphdmFTY3JpcHQoY29kZSkge1xuICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcbiAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmV4ZWN1dGVKYXZhU2NyaXB0Lmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5leGVjdXRlSmF2YVNjcmlwdChjb2RlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBleGVjdXRlSmF2YVNjcmlwdChgY29uc29sZS5sb2coJ0hlbGxvLCBPcGVuZmluJylgKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdKYXZhc2NyaXB0IGV4Y3V0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBleGVjdXRlSmF2YVNjcmlwdChjb2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdleGVjdXRlLWphdmFzY3JpcHQtaW4td2luZG93JywgeyAuLi50aGlzLmlkZW50aXR5LCBjb2RlIH0pXG4gICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHpvb20gbGV2ZWwgb2YgdGhlIFdlYkNvbnRlbnRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5nZXRab29tTGV2ZWwoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0Wm9vbUxldmVsLmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRab29tTGV2ZWwoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGdldFpvb21MZXZlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtem9vbS1sZXZlbCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB6b29tIGxldmVsIG9mIHRoZSBXZWJDb250ZW50cy5cbiAgICAgKiBAcGFyYW0gbGV2ZWwgVGhlIHpvb20gbGV2ZWxcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFpvb21MZXZlbChudW1iZXIpIHtcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcuc2V0Wm9vbUxldmVsKG51bWJlcik7XG4gICAgICogfVxuICAgICAqXG4gICAgICogc2V0Wm9vbUxldmVsKDQpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1NldHRpbmcgYSAgem9vbSBsZXZlbCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2V0Wm9vbUxldmVsLmh0bWwnLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfSk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogYXN5bmMgZnVuY3Rpb24gc2V0Wm9vbUxldmVsKG51bWJlcikge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zZXRab29tTGV2ZWwobnVtYmVyKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBzZXRab29tTGV2ZWwoNCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2V0dGluZyBhICB6b29tIGxldmVsJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgc2V0Wm9vbUxldmVsKGxldmVsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2V0LXpvb20tbGV2ZWwnLCB7IC4uLnRoaXMuaWRlbnRpdHksIGxldmVsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRoZSBXZWJDb250ZW50cyB0byBhIHNwZWNpZmllZCBVUkwuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGUgdXJsIG11c3QgY29udGFpbiB0aGUgcHJvdG9jb2wgcHJlZml4IHN1Y2ggYXMgaHR0cDovLyBvciBodHRwczovLy5cbiAgICAgKiBAcGFyYW0gdXJsIC0gVGhlIFVSTCB0byBuYXZpZ2F0ZSB0aGUgV2ViQ29udGVudHMgdG8uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IG1lLmlkZW50aXR5LFxuICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuICAgICAqICAgICB9KTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBjcmVhdGVWaWV3KClcbiAgICAgKiAgICAgLnRoZW4odmlldyA9PiB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2V4YW1wbGUuY29tJykpXG4gICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCduYXZpZ2F0aW9uIGNvbXBsZXRlJykpXG4gICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBuYXZpZ2F0ZSgpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubmF2aWdhdGUoJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cubmF2aWdhdGUuaHRtbCcpO1xuICAgICAqIH1cbiAgICAgKiBuYXZpZ2F0ZSgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ05hdmlnYXRlIHRvIHR1dG9yaWFsJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIG5hdmlnYXRlKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ25hdmlnYXRlLXdpbmRvdycsIHsgLi4udGhpcy5pZGVudGl0eSwgdXJsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmF2aWdhdGVzIHRoZSBXZWJDb250ZW50cyBiYWNrIG9uZSBwYWdlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGVCYWNrKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7IG5hbWU6ICd0ZXN0YXBwLXZpZXcnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHZpZXcubmF2aWdhdGUoJ2h0dHBzOi8vd3d3Lmdvb2dsZS5jb20nKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcubmF2aWdhdGVCYWNrKCk7XG4gICAgICogfVxuICAgICAqIG5hdmlnYXRlQmFjaygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ05hdmlnYXRlZCBiYWNrJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIG5hdmlnYXRlQmFjaygpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy53cmFwKHsgbmFtZTogJ3Rlc3RhcHAnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHdpbi5uYXZpZ2F0ZSgnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbScpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLm5hdmlnYXRlQmFjaygpO1xuICAgICAqIH1cbiAgICAgKiBuYXZpZ2F0ZUJhY2soKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdOYXZpZ2F0ZWQgYmFjaycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIG5hdmlnYXRlQmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCduYXZpZ2F0ZS13aW5kb3ctYmFjaycsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5hdmlnYXRlcyB0aGUgV2ViQ29udGVudHMgZm9yd2FyZCBvbmUgcGFnZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIG5hdmlnYXRlRm9yd2FyZCgpIHtcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbScpO1xuICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlQmFjaygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5uYXZpZ2F0ZUZvcndhcmQoKTtcbiAgICAgKiB9XG4gICAgICogbmF2aWdhdGVGb3J3YXJkKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTmF2aWdhdGVkIGZvcndhcmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGVGb3J3YXJkKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLm5hdmlnYXRlKCdodHRwczovL3d3dy5nb29nbGUuY29tJyk7XG4gICAgICogICAgIGF3YWl0IHdpbi5uYXZpZ2F0ZUJhY2soKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5uYXZpZ2F0ZUZvcndhcmQoKTtcbiAgICAgKiB9XG4gICAgICogbmF2aWdhdGVGb3J3YXJkKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTmF2aWdhdGVkIGZvcndhcmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBhc3luYyBuYXZpZ2F0ZUZvcndhcmQoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCduYXZpZ2F0ZS13aW5kb3ctZm9yd2FyZCcsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcHMgYW55IGN1cnJlbnQgbmF2aWdhdGlvbiB0aGUgV2ViQ29udGVudHMgaXMgcGVyZm9ybWluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BOYXZpZ2F0aW9uKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcud3JhcCh7IG5hbWU6ICd0ZXN0YXBwLXZpZXcnLCB1dWlkOiAndGVzdGFwcCcgfSk7XG4gICAgICogICAgIGF3YWl0IHZpZXcubmF2aWdhdGUoJ2h0dHBzOi8vd3d3Lmdvb2dsZS5jb20nKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHZpZXcuc3RvcE5hdmlnYXRpb24oKTtcbiAgICAgKiB9XG4gICAgICogc3RvcE5hdmlnYXRpb24oKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCd5b3Ugc2hhbGwgbm90IG5hdmlnYXRlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BOYXZpZ2F0aW9uKCkge1xuICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LndyYXAoeyBuYW1lOiAndGVzdGFwcCcsIHV1aWQ6ICd0ZXN0YXBwJyB9KTtcbiAgICAgKiAgICAgYXdhaXQgd2luLm5hdmlnYXRlKCdodHRwczovL3d3dy5nb29nbGUuY29tJyk7XG4gICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc3RvcE5hdmlnYXRpb24oKTtcbiAgICAgKiB9XG4gICAgICogc3RvcE5hdmlnYXRpb24oKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCd5b3Ugc2hhbGwgbm90IG5hdmlnYXRlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgc3RvcE5hdmlnYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc3RvcC13aW5kb3ctbmF2aWdhdGlvbicsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbG9hZHMgdGhlIFdlYkNvbnRlbnRzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWxvYWQoKSB7XG4gICAgICogXHRjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgdmlldy5yZWxvYWQoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiByZWxvYWQoKS50aGVuKCgpID0+IHtcbiAgICAgKiBcdFx0Y29uc29sZS5sb2coJ1JlbG9hZGVkIHZpZXcnKVxuICAgICAqIH0pLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlbG9hZFdpbmRvdygpIHtcbiAgICAgKiBcdFx0Y29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcbiAgICAgKiBcdFx0XHRcdG5hbWU6ICdteUFwcCcsXG4gICAgICogXHRcdFx0XHR1dWlkOiAnYXBwLTEnLFxuICAgICAqIFx0XHRcdFx0dXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5yZWxvYWQuaHRtbCcsXG4gICAgICogXHRcdFx0XHRhdXRvU2hvdzogdHJ1ZVxuICAgICAqIFx0XHR9KTtcbiAgICAgKiBcdFx0Y29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnJlbG9hZCgpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHJlbG9hZFdpbmRvdygpLnRoZW4oKCkgPT4ge1xuICAgICAqIFx0XHRjb25zb2xlLmxvZygnUmVsb2FkZWQgd2luZG93JylcbiAgICAgKiB9KS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHJlbG9hZChpZ25vcmVDYWNoZSA9IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdyZWxvYWQtd2luZG93Jywge1xuICAgICAgICAgICAgaWdub3JlQ2FjaGUsXG4gICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG4gICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQcmludHMgdGhlIFdlYkNvbnRlbnRzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIFByaW50ZXIgT3B0aW9uc1xuICAgICAqXG4gICAgICogTm90ZTogV2hlbiBgc2lsZW50YCBpcyBzZXQgdG8gYHRydWVgLCB0aGUgQVBJIHdpbGwgcGljayB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBwcmludGVyIGlmIGRldmljZU5hbWVcbiAgICAgKiBpcyBlbXB0eSBhbmQgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIHByaW50aW5nLlxuICAgICAqXG4gICAgICogVXNlIHRoZSBDU1Mgc3R5bGUgYHBhZ2UtYnJlYWstYmVmb3JlOiBhbHdheXM7YCB0byBmb3JjZSBwcmludCB0byBhIG5ldyBwYWdlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogdmlldy5wcmludCh7IHNpbGVudDogZmFsc2UsIGRldmljZU5hbWU6ICdzeXN0ZW0tcHJpbnRlci1uYW1lJyB9KS50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ3ByaW50IGNhbGwgaGFzIGJlZW4gc2VudCB0byB0aGUgc3lzdGVtJyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHByaW50KG9wdGlvbnMgPSB7fSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ByaW50JywgeyAuLi50aGlzLmlkZW50aXR5LCBvcHRpb25zIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluZCBhbmQgaGlnaGxpZ2h0IHRleHQgb24gYSBwYWdlLlxuICAgICAqIEBwYXJhbSBzZWFyY2hUZXJtIFRlcm0gdG8gZmluZCBpbiBwYWdlXG4gICAgICogQHBhcmFtIG9wdGlvbnMgU2VhcmNoIG9wdGlvbnNcbiAgICAgKlxuICAgICAqIE5vdGU6IEJ5IGRlZmF1bHQsIGVhY2ggc3Vic2VxdWVudCBjYWxsIHdpbGwgaGlnaGxpZ2h0IHRoZSBuZXh0IHRleHQgdGhhdCBtYXRjaGVzIHRoZSBzZWFyY2ggdGVybS5cbiAgICAgKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdHMgZm9yIHRoZSByZXF1ZXN0LiBCeSBzdWJzY3JpYmluZyB0byB0aGVcbiAgICAgKiBmb3VuZC1pbi1wYWdlIGV2ZW50LCB5b3UgY2FuIGdldCB0aGUgcmVzdWx0cyBvZiB0aGlzIGNhbGwgYXMgd2VsbC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogLy9CeSBzdWJzY3JpYmluZyB0byB0aGUgJ2ZvdW5kIGluIHBhZ2UnIGV2ZW50IHdlIGNhbiBnZXQgdGhlIHJlc3VsdHMgb2YgZWFjaCBmaW5kSW5QYWdlIGNhbGwgbWFkZS5cbiAgICAgKiB2aWV3LmFkZExpc3RlbmVyKCdmb3VuZC1pbi1wYWdlJywgKGV2ZW50KSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGV2ZW50KTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBwcm9taXNlIGFsc28gcmV0dXJucyB0aGUgcmVzdWx0cyBmb3IgdGhlIHJlcXVlc3RcbiAgICAgKiB2aWV3LmZpbmRJblBhZ2UoJ2EnKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocmVzdWx0KVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogLy9CeSBzdWJzY3JpYmluZyB0byB0aGUgJ2ZvdW5kIGluIHBhZ2UnIGV2ZW50IHdlIGNhbiBnZXQgdGhlIHJlc3VsdHMgb2YgZWFjaCBmaW5kSW5QYWdlIGNhbGwgbWFkZS5cbiAgICAgKiB3aW4uYWRkTGlzdGVuZXIoJ2ZvdW5kLWluLXBhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXZlbnQpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gVGhlIHByb21pc2UgYWxzbyByZXR1cm5zIHRoZSByZXN1bHRzIGZvciB0aGUgcmVxdWVzdFxuICAgICAqIHdpbi5maW5kSW5QYWdlKCdhJykudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdClcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgZmluZEluUGFnZShzZWFyY2hUZXJtLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdmaW5kLWluLXBhZ2UnLCB7IC4uLnRoaXMuaWRlbnRpdHksIHNlYXJjaFRlcm0sIG9wdGlvbnMgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhIHtAbGluayBWaWV3I2ZpbmRJblBhZ2UgZmluZEluUGFnZX0gY2FsbCBieSBzcGVjaWZ5aW5nIGFueSBvZiB0aGVzZSBhY3Rpb25zOlxuICAgICAqXG4gICAgICogKiBjbGVhclNlbGVjdGlvbiAtIENsZWFyIHRoZSBzZWxlY3Rpb24uXG4gICAgICogKiBrZWVwU2VsZWN0aW9uIC0gVHJhbnNsYXRlIHRoZSBzZWxlY3Rpb24gaW50byBhIG5vcm1hbCBzZWxlY3Rpb24uXG4gICAgICogKiBhY3RpdmF0ZVNlbGVjdGlvbiAtIEZvY3VzIGFuZCBjbGljayB0aGUgc2VsZWN0aW9uIG5vZGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcuZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKlxuICAgICAqIHZpZXcuYWRkTGlzdGVuZXIoJ2ZvdW5kLWluLXBhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgKiAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICogICAgICAgICB2aWV3LnN0b3BGaW5kSW5QYWdlKCdjbGVhclNlbGVjdGlvbicpO1xuICAgICAqICAgICB9LCA1MDAwKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHZpZXcuZmluZEluUGFnZSgnYScpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogd2luLmFkZExpc3RlbmVyKCdmb3VuZC1pbi1wYWdlJywgKGV2ZW50KSA9PiB7XG4gICAgICogICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAqICAgICAgICAgd2luLnN0b3BGaW5kSW5QYWdlKCdjbGVhclNlbGVjdGlvbicpO1xuICAgICAqICAgICB9LCA1MDAwKTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHdpbi5maW5kSW5QYWdlKCdhJykudGhlbihyZXN1bHRzID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIHN0b3BGaW5kSW5QYWdlKGFjdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3N0b3AtZmluZC1pbi1wYWdlJywgeyAuLi50aGlzLmlkZW50aXR5LCBhY3Rpb24gfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggYWxsIHN5c3RlbSBwcmludGVyc1xuICAgICAqIEBkZXByZWNhdGVkIHVzZSBTeXN0ZW0uZ2V0UHJpbnRlcnMgaW5zdGVhZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiB2aWV3LmdldFByaW50ZXJzKClcbiAgICAgKiAgICAgLnRoZW4oKHByaW50ZXJzKSA9PiB7XG4gICAgICogICAgICAgICBwcmludGVycy5mb3JFYWNoKChwcmludGVyKSA9PiB7XG4gICAgICogICAgICAgICAgICAgaWYgKHByaW50ZXIuaXNEZWZhdWx0KSB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHByaW50ZXIpO1xuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9KVxuICAgICAqICAgICAuY2F0Y2goKGVycikgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICpcbiAgICAgKiB3aW4uZ2V0UHJpbnRlcnMoKVxuICAgICAqICAgICAudGhlbigocHJpbnRlcnMpID0+IHtcbiAgICAgKiAgICAgICAgIHByaW50ZXJzLmZvckVhY2goKHByaW50ZXIpID0+IHtcbiAgICAgKiAgICAgICAgICAgICBpZiAocHJpbnRlci5pc0RlZmF1bHQpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocHJpbnRlcik7XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH0pXG4gICAgICogICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgZ2V0UHJpbnRlcnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByaW50ZXJzJywgeyAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlcyBmb2N1cyB0byB0aGUgV2ViQ29udGVudHMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZm9jdXNXaW5kb3coKSB7XG4gICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG4gICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZm9jdXMuaHRtbCcsXG4gICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuICAgICAqICAgICB9KTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmZvY3VzKCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZm9jdXNXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgZm9jdXNlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGZvY3VzKHsgZW1pdFN5bnRoRm9jdXNlZCB9ID0geyBlbWl0U3ludGhGb2N1c2VkOiB0cnVlIH0pIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZvY3VzLXdpbmRvdycsIHsgZW1pdFN5bnRoRm9jdXNlZCwgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29sc1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd0RldmVsb3BlclRvb2xzKCkge1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gdmlldy5zaG93RGV2ZWxvcGVyVG9vbHMoKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBzaG93RGV2ZWxvcGVydG9vbHMoKVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTaG93aW5nIGRldiB0b29scycpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFdpbmRvdzpcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNob3dEZXZlbG9wZXJUb29scygpIHtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIHJldHVybiB3aW4uc2hvd0RldmVsb3BlclRvb2xzKCk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogc2hvd0RldmVsb3BlcnRvb2xzKClcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2hvd2luZyBkZXYgdG9vbHMnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIHNob3dEZXZlbG9wZXJUb29scygpIHtcbiAgICAgICAgLy8gTm90ZSB0aGlzIGhpdHMgdGhlIHN5c3RlbSBhY3Rpb24gbWFwIGluIGNvcmUgc3RhdGUgZm9yIGxlZ2FjeSByZWFzb25zLlxuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy1kZXZlbG9wZXItdG9vbHMnLCB0aGlzLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBwcm9jZXNzIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgd2l0aCBhIFdlYkNvbnRlbnRzLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBpbmNsdWRlcyBhbnkgaWZyYW1lcyBhc3NvY2lhdGVkIHdpdGggdGhlIFdlYkNvbnRlbnRzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgY29uc3QgcHJvY2Vzc0luZm8gPSBhd2FpdCB2aWV3LmdldFByb2Nlc3NJbmZvKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG4gICAgICogICAgIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgd2luLmdldFByb2Nlc3NJbmZvKCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGdldFByb2Nlc3NJbmZvKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgZGF0YSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByb2Nlc3MtaW5mbycsIHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIG9uIGFsbCBTaGFyZWQgV29ya2Vycy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9tZG4uZ2l0aHViLmlvL2RvbS1leGFtcGxlcy93ZWItd29ya2Vycy9zaW1wbGUtc2hhcmVkLXdvcmtlci8nKTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBzaGFyZWRXb3JrZXJzID0gYXdhaXQgdmlldy5nZXRTaGFyZWRXb3JrZXJzKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luT3B0aW9uID0ge1xuICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuICAgICAqICAgICAgICAgZGVmYXVsdFdpZHRoOiAzMDAsXG4gICAgICogICAgICAgICBkZWZhdWx0SGVpZ2h0OiAzMDAsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycsXG4gICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcbiAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG4gICAgICogICAgIH07XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG4gICAgICogICAgIGNvbnN0IHNoYXJlZFdvcmtlcnMgPSBhd2FpdCB3aW4uZ2V0U2hhcmVkV29ya2VycygpO1xuICAgICAqIGBgYFxuICAgICAqIEByZW1hcmtzXG4gICAgICogYFdlYkNvbnRlbnRzYCByZWZlcnMgdG8gc2hhcmVkIGZ1bmN0aW9uYWxpdHkgYmV0d2VlbiB7QGxpbmsgT3BlbkZpbi5XaW5kb3d9IGFuZCB7QGxpbmsgT3BlbkZpbi5WaWV3fS5cbiAgICAgKiBXZSBkbyBub3QgZXhwb3NlIGFuIGV4cGxpY2l0IHN1cGVyY2xhc3MgZm9yIHRoaXMgZnVuY3Rpb25hbGl0eSwgYnV0IGl0IGRvZXMgaGF2ZSBpdHMgb3duXG4gICAgICoge0BsaW5rIE9wZW5GaW4uV2ViQ29udGVudHNFdmVudHMgZXZlbnQgbmFtZXNwYWNlfS5cbiAgICAgKi9cbiAgICBhc3luYyBnZXRTaGFyZWRXb3JrZXJzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1zaGFyZWQtd29ya2VycycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZGV2ZWxvcGVyIHRvb2xzIGZvciB0aGUgc2hhcmVkIHdvcmtlciBjb250ZXh0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBWaWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lJyxcbiAgICAgKiAgICAgICAgIHRhcmdldDogZmluLm1lLmlkZW50aXR5LFxuICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHZpZXcuaW5zcGVjdFNoYXJlZFdvcmtlcigpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhhbXBsZTpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB3aW5PcHRpb24gPSB7XG4gICAgICogICAgICAgICBuYW1lOidjaGlsZCcsXG4gICAgICogICAgICAgICBkZWZhdWx0V2lkdGg6IDMwMCxcbiAgICAgKiAgICAgICAgIGRlZmF1bHRIZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vbWRuLmdpdGh1Yi5pby9kb20tZXhhbXBsZXMvd2ViLXdvcmtlcnMvc2ltcGxlLXNoYXJlZC13b3JrZXIvJyxcbiAgICAgKiAgICAgICAgIGZyYW1lOiB0cnVlLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLmluc3BlY3RTaGFyZWRXb3JrZXIoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgYXN5bmMgaW5zcGVjdFNoYXJlZFdvcmtlcigpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2luc3BlY3Qtc2hhcmVkLXdvcmtlcicsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zcGVjdHMgdGhlIHNoYXJlZCB3b3JrZXIgYmFzZWQgb24gaXRzIElELlxuICAgICAqIEBwYXJhbSB3b3JrZXJJZCAtIFRoZSBpZCBvZiB0aGUgc2hhcmVkIHdvcmtlci5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9tZG4uZ2l0aHViLmlvL2RvbS1leGFtcGxlcy93ZWItd29ya2Vycy9zaW1wbGUtc2hhcmVkLXdvcmtlci8nKTtcbiAgICAgKlxuICAgICAqICAgICBjb25zdCBzaGFyZWRXb3JrZXJzID0gYXdhaXQgdmlldy5nZXRTaGFyZWRXb3JrZXJzKCk7XG4gICAgICogICAgIGF3YWl0IHZpZXcuaW5zcGVjdFNoYXJlZFdvcmtlckJ5SWQoc2hhcmVkV29ya2Vyc1swXS5pZCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXaW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgY29uc3Qgd2luT3B0aW9uID0ge1xuICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuICAgICAqICAgICAgICAgZGVmYXVsdFdpZHRoOiAzMDAsXG4gICAgICogICAgICAgICBkZWZhdWx0SGVpZ2h0OiAzMDAsXG4gICAgICogICAgICAgICB1cmw6ICdodHRwczovL21kbi5naXRodWIuaW8vZG9tLWV4YW1wbGVzL3dlYi13b3JrZXJzL3NpbXBsZS1zaGFyZWQtd29ya2VyLycsXG4gICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcbiAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG4gICAgICogICAgIH07XG4gICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG4gICAgICogICAgIGNvbnN0IHNoYXJlZFdvcmtlcnMgPSBhd2FpdCB3aW4uZ2V0U2hhcmVkV29ya2VycygpO1xuICAgICAqICAgICBhd2FpdCB3aW4uaW5zcGVjdFNoYXJlZFdvcmtlckJ5SWQoc2hhcmVkV29ya2Vyc1swXS5pZCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGluc3BlY3RTaGFyZWRXb3JrZXJCeUlkKHdvcmtlcklkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnNwZWN0LXNoYXJlZC13b3JrZXItYnktaWQnLCB7IC4uLnRoaXMuaWRlbnRpdHksIHdvcmtlcklkIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZGV2ZWxvcGVyIHRvb2xzIGZvciB0aGUgc2VydmljZSB3b3JrZXIgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVmlldzpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHtcbiAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZScsXG4gICAgICogICAgICAgICB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSxcbiAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cbiAgICAgKiAgICAgfSk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cDovL2dvb2dsZWNocm9tZS5naXRodWIuaW8vc2FtcGxlcy9zZXJ2aWNlLXdvcmtlci9iYXNpYy9pbmRleC5odG1sJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgdmlldy5pbnNwZWN0U2VydmljZVdvcmtlcigpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2luZG93OlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIGNvbnN0IHdpbk9wdGlvbiA9IHtcbiAgICAgKiAgICAgICAgIG5hbWU6J2NoaWxkJyxcbiAgICAgKiAgICAgICAgIGRlZmF1bHRXaWR0aDogMzAwLFxuICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuICAgICAqICAgICAgICAgdXJsOiAnaHR0cDovL2dvb2dsZWNocm9tZS5naXRodWIuaW8vc2FtcGxlcy9zZXJ2aWNlLXdvcmtlci9iYXNpYy9pbmRleC5odG1sJyxcbiAgICAgKiAgICAgICAgIGZyYW1lOiB0cnVlLFxuICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcbiAgICAgKiAgICAgfTtcbiAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcbiAgICAgKiAgICAgYXdhaXQgd2luLmluc3BlY3RTZXJ2aWNlV29ya2VyKCk7XG4gICAgICogYGBgXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBgV2ViQ29udGVudHNgIHJlZmVycyB0byBzaGFyZWQgZnVuY3Rpb25hbGl0eSBiZXR3ZWVuIHtAbGluayBPcGVuRmluLldpbmRvd30gYW5kIHtAbGluayBPcGVuRmluLlZpZXd9LlxuICAgICAqIFdlIGRvIG5vdCBleHBvc2UgYW4gZXhwbGljaXQgc3VwZXJjbGFzcyBmb3IgdGhpcyBmdW5jdGlvbmFsaXR5LCBidXQgaXQgZG9lcyBoYXZlIGl0cyBvd25cbiAgICAgKiB7QGxpbmsgT3BlbkZpbi5XZWJDb250ZW50c0V2ZW50cyBldmVudCBuYW1lc3BhY2V9LlxuICAgICAqL1xuICAgIGFzeW5jIGluc3BlY3RTZXJ2aWNlV29ya2VyKCkge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignaW5zcGVjdC1zZXJ2aWNlLXdvcmtlcicsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgYSBwb3B1cCB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBOb3RlOiBJZiB0aGlzIFdlYkNvbnRlbnRzIGlzIGEgdmlldyBhbmQgaXRzIGF0dGFjaGVkIHdpbmRvdyBoYXMgYSBwb3B1cCBvcGVuLCB0aGlzIHdpbGwgY2xvc2UgaXQuXG4gICAgICpcbiAgICAgKiBTaG93cyBhIHBvcHVwIHdpbmRvdy4gSW5jbHVkaW5nIGEgYG5hbWVgIGluIGBvcHRpb25zYCB3aWxsIGF0dGVtcHQgdG8gc2hvdyBhbiBleGlzdGluZyB3aW5kb3cgYXMgYSBwb3B1cCwgaWZcbiAgICAgKiB0aGF0IHdpbmRvdyBkb2Vzbid0IGV4aXN0IG9yIG5vIGBuYW1lYCBpcyBpbmNsdWRlZCBhIHdpbmRvdyB3aWxsIGJlIGNyZWF0ZWQuIElmIHRoZSBjYWxsZXIgdmlldyBvciB0aGUgY2FsbGVyXG4gICAgICogdmlldydzIHBhcmVudCB3aW5kb3cgY3VycmVudGx5IGhhcyBhIHBvcHVwIHdpbmRvdyBvcGVuLCBjYWxsaW5nIGBzaG93UG9wdXBXaW5kb3dgIGFnYWluIHdpbGwgZGlzbWlzcyB0aGUgY3VycmVudGx5XG4gICAgICogb3BlbiBwb3B1cCB3aW5kb3cgYmVmb3JlIHNob3dpbmcgdGhlIG5ldyBwb3B1cCB3aW5kb3cuIEFsc28sIGlmIHRoZSBjYWxsZXIgdmlldyBpcyBkZXN0cm95ZWQgb3IgZGV0YWNoZWQsIHRoZSBwb3B1cFxuICAgICAqIHdpbGwgYmUgZGlzbWlzc2VkLlxuICAgICAqXG4gICAgICogTm90ZTogaW4gdGhlIGNhc2Ugd2hlcmUgdGhlIHdpbmRvdyBiZWluZyBzaG93biBhcyBhIHBvcHVwIG5lZWRzIHRvIGJlIGNyZWF0ZWQsIGl0IGlzIGEgY2hpbGQgb2YgdGhlIGNhbGxlciB2aWV3J3MgcGFyZW50IHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYW5kIHNob3cgYSBzaW5nbGUtdXNlIHBvcHVwIHdpbmRvdyB0aGF0IHJldHVybnMgYSBzaW5nbGUgcmVzdWx0IHRvIHRoZSBjYWxsZXIuIGBpbml0aWFsT3B0aW9uc2AgYWxsb3dzXG4gICAgICogdXMgdG8gcGFzcyB3aW5kb3cgb3B0aW9ucyB0byB0aGUgcG9wdXAgd2luZG93IHRoYXQgd2lsbCBiZSBjcmVhdGVkLiBgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJ2AgZW5zdXJlc1xuICAgICAqIHRoYXQgb25jZSB0aGUgcG9wdXAgd2luZG93IGNhbGxzIGBkaXNwYXRjaFBvcHVwUmVzdWx0YCBpdCBpcyBjbG9zZWQuIGBibHVyQmVoYXZpb3I6ICdjbG9zZSdgIHdpbGwgeWllbGQgYSBkaXNtaXNzZWRcbiAgICAgKiByZXN1bHQgc2hvdWxkIHRoZSBwb3B1cCB3aW5kb3cgbG9zZSBmb2N1cy5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIGluaXRpYWxPcHRpb25zOiB7XG4gICAgICogICAgICAgICBmcmFtZTogZmFsc2VcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdjbG9zZScsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogU2FtZSBhcyBhYm92ZSBidXQgdXNpbmcgYW4gZXhpc3Rpbmcgd2luZG93IGFzIGEgcG9wdXAgYnkgcmVmZXJlbmNpbmcgaXRzIGBuYW1lYDpcbiAgICAgKlxuICAgICAqIE5vdGU6IGlmIGEgd2luZG93IHdpdGggdGhlIGBuYW1lYCBwcm92aWRlZCBkb2Vzbid0IGV4aXN0LCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBpbml0aWFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgZnJhbWU6IHRydWVcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbmFtZTogJ215LXBvcHVwJywgLy8gc2hvd3MgdGhlICdteS1wb3B1cCcgd2luZG93IGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIGNyZWF0ZXMgaXRcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLCAvLyBuYXZpZ2F0ZXMgdG8gdGhpcyB1cmwgaWYgaXQgZG9lc24ndCBtYXRjaCB0aGUgbG9jYXRpb24uaHJlZiBvZiB0aGUgJ215LXBvcHVwJyB3aW5kb3dcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIHBlcnNpc3Qgd2luZG93IG9uICdkaXNtaXNzZWQnIHJlc3VsdCwgYWx0ZXJuYXRpdmVseSBjaGFuZ2Ugb25SZXN1bHREaXNwYXRjaCBhbmQgYmx1ckJlaGF2aW9yIHRvICdoaWRlJ1xuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIGFuZCBzaG93IGEgcG9wdXAgd2luZG93IHRoYXQgaXMgYWJsZSB0byByZXR1cm4gbXVsdGlwbGUgcmVzdWx0cyB0byB0aGUgY2FsbGVyIHZpYSBhbiBgb25Qb3B1cFJlc3VsdGAgY2FsbGJhY2suIEVhY2hcbiAgICAgKiB0aW1lIHRoZSBwb3B1cCB3aW5kb3cgY2FsbHMgYGRpc3BhdGNoUG9wdXBSZXN1bHRgLCB0aGUgY2FsbGJhY2sgd2lsbCBiZSBleGVjdXRlZCBvbiB0aGUgcmVzdWx0LiBPbmNlIHRoZSBwb3B1cCB3aW5kb3cgaXNcbiAgICAgKiBjbG9zZWQgb3IgaGlkZGVuLCB0aGUgYHNob3dQb3B1cFdpbmRvd2AgcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhIGBkaXNtaXNzZWRgIHJlc3VsdCB0aGF0IHdpbGwgaW5jbHVkZSB0aGUgbW9zdCByZWNlbnRseVxuICAgICAqIGRpc3BhdGNoZWQgcmVzdWx0IGFzIGBsYXN0RGlzcGF0Y2hSZXN1bHRgOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFJlc3VsdENhbGxiYWNrID0gKHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgaWYgKHBheWxvYWQucmVzdWx0ID09PSAnY2xpY2tlZCcpIHtcbiAgICAgKiAgICAgICAgICAgIGlmIChwYXlsb2FkLmRhdGEudG9waWMgPT09ICdjb2xvci1jaGFuZ2VkJykge1xuICAgICAqICAgICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBsaWtlXG4gICAgICogICAgICAgICAgICAgICAgLy8gc2V0Q29sb3IocGF5bG9hZC5kYXRhLnZhbHVlKTtcbiAgICAgKiAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4ubWUuc2hvd1BvcHVwV2luZG93KHtcbiAgICAgKiAgICAgaW5pdGlhbE9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGZyYW1lOiBmYWxzZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICB1cmw6ICc8bXlfcG9wdXBfdXJsPicsXG4gICAgICogICAgIHJlc3VsdERpc3BhdGNoQmVoYXZpb3I6ICdub25lJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDAsXG4gICAgICogICAgIG9uUG9wdXBSZXN1bHQ6IHBvcHVwUmVzdWx0Q2FsbGJhY2tcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFNhbWUgYXMgYWJvdmUgYnV0IHVzaW5nIGFuIGV4aXN0aW5nIHdpbmRvdyBhcyBhIHBvcHVwOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFJlc3VsdENhbGxiYWNrID0gKHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgaWYgKHBheWxvYWQucmVzdWx0ID09PSAnY2xpY2tlZCcpIHtcbiAgICAgKiAgICAgICAgICAgIGlmIChwYXlsb2FkLmRhdGEudG9waWMgPT09ICdjb2xvci1jaGFuZ2VkJykge1xuICAgICAqICAgICAgICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBsaWtlXG4gICAgICogICAgICAgICAgICAgICAgLy8gc2V0Q29sb3IocGF5bG9hZC5kYXRhLnZhbHVlKTtcbiAgICAgKiAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4ubWUuc2hvd1BvcHVwV2luZG93KHtcbiAgICAgKiAgICAgaW5pdGlhbE9wdGlvbnM6IHtcbiAgICAgKiAgICAgICAgIGZyYW1lOiBmYWxzZVxuICAgICAqICAgICB9LFxuICAgICAqICAgICBuYW1lOiAnbXktcG9wdXAnLCAvLyBzaG93cyB0aGUgJ215LXBvcHVwJyB3aW5kb3cgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgY3JlYXRlcyBpdFxuICAgICAqICAgICB1cmw6ICc8bXlfcG9wdXBfdXJsPicsIC8vIG5hdmlnYXRlcyB0byB0aGlzIHVybCBpZiBpdCBkb2Vzbid0IG1hdGNoIHRoZSBsb2NhdGlvbi5ocmVmIG9mIHRoZSAnbXktcG9wdXAnIHdpbmRvd1xuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnbm9uZScsXG4gICAgICogICAgIGJsdXJCZWhhdmlvcjogJ2hpZGUnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGlkZU9uQ2xvc2U6IHRydWUsIC8vIHdlIGNhbiBqdXN0IHVzZSB0aGlzIG9yIHdlIGNhbiBjaGFuZ2UgYmx1ckJlaGF2aW9yIHRvICdoaWRlJ1xuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMCxcbiAgICAgKiAgICAgb25Qb3B1cFJlc3VsdDogcG9wdXBSZXN1bHRDYWxsYmFja1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIG9yIHNob3cgYSBwb3B1cCB3aW5kb3cgdGhhdCBkaXNhYmxlcyB1c2VyIG1vdmVtZW50IChwb3NpdGlvbmluZyBhbmQgcmVzaXppbmcpIGluIHRoZSBjYWxsZXJcbiAgICAgKiB2aWV3J3MgcGFyZW50IHdpbmRvdyBieSB1c2luZyBgYmx1ckJlaGF2aW9yOiAnbW9kYWwnYDpcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIGluaXRpYWxPcHRpb25zOiB7XG4gICAgICogICAgICAgICBmcmFtZTogZmFsc2VcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdtb2RhbCcsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQ3JlYXRlIGEgcG9wdXAgd2luZG93IGFzIGEgbW9kYWw6XG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGUgb25seSB3YXkgdG8gZW5zdXJlIHRydWUgbW9kYWwgYmVoYXZpb3IgaXMgdG8gY3JlYXRlIHRoZSB3aW5kb3cgYmVpbmcgc2hvd24gYXMgYSBwb3B1cCB3aXRoIGFcbiAgICAgKiBgbW9kYWxQYXJlbnRJZGVudGl0eWAgdGhhdCB1c2VzIHRoZSBjYWxsZXIgdmlldydzIHBhcmVudCB3aW5kb3cgaWRlbnRpdHkuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBpbml0aWFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgZnJhbWU6IGZhbHNlLFxuICAgICAqICAgICAgICAgbW9kYWxQYXJlbnRJZGVudGl0eTogZmluLm1lLmlkZW50aXR5XG4gICAgICogICAgIH0sXG4gICAgICogICAgIHVybDogJzxteV9wb3B1cF91cmw+JyxcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnbW9kYWwnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDBcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFBhc3MgZGF0YSB0byBhIHBvcHVwIHdpbmRvdyB0aGF0IGlzIGF2YWlsYWJsZSB3aGVuIHRoZSBwb3B1cCBpcyBzaG93bi5cbiAgICAgKlxuICAgICAqIE5vdGU6IHRoaXMgaXMganVzdCBvbmUgZXhhbXBsZSBmb3IgYSB1c2Ugb2YgYGFkZGl0aW9uYWxPcHRpb25zYCwgaXQgY2FuIGJlIHVzZWQgdG8gdXBkYXRlIGFueSB1cGRhdGFibGVcbiAgICAgKiB3aW5kb3cgb3B0aW9ucyB3aGVuIGNyZWF0aW5nIG9yIHNob3dpbmcgYW4gZXhpc3Rpbmcgd2luZG93IGFzIGEgcG9wdXAuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbi5tZS5zaG93UG9wdXBXaW5kb3coe1xuICAgICAqICAgICBhZGRpdGlvbmFsT3B0aW9uczoge1xuICAgICAqICAgICAgICAgY3VzdG9tRGF0YToge1xuICAgICAqICAgICAgICAgICAgIGZvbzogJ2JhcidcbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdXJsOiAnPG15X3BvcHVwX3VybD4nLFxuICAgICAqICAgICByZXN1bHREaXNwYXRjaEJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBibHVyQmVoYXZpb3I6ICdjbG9zZScsXG4gICAgICogICAgIGZvY3VzOiB0cnVlLFxuICAgICAqICAgICBoZWlnaHQ6IDMwMCxcbiAgICAgKiAgICAgd2lkdGg6IDMwMCxcbiAgICAgKiAgICAgeDogMCxcbiAgICAgKiAgICAgeTogMFxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogLy8gQWNjZXNzIGZyb20gdGhlIHBvcHVwIHdpbmRvdyBjb250ZXh0IGxpa2Ugc286XG4gICAgICogY29uc3QgeyBjdXN0b21EYXRhIH0gPSBhd2FpdCBmaW4ubWUuZ2V0T3B0aW9ucygpO1xuICAgICAqIGNvbnN0IHsgZm9vIH0gPSBjdXN0b21EYXRhO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhlY3V0ZSBhIGNhbGxiYWNrIG9uIHRoZSBwb3B1cCdzIE9wZW5GaW4gd2luZG93IHdoZW4gdGhlIHBvcHVwIGlzIHNob3duOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwb3B1cFdpbmRvd0NhbGxiYWNrID0gYXN5bmMgKHdpbikgPT4ge1xuICAgICAqICAgICBhd2FpdCB3aW4uZmxhc2goKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluLm1lLnNob3dQb3B1cFdpbmRvdyh7XG4gICAgICogICAgIHVybDogJzxteV9wb3B1cF91cmw+JyxcbiAgICAgKiAgICAgcmVzdWx0RGlzcGF0Y2hCZWhhdmlvcjogJ2Nsb3NlJyxcbiAgICAgKiAgICAgYmx1ckJlaGF2aW9yOiAnY2xvc2UnLFxuICAgICAqICAgICBmb2N1czogdHJ1ZSxcbiAgICAgKiAgICAgaGVpZ2h0OiAzMDAsXG4gICAgICogICAgIHdpZHRoOiAzMDAsXG4gICAgICogICAgIHg6IDAsXG4gICAgICogICAgIHk6IDAsXG4gICAgICogICAgIG9uUG9wdXBSZWFkeTogcG9wdXBXaW5kb3dDYWxsYmFjaztcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIGBXZWJDb250ZW50c2AgcmVmZXJzIHRvIHNoYXJlZCBmdW5jdGlvbmFsaXR5IGJldHdlZW4ge0BsaW5rIE9wZW5GaW4uV2luZG93fSBhbmQge0BsaW5rIE9wZW5GaW4uVmlld30uXG4gICAgICogV2UgZG8gbm90IGV4cG9zZSBhbiBleHBsaWNpdCBzdXBlcmNsYXNzIGZvciB0aGlzIGZ1bmN0aW9uYWxpdHksIGJ1dCBpdCBkb2VzIGhhdmUgaXRzIG93blxuICAgICAqIHtAbGluayBPcGVuRmluLldlYkNvbnRlbnRzRXZlbnRzIGV2ZW50IG5hbWVzcGFjZX0uXG4gICAgICovXG4gICAgYXN5bmMgc2hvd1BvcHVwV2luZG93KG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oYCR7dGhpcy5lbnRpdHlUeXBlfS1zaG93LXBvcHVwLXdpbmRvd2AsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9wdGlvbnM/Lm9uUG9wdXBSZWFkeSkge1xuICAgICAgICAgICAgY29uc3QgcmVhZHlMaXN0ZW5lciA9IGFzeW5jICh7IHBvcHVwTmFtZSB9KSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9wdXBXaW5kb3cgPSB0aGlzLmZpbi5XaW5kb3cud3JhcFN5bmMoeyB1dWlkOiB0aGlzLmZpbi5tZS51dWlkLCBuYW1lOiBwb3B1cE5hbWUgfSk7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG9wdGlvbnMub25Qb3B1cFJlYWR5KHBvcHVwV2luZG93KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU29tZXRoaW5nIHdlbnQgd3JvbmcgZHVyaW5nIG9uUG9wdXBSZWFkeSBleGVjdXRpb246ICR7ZXJyb3J9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGludGVybmFsKVxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbmNlKCdwb3B1cC1yZWFkeScsIHJlYWR5TGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogdHJ5Q3JlYXRlUGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3RyeS1jcmVhdGUtcG9wdXAtd2luZG93Jywge1xuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgLy8gSW50ZXJuYWwgdXNlIG9ubHkuXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIGhhc1Jlc3VsdENhbGxiYWNrOiAhIW9wdGlvbnM/Lm9uUG9wdXBSZXN1bHQsXG4gICAgICAgICAgICAgICAgaGFzUmVhZHlDYWxsYmFjazogISFvcHRpb25zPy5vblBvcHVwUmVhZHlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IGRhdGE6IHsgd2lsbE9wZW4sIG9wdGlvbnM6IHBvcHVwT3B0aW9ucyB9IH0gPSB0cnlDcmVhdGVQYXlsb2FkO1xuICAgICAgICBpZiAod2lsbE9wZW4pIHtcbiAgICAgICAgICAgIC8vIFNvbHZlIHRoZSBpc3N1ZSB3aGVyZSBJbnRlcm9wIGluIGEgcG9wdXAgd2luZG93IHdpdGggbm9uIGNyb3NzLW9yaWdpbiB1cmwgaXMgbm90IHdvcmtpbmcoY29yZS0xMDc2KS5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZmluLldpbmRvdy5jcmVhdGUocG9wdXBPcHRpb25zLmluaXRpYWxPcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBub3JtYWxpemVQb3B1cFJlc3VsdCA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IG5hbWUsIHV1aWQsIHJlc3VsdCwgZGF0YSB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgIGNvbnN0IHBvcHVwUmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIGlkZW50aXR5OiB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHV1aWRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgcG9wdXBSZXN1bHQuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcG9wdXBSZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICAgIGlmIChvcHRpb25zPy5vblBvcHVwUmVzdWx0KSB7XG4gICAgICAgICAgICBjb25zdCBkaXNwYXRjaFJlc3VsdExpc3RlbmVyID0gYXN5bmMgKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBvcHRpb25zLm9uUG9wdXBSZXN1bHQobm9ybWFsaXplUG9wdXBSZXN1bHQocGF5bG9hZCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHRlYXJkb3duTGlzdGVuZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogZml4IHR5cGluZyAoaW50ZXJuYWwpXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3BvcHVwLXJlc3VsdCcsIGRpc3BhdGNoUmVzdWx0TGlzdGVuZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGludGVybmFsKVxuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbigncG9wdXAtcmVzdWx0JywgZGlzcGF0Y2hSZXN1bHRMaXN0ZW5lcik7XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgIC8vIGhpbGFyaW91c2x5IHRoaXMgZG9lcyBub3QgbmVlZCBhIHRzLWV4cGVjdC1lcnJvciAtIHRoaXMgaXMgZ2FwIGluIHR5cGUgc291bmRuZXNzXG4gICAgICAgICAgICAvLyBzaG91bGQgaW52ZXN0aWdhdGUgLSBwcm9iYWJseSBkdWUgdG8gYHRlYXJkb3duTGlzdGVuZXJgIHRha2luZyBhIHZvaWQgYXJndW1lbnRcbiAgICAgICAgICAgIC8vIHdoaWNoIG1pZ2h0IHBsYXkgbmljZWx5IHdpdGggdGhlIGBuZXZlcmAgdHlwZT8gIGh1aC4uLlxuICAgICAgICAgICAgYXdhaXQgdGhpcy5vbmNlKCdwb3B1cC10ZWFyZG93bicsIHRlYXJkb3duTGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctcG9wdXAtd2luZG93Jywge1xuICAgICAgICAgICAgb3B0aW9uczogcG9wdXBPcHRpb25zLFxuICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG59XG5tYWluLldlYkNvbnRlbnRzID0gV2ViQ29udGVudHM7XG5cbnZhciBoYXNSZXF1aXJlZEluc3RhbmNlJDI7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSQyICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkSW5zdGFuY2UkMikgcmV0dXJuIEluc3RhbmNlJDU7XG5cdGhhc1JlcXVpcmVkSW5zdGFuY2UkMiA9IDE7XG5cdHZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcblx0ICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcblx0ICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuXHQgICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcblx0fTtcblx0dmFyIF9WaWV3X3Byb3ZpZGVyQ2hhbm5lbENsaWVudDtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDUsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRJbnN0YW5jZSQ1LlZpZXcgPSB2b2lkIDA7XG5cdGNvbnN0IHRyYW5zcG9ydF9lcnJvcnNfMSA9IHRyYW5zcG9ydEVycm9ycztcblx0Y29uc3QgbGF6eV8xID0gbGF6eTtcblx0Y29uc3QgbGF5b3V0X2VudGl0aWVzXzEgPSBsYXlvdXRFbnRpdGllcztcblx0Y29uc3QgbGF5b3V0X2NvbnN0YW50c18xID0gbGF5b3V0X2NvbnN0YW50cztcblx0Y29uc3QgbWFpbl8xID0gbWFpbjtcblx0Y29uc3Qgd2luZG93XzEgPSByZXF1aXJlV2luZG93KCk7XG5cdC8qKlxuXHQgKiBBIFZpZXcgY2FuIGJlIHVzZWQgdG8gZW1iZWQgYWRkaXRpb25hbCB3ZWIgY29udGVudCBpbnRvIGEgV2luZG93LlxuXHQgKiBJdCBpcyBsaWtlIGEgY2hpbGQgd2luZG93LCBleGNlcHQgaXQgaXMgcG9zaXRpb25lZCByZWxhdGl2ZSB0byBpdHMgb3duaW5nIHdpbmRvdy5cblx0ICogSXQgaGFzIHRoZSBhYmlsaXR5IHRvIGxpc3RlbiBmb3Ige0BsaW5rIE9wZW5GaW4uVmlld0V2ZW50cyBWaWV3LXNwZWNpZmljIGV2ZW50c30uXG5cdCAqXG5cdCAqIEJ5IGRlZmF1bHQsIGEgVmlldyB3aWxsIHRyeSB0byBzaGFyZSB0aGUgc2FtZSByZW5kZXJlciBwcm9jZXNzIGFzIG90aGVyIFZpZXdzIG93bmVkIGJ5IGl0cyBwYXJlbnQgQXBwbGljYXRpb24uXG5cdCAqIFRvIGNoYW5nZSB0aGF0IGJlaGF2aW9yLCBzZWUgdGhlIHByb2Nlc3NBZmZpbml0eSB7QGxpbmsgT3BlbkZpbi5WaWV3T3B0aW9ucyB2aWV3IG9wdGlvbn0uXG5cdCAqXG5cdCAqIEEgVmlldydzIGxpZmVjeWNsZSBpcyB0aWVkIHRvIGl0cyBvd25pbmcgd2luZG93IGFuZCBjYW4gYmUgcmUtYXR0YWNoZWQgdG8gYSBkaWZmZXJlbnQgd2luZG93IGF0IGFueSBwb2ludCBkdXJpbmcgaXRzIGxpZmVjeWNsZS5cblx0ICovXG5cdGNsYXNzIFZpZXcgZXh0ZW5kcyBtYWluXzEuV2ViQ29udGVudHMge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCBpZGVudGl0eSwgJ3ZpZXcnKTtcblx0ICAgICAgICB0aGlzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5cdCAgICAgICAgX1ZpZXdfcHJvdmlkZXJDaGFubmVsQ2xpZW50LnNldCh0aGlzLCBuZXcgbGF6eV8xLkxhenkoKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IHRoaXMuZmluLlBsYXRmb3JtLndyYXBTeW5jKHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgICAgICAgICByZXR1cm4gcGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG5cdCAgICAgICAgfSkpO1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEF0dGFjaGVzIHRoZSBjdXJyZW50IHZpZXcgdG8gdGhlIGdpdmVuIHdpbmRvdyBpZGVudGl0eS5cblx0ICAgICAgICAgKiBJZGVudGl0eSBtdXN0IGJlIHRoZSBpZGVudGl0eSBvZiBhIHdpbmRvdyBpbiB0aGUgc2FtZSBhcHBsaWNhdGlvbi5cblx0ICAgICAgICAgKiBUaGlzIGRldGFjaGVzIHRoZSB2aWV3IGZyb20gaXRzIGN1cnJlbnQgd2luZG93LCBhbmQgc2V0cyB0aGUgdmlldyB0byBiZSBkZXN0cm95ZWQgd2hlbiBpdHMgbmV3IHdpbmRvdyBjbG9zZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVBdHRhY2gnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gYXR0YWNoVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBjb25zdCB3aW5PcHRpb24gPSB7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOid3aW5PcHRpb25OYW1lJyxcblx0ICAgICAgICAgKiAgICAgICAgIGRlZmF1bHRXaWR0aDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5jcmVhdGUuaHRtbCcsXG5cdCAgICAgICAgICogICAgICAgICBmcmFtZTogdHJ1ZSxcblx0ICAgICAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgICAgICogICAgIH07XG5cdCAgICAgICAgICogICAgIGNvbnN0IG5ld1dpbmRvdyA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHdpbk9wdGlvbik7XG5cdCAgICAgICAgICogICAgIHZpZXcuYXR0YWNoKG5ld1dpbmRvdy5pZGVudGl0eSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXR0YWNoVmlldygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IGF0dGFjaGVkIHRvIG5ldyB3aW5kb3cuJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuYXR0YWNoID0gYXN5bmMgKHRhcmdldCkgPT4ge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignYXR0YWNoLXZpZXcnLCB7IHRhcmdldCwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlc3Ryb3lzIHRoZSBjdXJyZW50IHZpZXdcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBjb25zdCB2aWV3ID0gZmluLlZpZXcud3JhcFN5bmMoeyB1dWlkOiAndmlld1V1aWQnLCBuYW1lOiAndmlld05hbWUnIH0pO1xuXHQgICAgICAgICAqIHZpZXcuZGVzdHJveSgpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmRlc3Ryb3kgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdkZXN0cm95LXZpZXcnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBTaG93cyB0aGUgY3VycmVudCB2aWV3IGlmIGl0IGlzIGN1cnJlbnRseSBoaWRkZW4uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVTaG93Jyxcblx0ICAgICAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgICAgICogICAgICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIGhpZGVBbmRTaG93VmlldygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybCBvcHRpb24uJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5oaWRlKCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKFwiVmlldyBoaWRkZW4uXCIpO1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZpZXcuc2hvdygpO1xuXHQgICAgICAgICAqICAgICBjb25zb2xlLmxvZyhcIlZpZXcgc2hvd24uXCIpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGhpZGVBbmRTaG93VmlldygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IGhpZGRlbiBhbmQgc2hvd24uJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuc2hvdyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctdmlldycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFNldHMgdGhlIGJvdW5kcyAodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgdmlldyByZWxhdGl2ZSB0byBpdHMgd2luZG93IGFuZCBzaG93cyBpdCBpZiBpdCBpcyBoaWRkZW4uXG5cdCAgICAgICAgICogVGhpcyBtZXRob2QgZW5zdXJlcyB0aGUgdmlldyBpcyBib3RoIHBvc2l0aW9uZWQgYW5kIHNob3dpbmcuIEl0IHdpbGwgcmVwb3NpdGlvbiBhIHZpc2libGUgdmlldyBhbmQgYm90aCBzaG93IGFuZCByZXBvc2l0aW9uIGEgaGlkZGVuIHZpZXcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmVtYXJrcyBWaWV3IHBvc2l0aW9uIGlzIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAgICAgKiAoe3RvcDogMCwgbGVmdDogMH0gcmVwcmVzZW50cyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cpXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICBuYW1lOiAndmlld05hbWVTZXRCb3VuZHMnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd1ZpZXdBdCgpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3LnNob3dBdCh7XG5cdCAgICAgICAgICogICAgICAgICB0b3A6IDEwMCxcblx0ICAgICAgICAgKiAgICAgICAgIGxlZnQ6IDEwMCxcblx0ICAgICAgICAgKiAgICAgICAgIHdpZHRoOiAzMDAsXG5cdCAgICAgICAgICogICAgICAgICBoZWlnaHQ6IDMwMFxuXHQgICAgICAgICAqICAgICB9LCB7XG5cdCAgICAgICAgICogICAgICAgYnJpbmdUb0Zyb250IDogdHJ1ZVxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBzaG93Vmlld0F0KClcblx0ICAgICAgICAgKiAgICAgLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1ZpZXcgc2V0IHRvIG5ldyBib3VuZHMgYW5kIHNob3duLicpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnNob3dBdCA9IGFzeW5jIChib3VuZHMsIG9wdGlvbnMgPSB7fSkgPT4ge1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy12aWV3LWF0JywgeyBib3VuZHMsIC4uLnRoaXMuaWRlbnRpdHksIG9wdGlvbnMgfSk7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBCcmluZ3MgdGhlIHNwZWNpZmllZCB2aWV3IHRvIHRoZSBmcm9udCBvZiBpdHMgY3VycmVudCB3aW5kb3cuIFRoaXMgZW5zdXJlcyB0aGUgdmlldyB3aWxsIGJlIHZpc2libGUgb24gdG9wIG9mIGFueSBvdGhlciB2aWV3c1xuXHQgICAgICAgICAqIHdoaWNoIGhhdmUgb3ZlcmxhcHBpbmcgYm91bmRzIHdpdGggaXQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBQbGVhc2Ugbm90ZSwgdGhpcyBpcyBub3QgYSBwZXJtYW5lbnQgYWN0aW9uIC0gd2hlbiBhIG5ldyB2aWV3IGlzIGNyZWF0ZWQgb3IgYXR0YWNoZWQgdG8gdGhlIHdpbmRvdywgaXQgd2lsbCBkaXNwbGF5IG9uIHRvcCBvZiBhbGwgb3RoZXIgdmlld3Ncblx0ICAgICAgICAgKiBpbiB0aGUgd2luZG93IHRoYXQgc2hhcmUgYm91bmRzIHdpdGggaXQuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5icmluZ1RvRnJvbnQgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdicmluZy12aWV3LXRvLWZyb250JywgeyAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSGlkZXMgdGhlIGN1cnJlbnQgdmlldyBpZiBpdCBpcyBjdXJyZW50bHkgdmlzaWJsZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUhpZGUnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gaGlkZVZpZXcoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5oaWRlKCk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogaGlkZVZpZXcoKVxuXHQgICAgICAgICAqICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnVmlldyBoaWRkZW4uJykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuaGlkZSA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hpZGUtdmlldycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFNldHMgdGhlIGJvdW5kcyAodG9wLCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgdmlldyByZWxhdGl2ZSB0byBpdHMgd2luZG93LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJlbWFya3MgVmlldyBwb3NpdGlvbiBpcyByZWxhdGl2ZSB0byB0aGUgYm91bmRzIG9mIHRoZSB3aW5kb3cuXG5cdCAgICAgICAgICogKHt0b3A6IDAsIGxlZnQ6IDB9IHJlcHJlc2VudHMgdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93KVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBqc1xuXHQgICAgICAgICAqIGxldCB2aWV3O1xuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVZpZXcoKSB7XG5cdCAgICAgICAgICogICAgIGNvbnN0IG1lID0gYXdhaXQgZmluLldpbmRvdy5nZXRDdXJyZW50KCk7XG5cdCAgICAgICAgICogICAgIHJldHVybiBmaW4uVmlldy5jcmVhdGUoe1xuXHQgICAgICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lU2V0Qm91bmRzJyxcblx0ICAgICAgICAgKiAgICAgICAgIHRhcmdldDogbWUuaWRlbnRpdHksXG5cdCAgICAgICAgICogICAgICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFZpZXdCb3VuZHMoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5zZXRCb3VuZHMoe1xuXHQgICAgICAgICAqICAgICAgICAgdG9wOiAxMDAsXG5cdCAgICAgICAgICogICAgICAgICBsZWZ0OiAxMDAsXG5cdCAgICAgICAgICogICAgICAgICB3aWR0aDogMzAwLFxuXHQgICAgICAgICAqICAgICAgICAgaGVpZ2h0OiAzMDBcblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogc2V0Vmlld0JvdW5kcygpXG5cdCAgICAgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdWaWV3IHNldCB0byBuZXcgYm91bmRzLicpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnNldEJvdW5kcyA9IGFzeW5jIChib3VuZHMpID0+IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC12aWV3LWJvdW5kcycsIHsgYm91bmRzLCAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogR2V0cyB0aGUgYm91bmRzICh0b3AsIGxlZnQsIHdpZHRoLCBoZWlnaHQpIG9mIHRoZSB2aWV3IHJlbGF0aXZlIHRvIGl0cyB3aW5kb3cuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmVtYXJrcyBWaWV3IHBvc2l0aW9uIGlzIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAgICAgKiAoe3RvcDogMCwgbGVmdDogMH0gcmVwcmVzZW50cyB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3cpXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogY29uc3QgdmlldyA9IGF3YWl0IGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgIG5hbWU6ICd2aWV3TmFtZVNldEJvdW5kcycsXG5cdCAgICAgICAgICogICAgIHRhcmdldDogZmluLm1lLmlkZW50aXR5LFxuXHQgICAgICAgICAqICAgICBib3VuZHM6IHt0b3A6IDEwLCBsZWZ0OiAxMCwgd2lkdGg6IDIwMCwgaGVpZ2h0OiAyMDB9XG5cdCAgICAgICAgICogfSk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGF3YWl0IHZpZXcuc2V0Qm91bmRzKHtcblx0ICAgICAgICAgKiAgICAgdG9wOiAxMDAsXG5cdCAgICAgICAgICogICAgIGxlZnQ6IDEwMCxcblx0ICAgICAgICAgKiAgICAgd2lkdGg6IDMwMCxcblx0ICAgICAgICAgKiAgICAgaGVpZ2h0OiAzMDBcblx0ICAgICAgICAgKiB9KTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGNvbnNvbGUubG9nKGF3YWl0IHZpZXcuZ2V0Qm91bmRzKCkpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldEJvdW5kcyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgYWNrID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC12aWV3LWJvdW5kcycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFjay5wYXlsb2FkLmRhdGE7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBHZXRzIHRoZSBWaWV3J3MgaW5mby5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUdldEluZm8nLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Vmlld0luZm8oKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIHZpZXcuZ2V0SW5mbygpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGdldFZpZXdJbmZvKClcblx0ICAgICAgICAgKiAgICAgLnRoZW4oKGluZm8pID0+IGNvbnNvbGUubG9nKCdWaWV3IGluZm8gZmV0Y2hlZC4nLCBpbmZvKSlcblx0ICAgICAgICAgKiAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAgICAgKiBgYGBcblx0ICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5nZXRJbmZvID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBhY2sgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXZpZXctaW5mbycsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFjay5wYXlsb2FkLmRhdGE7XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXRyaWV2ZXMgdGhlIGxheW91dCBmb3IgdGhlIHdpbmRvdyB0aGUgdmlldyBpcyBhdHRhY2hlZCB0by5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiAgICAgLy9nZXQgdGhlIGN1cnJlbnQgVmlld1xuXHQgICAgICAgICAqICAgICBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIC8vZ2V0IGEgcmVmZXJlbmNlIHRvIHRoZSBMYXlvdXQgZm9yIHRoZSBXaW5kb3cgdGhlIHZpZXcgaXMgcGFydCBvZlxuXHQgICAgICAgICAqICAgICBjb25zdCBsYXlvdXQgPSBhd2FpdCB2aWV3LmdldFBhcmVudExheW91dCgpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldFBhcmVudExheW91dCA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3ZpZXctZ2V0LXBhcmVudC1sYXlvdXQnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSkuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBjb25zdCBsYXlvdXRXaW5kb3cgPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRXaW5kb3coKTtcblx0ICAgICAgICAgICAgbGV0IGxheW91dFdpbmRvd0lkZW50aXR5ID0gbGF5b3V0V2luZG93LmlkZW50aXR5O1xuXHQgICAgICAgICAgICAvLyBUT0RPOiBDT1JFLTE4NTcgLSB3aGVuIHdlIHRlYXJvdXQgYWN0aXZlIGxheW91dCBvciBkcmFnIGEgdmlldyBvdXQgb2YgYSB3aW5kb3csIHRoZSBhYm92ZSBpZGVudGl0eSBpbmNsdWRlcyB0aGUgd2hvbGUgd2luZG93IGluZm8uXG5cdCAgICAgICAgICAgIGlmIChsYXlvdXRXaW5kb3dJZGVudGl0eS5pZGVudGl0eSkge1xuXHQgICAgICAgICAgICAgICAgbGF5b3V0V2luZG93SWRlbnRpdHkgPSBsYXlvdXRXaW5kb3dJZGVudGl0eS5pZGVudGl0eTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJDaGFubmVsQ2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVmlld19wcm92aWRlckNoYW5uZWxDbGllbnQsIFwiZlwiKS5nZXRWYWx1ZSgpO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgbGF5b3V0X2VudGl0aWVzXzEuTGF5b3V0Tm9kZS5uZXdMYXlvdXRFbnRpdGllc0NsaWVudChwcm92aWRlckNoYW5uZWxDbGllbnQsIGxheW91dF9jb25zdGFudHNfMS5MQVlPVVRfQ09OVFJPTExFUl9JRCwgbGF5b3V0V2luZG93SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0SWRlbnRpdHkgPSBhd2FpdCBjbGllbnQuZ2V0TGF5b3V0SWRlbnRpdHlGb3JWaWV3T3JUaHJvdyh0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcChsYXlvdXRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IGFsbG93ZWRFcnJvcnMgPSBbXG5cdCAgICAgICAgICAgICAgICAgICAgJ05vIGFjdGlvbiByZWdpc3RlcmVkIGF0IHRhcmdldCBmb3InLFxuXHQgICAgICAgICAgICAgICAgICAgICdnZXRMYXlvdXRJZGVudGl0eUZvclZpZXdPclRocm93IGlzIG5vdCBhIGZ1bmN0aW9uJ1xuXHQgICAgICAgICAgICAgICAgXTtcblx0ICAgICAgICAgICAgICAgIGlmICghYWxsb3dlZEVycm9ycy5zb21lKChtKSA9PiBlLm1lc3NhZ2UuaW5jbHVkZXMobSkpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIC8vIGZhbGxiYWNrIGxvZ2ljIGZvciBtaXNzaW5nIGVuZHBvaW50XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5maW4uUGxhdGZvcm0uTGF5b3V0LndyYXAobGF5b3V0V2luZG93SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBHZXRzIHRoZSBWaWV3J3Mgb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiBsZXQgdmlldztcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVWaWV3KCkge1xuXHQgICAgICAgICAqICAgICBjb25zdCBtZSA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICAgICAqICAgICByZXR1cm4gZmluLlZpZXcuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIG5hbWU6ICd2aWV3TmFtZUdldE9wdGlvbnMnLFxuXHQgICAgICAgICAqICAgICAgICAgdGFyZ2V0OiBtZS5pZGVudGl0eSxcblx0ICAgICAgICAgKiAgICAgICAgIGJvdW5kczoge3RvcDogMTAsIGxlZnQ6IDEwLCB3aWR0aDogMjAwLCBoZWlnaHQ6IDIwMH1cblx0ICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICogfVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Vmlld09wdGlvbnMoKSB7XG5cdCAgICAgICAgICogICAgIHZpZXcgPSBhd2FpdCBjcmVhdGVWaWV3KCk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IGNyZWF0ZWQuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSgnaHR0cHM6Ly9nb29nbGUuY29tJyk7XG5cdCAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdWaWV3IG5hdmlnYXRlZCB0byBnaXZlbiB1cmwuJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogbWUuaWRlbnRpdHkudXVpZCwgbmFtZTogJ3ZpZXdOYW1lR2V0T3B0aW9ucycgfSk7XG5cdCAgICAgICAgICogICAgIHJldHVybiB2aWV3LmdldE9wdGlvbnMoKTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBnZXRWaWV3T3B0aW9ucygpXG5cdCAgICAgICAgICogICAgIC50aGVuKChpbmZvKSA9PiBjb25zb2xlLmxvZygnVmlldyBvcHRpb25zIGZldGNoZWQuJywgaW5mbykpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRoaXMuZ2V0T3B0aW9ucyA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtdmlldy1vcHRpb25zJywgeyAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogVXBkYXRlcyB0aGUgdmlldydzIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogbGV0IHZpZXc7XG5cdCAgICAgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgY29uc3QgbWUgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAgICAgKiAgICAgcmV0dXJuIGZpbi5WaWV3LmNyZWF0ZSh7XG5cdCAgICAgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2dvb2dsZS5jb20nLFxuXHQgICAgICAgICAqICAgICAgICAgbmFtZTogJ3ZpZXdOYW1lVXBkYXRlT3B0aW9ucycsXG5cdCAgICAgICAgICogICAgICAgICB0YXJnZXQ6IG1lLmlkZW50aXR5LFxuXHQgICAgICAgICAqICAgICAgICAgYm91bmRzOiB7dG9wOiAxMCwgbGVmdDogMTAsIHdpZHRoOiAyMDAsIGhlaWdodDogMjAwfVxuXHQgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgKiB9XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBhc3luYyBmdW5jdGlvbiB1cGRhdGVWaWV3T3B0aW9ucygpIHtcblx0ICAgICAgICAgKiAgICAgdmlldyA9IGF3YWl0IGNyZWF0ZVZpZXcoKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgY3JlYXRlZC4nKTtcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBhd2FpdCB2aWV3Lm5hdmlnYXRlKCdodHRwczovL2dvb2dsZS5jb20nKTtcblx0ICAgICAgICAgKiAgICAgY29uc29sZS5sb2coJ1ZpZXcgbmF2aWdhdGVkIHRvIGdpdmVuIHVybCBvcHRpb24uJyk7XG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY29uc3QgbmV3T3B0aW9ucyA9IHsgYXV0b1Jlc2l6ZToge1xuXHQgICAgICAgICAqICAgICAgICAgd2lkdGg6IHRydWUsXG5cdCAgICAgICAgICogICAgICAgICBob3Jpem9udGFsOiB0cnVlXG5cdCAgICAgICAgICogICAgIH19O1xuXHQgICAgICAgICAqICAgICByZXR1cm4gdmlldy51cGRhdGVPcHRpb25zKG5ld09wdGlvbnMpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIHVwZGF0ZVZpZXdPcHRpb25zKClcblx0ICAgICAgICAgKiAgICAgLnRoZW4ocGF5bG9hZCA9PiBjb25zb2xlLmxvZygnVmlldyBvcHRpb25zIHVwZGF0ZWQ6ICcsIHBheWxvYWQpKVxuXHQgICAgICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLnVwZGF0ZU9wdGlvbnMgPSBhc3luYyAob3B0aW9ucykgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3VwZGF0ZS12aWV3LW9wdGlvbnMnLCB7IG9wdGlvbnMsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmV0cmlldmVzIHRoZSB3aW5kb3cgdGhlIHZpZXcgaXMgY3VycmVudGx5IGF0dGFjaGVkIHRvLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBqc1xuXHQgICAgICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy53cmFwU3luYyh7IHV1aWQ6ICd2aWV3VXVpZCcsIG5hbWU6ICd2aWV3TmFtZScgfSk7XG5cdCAgICAgICAgICogdmlldy5nZXRDdXJyZW50V2luZG93KClcblx0ICAgICAgICAgKiAgICAgLnRoZW4od2luID0+IGNvbnNvbGUubG9nKCdjdXJyZW50IHdpbmRvdycsIHdpbikpXG5cdCAgICAgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7KVxuXHQgICAgICAgICAqIGBgYFxuXHQgICAgICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmdldEN1cnJlbnRXaW5kb3cgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtdmlldy13aW5kb3cnLCB7IC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgd2luZG93XzEuX1dpbmRvdyh0aGlzLndpcmUsIGRhdGEpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmV0cmlldmVzIHRoZSBjdXJyZW50IHtAbGluayBPcGVuRmluLlRhYlN0YWNrfSBvZiB0aGUgdmlldyBpZiBpdCBiZWxvbmdzIHRvIG9uZS5cblx0ICAgICAgICAgKiBAcmV0dXJucyB0aGlzIHZpZXcgYmVsb25ncyB0by5cblx0ICAgICAgICAgKiBAdGhyb3dzIGlmIHRoaXMgdmlldyBkb2VzIG5vdCBiZWxvbmcgdG8gYSBUYWJTdGFjayBvciBpZiB0aGUgd2luZG93IGhhcyBiZWVuIGRlc3Ryb3llZC5cblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqIGBgYGpzXG5cdCAgICAgICAgICogaWYgKCFmaW4ubWUuaXNWaWV3KSB7XG5cdCAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuXHQgICAgICAgICAqIH1cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIGNvbnN0IHN0YWNrID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRTdGFjaygpO1xuXHQgICAgICAgICAqIC8vIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gd3JhcCBhbnkgdmlldyBhbmQgZ2V0IHRoZSBzdGFjayBmcm9tIHRoZXJlXG5cdCAgICAgICAgICogLy8gY29uc3Qgdmlld0Zyb21Tb21ld2hlcmUgPSBmaW4uVmlldy53cmFwU3luYyhzb21lVmlldy5pZGVudGl0eSk7XG5cdCAgICAgICAgICogLy8gY29uc3Qgc3RhY2sgPSBhd2FpdCB2aWV3RnJvbVNvbWV3aGVyZS5nZXRDdXJyZW50U3RhY2soKTtcblx0ICAgICAgICAgKiBjb25zdCB2aWV3cyA9IGF3YWl0IHN0YWNrLmdldFZpZXdzKCk7XG5cdCAgICAgICAgICogY29uc29sZS5sb2coYFN0YWNrIGNvbnRhaW5zICR7dmlld3MubGVuZ3RofSB2aWV3KHMpYCk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy5nZXRDdXJyZW50U3RhY2sgPSBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd2aWV3LWdldC1jdXJyZW50LXN0YWNrJykuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0V2luZG93ID0gYXdhaXQgdGhpcy5nZXRDdXJyZW50V2luZG93KCk7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwcm92aWRlckNoYW5uZWxDbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9WaWV3X3Byb3ZpZGVyQ2hhbm5lbENsaWVudCwgXCJmXCIpLmdldFZhbHVlKCk7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBsYXlvdXRfZW50aXRpZXNfMS5MYXlvdXROb2RlLm5ld0xheW91dEVudGl0aWVzQ2xpZW50KHByb3ZpZGVyQ2hhbm5lbENsaWVudCwgbGF5b3V0X2NvbnN0YW50c18xLkxBWU9VVF9DT05UUk9MTEVSX0lELCBsYXlvdXRXaW5kb3cuaWRlbnRpdHkpO1xuXHQgICAgICAgICAgICAgICAgY29uc3Qgc3RhY2tEZWZpbml0aW9uID0gKGF3YWl0IGNsaWVudC5nZXRTdGFja0J5Vmlldyh0aGlzLmlkZW50aXR5KSk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbGF5b3V0X2VudGl0aWVzXzEuTGF5b3V0Tm9kZS5nZXRFbnRpdHkoc3RhY2tEZWZpbml0aW9uLCBjbGllbnQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5SdW50aW1lRXJyb3IoeyByZWFzb246ICdUaGlzIHZpZXcgZG9lcyBub3QgYmVsb25nIHRvIGEgc3RhY2suJywgZXJyb3IgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9O1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFRyaWdnZXJzIHRoZSBiZWZvcmUtdW5sb2FkIGhhbmRsZXIgZm9yIHRoZSBWaWV3LCBpZiBvbmUgaXMgc2V0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJlbWFya3MgUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGhhbmRsZXIgaXMgdHJ5aW5nIHRvIHByZXZlbnQgdGhlIFZpZXcgZnJvbSB1bmxvYWRpbmcsIGFuZCBgZmFsc2VgIGlmIGl0IGlzbid0LlxuXHQgICAgICAgICAqIE9ubHkgZW5hYmxlZCB3aGVuIHNldHRpbmcgZW5hYmxlQmVmb3JlVW5sb2FkOiB0cnVlIGluIHlvdXIgVmlldyBvcHRpb25zLiBJZiB0aGlzIG9wdGlvbiBpcyBub3QgZW5hYmxlZCBpdCB3aWxsXG5cdCAgICAgICAgICogYWx3YXlzIHJldHVybiBmYWxzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgUGxhdGZvcm0gUHJvdmlkZXIgdG8gZGV0ZXJtaW5lIHRoZSBzdGF0dXMgb2YgZWFjaCBiZWZvcmUgdW5sb2FkIGhhbmRsZXIgaW4gVmlld3Mgd2hlbiBjbG9zaW5nIHRoZSBXaW5kb3cuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogYGBganNcblx0ICAgICAgICAgKiAvLyBmcm9tIGluc2lkZSBhIFZpZXcgY29udGV4dFxuXHQgICAgICAgICAqIGNvbnN0IHVubG9hZFByZXZlbnRlZCA9IGF3YWl0IGZpbi5tZS50cmlnZ2VyQmVmb3JlVW5sb2FkKCk7XG5cdCAgICAgICAgICogYGBgXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdGhpcy50cmlnZ2VyQmVmb3JlVW5sb2FkID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3RyaWdnZXItYmVmb3JlLXVubG9hZCcsIHsgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2UucGF5bG9hZC5kYXRhO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogKipOT1RFKio6IEludGVybmFsIHVzZSBvbmx5LlxuXHQgICAgICAgICAqIEF0dGFjaGVzIHRoaXMgdmlldyB0byBhbiBIVE1MIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgY29udGV4dC4gVGhlIHZpZXcgd2lsbCByZXNpemUgcmVzcG9uc2l2ZWx5IHdoZW4gdGhlIGVsZW1lbnQgYm91bmRzIGNoYW5nZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICoqS25vd24gaXNzdWUqKjogVmlldy5iaW5kVG9FbGVtZW50IGRvZXMgbm90IHRyYWNrIHBvc2l0aW9uIGNoYW5nZXMsIGlmIHRoZSBlbGVtZW50IGhhcyBmaXhlZCBweCB3aWR0aCBhbmQgaGVpZ2h0IHZhbHVlcyBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIHZpZXcgdG8gbm90IHVwZGF0ZSByZXNwb25zaXZlbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAqKktub3duIGlzc3VlKio6IFdoZW4gVmlldy5iaW5kVG9FbGVtZW50IGlzIHVzZWQgb24gYSBlbGVtZW50IHRoYXQgdGFrZXMgdXAgdGhlIGVudGlyZSBwYWdlIGluIGEgcGxhdGZvcm0gd2luZG93LCB0aGUgYm91bmQgdmlldyB3aWxsIG5vdCByZXNwb25kIHJlc3BvbnNpdmVseSB3aGVuIHRoZSB3aW5kb3cgaXMgcmVzaXplZCB0byBiZSBzbWFsbGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgLSBIVE1MIGVsZW1lbnQgdG8gYXR0YWNoIHRoZSB2aWV3IHRvLlxuXHQgICAgICAgICAqIEByZXR1cm5zIC0gQ2xlYW51cCBmdW5jdGlvbiB0aGF0IHdpbGwgZGlzY29ubmVjdCB0aGUgZWxlbWVudCByZXNpemUgb2JzZXJ2ZXIuXG5cdCAgICAgICAgICogQGludGVybmFsXG5cdCAgICAgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICAgICAqIEByZW1hcmtzIFZpZXcgd2lsbCByZXNpemUgYWNjb3JkaW5nbHkgd2hlbiB0aGUgZWxlbWVudCBpcyByZXNpemVkLiBJZiB0aGUgZWxlbWVudCBpcyByZXBvc2l0aW9uZWQgaW4gdGhlIERPTSB0aGUgdmlldyB3aWxsIG5vdCBiZSByZXBvc2l0aW9uZWQsIHRvIGhhbmRsZSB0aGlzIGNhc2UgY2FsbCBgYmluZFRvRWxlbWVudGAgYWdhaW4gb25jZSB0aGUgZWxlbWVudCBjaGFuZ2VzIHBvc2l0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKiBgYGBodG1sXG5cdCAgICAgICAgICogPGRpdiBpZD1cInZpZXctY29udGFpbmVyXCI+PC9kaXY+XG5cdCAgICAgICAgICogPHNjcmlwdD5cblx0ICAgICAgICAgKiAgICAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQW5kQXR0YWNoVmlldygpIHtcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IHVybCA9ICdodHRwczovL2V4YW1wbGUuY29tJztcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IGVsZW1lbnRJZCA9ICd2aWV3LWNvbnRhaW5lcic7XG5cdCAgICAgICAgICogICAgICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudElkKTtcblx0ICAgICAgICAgKiAgICAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBmaW4uVmlldy5jcmVhdGUoe1xuXHQgICAgICAgICAqICAgICAgICAgICAgIG5hbWU6ICdteS12aWV3Jyxcblx0ICAgICAgICAgKiAgICAgICAgICAgICB1cmwsXG5cdCAgICAgICAgICogICAgICAgICAgICAgdGFyZ2V0OiBmaW4ubWUuaWRlbnRpdHlcblx0ICAgICAgICAgKiAgICAgICAgIH0pO1xuXHQgICAgICAgICAqICAgICAgICAgYXdhaXQgdmlldy5uYXZpZ2F0ZSh1cmwpO1xuXHQgICAgICAgICAqICAgICAgICAgYXdhaXQgdmlldy5iaW5kVG9FbGVtZW50KGVsZW1lbnQpO1xuXHQgICAgICAgICAqICAgICB9XG5cdCAgICAgICAgICogICAgIGNyZWF0ZUFuZEF0dGFjaFZpZXcoKS5jYXRjaChjb25zb2xlLmVycm9yKTtcblx0ICAgICAgICAgKiA8L3NjcmlwdD5cblx0ICAgICAgICAgKiBgYGBcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0aGlzLmJpbmRUb0VsZW1lbnQgPSBhc3luYyAoZWxlbWVudCkgPT4ge1xuXHQgICAgICAgICAgICBpZiAoIWVsZW1lbnQpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxlbWVudCBub3QgZm91bmQuJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3Qgb25DaGFuZ2UgPSBhc3luYyAoYm91bmRzKSA9PiB0aGlzLnNldEJvdW5kcyhib3VuZHMpO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50Lm9ic2VydmVCb3VuZHMoZWxlbWVudCwgb25DaGFuZ2UpO1xuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZvY3VzZXMgdGhlIHZpZXdcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHZpZXcgPSBmaW4uVmlldy53cmFwU3luYyh7IHV1aWQ6ICd2aWV3VXVpZCcsIG5hbWU6ICd2aWV3TmFtZScgfSk7XG5cdCAgICAgKiBhd2FpdCB2aWV3LmZvY3VzKCk7XG5cdCAgICAgKiAvLyBkbyB0aGluZ3Mgd2l0aCB0aGUgZm9jdXNlZCB2aWV3XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZm9jdXMoeyBlbWl0U3ludGhGb2N1c2VkIH0gPSB7IGVtaXRTeW50aEZvY3VzZWQ6IHRydWUgfSkge1xuXHQgICAgICAgIGNvbnN0IHdpbiA9IGF3YWl0IHRoaXMuZ2V0Q3VycmVudFdpbmRvdygpO1xuXHQgICAgICAgIGF3YWl0IHdpbi5mb2N1c2VkV2ViVmlld1dhc0NoYW5nZWQoKTtcblx0ICAgICAgICBhd2FpdCBzdXBlci5mb2N1cyh7IGVtaXRTeW50aEZvY3VzZWQgfSk7XG5cdCAgICB9XG5cdH1cblx0SW5zdGFuY2UkNS5WaWV3ID0gVmlldztcblx0X1ZpZXdfcHJvdmlkZXJDaGFubmVsQ2xpZW50ID0gbmV3IFdlYWtNYXAoKTtcblx0cmV0dXJuIEluc3RhbmNlJDU7XG59XG5cbnZhciBoYXNSZXF1aXJlZFZpZXc7XG5cbmZ1bmN0aW9uIHJlcXVpcmVWaWV3ICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkVmlldykgcmV0dXJuIHZpZXc7XG5cdGhhc1JlcXVpcmVkVmlldyA9IDE7XG5cdChmdW5jdGlvbiAoZXhwb3J0cykge1xuXHRcdHZhciBfX2NyZWF0ZUJpbmRpbmcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jcmVhdGVCaW5kaW5nKSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdFx0ICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG5cdFx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0XHQgICAgfVxuXHRcdCAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xuXHRcdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdFx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdFx0ICAgIG9bazJdID0gbVtrXTtcblx0XHR9KSk7XG5cdFx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0XHQgICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChleHBvcnRzLCBwKSkgX19jcmVhdGVCaW5kaW5nKGV4cG9ydHMsIG0sIHApO1xuXHRcdH07XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRcdC8qKlxuXHRcdCAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIE9wZW5GaW4gYFZpZXdgIEFQSSAoYGZpbi5WaWV3YCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBWaWV3TW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYFZpZXdgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uVmlld2AuXG5cdFx0ICogKiB7QGxpbmsgVmlld30gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gVmlldywgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlZpZXcuZ2V0Q3VycmVudGAuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdFx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQzKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UkMigpLCBleHBvcnRzKTsgXG5cdH0gKHZpZXcpKTtcblx0cmV0dXJuIHZpZXc7XG59XG5cbnZhciBoYXNSZXF1aXJlZEluc3RhbmNlJDE7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSQxICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkSW5zdGFuY2UkMSkgcmV0dXJuIEluc3RhbmNlJDY7XG5cdGhhc1JlcXVpcmVkSW5zdGFuY2UkMSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSQ2LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW5zdGFuY2UkNi5BcHBsaWNhdGlvbiA9IHZvaWQgMDtcblx0LyogZXNsaW50LWRpc2FibGUgaW1wb3J0L3ByZWZlci1kZWZhdWx0LWV4cG9ydCAqL1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCB3aW5kb3dfMSA9IHJlcXVpcmVXaW5kb3coKTtcblx0Y29uc3Qgdmlld18xID0gcmVxdWlyZVZpZXcoKTtcblx0LyoqXG5cdCAqIEFuIG9iamVjdCByZXByZXNlbnRpbmcgYW4gYXBwbGljYXRpb24uIEFsbG93cyB0aGUgZGV2ZWxvcGVyIHRvIGNyZWF0ZSxcblx0ICogZXhlY3V0ZSwgc2hvdy9jbG9zZSBhbiBhcHBsaWNhdGlvbiBhcyB3ZWxsIGFzIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5BcHBsaWNhdGlvbkV2ZW50cyBhcHBsaWNhdGlvbiBldmVudHN9LlxuXHQgKi9cblx0Y2xhc3MgQXBwbGljYXRpb24gZXh0ZW5kcyBiYXNlXzEuRW1pdHRlckJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCAnYXBwbGljYXRpb24nLCBpZGVudGl0eS51dWlkKTtcblx0ICAgICAgICB0aGlzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5cdCAgICAgICAgdGhpcy53aW5kb3cgPSBuZXcgd2luZG93XzEuX1dpbmRvdyh0aGlzLndpcmUsIHtcblx0ICAgICAgICAgICAgdXVpZDogdGhpcy5pZGVudGl0eS51dWlkLFxuXHQgICAgICAgICAgICBuYW1lOiB0aGlzLmlkZW50aXR5LnV1aWRcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIHdpbmRvd0xpc3RGcm9tSWRlbnRpdHlMaXN0KGlkZW50aXR5TGlzdCkge1xuXHQgICAgICAgIGNvbnN0IHdpbmRvd0xpc3QgPSBbXTtcblx0ICAgICAgICBpZGVudGl0eUxpc3QuZm9yRWFjaCgoaWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgd2luZG93TGlzdC5wdXNoKG5ldyB3aW5kb3dfMS5fV2luZG93KHRoaXMud2lyZSwge1xuXHQgICAgICAgICAgICAgICAgdXVpZDogaWRlbnRpdHkudXVpZCxcblx0ICAgICAgICAgICAgICAgIG5hbWU6IGlkZW50aXR5Lm5hbWVcblx0ICAgICAgICAgICAgfSkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB3aW5kb3dMaXN0O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBhcHBsaWNhdGlvbiBpcyBjdXJyZW50bHkgcnVubmluZy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc0FwcFJ1bm5pbmcoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmlzUnVubmluZygpO1xuXHQgICAgICogfVxuXHQgICAgICogaXNBcHBSdW5uaW5nKCkudGhlbihydW5uaW5nID0+IGNvbnNvbGUubG9nKGBDdXJyZW50IGFwcCBpcyBydW5uaW5nOiAke3J1bm5pbmd9YCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBpc1J1bm5pbmcoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpcy1hcHBsaWNhdGlvbi1ydW5uaW5nJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENsb3NlcyB0aGUgYXBwbGljYXRpb24gYW5kIGFueSBjaGlsZCB3aW5kb3dzIGNyZWF0ZWQgYnkgdGhlIGFwcGxpY2F0aW9uLlxuXHQgICAgICogQ2xlYW5zIHRoZSBhcHBsaWNhdGlvbiBmcm9tIHN0YXRlIHNvIGl0IGlzIG5vIGxvbmdlciBmb3VuZCBpbiBnZXRBbGxBcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgQ2xvc2Ugd2lsbCBiZSBwcmV2ZW50ZWQgZnJvbSBjbG9zaW5nIHdoZW4gZm9yY2UgaXMgZmFsc2UgYW5kXG5cdCAgICAgKiAg4oCYY2xvc2UtcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjbG9zZUFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhbGxBcHBzMSA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0QWxsQXBwbGljYXRpb25zKCk7IC8vW3t1dWlkOiAnYXBwMScsIGlzUnVubmluZzogdHJ1ZX0sIHt1dWlkOiAnYXBwMicsIGlzUnVubmluZzogdHJ1ZX1dXG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLndyYXAoe3V1aWQ6ICdhcHAyJ30pO1xuXHQgICAgICogICAgIGF3YWl0IGFwcC5xdWl0KCk7XG5cdCAgICAgKiAgICAgY29uc3QgYWxsQXBwczIgPSBhd2FpdCBmaW4uU3lzdGVtLmdldEFsbEFwcGxpY2F0aW9ucygpOyAvL1t7dXVpZDogJ2FwcDEnLCBpc1J1bm5pbmc6IHRydWV9XVxuXHQgICAgICpcblx0ICAgICAqIH1cblx0ICAgICAqIGNsb3NlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gcXVpdCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcXVpdChmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy5fY2xvc2UoZm9yY2UpO1xuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZGVzdHJveS1hcHBsaWNhdGlvbicsIHsgZm9yY2UsIC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBhY2NlcHRhYmxlRXJyb3JzID0gWydSZW1vdGUgY29ubmVjdGlvbiBoYXMgY2xvc2VkJywgJ0NvdWxkIG5vdCBsb2NhdGUgdGhlIHJlcXVlc3RlZCBhcHBsaWNhdGlvbiddO1xuXHQgICAgICAgICAgICBpZiAoIWFjY2VwdGFibGVFcnJvcnMuc29tZSgobXNnKSA9PiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKG1zZykpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIF9jbG9zZShmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Nsb3NlLWFwcGxpY2F0aW9uJywgeyBmb3JjZSwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGlmICghZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnUmVtb3RlIGNvbm5lY3Rpb24gaGFzIGNsb3NlZCcpKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgdXNlIEFwcGxpY2F0aW9uLnF1aXQgaW5zdGVhZFxuXHQgICAgICogQ2xvc2VzIHRoZSBhcHBsaWNhdGlvbiBhbmQgYW55IGNoaWxkIHdpbmRvd3MgY3JlYXRlZCBieSB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgLSBDbG9zZSB3aWxsIGJlIHByZXZlbnRlZCBmcm9tIGNsb3Npbmcgd2hlbiBmb3JjZSBpcyBmYWxzZSBhbmQg4oCYY2xvc2UtcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvdy5cblx0ICAgICAqIEBwYXJhbSBjYWxsYmFjayAtIGNhbGxlZCBpZiB0aGUgbWV0aG9kIHN1Y2NlZWRzLlxuXHQgICAgICogQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBjYWxsZWQgaWYgdGhlIG1ldGhvZCBmYWlscy4gVGhlIHJlYXNvbiBmb3IgZmFpbHVyZSBpcyBwYXNzZWQgYXMgYW4gYXJndW1lbnQuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY2xvc2VBcHAoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmNsb3NlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKiBjbG9zZUFwcCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIGNsb3NlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY2xvc2UoZm9yY2UgPSBmYWxzZSkge1xuXHQgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gV2FybmluZzogQXBwbGljYXRpb24uY2xvc2UgaXMgZGVwcmVjYXRlZCBQbGVhc2UgdXNlIEFwcGxpY2F0aW9uLnF1aXQnKTtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tY2xvc2UnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2UoZm9yY2UpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2Ygd3JhcHBlZCBmaW4uV2luZG93cyBmb3IgZWFjaCBvZiB0aGUgYXBwbGljYXRpb27igJlzIGNoaWxkIHdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Q2hpbGRXaW5kb3dzKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRDaGlsZFdpbmRvd3MoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRDaGlsZFdpbmRvd3MoKS50aGVuKGNoaWxkcmVuID0+IGNvbnNvbGUubG9nKGNoaWxkcmVuKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldENoaWxkV2luZG93cygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jaGlsZC13aW5kb3dzJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgaWRlbnRpdHlMaXN0ID0gW107XG5cdCAgICAgICAgICAgIHBheWxvYWQuZGF0YS5mb3JFYWNoKCh3aW5OYW1lKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZGVudGl0eUxpc3QucHVzaCh7IHV1aWQ6IHRoaXMuaWRlbnRpdHkudXVpZCwgbmFtZTogd2luTmFtZSB9KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLndpbmRvd0xpc3RGcm9tSWRlbnRpdHlMaXN0KGlkZW50aXR5TGlzdCk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyB0aGUgSlNPTiBtYW5pZmVzdCB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSB0aGUgYXBwbGljYXRpb24uIEludm9rZXMgdGhlIGVycm9yIGNhbGxiYWNrXG5cdCAgICAgKiBpZiB0aGUgYXBwbGljYXRpb24gd2FzIG5vdCBjcmVhdGVkIGZyb20gYSBtYW5pZmVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRNYW5pZmVzdCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0TWFuaWZlc3QoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRNYW5pZmVzdCgpLnRoZW4obWFuaWZlc3QgPT4gY29uc29sZS5sb2cobWFuaWZlc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0TWFuaWZlc3QoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYXBwbGljYXRpb24tbWFuaWZlc3QnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIFVVSUQgb2YgdGhlIGFwcGxpY2F0aW9uIHRoYXQgbGF1bmNoZXMgdGhpcyBhcHBsaWNhdGlvbi4gSW52b2tlcyB0aGUgZXJyb3IgY2FsbGJhY2tcblx0ICAgICAqIGlmIHRoZSBhcHBsaWNhdGlvbiB3YXMgY3JlYXRlZCBmcm9tIGEgbWFuaWZlc3QuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50VXVpZCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtQXBwbGljYXRpb24uZ2V0UGFyZW50VXVpZC5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFBhcmVudFV1aWQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRQYXJlbnRVdWlkKCkudGhlbihwYXJlbnRVdWlkID0+IGNvbnNvbGUubG9nKHBhcmVudFV1aWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0UGFyZW50VXVpZCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1wYXJlbnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGN1cnJlbnQgYXBwbGljYXRpb24ncyBzaG9ydGN1dCBjb25maWd1cmF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFNob3J0Y3V0cygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24ud3JhcCh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFNob3J0Y3V0cygpO1xuXHQgICAgICogfVxuXHQgICAgICogZ2V0U2hvcnRjdXRzKCkudGhlbihjb25maWcgPT4gY29uc29sZS5sb2coY29uZmlnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldFNob3J0Y3V0cygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1zaG9ydGN1dHMnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGN1cnJlbnQgYXBwbGljYXRpb24ncyB2aWV3cy5cblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRWaWV3cygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0Vmlld3MoKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGdldFZpZXdzKCkudGhlbih2aWV3cyA9PiBjb25zb2xlLmxvZyh2aWV3cykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRWaWV3cygpIHtcblx0ICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdhcHBsaWNhdGlvbi1nZXQtdmlld3MnLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhLm1hcCgoaWQpID0+IG5ldyB2aWV3XzEuVmlldyh0aGlzLndpcmUsIGlkKSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgem9vbSBsZXZlbCBvZiB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Wm9vbUxldmVsKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRab29tTGV2ZWwoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRab29tTGV2ZWwoKS50aGVuKHpvb21MZXZlbCA9PiBjb25zb2xlLmxvZyh6b29tTGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0Wm9vbUxldmVsKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWFwcGxpY2F0aW9uLXpvb20tbGV2ZWwnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhbiBpbnN0YW5jZSBvZiB0aGUgbWFpbiBXaW5kb3cgb2YgdGhlIGFwcGxpY2F0aW9uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0V2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1BcHBsaWNhdGlvbi5nZXRXaW5kb3cuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3coKS50aGVuKHdpbiA9PiB7XG5cdCAgICAgKiAgICAgd2luLnNob3dBdCgwLCA0MDApO1xuXHQgICAgICogICAgIHdpbi5mbGFzaCgpO1xuXHQgICAgICogfSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldFdpbmRvdygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tZ2V0LXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy53aW5kb3cpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBNYW51YWxseSByZWdpc3RlcnMgYSB1c2VyIHdpdGggdGhlIGxpY2Vuc2luZyBzZXJ2aWNlLiBUaGUgb25seSBkYXRhIHNlbnQgYnkgdGhpcyBjYWxsIGlzIHVzZXJOYW1lIGFuZCBhcHBOYW1lLlxuXHQgICAgICogQHBhcmFtIHVzZXJOYW1lIC0gdXNlcm5hbWUgdG8gYmUgcGFzc2VkIHRvIHRoZSBSVk0uXG5cdCAgICAgKiBAcGFyYW0gYXBwTmFtZSAtIGFwcCBuYW1lIHRvIGJlIHBhc3NlZCB0byB0aGUgUlZNLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlZ2lzdGVyVXNlcigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAucmVnaXN0ZXJVc2VyKCd1c2VyJywgJ215QXBwJyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogcmVnaXN0ZXJVc2VyKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQgdGhlIHVzZXInKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHJlZ2lzdGVyVXNlcih1c2VyTmFtZSwgYXBwTmFtZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVnaXN0ZXItdXNlcicsIHsgdXNlck5hbWUsIGFwcE5hbWUsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZW1vdmVzIHRoZSBhcHBsaWNhdGlvbuKAmXMgaWNvbiBmcm9tIHRoZSB0cmF5LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlbW92ZVRyYXlJY29uKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5yZW1vdmVUcmF5SWNvbigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlbW92ZVRyYXlJY29uKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnUmVtb3ZlZCB0aGUgdHJheSBpY29uLicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVtb3ZlVHJheUljb24oKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdyZW1vdmUtdHJheS1pY29uJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXN0YXJ0cyB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcmVzdGFydEFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAucmVzdGFydCgpO1xuXHQgICAgICogfVxuXHQgICAgICogcmVzdGFydEFwcCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIHJlc3RhcnRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVzdGFydCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Jlc3RhcnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIERFUFJFQ0FURUQgbWV0aG9kIHRvIHJ1biB0aGUgYXBwbGljYXRpb24uXG5cdCAgICAgKiBOZWVkZWQgd2hlbiBzdGFydGluZyBhcHBsaWNhdGlvbiB2aWEge0BsaW5rIEFwcGxpY2F0aW9uLmNyZWF0ZX0sIGJ1dCBOT1QgbmVlZGVkIHdoZW4gc3RhcnRpbmcgdmlhIHtAbGluayBBcHBsaWNhdGlvbi5zdGFydH0uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcnVuKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5jcmVhdGUoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtQXBwbGljYXRpb24ucnVuLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGF3YWl0IGFwcC5ydW4oKTtcblx0ICAgICAqIH1cblx0ICAgICAqIHJ1bigpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0FwcGxpY2F0aW9uIGlzIHJ1bm5pbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICBydW4oKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiBXYXJuaW5nOiBBcHBsaWNhdGlvbi5ydW4gaXMgZGVwcmVjYXRlZCBQbGVhc2UgdXNlIGZpbi5BcHBsaWNhdGlvbi5zdGFydCcpO1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdhcHBsaWNhdGlvbi1ydW4nLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fcnVuKCk7XG5cdCAgICB9XG5cdCAgICBfcnVuKG9wdHMgPSB7fSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3J1bi1hcHBsaWNhdGlvbicsIHtcblx0ICAgICAgICAgICAgbWFuaWZlc3RVcmw6IHRoaXMuX21hbmlmZXN0VXJsLFxuXHQgICAgICAgICAgICBvcHRzLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSW5zdHJ1Y3RzIHRoZSBSVk0gdG8gc2NoZWR1bGUgb25lIHJlc3RhcnQgb2YgdGhlIGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNjaGVkdWxlUmVzdGFydCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2NoZWR1bGVSZXN0YXJ0KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2NoZWR1bGVSZXN0YXJ0KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gaXMgc2NoZWR1bGVkIHRvIHJlc3RhcnQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNjaGVkdWxlUmVzdGFydCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlbGF1bmNoLW9uLWNsb3NlJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIFJWTSB0byB1cGxvYWQgdGhlIGFwcGxpY2F0aW9uJ3MgbG9ncy4gT24gc3VjY2Vzcyxcblx0ICAgICAqIGFuIG9iamVjdCBjb250YWluaW5nIGxvZ0lkIGlzIHJldHVybmVkLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNlbmRMb2coKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnNlbmRBcHBsaWNhdGlvbkxvZygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHNlbmRMb2coKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mby5sb2dJZCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZW5kQXBwbGljYXRpb25Mb2coKSB7XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2VuZC1hcHBsaWNhdGlvbi1sb2cnLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIG9yIHJlbW92ZXMgYSBjdXN0b20gSnVtcExpc3QgZm9yIHRoZSBhcHBsaWNhdGlvbi4gT25seSBhcHBsaWNhYmxlIGluIFdpbmRvd3MgT1MuXG5cdCAgICAgKiBJZiBjYXRlZ29yaWVzIGlzIG51bGwgdGhlIHByZXZpb3VzbHkgc2V0IGN1c3RvbSBKdW1wTGlzdCAoaWYgYW55KSB3aWxsIGJlIHJlcGxhY2VkIGJ5IHRoZSBzdGFuZGFyZCBKdW1wTGlzdCBmb3IgdGhlIGFwcCAobWFuYWdlZCBieSBXaW5kb3dzKS5cblx0ICAgICAqXG5cdCAgICAgKiBOb3RlOiBJZiB0aGUgXCJuYW1lXCIgcHJvcGVydHkgaXMgb21pdHRlZCBpdCBkZWZhdWx0cyB0byBcInRhc2tzXCIuXG5cdCAgICAgKiBAcGFyYW0ganVtcExpc3RDYXRlZ29yaWVzIEFuIGFycmF5IG9mIEp1bXBMaXN0IENhdGVnb3JpZXMgdG8gcG9wdWxhdGUuIElmIG51bGwsIHJlbW92ZSBhbnkgZXhpc3RpbmcgSnVtcExpc3QgY29uZmlndXJhdGlvbiBhbmQgc2V0IHRvIFdpbmRvd3MgZGVmYXVsdC5cblx0ICAgICAqXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSWYgY2F0ZWdvcmllcyBpcyBudWxsIHRoZSBwcmV2aW91c2x5IHNldCBjdXN0b20gSnVtcExpc3QgKGlmIGFueSkgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgc3RhbmRhcmQgSnVtcExpc3QgZm9yIHRoZSBhcHAgKG1hbmFnZWQgYnkgV2luZG93cykuXG5cdCAgICAgKlxuXHQgICAgICogVGhlIGJvdHRvbW1vc3QgaXRlbSBpbiB0aGUganVtcGxpc3Qgd2lsbCBhbHdheXMgYmUgYW4gaXRlbSBwb2ludGluZyB0byB0aGUgY3VycmVudCBhcHAuIEl0cyBuYW1lIGlzIHRha2VuIGZyb20gdGhlIG1hbmlmZXN0J3Ncblx0ICAgICAqICoqYCBzaG9ydGN1dC5uYW1lIGAqKiBhbmQgdXNlcyAqKmAgc2hvcnRjdXQuY29tcGFueSBgKiogYXMgYSBmYWxsYmFjay4gQ2xpY2tpbmcgdGhhdCBpdGVtIHdpbGwgbGF1bmNoIHRoZSBhcHAgZnJvbSBpdHMgY3VycmVudCBtYW5pZmVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBOb3RlOiBJZiB0aGUgXCJuYW1lXCIgcHJvcGVydHkgaXMgb21pdHRlZCBpdCBkZWZhdWx0cyB0byBcInRhc2tzXCIuXG5cdCAgICAgKlxuXHQgICAgICogTm90ZTogV2luZG93IE9TIGNhY2hlcyBqdW1wbGlzdHMgaWNvbnMsIHRoZXJlZm9yZSBhbiBpY29uIGNoYW5nZSBtaWdodCBvbmx5IGJlIHZpc2libGUgYWZ0ZXIgdGhlIGNhY2hlIGlzIHJlbW92ZWQgb3IgdGhlXG5cdCAgICAgKiB1dWlkIG9yIHNob3J0Y3V0Lm5hbWUgaXMgY2hhbmdlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwTmFtZSA9ICdNeSBBcHAnO1xuXHQgICAgICogICAgIGNvbnN0IGp1bXBMaXN0Q29uZmlnID0gWyAvLyBhcnJheSBvZiBKdW1wTGlzdCBjYXRlZ29yaWVzXG5cdCAgICAgKiAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgIC8vIGhhcyBubyBuYW1lIGFuZCBubyB0eXBlIHNvIGB0eXBlYCBpcyBhc3N1bWVkIHRvIGJlIFwidGFza3NcIlxuXHQgICAgICogICAgICAgICAgICAgaXRlbXM6IFsgLy8gYXJyYXkgb2YgSnVtcExpc3QgaXRlbXNcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6IGBMYXVuY2ggJHthcHBOYW1lfWAsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBSdW5zICR7YXBwTmFtZX0gd2l0aCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uYCxcblx0ICAgICAqICAgICAgICAgICAgICAgICBkZWVwTGluazogJ2ZpbnM6Ly9wYXRoLnRvL2FwcC9tYW5pZmVzdC5qc29uJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICBpY29uUGF0aDogJ2h0dHBzOi8vcGF0aC50by9hcHAvaWNvbi5pY28nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25JbmRleDogMFxuXHQgICAgICogICAgICAgICAgICAgfSxcblx0ICAgICAqICAgICAgICAgICAgIHsgdHlwZTogJ3NlcGFyYXRvcicgfSxcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6IGBSZXN0b3JlICR7YXBwTmFtZX1gLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVzdG9yZSB0byBsYXN0IGNvbmZpZ3VyYXRpb24nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlZXBMaW5rOiAnZmluczovL3BhdGgudG8vYXBwL21hbmlmZXN0Lmpzb24/JCR1c2UtbGFzdC1jb25maWd1cmF0aW9uPXRydWUnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25QYXRoOiAnaHR0cHM6Ly9wYXRoLnRvL2FwcC9pY29uLmljbycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvbkluZGV4OiAwXG5cdCAgICAgKiAgICAgICAgICAgICB9LFxuXHQgICAgICogICAgICAgICAgICAgXVxuXHQgICAgICogICAgICAgICB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBuYW1lOiAnVG9vbHMnLFxuXHQgICAgICogICAgICAgICAgICAgaXRlbXM6IFsgLy8gYXJyYXkgb2YgSnVtcExpc3QgaXRlbXNcblx0ICAgICAqICAgICAgICAgICAgIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAndGFzaycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgdGl0bGU6ICdUb29sIEEnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUnVucyBUb29sIEEnLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGRlZXBMaW5rOiAnZmluczovL3BhdGgudG8vdG9vbC1hL21hbmlmZXN0Lmpzb24nLFxuXHQgICAgICogICAgICAgICAgICAgICAgIGljb25QYXRoOiAnaHR0cHM6Ly9wYXRoLnRvL3Rvb2wtYS9pY29uLmljbycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvbkluZGV4OiAwXG5cdCAgICAgKiAgICAgICAgICAgICB9LFxuXHQgICAgICogICAgICAgICAgICAge1xuXHQgICAgICogICAgICAgICAgICAgICAgIHR5cGU6ICd0YXNrJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICB0aXRsZTogJ1Rvb2wgQicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdSdW5zIFRvb2wgQicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgZGVlcExpbms6ICdmaW5zOi8vcGF0aC50by90b29sLWIvbWFuaWZlc3QuanNvbicsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgaWNvblBhdGg6ICdodHRwczovL3BhdGgudG8vdG9vbC1iL2ljb24uaWNvJyxcblx0ICAgICAqICAgICAgICAgICAgICAgICBpY29uSW5kZXg6IDBcblx0ICAgICAqICAgICAgICAgICAgIH1dXG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICBdO1xuXHQgICAgICpcblx0ICAgICAqICAgICBhcHAuc2V0SnVtcExpc3QoanVtcExpc3RDb25maWcpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0p1bXBMaXN0IGFwcGxpZWQnKSkuY2F0Y2goZSA9PiBjb25zb2xlLmxvZyhgSnVtcExpc3QgZmFpbGVkIHRvIGFwcGx5OiAke2UudG9TdHJpbmcoKX1gKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBUbyBoYW5kbGUgZGVlcGxpbmsgYXJnczpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgZnVuY3Rpb24gaGFuZGxlVXNlTGFzdENvbmZpZ3VyYXRpb24oKSB7XG5cdCAgICAgKiAgICAgICAgIC8vIHRoaXMgaGFuZGxlciBpcyBjYWxsZWQgd2hlbiB0aGUgYXBwIGlzIGJlaW5nIGxhdW5jaGVkXG5cdCAgICAgKiAgICAgICAgIGFwcC5vbigncnVuLXJlcXVlc3RlZCcsIGV2ZW50ID0+IHtcblx0ICAgICAqICAgICAgICAgICAgIGlmKGV2ZW50LnVzZXJBcHBDb25maWdBcmdzWyd1c2UtbGFzdC1jb25maWd1cmF0aW9uJ10pIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAvLyB5b3VyIGxvZ2ljIGhlcmVcblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgIC8vIHRoaXMgaGFuZGxlciBpcyBjYWxsZWQgd2hlbiB0aGUgYXBwIHdhcyBhbHJlYWR5IHJ1bm5pbmcgd2hlbiB0aGUgbGF1bmNoIHdhcyByZXF1ZXN0ZWRcblx0ICAgICAqICAgICAgICAgZmluLmRlc2t0b3AubWFpbihmdW5jdGlvbihhcmdzKSB7XG5cdCAgICAgKiAgICAgICAgICAgICBpZihhcmdzICYmIGFyZ3NbJ3VzZS1sYXN0LWNvbmZpZ3VyYXRpb24nXSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIHlvdXIgbG9naWMgaGVyZVxuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9KTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc2V0SnVtcExpc3QoanVtcExpc3RDYXRlZ29yaWVzKSB7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1qdW1wLWxpc3QnLCB7IGNvbmZpZzoganVtcExpc3RDYXRlZ29yaWVzLCAuLi50aGlzLmlkZW50aXR5IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBZGRzIGEgY3VzdG9taXphYmxlIGljb24gaW4gdGhlIHN5c3RlbSB0cmF5LiAgVG8gbGlzdGVuIGZvciBhIGNsaWNrIG9uIHRoZSBpY29uIHVzZSB0aGUgYHRyYXktaWNvbi1jbGlja2VkYCBldmVudC5cblx0ICAgICAqIEBwYXJhbSBpY29uIEltYWdlIFVSTCBvciBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYmUgdXNlZCBhcyB0aGUgaWNvblxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGltYWdlVXJsID0gXCJodHRwOi8vY2RuLm9wZW5maW4uY28vYXNzZXRzL3Rlc3RpbmcvaWNvbnMvY2lyY2xlZC1kaWdpdC1vbmUucG5nXCI7XG5cdCAgICAgKiBjb25zdCBiYXNlNjRFbmNvZGVkSW1hZ2UgPSBcImlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBZ0FBQUFJQVFNQUFBRCt3U3pJQUFBQUJsQk1WRVhcXFxuXHQgICAgICogLy8vKy92NytqUTNZNUFBQUFEa2xFUVZRSTEyUDRBSVg4RUFnQUxnQUQvYU5wYnRFQUFBQUFTVVZPUks1Q1lJSVwiO1xuXHQgICAgICogY29uc3QgZGF0YVVSTCA9IFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFBVUFBQUFGQ0FZQUFBQ05ieWJsQUFBQUhFbEVRVlFJMTJQNC8vOC93MzhHSUFYRElCS0UwREhcXFxuXHQgICAgICogeGdsak5CQUFPOVRYTDBZNE9Id0FBQUFCSlJVNUVya0pnZ2c9PVwiO1xuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFRyYXlJY29uKGljb24pIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2V0VHJheUljb24oaWNvbik7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogLy8gdXNlIGltYWdlIHVybCB0byBzZXQgdHJheSBpY29uXG5cdCAgICAgKiBzZXRUcmF5SWNvbihpbWFnZVVybCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2V0dGluZyB0cmF5IGljb24nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICpcblx0ICAgICAqIC8vIHVzZSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gc2V0IHRyYXkgaWNvblxuXHQgICAgICogc2V0VHJheUljb24oYmFzZTY0RW5jb2RlZEltYWdlKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIHRyYXkgaWNvbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKlxuXHQgICAgICogLy8gdXNlIGEgZGF0YVVSTCB0byBzZXQgdHJheSBpY29uXG5cdCAgICAgKiBzZXRUcmF5SWNvbihkYXRhVVJMKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIHRyYXkgaWNvbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgc2V0VHJheUljb24oaWNvbikge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3NldC10cmF5LWljb24nLCB7XG5cdCAgICAgICAgICAgIGVuYWJsZWRJY29uOiBpY29uLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBuZXcgYXBwbGljYXRpb24ncyBzaG9ydGN1dCBjb25maWd1cmF0aW9uLiBXaW5kb3dzIG9ubHkuXG5cdCAgICAgKiBAcGFyYW0gY29uZmlnIE5ldyBhcHBsaWNhdGlvbidzIHNob3J0Y3V0IGNvbmZpZ3VyYXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgQXBwbGljYXRpb24gaGFzIHRvIGJlIGxhdW5jaGVkIHdpdGggYSBtYW5pZmVzdCBhbmQgaGFzIHRvIGhhdmUgc2hvcnRjdXQgY29uZmlndXJhdGlvbiAoaWNvbiB1cmwsIG5hbWUsIGV0Yy4pIGluIGl0cyBtYW5pZmVzdFxuXHQgICAgICogdG8gYmUgYWJsZSB0byBjaGFuZ2Ugc2hvcnRjdXQgc3RhdGVzLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldFNob3J0Y3V0cyhjb25maWcpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuc2V0U2hvcnRjdXRzKGNvbmZpZyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0U2hvcnRjdXRzKHtcblx0ICAgICAqICAgICBkZXNrdG9wOiB0cnVlLFxuXHQgICAgICogICAgIHN0YXJ0TWVudTogZmFsc2UsXG5cdCAgICAgKiAgICAgc3lzdGVtU3RhcnR1cDogdHJ1ZVxuXHQgICAgICogfSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU2hvcnRjdXRzIGFyZSBzZXQuJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBzZXRTaG9ydGN1dHMoY29uZmlnKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtc2hvcnRjdXRzJywgeyBkYXRhOiBjb25maWcsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIHRoZSBxdWVyeSBzdHJpbmcgaW4gYWxsIHNob3J0Y3V0cyBmb3IgdGhpcyBhcHAuIFJlcXVpcmVzIFJWTSA1LjUrLlxuXHQgICAgICogQHBhcmFtIHF1ZXJ5U3RyaW5nIFRoZSBuZXcgcXVlcnkgc3RyaW5nIGZvciB0aGlzIGFwcCdzIHNob3J0Y3V0cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBuZXdRdWVyeUFyZ3MgPSAnYXJnPXRydWUmYXJnMj1mYWxzZSc7XG5cdCAgICAgKiBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogdHJ5IHtcblx0ICAgICAqICAgICBhd2FpdCBhcHAuc2V0U2hvcnRjdXRRdWVyeVBhcmFtcyhuZXdRdWVyeUFyZ3MpO1xuXHQgICAgICogfSBjYXRjaChlcnIpIHtcblx0ICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRTaG9ydGN1dFF1ZXJ5UGFyYW1zKHF1ZXJ5U3RyaW5nKSB7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1zaG9ydGN1dC1xdWVyeS1hcmdzJywgeyBkYXRhOiBxdWVyeVN0cmluZywgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyB0aGUgem9vbSBsZXZlbCBvZiB0aGUgYXBwbGljYXRpb24uIFRoZSBvcmlnaW5hbCBzaXplIGlzIDAgYW5kIGVhY2ggaW5jcmVtZW50IGFib3ZlIG9yIGJlbG93IHJlcHJlc2VudHMgem9vbWluZyAyMCVcblx0ICAgICAqIGxhcmdlciBvciBzbWFsbGVyIHRvIGRlZmF1bHQgbGltaXRzIG9mIDMwMCUgYW5kIDUwJSBvZiBvcmlnaW5hbCBzaXplLCByZXNwZWN0aXZlbHkuXG5cdCAgICAgKiBAcGFyYW0gbGV2ZWwgVGhlIHpvb20gbGV2ZWxcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzZXRab29tTGV2ZWwobnVtYmVyKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnNldFpvb21MZXZlbChudW1iZXIpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHNldFpvb21MZXZlbCg1KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTZXR0aW5nIGEgIHpvb20gbGV2ZWwnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNldFpvb21MZXZlbChsZXZlbCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2V0LWFwcGxpY2F0aW9uLXpvb20tbGV2ZWwnLCB7IGxldmVsLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBhIHVzZXJuYW1lIHRvIGNvcnJlbGF0ZSB3aXRoIEFwcCBMb2cgTWFuYWdlbWVudC5cblx0ICAgICAqIEBwYXJhbSB1c2VybmFtZSBVc2VybmFtZSB0byBjb3JyZWxhdGUgd2l0aCBBcHAncyBMb2cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gc2V0QXBwTG9nVXNlcigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuc2V0QXBwTG9nVXNlcm5hbWUoJ3VzZXJuYW1lJyk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0QXBwTG9nVXNlcigpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1N1Y2Nlc3MnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICpcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRBcHBMb2dVc2VybmFtZSh1c2VybmFtZSkge1xuXHQgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtYXBwLWxvZy11c2VybmFtZScsIHsgZGF0YTogdXNlcm5hbWUsIC4uLnRoaXMuaWRlbnRpdHkgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgc3lzdGVtIHRyYXkuIElmIHRoZSBzeXN0ZW0gdHJheSBpcyBub3Qgc2V0LCBpdCB3aWxsIHRocm93IGFuIGVycm9yIG1lc3NhZ2UuXG5cdCAgICAgKiBAcmVtYXJrcyBUaGUgb25seSBpbmZvcm1hdGlvbiBjdXJyZW50bHkgcmV0dXJuZWQgaXMgdGhlIHBvc2l0aW9uIGFuZCBkaW1lbnNpb25zLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFRyYXlJY29uSW5mbygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24ud3JhcCh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFRyYXlJY29uSW5mbygpO1xuXHQgICAgICogfVxuXHQgICAgICogZ2V0VHJheUljb25JbmZvKCkudGhlbihpbmZvID0+IGNvbnNvbGUubG9nKGluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0VHJheUljb25JbmZvKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXRyYXktaWNvbi1pbmZvJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENoZWNrcyBpZiB0aGUgYXBwbGljYXRpb24gaGFzIGFuIGFzc29jaWF0ZWQgdHJheSBpY29uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi53cmFwKHsgdXVpZDogJ3Rlc3RhcHAnIH0pO1xuXHQgICAgICogY29uc3QgaGFzVHJheUljb24gPSBhd2FpdCBhcHAuaGFzVHJheUljb24oKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKGhhc1RyYXlJY29uKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBoYXNUcmF5SWNvbigpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hhcy10cmF5LWljb24nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2xvc2VzIHRoZSBhcHBsaWNhdGlvbiBieSB0ZXJtaW5hdGluZyBpdHMgcHJvY2Vzcy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiB0ZXJtaW5hdGVBcHAoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLnRlcm1pbmF0ZSgpO1xuXHQgICAgICogfVxuXHQgICAgICogdGVybWluYXRlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gdGVybWluYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgdGVybWluYXRlKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndGVybWluYXRlLWFwcGxpY2F0aW9uJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBXYWl0cyBmb3IgYSBoYW5naW5nIGFwcGxpY2F0aW9uLiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGluIHJlc3BvbnNlIHRvIGFuIGFwcGxpY2F0aW9uXG5cdCAgICAgKiBcIm5vdC1yZXNwb25kaW5nXCIgdG8gYWxsb3cgdGhlIGFwcGxpY2F0aW9uIHRvIGNvbnRpbnVlIGFuZCB0byBnZW5lcmF0ZSBhbm90aGVyIFwibm90LXJlc3BvbmRpbmdcIlxuXHQgICAgICogbWVzc2FnZSBhZnRlciBhIGNlcnRhaW4gcGVyaW9kIG9mIHRpbWUuXG5cdCAgICAgKlxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICB3YWl0KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignd2FpdC1mb3ItaHVuZy1hcHBsaWNhdGlvbicsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBhcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBJZiB0aGUgYXBwbGljYXRpb24gd2FzIG5vdCBsYXVuY2hlZCBmcm9tIGEgbWFuaWZlc3QsIHRoZSBjYWxsIHdpbGwgcmV0dXJuIHRoZSBjbG9zZXN0IHBhcmVudCBhcHBsaWNhdGlvbiBgbWFuaWZlc3RgXG5cdCAgICAgKiBhbmQgYG1hbmlmZXN0VXJsYC4gIGBpbml0aWFsT3B0aW9uc2Agc2hvd3MgdGhlIHBhcmFtZXRlcnMgdXNlZCB3aGVuIGxhdW5jaGVkIHByb2dyYW1tYXRpY2FsbHksIG9yIHRoZSBgc3RhcnR1cF9hcHBgIG9wdGlvbnNcblx0ICAgICAqIGlmIGxhdW5jaGVkIGZyb20gbWFuaWZlc3QuIFRoZSBgcGFyZW50VXVpZGAgd2lsbCBiZSB0aGUgdXVpZCBvZiB0aGUgaW1tZWRpYXRlIHBhcmVudCAoaWYgYXBwbGljYWJsZSkuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0SW5mbygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0SW5mbygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldEluZm8oKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRJbmZvKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWluZm8nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGFsbCBwcm9jZXNzIGluZm9ybWF0aW9uIGZvciBlbnRpdGllcyAod2luZG93cyBhbmQgdmlld3MpIGFzc29jaWF0ZWQgd2l0aCBhbiBhcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIGNvbnN0IHByb2Nlc3NJbmZvID0gYXdhaXQgYXBwLmdldFByb2Nlc3NJbmZvKCk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqIEBleHBlcmltZW50YWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0UHJvY2Vzc0luZm8oKSB7XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGEgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLWdldC1wcm9jZXNzLWluZm8nLCB0aGlzLmlkZW50aXR5KTtcblx0ICAgICAgICByZXR1cm4gZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBmaWxlIGF1dG8gZG93bmxvYWQgbG9jYXRpb24uIEl0J3Mgb25seSBhbGxvd2VkIGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuXHQgICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cblx0ICAgICAqIEBwYXJhbSBkb3dubG9hZExvY2F0aW9uIGZpbGUgYXV0byBkb3dubG9hZCBsb2NhdGlvblxuXHQgICAgICpcblx0ICAgICAqIEB0aHJvd3MgaWYgc2V0dGluZyBmaWxlIGF1dG8gZG93bmxvYWQgbG9jYXRpb24gb24gZGlmZmVyZW50IGFwcGxpY2F0aW9ucy5cblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGRvd25sb2FkTG9jYXRpb24gPSAnQzpcXFxcZGV2XFxcXHRlbXAnO1xuXHQgICAgICogY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnQoKTtcblx0ICAgICAqIHRyeSB7XG5cdCAgICAgKiAgICAgYXdhaXQgYXBwLnNldEZpbGVEb3dubG9hZExvY2F0aW9uKGRvd25sb2FkTG9jYXRpb24pO1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKCdGaWxlIGRvd25sb2FkIGxvY2F0aW9uIGlzIHNldCcpO1xuXHQgICAgICogfSBjYXRjaChlcnIpIHtcblx0ICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRGaWxlRG93bmxvYWRMb2NhdGlvbihkb3dubG9hZExvY2F0aW9uKSB7XG5cdCAgICAgICAgY29uc3QgeyBuYW1lIH0gPSB0aGlzLndpcmUubWU7XG5cdCAgICAgICAgY29uc3QgZW50aXR5SWRlbnRpdHkgPSB7IHV1aWQ6IHRoaXMuaWRlbnRpdHkudXVpZCwgbmFtZSB9O1xuXHQgICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtZmlsZS1kb3dubG9hZC1sb2NhdGlvbicsIHsgLi4uZW50aXR5SWRlbnRpdHksIGRvd25sb2FkTG9jYXRpb24gfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdldHMgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uLiBJdCdzIG9ubHkgYWxsb3dlZCBpbiB0aGUgc2FtZSBhcHBsaWNhdGlvbi4gSWYgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uIGlzIG5vdCBzZXQsIGl0IHdpbGwgcmV0dXJuIHRoZSBkZWZhdWx0IGxvY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuXHQgICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cblx0ICAgICAqXG5cdCAgICAgKiBAdGhyb3dzIGlmIGdldHRpbmcgZmlsZSBhdXRvIGRvd25sb2FkIGxvY2F0aW9uIG9uIGRpZmZlcmVudCBhcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogY29uc3QgZmlsZURvd25sb2FkRGlyID0gIGF3YWl0IGFwcC5nZXRGaWxlRG93bmxvYWRMb2NhdGlvbigpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEZpbGVEb3dubG9hZExvY2F0aW9uKCkge1xuXHQgICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZmlsZS1kb3dubG9hZC1sb2NhdGlvbicsIHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgICAgIHJldHVybiBkYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG93cyBhIG1lbnUgb24gdGhlIHRyYXkgaWNvbi4gVXNlIHdpdGggdHJheS1pY29uLWNsaWNrZWQgZXZlbnQuXG5cdCAgICAgKiBAcGFyYW0gb3B0aW9uc1xuXHQgICAgICogQHR5cGVQYXJhbSBEYXRhIFVzZXItZGVmaW5lZCBzaGFwZSBmb3IgZGF0YSByZXR1cm5lZCB1cG9uIG1lbnUgaXRlbSBjbGljay4gU2hvdWxkIGJlIGFcblx0ICAgICAqIFt1bmlvbl0oaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL2RvY3MvaGFuZGJvb2svMi9ldmVyeWRheS10eXBlcy5odG1sI3VuaW9uLXR5cGVzKVxuXHQgICAgICogb2YgYWxsIHBvc3NpYmxlIGRhdGEgc2hhcGVzIGZvciB0aGUgZW50aXJlIG1lbnUsIGFuZCB0aGUgY2xpY2sgaGFuZGxlciBzaG91bGQgcHJvY2Vzc1xuXHQgICAgICogdGhlc2Ugd2l0aCBhIFwicmVkdWNlclwiIHBhdHRlcm4uXG5cdCAgICAgKiBAdGhyb3dzIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gdHJheSBpY29uIHNldFxuXHQgICAgICogQHRocm93cyBpZiB0aGUgc3lzdGVtIHRyYXkgaXMgY3VycmVudGx5IGhpZGRlblxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgaWNvblVybCA9ICdodHRwOi8vY2RuLm9wZW5maW4uY28vYXNzZXRzL3Rlc3RpbmcvaWNvbnMvY2lyY2xlZC1kaWdpdC1vbmUucG5nJztcblx0ICAgICAqIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICpcblx0ICAgICAqIGF3YWl0IGFwcC5zZXRUcmF5SWNvbihpY29uVXJsKTtcblx0ICAgICAqXG5cdCAgICAgKiBjb25zdCB0ZW1wbGF0ZSA9IFtcblx0ICAgICAqICB7XG5cdCAgICAgKiAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgIGRhdGE6ICdoZWxsbyBmcm9tIGl0ZW0gMSdcblx0ICAgICAqICB9LFxuXHQgICAgICogIHsgdHlwZTogJ3NlcGFyYXRvcicgfSxcblx0ICAgICAqICB7XG5cdCAgICAgKiAgICBsYWJlbDogJ01lbnUgSXRlbSAyJyxcblx0ICAgICAqICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICBjaGVja2VkOiB0cnVlLFxuXHQgICAgICogICAgZGF0YTogJ1RoZSB1c2VyIGNsaWNrZWQgdGhlIGNoZWNrYm94J1xuXHQgICAgICogIH0sXG5cdCAgICAgKiAge1xuXHQgICAgICogICAgbGFiZWw6ICdzZWUgbW9yZScsXG5cdCAgICAgKiAgICBlbmFibGVkOiBmYWxzZSxcblx0ICAgICAqICAgIHN1Ym1lbnU6IFtcblx0ICAgICAqICAgICAgeyBsYWJlbDogJ3N1Ym1lbnUgMScsIGRhdGE6ICdoZWxsbyBmcm9tIHN1Ym1lbnUnIH1cblx0ICAgICAqICAgIF1cblx0ICAgICAqICB9XG5cdCAgICAgKiBdO1xuXHQgICAgICpcblx0ICAgICAqIGFwcC5hZGRMaXN0ZW5lcigndHJheS1pY29uLWNsaWNrZWQnLCAoZXZlbnQpID0+IHtcblx0ICAgICAqICAgLy8gcmlnaHQtY2xpY2tcblx0ICAgICAqICAgaWYgKGV2ZW50LmJ1dHRvbiA9PT0gMikge1xuXHQgICAgICogICAgIGFwcC5zaG93VHJheUljb25Qb3B1cE1lbnUoeyB0ZW1wbGF0ZSB9KS50aGVuKHIgPT4ge1xuXHQgICAgICogICAgICAgaWYgKHIucmVzdWx0ID09PSAnY2xvc2VkJykge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZygnbm90aGluZyBoYXBwZW5lZCcpO1xuXHQgICAgICogICAgICAgfSBlbHNlIHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coci5kYXRhKTtcblx0ICAgICAqICAgICAgIH1cblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgfVxuXHQgICAgICogfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc2hvd1RyYXlJY29uUG9wdXBNZW51KG9wdGlvbnMpIHtcblx0ICAgICAgICBjb25zdCB7IG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICBjb25zdCBlbnRpdHlJZGVudGl0eSA9IHsgdXVpZDogdGhpcy5pZGVudGl0eS51dWlkLCBuYW1lIH07XG5cdCAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy10cmF5LWljb24tcG9wdXAtbWVudScsIHsgLi4uZW50aXR5SWRlbnRpdHksIG9wdGlvbnMgfSk7XG5cdCAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2xvc2VzIHRoZSB0cmF5IGljb24gbWVudS5cblx0ICAgICAqXG5cdCAgICAgKiBAdGhyb3dzIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gdHJheSBpY29uIHNldFxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgYXBwID0gZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKlxuXHQgICAgICogYXdhaXQgYXBwLmNsb3NlVHJheUljb25Qb3B1cE1lbnUoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjbG9zZVRyYXlJY29uUG9wdXBNZW51KCkge1xuXHQgICAgICAgIGNvbnN0IHsgbmFtZSB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIGNvbnN0IGVudGl0eUlkZW50aXR5ID0geyB1dWlkOiB0aGlzLmlkZW50aXR5LnV1aWQsIG5hbWUgfTtcblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xvc2UtdHJheS1pY29uLXBvcHVwLW1lbnUnLCB7IC4uLmVudGl0eUlkZW50aXR5IH0pO1xuXHQgICAgfVxuXHR9XG5cdEluc3RhbmNlJDYuQXBwbGljYXRpb24gPSBBcHBsaWNhdGlvbjtcblx0cmV0dXJuIEluc3RhbmNlJDY7XG59XG5cbnZhciBoYXNSZXF1aXJlZEZhY3RvcnkkMjtcblxuZnVuY3Rpb24gcmVxdWlyZUZhY3RvcnkkMiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZhY3RvcnkkMikgcmV0dXJuIEZhY3RvcnkkNztcblx0aGFzUmVxdWlyZWRGYWN0b3J5JDIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoRmFjdG9yeSQ3LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0RmFjdG9yeSQ3LkFwcGxpY2F0aW9uTW9kdWxlID0gdm9pZCAwO1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCB2YWxpZGF0ZV8xID0gdmFsaWRhdGU7XG5cdGNvbnN0IEluc3RhbmNlXzEgPSByZXF1aXJlSW5zdGFuY2UkMSgpO1xuXHQvKipcblx0ICogU3RhdGljIG5hbWVzcGFjZSBmb3IgT3BlbkZpbiBBUEkgbWV0aG9kcyB0aGF0IGludGVyYWN0IHdpdGggdGhlIHtAbGluayBBcHBsaWNhdGlvbn0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkFwcGxpY2F0aW9uYC5cblx0ICovXG5cdGNsYXNzIEFwcGxpY2F0aW9uTW9kdWxlIGV4dGVuZHMgYmFzZV8xLkJhc2Uge1xuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBBcHBsaWNhdGlvbiBpZGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBXcmFwcGluZyBhbiBBcHBsaWNhdGlvbiBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuXHQgICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuXHQgICAgICogZm9yIGFuIEFwcGxpY2F0aW9uIHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLndyYXAoeyB1dWlkOiAndGVzdGFwcCcgfSlcblx0ICAgICAqIC50aGVuKGFwcCA9PiBhcHAuaXNSdW5uaW5nKCkpXG5cdCAgICAgKiAudGhlbihydW5uaW5nID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiBpcyBydW5uaW5nOiAnICsgcnVubmluZykpXG5cdCAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBhc3luYyB3cmFwKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dyYXAtYXBwbGljYXRpb24nKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIEFwcGxpY2F0aW9uIGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGFuIEFwcGxpY2F0aW9uIGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYW4gQXBsaWNhdGlvbiB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi53cmFwU3luYyh7IHV1aWQ6ICd0ZXN0YXBwJyB9KTtcblx0ICAgICAqIGF3YWl0IGFwcC5jbG9zZSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3cmFwLWFwcGxpY2F0aW9uLXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgX2NyZWF0ZShhcHBPcHRpb25zKSB7XG5cdCAgICAgICAgLy8gc2V0IGRlZmF1bHRzOlxuXHQgICAgICAgIGlmIChhcHBPcHRpb25zLndhaXRGb3JQYWdlTG9hZCA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIGFwcE9wdGlvbnMud2FpdEZvclBhZ2VMb2FkID0gZmFsc2U7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhcHBPcHRpb25zLmF1dG9TaG93ID09PSB1bmRlZmluZWQgJiYgYXBwT3B0aW9ucy5pc1BsYXRmb3JtQ29udHJvbGxlciA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIGFwcE9wdGlvbnMuYXV0b1Nob3cgPSB0cnVlO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLWFwcGxpY2F0aW9uJywgYXBwT3B0aW9ucyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQ6IGFwcE9wdGlvbnMudXVpZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogREVQUkVDQVRFRCBtZXRob2QgdG8gY3JlYXRlIGEgbmV3IEFwcGxpY2F0aW9uLiBVc2Uge0BsaW5rIEFwcGxpY2F0aW9uLkFwcGxpY2F0aW9uTW9kdWxlLnN0YXJ0IEFwcGxpY2F0aW9uLnN0YXJ0fSBpbnN0ZWFkLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUFwcCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uY3JlYXRlKHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0zJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLUFwcGxpY2F0aW9uLmNyZWF0ZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBhd2FpdCBhcHAucnVuKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogY3JlYXRlQXBwKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQXBwbGljYXRpb24gaXMgY3JlYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBAaWdub3JlXG5cdCAgICAgKi9cblx0ICAgIGNyZWF0ZShhcHBPcHRpb25zKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiBXYXJuaW5nOiBmaW4uQXBwbGljYXRpb24uY3JlYXRlIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgZmluLkFwcGxpY2F0aW9uLnN0YXJ0Jyk7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLWNyZWF0ZScpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLl9jcmVhdGUoYXBwT3B0aW9ucyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYW5kIHN0YXJ0cyBhIG5ldyBBcHBsaWNhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzdGFydCgpIHtcblx0ICAgICAqICAgICByZXR1cm4gZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLUFwcGxpY2F0aW9uLnN0YXJ0Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogfVxuXHQgICAgICogc3RhcnQoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiBpcyBydW5uaW5nJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgc3RhcnQoYXBwT3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzdGFydC1hcHBsaWNhdGlvbicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGFwcCA9IGF3YWl0IHRoaXMuX2NyZWF0ZShhcHBPcHRpb25zKTtcblx0ICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncnVuLWFwcGxpY2F0aW9uJywgeyB1dWlkOiBhcHBPcHRpb25zLnV1aWQgfSk7XG5cdCAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQXN5bmNocm9ub3VzbHkgc3RhcnRzIGEgYmF0Y2ggb2YgYXBwbGljYXRpb25zIGdpdmVuIGFuIGFycmF5IG9mIGFwcGxpY2F0aW9uIGlkZW50aWZpZXJzIGFuZCBtYW5pZmVzdFVybHMuXG5cdCAgICAgKiBSZXR1cm5zIG9uY2UgdGhlIFJWTSBpcyBmaW5pc2hlZCBhdHRlbXB0aW5nIHRvIGxhdW5jaCB0aGUgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIG9wdHMgLSBQYXJhbWV0ZXJzIHRoYXQgdGhlIFJWTSB3aWxsIHVzZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKlxuXHQgICAgICogY29uc3QgYXBwbGljYXRpb25JbmZvQXJyYXkgPSBbXG5cdCAgICAgKiAgICAge1xuXHQgICAgICogICAgICAgICBcInV1aWRcIjogJ0FwcC0xJyxcblx0ICAgICAqICAgICAgICAgXCJtYW5pZmVzdFVybFwiOiAnaHR0cDovL2xvY2FsaG9zdDo1NTU1L2FwcDEuanNvbicsXG5cdCAgICAgKiAgICAgfSxcblx0ICAgICAqICAgICB7XG5cdCAgICAgKiAgICAgICAgIFwidXVpZFwiOiAnQXBwLTInLFxuXHQgICAgICogICAgICAgICBcIm1hbmlmZXN0VXJsXCI6ICdodHRwOi8vbG9jYWxob3N0OjU1NTUvYXBwMi5qc29uJyxcblx0ICAgICAqICAgICB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgXCJ1dWlkXCI6ICdBcHAtMycsXG5cdCAgICAgKiAgICAgICAgIFwibWFuaWZlc3RVcmxcIjogJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAzLmpzb24nLFxuXHQgICAgICogICAgIH1cblx0ICAgICAqIF1cblx0ICAgICAqXG5cdCAgICAgKiBmaW4uQXBwbGljYXRpb24uc3RhcnRNYW55TWFuaWZlc3RzKGFwcGxpY2F0aW9uSW5mb0FycmF5KVxuXHQgICAgICogICAgIC50aGVuKCgpID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1JWTSBoYXMgZmluaXNoZWQgbGF1bmNoaW5nIHRoZSBhcHBsaWNhdGlvbiBsaXN0LicpO1xuXHQgICAgICogICAgIH0pXG5cdCAgICAgKiAgICAgLmNhdGNoKChlcnIpID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzdGFydE1hbnlNYW5pZmVzdHMoYXBwbGljYXRpb25zLCBvcHRzKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdydW4tYXBwbGljYXRpb25zJywgeyBhcHBsaWNhdGlvbnMsIG9wdHMgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFwcGxpY2F0aW9uIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgYXBwbGljYXRpb25cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc0N1cnJlbnRBcHBSdW5uaW5nICgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuaXNSdW5uaW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNDdXJyZW50QXBwUnVubmluZygpLnRoZW4ocnVubmluZyA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coYEN1cnJlbnQgYXBwIGlzIHJ1bm5pbmc6ICR7cnVubmluZ31gKTtcblx0ICAgICAqIH0pLmNhdGNoKGVyciA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuXHQgICAgICogfSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnQoKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jdXJyZW50LWFwcGxpY2F0aW9uJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQ6IHRoaXMud2lyZS5tZS51dWlkIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQXBwbGljYXRpb24gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBhcHBsaWNhdGlvblxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGlzQ3VycmVudEFwcFJ1bm5pbmcgKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGZpbi5BcHBsaWNhdGlvbi5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgIHJldHVybiBhcHAuaXNSdW5uaW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNDdXJyZW50QXBwUnVubmluZygpLnRoZW4ocnVubmluZyA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coYEN1cnJlbnQgYXBwIGlzIHJ1bm5pbmc6ICR7cnVubmluZ31gKTtcblx0ICAgICAqIH0pLmNhdGNoKGVyciA9PiB7XG5cdCAgICAgKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuXHQgICAgICogfSk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY3VycmVudC1hcHBsaWNhdGlvbi1zeW5jJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud3JhcFN5bmMoeyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3QgYW5kIHJldHVybnMgYSBydW5uaW5nIGluc3RhbmNlIG9mIHRoZSBhcHBsaWNhdGlvbi5cblx0ICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgYXBwJ3MgbWFuaWZlc3QuXG5cdCAgICAgKiBAcGFyYW0gb3B0cyAtIFBhcmFtZXRlcnMgdGhhdCB0aGUgUlZNIHdpbGwgdXNlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5BcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdCgnaHR0cDovL2xvY2FsaG9zdDo1NTU1L2FwcC5qc29uJykudGhlbihhcHAgPT4gY29uc29sZS5sb2coJ0FwcCBpcyBydW5uaW5nJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBGb3IgYSBsb2NhbCBtYW5pZmVzdCBmaWxlOlxuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLnN0YXJ0RnJvbU1hbmlmZXN0KCdmaWxlOi8vL0M6L3NvbWVmb2xkZXIvYXBwLmpzb24nKS50aGVuKGFwcCA9PiBjb25zb2xlLmxvZygnQXBwIGlzIHJ1bm5pbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHN0YXJ0RnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsLCBvcHRzKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2FwcGxpY2F0aW9uLXN0YXJ0LWZyb20tbWFuaWZlc3QnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLl9jcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpO1xuXHQgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSBtZXRob2Qgd2l0aG91dCB3YXJuaW5nLlxuXHQgICAgICAgIGF3YWl0IGFwcC5fcnVuKG9wdHMpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBBcHBsaWNhdGlvbi5BcHBsaWNhdGlvbk1vZHVsZS5zdGFydEZyb21NYW5pZmVzdCBBcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdH0gaW5zdGVhZC5cblx0ICAgICAqIFJldHJpZXZlcyBhcHBsaWNhdGlvbidzIG1hbmlmZXN0IGFuZCByZXR1cm5zIGEgd3JhcHBlZCBhcHBsaWNhdGlvbi5cblx0ICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgYXBwJ3MgbWFuaWZlc3QuXG5cdCAgICAgKiBAcGFyYW0gY2FsbGJhY2sgLSBjYWxsZWQgaWYgdGhlIG1ldGhvZCBzdWNjZWVkcy5cblx0ICAgICAqIEBwYXJhbSBlcnJvckNhbGxiYWNrIC0gY2FsbGVkIGlmIHRoZSBtZXRob2QgZmFpbHMuIFRoZSByZWFzb24gZm9yIGZhaWx1cmUgaXMgcGFzc2VkIGFzIGFuIGFyZ3VtZW50LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5BcHBsaWNhdGlvbi5jcmVhdGVGcm9tTWFuaWZlc3QoJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAuanNvbicpLnRoZW4oYXBwID0+IGNvbnNvbGUubG9nKGFwcCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICogQGlnbm9yZVxuXHQgICAgICovXG5cdCAgICBjcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ0RlcHJlY2F0aW9uIFdhcm5pbmc6IGZpbi5BcHBsaWNhdGlvbi5jcmVhdGVGcm9tTWFuaWZlc3QgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBmaW4uQXBwbGljYXRpb24uc3RhcnRGcm9tTWFuaWZlc3QnKTtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignYXBwbGljYXRpb24tY3JlYXRlLWZyb20tbWFuaWZlc3QnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlRnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsKTtcblx0ICAgIH1cblx0ICAgIF9jcmVhdGVGcm9tTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdnZXQtYXBwbGljYXRpb24tbWFuaWZlc3QnLCB7IG1hbmlmZXN0VXJsIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB1dWlkID0gcGF5bG9hZC5kYXRhLnBsYXRmb3JtID8gcGF5bG9hZC5kYXRhLnBsYXRmb3JtLnV1aWQgOiBwYXlsb2FkLmRhdGEuc3RhcnR1cF9hcHAudXVpZDtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQgfSk7XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKGFwcCkgPT4ge1xuXHQgICAgICAgICAgICBhcHAuX21hbmlmZXN0VXJsID0gbWFuaWZlc3RVcmw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZXJzY29yZS1kYW5nbGVcblx0ICAgICAgICAgICAgcmV0dXJuIGFwcDtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0fVxuXHRGYWN0b3J5JDcuQXBwbGljYXRpb25Nb2R1bGUgPSBBcHBsaWNhdGlvbk1vZHVsZTtcblx0cmV0dXJuIEZhY3RvcnkkNztcbn1cblxudmFyIGhhc1JlcXVpcmVkQXBwbGljYXRpb247XG5cbmZ1bmN0aW9uIHJlcXVpcmVBcHBsaWNhdGlvbiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEFwcGxpY2F0aW9uKSByZXR1cm4gYXBwbGljYXRpb247XG5cdGhhc1JlcXVpcmVkQXBwbGljYXRpb24gPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHRcdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHRcdCAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG5cdFx0ICAgIH1cblx0XHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0XHR9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICBvW2syXSA9IG1ba107XG5cdFx0fSkpO1xuXHRcdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdFx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0XHR9O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludHMgZm9yIHRoZSBPcGVuRmluIGBBcHBsaWNhdGlvbmAgQVBJIChgZmluLkFwcGxpY2F0aW9uYCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBBcHBsaWNhdGlvbk1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBBcHBsaWNhdGlvbmAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5BcHBsaWNhdGlvbmAuXG5cdFx0ICogKiB7QGxpbmsgQXBwbGljYXRpb259IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIEFwcGxpY2F0aW9uLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uQXBwbGljYXRpb24uZ2V0Q3VycmVudGAuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdFx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQyKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UkMSgpLCBleHBvcnRzKTsgXG5cdH0gKGFwcGxpY2F0aW9uKSk7XG5cdHJldHVybiBhcHBsaWNhdGlvbjtcbn1cblxudmFyIHByb21pc2lmeVN1YnNjcmlwdGlvbiQxID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9taXNpZnlTdWJzY3JpcHRpb24kMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5wcm9taXNpZnlTdWJzY3JpcHRpb24kMS5wcm9taXNpZnlTdWJzY3JpcHRpb24gPSB2b2lkIDA7XG5jb25zdCBwcm9taXNpZnlTdWJzY3JpcHRpb24gPSBhc3luYyAoZW1pdHRlciwgZXZlbnROYW1lLCBwcmVkaWNhdGUgPSAoKSA9PiB0cnVlLCB0aW1lb3V0KSA9PiB7XG4gICAgbGV0IHJlc29sdmU7XG4gICAgbGV0IHJlamVjdDtcbiAgICBsZXQgdGltZXI7XG4gICAgY29uc3QgdmFsdWVQcm9taXNlID0gbmV3IFByb21pc2UoKHksIG4pID0+IHtcbiAgICAgICAgcmVzb2x2ZSA9IHk7XG4gICAgICAgIHJlamVjdCA9IG47XG4gICAgfSk7XG4gICAgY29uc3QgbGlzdGVuZXIgPSAoZSkgPT4ge1xuICAgICAgICBpZiAocHJlZGljYXRlKGUpKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZShlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgYXdhaXQgZW1pdHRlci5vbihldmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICBpZiAodGltZW91dCkge1xuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignZXZlbnQgdGltZWQgb3V0JykpLCB0aW1lb3V0KTtcbiAgICB9XG4gICAgdmFsdWVQcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSwgbGlzdGVuZXIpLmNhdGNoKCgpID0+IG51bGwpO1xuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICAgIGdldFZhbHVlOiAoKSA9PiB2YWx1ZVByb21pc2VcbiAgICB9O1xufTtcbnByb21pc2lmeVN1YnNjcmlwdGlvbiQxLnByb21pc2lmeVN1YnNjcmlwdGlvbiA9IHByb21pc2lmeVN1YnNjcmlwdGlvbjtcblxudmFyIGhhc1JlcXVpcmVkSW5zdGFuY2U7XG5cbmZ1bmN0aW9uIHJlcXVpcmVJbnN0YW5jZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEluc3RhbmNlKSByZXR1cm4gSW5zdGFuY2UkNztcblx0aGFzUmVxdWlyZWRJbnN0YW5jZSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSQ3LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW5zdGFuY2UkNy5fV2luZG93ID0gdm9pZCAwO1xuXHQvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5cdC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuXHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5cdC8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cblx0Y29uc3QgYXBwbGljYXRpb25fMSA9IHJlcXVpcmVBcHBsaWNhdGlvbigpO1xuXHRjb25zdCBtYWluXzEgPSBtYWluO1xuXHRjb25zdCB2aWV3XzEgPSByZXF1aXJlVmlldygpO1xuXHRjb25zdCB3YXJuaW5nc18xID0gd2FybmluZ3M7XG5cdGNvbnN0IHByb21pc2lmeVN1YnNjcmlwdGlvbl8xID0gcHJvbWlzaWZ5U3Vic2NyaXB0aW9uJDE7XG5cdC8qKlxuXHQgKiBBIGJhc2ljIHdpbmRvdyB0aGF0IHdyYXBzIGEgbmF0aXZlIEhUTUwgd2luZG93LiBQcm92aWRlcyBtb3JlIGZpbmUtZ3JhaW5lZFxuXHQgKiBjb250cm9sIG92ZXIgdGhlIHdpbmRvdyBzdGF0ZSBzdWNoIGFzIHRoZSBhYmlsaXR5IHRvIG1pbmltaXplLCBtYXhpbWl6ZSwgcmVzdG9yZSwgZXRjLlxuXHQgKiBCeSBkZWZhdWx0IGEgd2luZG93IGRvZXMgbm90IHNob3cgdXBvbiBpbnN0YW50aWF0aW9uOyBpbnN0ZWFkIHRoZSB3aW5kb3cncyBzaG93KCkgbWV0aG9kXG5cdCAqIG11c3QgYmUgaW52b2tlZCBtYW51YWxseS4gVGhlIG5ldyB3aW5kb3cgYXBwZWFycyBpbiB0aGUgc2FtZSBwcm9jZXNzIGFzIHRoZSBwYXJlbnQgd2luZG93LlxuXHQgKiBJdCBoYXMgdGhlIGFiaWxpdHkgdG8gbGlzdGVuIGZvciB7QGxpbmsgT3BlbkZpbi5XaW5kb3dFdmVudHMgd2luZG93IHNwZWNpZmljIGV2ZW50c30uXG5cdCAqL1xuXHQvLyBUaGUgd2luZG93LldpbmRvdyBuYW1lIGlzIHRha2VuXG5cdGNsYXNzIF9XaW5kb3cgZXh0ZW5kcyBtYWluXzEuV2ViQ29udGVudHMge1xuXHQgICAgLyoqXG5cdCAgICAgKiBAaW50ZXJuYWxcblx0ICAgICAqL1xuXHQgICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcblx0ICAgICAgICBzdXBlcih3aXJlLCBpZGVudGl0eSwgJ3dpbmRvdycpO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgY3JlYXRlV2luZG93KG9wdGlvbnMpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWNyZWF0ZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBDT05TVFJVQ1RPUl9DQl9UT1BJQyA9ICdmaXJlLWNvbnN0cnVjdG9yLWNhbGxiYWNrJztcblx0ICAgICAgICBjb25zdCByZXNwb25zZVN1YnNjcmlwdGlvbiA9IGF3YWl0ICgwLCBwcm9taXNpZnlTdWJzY3JpcHRpb25fMS5wcm9taXNpZnlTdWJzY3JpcHRpb24pKHRoaXMsIENPTlNUUlVDVE9SX0NCX1RPUElDKTtcblx0ICAgICAgICAvLyBzZXQgZGVmYXVsdHM6XG5cdCAgICAgICAgaWYgKG9wdGlvbnMud2FpdEZvclBhZ2VMb2FkID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgb3B0aW9ucy53YWl0Rm9yUGFnZUxvYWQgPSBmYWxzZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKG9wdGlvbnMuYXV0b1Nob3cgPT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICBvcHRpb25zLmF1dG9TaG93ID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgKDAsIHdhcm5pbmdzXzEuaGFuZGxlRGVwcmVjYXRlZFdhcm5pbmdzKShvcHRpb25zKTtcblx0ICAgICAgICBjb25zdCB3aW5kb3dDcmVhdGlvbiA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5jcmVhdGVDaGlsZENvbnRlbnQoeyBlbnRpdHlUeXBlOiAnd2luZG93Jywgb3B0aW9ucyB9KTtcblx0ICAgICAgICBjb25zdCBbcmVzcG9uc2VdID0gYXdhaXQgUHJvbWlzZS5hbGwoW3Jlc3BvbnNlU3Vic2NyaXB0aW9uLmdldFZhbHVlKCksIHdpbmRvd0NyZWF0aW9uXSk7XG5cdCAgICAgICAgbGV0IGNiUGF5bG9hZDtcblx0ICAgICAgICBjb25zdCB7IHN1Y2Nlc3MgfSA9IHJlc3BvbnNlO1xuXHQgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IHJlc3BvbnNlLmRhdGE7XG5cdCAgICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSByZXNwb25zZURhdGE7XG5cdCAgICAgICAgaWYgKHN1Y2Nlc3MpIHtcblx0ICAgICAgICAgICAgY2JQYXlsb2FkID0ge1xuXHQgICAgICAgICAgICAgICAgaHR0cFJlc3BvbnNlQ29kZTogcmVzcG9uc2VEYXRhLmh0dHBSZXNwb25zZUNvZGUsXG5cdCAgICAgICAgICAgICAgICBhcGlJbmplY3RlZDogcmVzcG9uc2VEYXRhLmFwaUluamVjdGVkXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICBjYlBheWxvYWQgPSB7XG5cdCAgICAgICAgICAgICAgICBtZXNzYWdlOiByZXNwb25zZURhdGEubWVzc2FnZSxcblx0ICAgICAgICAgICAgICAgIG5ldHdvcmtFcnJvckNvZGU6IHJlc3BvbnNlRGF0YS5uZXR3b3JrRXJyb3JDb2RlLFxuXHQgICAgICAgICAgICAgICAgc3RhY2s6IHJlc3BvbnNlRGF0YS5zdGFja1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCBwYWdlUmVzb2x2ZSA9IHtcblx0ICAgICAgICAgICAgbWVzc2FnZSxcblx0ICAgICAgICAgICAgY2JQYXlsb2FkLFxuXHQgICAgICAgICAgICBzdWNjZXNzXG5cdCAgICAgICAgfTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAvLyB0aGlzIGlzIHRvIGVuZm9yY2UgYSA1LjAgY29udHJhY3QgdGhhdCB0aGUgY2hpbGQncyBtYWluIGZ1bmN0aW9uXG5cdCAgICAgICAgICAgIC8vIHdpbGwgbm90IGZpcmUgYmVmb3JlIHRoZSBwYXJlbnQncyBzdWNjZXNzIGNhbGxiYWNrIG9uIGNyZWF0aW9uLlxuXHQgICAgICAgICAgICAvLyBpZiB0aGUgY2hpbGQgd2luZG93IGlzIG5vdCBhY2Nlc3NpYmxlIChDT1JTKSB0aGlzIGNvbnRyYWN0IGRvZXNcblx0ICAgICAgICAgICAgLy8gbm90IGhvbGQuXG5cdCAgICAgICAgICAgIGNvbnN0IHdlYldpbmRvdyA9IHRoaXMuZ2V0V2ViV2luZG93KCk7XG5cdCAgICAgICAgICAgIHdlYldpbmRvdy5maW4uX19pbnRlcm5hbF8ub3BlbmVyU3VjY2Vzc0NCQ2FsbGVkKCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgIC8vIGNvbW1vbiBmb3IgbWFpbiB3aW5kb3dzLCB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvci4gaGVyZSBqdXN0IHRvIGhhdmUgYSBkZWJ1ZyB0YXJnZXQuXG5cdCAgICAgICAgICAgIC8vIGNvbnNvbGUuZXJyb3IoZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChwYWdlUmVzb2x2ZS5zdWNjZXNzKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QocGFnZVJlc29sdmUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2YgZnJhbWUgaW5mbyBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgbWFpbiBmcmFtZSBhbmQgYW55XG5cdCAgICAgKiBpZnJhbWVzIHRoYXQgYXJlIGN1cnJlbnRseSBvbiB0aGUgcGFnZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldEFsbEZyYW1lcygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmdldEFsbEZyYW1lcy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRBbGxGcmFtZXMoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRBbGxGcmFtZXMoKS50aGVuKGZyYW1lc0luZm8gPT4gY29uc29sZS5sb2coZnJhbWVzSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRBbGxGcmFtZXMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWZyYW1lcycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGJvdW5kcyAodG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0LCB3aWR0aCwgaGVpZ2h0KSBvZiB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0Qm91bmRzKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMycsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0Qm91bmRzLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldEJvdW5kcygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldEJvdW5kcygpLnRoZW4oYm91bmRzID0+IGNvbnNvbGUubG9nKGJvdW5kcykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRCb3VuZHMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignZ2V0LXdpbmRvdy1ib3VuZHMnLCB0aGlzLmlkZW50aXR5KVxuXHQgICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENlbnRlcnMgdGhlIHdpbmRvdyBvbiBpdHMgY3VycmVudCBzY3JlZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgRG9lcyBub3QgaGF2ZSBhbiBlZmZlY3Qgb24gbWluaW1pemVkIG9yIG1heGltaXplZCB3aW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY2VudGVyV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuY2VudGVyLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmNlbnRlcigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGNlbnRlcldpbmRvdygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBjZW50ZXJlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIGNlbnRlcigpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NlbnRlci13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlbW92ZXMgZm9jdXMgZnJvbSB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gYmx1cldpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmJsdXIuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uYmx1cigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGJsdXJXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdCbHVyZWQgV2luZG93JykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBibHVyKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignYmx1ci13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEJyaW5ncyB0aGUgd2luZG93IHRvIHRoZSBmcm9udCBvZiB0aGUgd2luZG93IHN0YWNrLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gQnJpbmdXaW5kb3dUb0Zyb250KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuYnJpbmdUb0Zyb250Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmJyaW5nVG9Gcm9udCgpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIEJyaW5nV2luZG93VG9Gcm9udCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBpcyBpbiB0aGUgZnJvbnQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGJyaW5nVG9Gcm9udCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2JyaW5nLXdpbmRvdy10by1mcm9udCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUGVyZm9ybXMgdGhlIHNwZWNpZmllZCB3aW5kb3cgdHJhbnNpdGlvbnMuXG5cdCAgICAgKiBAcGFyYW0gdHJhbnNpdGlvbnMgLSBEZXNjcmliZXMgdGhlIGFuaW1hdGlvbnMgdG8gcGVyZm9ybS4gU2VlIHRoZSB0dXRvcmlhbC5cblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9ucyBmb3IgdGhlIGFuaW1hdGlvbi4gU2VlIHRoZSB0dXRvcmlhbC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBgXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBhbmltYXRlV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHRyYW5zaXRpb25zID0ge1xuXHQgICAgICogICAgICAgICBvcGFjaXR5OiB7XG5cdCAgICAgKiAgICAgICAgICAgICBvcGFjaXR5OiAwLjcsXG5cdCAgICAgKiAgICAgICAgICAgICBkdXJhdGlvbjogNTAwXG5cdCAgICAgKiAgICAgICAgIH0sXG5cdCAgICAgKiAgICAgICAgIHBvc2l0aW9uOiB7XG5cdCAgICAgKiAgICAgICAgICAgICB0b3A6IDEwMCxcblx0ICAgICAqICAgICAgICAgICAgIGxlZnQ6IDEwMCxcblx0ICAgICAqICAgICAgICAgICAgIGR1cmF0aW9uOiA1MDAsXG5cdCAgICAgKiAgICAgICAgICAgICByZWxhdGl2ZTogdHJ1ZVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqICAgICBjb25zdCBvcHRpb25zID0ge1xuXHQgICAgICogICAgICAgICBpbnRlcnJ1cHQ6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIHR3ZWVuOiAnZWFzZS1pbidcblx0ICAgICAqICAgICB9O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gd2luLmFuaW1hdGUodHJhbnNpdGlvbnMsIG9wdGlvbnMpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFuaW1hdGVXaW5kb3coKVxuXHQgICAgICogICAgIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBbmltYXRpb24gZG9uZScpKVxuXHQgICAgICogICAgIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhbmltYXRlKHRyYW5zaXRpb25zLCBvcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignYW5pbWF0ZS13aW5kb3cnLCB7XG5cdCAgICAgICAgICAgIHRyYW5zaXRpb25zLFxuXHQgICAgICAgICAgICBvcHRpb25zLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSGlkZXMgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGhpZGVXaW5kb3coKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5oaWRlLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmhpZGUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBoaWRlV2luZG93KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnV2luZG93IGlzIGhpZGRlbicpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgaGlkZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2hpZGUtd2luZG93JywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBjbG9zZXMgdGhlIHdpbmRvdyBhcHBsaWNhdGlvblxuXHQgICAgICogQHBhcmFtIGZvcmNlIENsb3NlIHdpbGwgYmUgcHJldmVudGVkIGZyb20gY2xvc2luZyB3aGVuIGZvcmNlIGlzIGZhbHNlIGFuZFxuXHQgICAgICogIOKAmGNsb3NlLXJlcXVlc3RlZOKAmSBoYXMgYmVlbiBzdWJzY3JpYmVkIHRvIGZvciBhcHBsaWNhdGlvbuKAmXMgbWFpbiB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjbG9zZVdpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTMnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmNsb3NlLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmNsb3NlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogY2xvc2VXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgY2xvc2VkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBjbG9zZShmb3JjZSA9IGZhbHNlKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbG9zZS13aW5kb3cnLCB7IGZvcmNlLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4ge1xuXHQgICAgICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgbnVsbCk7XG5cdCAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBmb2N1c2VkV2ViVmlld1dhc0NoYW5nZWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmb2N1c2VkLXdlYnZpZXctY2hhbmdlZCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyB0aGUgbmF0aXZlIE9TIGxldmVsIElkLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIEluIFdpbmRvd3MsIGl0IHdpbGwgcmV0dXJuIHRoZSBXaW5kb3dzIFtoYW5kbGVdKGh0dHBzOi8vZG9jcy5taWNyb3NvZnQuY29tL2VuLXVzL3dpbmRvd3MvZGVza3RvcC9XaW5Qcm9nL3dpbmRvd3MtZGF0YS10eXBlcyNIV05EKS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFdpbmRvd05hdGl2ZUlkKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMycsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0TmF0aXZlSWQuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZ2V0TmF0aXZlSWQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3dOYXRpdmVJZCgpLnRoZW4obmF0aXZlSWQgPT4gY29uc29sZS5sb2cobmF0aXZlSWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0TmF0aXZlSWQoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LW5hdGl2ZS1pZCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgd2luZG93J3MgYXR0YWNoZWQgdmlld3MuXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG5cdCAgICAgKlxuXHQgICAgICogd2luLmdldEN1cnJlbnRWaWV3cygpXG5cdCAgICAgKiAgIC50aGVuKHZpZXdzID0+IGNvbnNvbGUubG9nKHZpZXdzKSlcblx0ICAgICAqICAgLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEN1cnJlbnRWaWV3cygpIHtcblx0ICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZ2V0LXZpZXdzJywgdGhpcy5pZGVudGl0eSk7XG5cdCAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YS5tYXAoKGlkKSA9PiBuZXcgdmlld18xLlZpZXcodGhpcy53aXJlLCBpZCkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFdpbmRvdy5fV2luZG93LmRpc2FibGVVc2VyTW92ZW1lbnR9IGluc3RlYWQuXG5cdCAgICAgKi9cblx0ICAgIGRpc2FibGVGcmFtZSgpIHtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ0Z1bmN0aW9uIGlzIGRlcHJlY2F0ZWQ7IHVzZSBkaXNhYmxlVXNlck1vdmVtZW50IGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdkaXNhYmxlLXdpbmRvdy1mcmFtZScsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJldmVudHMgYSB1c2VyIGZyb20gY2hhbmdpbmcgYSB3aW5kb3cncyBzaXplL3Bvc2l0aW9uIHdoZW4gdXNpbmcgdGhlIHdpbmRvdydzIGZyYW1lLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZGlzYWJsZVVzZXJNb3ZlbWVudCgpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTMnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmRpc2FibGVGcmFtZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5kaXNhYmxlVXNlck1vdmVtZW50KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZGlzYWJsZVVzZXJNb3ZlbWVudCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBpcyBkaXNhYmxlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZGlzYWJsZVVzZXJNb3ZlbWVudCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rpc2FibGUtd2luZG93LWZyYW1lJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIFdpbmRvdy5fV2luZG93LmVuYWJsZVVzZXJNb3ZlbWVudH0gaW5zdGVhZC5cblx0ICAgICAqL1xuXHQgICAgZW5hYmxlRnJhbWUoKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdGdW5jdGlvbiBpcyBkZXByZWNhdGVkOyB1c2UgZW5hYmxlVXNlck1vdmVtZW50IGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdlbmFibGUtd2luZG93LWZyYW1lJywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZS1lbmFibGVzIHVzZXIgY2hhbmdlcyB0byBhIHdpbmRvdydzIHNpemUvcG9zaXRpb24gd2hlbiB1c2luZyB0aGUgd2luZG93J3MgZnJhbWUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBlbmFibGVVc2VyTW92ZW1lbnQoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0zJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5lbmFibGVGcmFtZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5lbmFibGVVc2VyTW92ZW1lbnQoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBlbmFibGVVc2VyTW92ZW1lbnQoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgaXMgZW5hYmxlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZW5hYmxlVXNlck1vdmVtZW50KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZW5hYmxlLXdpbmRvdy1mcmFtZScsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmxhc2hlcyB0aGUgd2luZG934oCZcyBmcmFtZSBhbmQgdGFza2JhciBpY29uIHVudGlsIHN0b3BGbGFzaGluZyBpcyBjYWxsZWQgb3IgdW50aWwgYSBmb2N1cyBldmVudCBpcyBmaXJlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBPbiBtYWNPUyBmbGFzaCBvbmx5IHdvcmtzIG9uIGluYWN0aXZlIHdpbmRvd3MuXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHdpbmRvd0ZsYXNoKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZmxhc2guaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZmxhc2goKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiB3aW5kb3dGbGFzaCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1dpbmRvdyBmbGFzaGluZycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZmxhc2goKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmbGFzaC13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFN0b3BzIHRoZSB0YXNrYmFyIGljb24gZnJvbSBmbGFzaGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHN0b3BXaW5kb3dGbGFzaGluZygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnN0b3BGbGFzaGluZy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zdG9wRmxhc2hpbmcoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzdG9wV2luZG93Rmxhc2hpbmcoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdBcHBsaWNhdGlvbiB3aW5kb3cgZmxhc2hpbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHN0b3BGbGFzaGluZygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3N0b3AtZmxhc2gtd2luZG93JywgdGhpcy5pZGVudGl0eSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGFuIGluZm9ybWF0aW9uIG9iamVjdCBmb3IgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldEluZm8oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5nZXRJbmZvLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldEluZm8oKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRJbmZvKCkudGhlbihpbmZvID0+IGNvbnNvbGUubG9nKGluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mbygpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC13aW5kb3ctaW5mbycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgdGhlIHdpbmRvdydzIExheW91dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogICAgIC8vZ2V0IHRoZSBjdXJyZW50IHdpbmRvd1xuXHQgICAgICogICAgIGNvbnN0IHdpbmRvdyA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAvL2dldCB0aGUgbGF5b3V0IGZvciB0aGUgd2luZG93XG5cdCAgICAgKiAgICAgY29uc3QgbGF5b3V0ID0gYXdhaXQgd2luZG93LmdldExheW91dCgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldExheW91dChsYXlvdXRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZ2V0LWxheW91dCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IG9wdHMgPSBhd2FpdCB0aGlzLmdldE9wdGlvbnMoKTtcblx0ICAgICAgICBpZiAoIW9wdHMubGF5b3V0ICYmICFvcHRzLmxheW91dFNuYXBzaG90KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2luZG93IGRvZXMgbm90IGhhdmUgYSBMYXlvdXQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuZmluLlBsYXRmb3JtLkxheW91dC53cmFwKGxheW91dElkZW50aXR5ID8/IHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHNldHRpbmdzIG9mIHRoZSB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRXaW5kb3dPcHRpb25zKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0T3B0aW9ucy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRPcHRpb25zKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZ2V0V2luZG93T3B0aW9ucygpLnRoZW4ob3B0cyA9PiBjb25zb2xlLmxvZyhvcHRzKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldE9wdGlvbnMoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LW9wdGlvbnMnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgcGFyZW50IGFwcGxpY2F0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50QXBwbGljYXRpb24oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5nZXRQYXJlbnRBcHBsaWNhdGlvbi5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5nZXRQYXJlbnRBcHBsaWNhdGlvbigpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldFBhcmVudEFwcGxpY2F0aW9uKCkudGhlbihwYXJlbnRBcHBsaWNhdGlvbiA9PiBjb25zb2xlLmxvZyhwYXJlbnRBcHBsaWNhdGlvbikpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRQYXJlbnRBcHBsaWNhdGlvbigpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWdldC1wYXJlbnQtYXBwbGljYXRpb24nLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBhcHBsaWNhdGlvbl8xLkFwcGxpY2F0aW9uKHRoaXMud2lyZSwgdGhpcy5pZGVudGl0eSkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIHRoZSBwYXJlbnQgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50V2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0UGFyZW50V2luZG93Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLmdldFBhcmVudFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGdldFBhcmVudFdpbmRvdygpLnRoZW4ocGFyZW50V2luZG93ID0+IGNvbnNvbGUubG9nKHBhcmVudFdpbmRvdykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRQYXJlbnRXaW5kb3coKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy1nZXQtcGFyZW50LXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IGFwcGxpY2F0aW9uXzEuQXBwbGljYXRpb24odGhpcy53aXJlLCB0aGlzLmlkZW50aXR5KSkudGhlbigoYXBwKSA9PiBhcHAuZ2V0V2luZG93KCkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiAqKipERVBSRUNBVEVEIC0gcGxlYXNlIHVzZSBXaW5kb3cuY2FwdHVyZVBhZ2UuKioqXG5cdCAgICAgKiBHZXRzIGEgYmFzZTY0IGVuY29kZWQgUE5HIGltYWdlIG9mIHRoZSB3aW5kb3cgb3IganVzdCBwYXJ0IGEgb2YgaXQuXG5cdCAgICAgKiBAcGFyYW0gYXJlYSBUaGUgYXJlYSBvZiB0aGUgd2luZG93IHRvIGJlIGNhcHR1cmVkLlxuXHQgICAgICogT21pdHRpbmcgaXQgd2lsbCBjYXB0dXJlIHRoZSB3aG9sZSB2aXNpYmxlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgV2luZG93LmNhcHR1cmVQYWdlXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldFNuYXBzaG90KGFyZWEpIHtcblx0ICAgICAgICBjb25zdCByZXEgPSB7IGFyZWEsIC4uLnRoaXMuaWRlbnRpdHkgfTtcblx0ICAgICAgICBjb25zb2xlLndhcm4oJ1dpbmRvdy5nZXRTbmFwc2hvdCBoYXMgYmVlbiBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIFdpbmRvdy5jYXB0dXJlUGFnZScpO1xuXHQgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LXNuYXBzaG90JywgcmVxKTtcblx0ICAgICAgICByZXR1cm4gcmVzLnBheWxvYWQuZGF0YTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgY3VycmVudCBzdGF0ZSAoXCJtaW5pbWl6ZWRcIiwgXCJtYXhpbWl6ZWRcIiwgb3IgXCJub3JtYWxcIikgb2YgdGhlIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldFdpbmRvd1N0YXRlKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuZ2V0U3RhdGUuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uZ2V0U3RhdGUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRXaW5kb3dTdGF0ZSgpLnRoZW4od2luU3RhdGUgPT4gY29uc29sZS5sb2cod2luU3RhdGUpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0U3RhdGUoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtd2luZG93LXN0YXRlJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFByZXZpb3VzbHkgY2FsbGVkIGdldE5hdGl2ZVdpbmRvdy5cblx0ICAgICAqIFJldHVybnMgdGhlIFtXaW5kb3cgT2JqZWN0XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93KVxuXHQgICAgICogdGhhdCByZXByZXNlbnRzIHRoZSB3ZWIgY29udGV4dCBvZiB0aGUgdGFyZ2V0IHdpbmRvdy4gVGhpcyBpcyB0aGUgc2FtZSBvYmplY3QgdGhhdFxuXHQgICAgICogeW91IHdvdWxkIGdldCBmcm9tIGNhbGxpbmcgW3dpbmRvdy5vcGVuKCldKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvb3BlbikgaW4gYSBzdGFuZGFyZCB3ZWIgY29udGV4dC5cblx0ICAgICAqIFRoZSB0YXJnZXQgd2luZG93IG5lZWRzIHRvIGJlIGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGFzIHRoZSByZXF1ZXN0aW5nIHdpbmRvd1xuXHQgICAgICogYXMgd2VsbCBhcyBjb21wbHkgd2l0aCBbc2FtZS1vcmlnaW5dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL1NlY3VyaXR5L1NhbWUtb3JpZ2luX3BvbGljeSkgcG9saWN5IHJlcXVpcmVtZW50cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogSW5qZWN0aW5nIGNvbnRlbnQgaW50byBhbiBlbXB0eSB3aW5kb3c6XG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIChhc3luYyAoKT0+IHtcblx0ICAgICAqICAgICB0cnkge1xuXHQgICAgICogICAgICAgICBjb25zdCB3aW5OYW1lID0gYGNoaWxkLXdpbmRvdy0ke0RhdGUubm93KCl9YDtcblx0ICAgICAqICAgICAgICAgY29uc3Qgd2luID0gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUoe1xuXHQgICAgICogICAgICAgICAgICAgbmFtZTogd2luTmFtZSxcblx0ICAgICAqICAgICAgICAgICAgIHVybDogJ2Fib3V0OmJsYW5rJ1xuXHQgICAgICogICAgICAgICB9KTtcblx0ICAgICAqICAgICAgICAgd2luLmdldFdlYldpbmRvdygpLmRvY3VtZW50LndyaXRlKCc8aDE+SGVsbG8gV29ybGQ8L2gxPicpO1xuXHQgICAgICogICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSkoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIENsb25pbmcgRE9NIGVsZW1lbnRzIGZyb20gdGhlIHBhcmVudCB3aW5kb3cgKGluIHRoaXMgZXhhbXBsZSB3ZSBjbG9uZSBhbiBgaDNgIGVsZW1lbnQgZnJvbSB0aGUgcGFyZW50IHdpbmRvdyk6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogKGFzeW5jICgpPT4ge1xuXHQgICAgICogICAgIHRyeSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IGN1cnJlbnRXaW5kb3cgPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICAgICAgY29uc3QgcGFyZW50V2luZG93ID0gYXdhaXQgY3VycmVudFdpbmRvdy5nZXRQYXJlbnRXaW5kb3coKTtcblx0ICAgICAqICAgICAgICAgY29uc3QgY2xvbmVkSDMgPSBwYXJlbnRXaW5kb3cuZ2V0V2ViV2luZG93KCkuZG9jdW1lbnQucXVlcnlTZWxlY3RvcignaDMnKS5jbG9uZU5vZGUodHJ1ZSk7XG5cdCAgICAgKiAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kKGNsb25lZEgzKTtcblx0ICAgICAqXG5cdCAgICAgKiAgICAgfSBjYXRjaCAoZXJyKSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogUmVuZGVyaW5nIG9uIGEgY2hpbGQgd2luZG93IHZpYSBhIGxpYnJhcnkgKGluIHRoaXMgZXhhbXBsZSB3ZSBhcmUgdXNpbmcgdGhlIFtsaXQtaHRtbF0oaHR0cHM6Ly9saXQtaHRtbC5wb2x5bWVyLXByb2plY3Qub3JnLylcblx0ICAgICAqIHRlbXBsYXRlIGxpYnJhcnkgdG8gcmVuZGVyIGNvbnRlbnQgb24gYSBibGFuayBjaGlsZCB3aW5kb3cuIFlvdSBhcmUgbm90IGdvaW5nIHRvIGJlIGFibGUgdG8gY29weSBwYXN0ZSB0aGlzIGV4YW1wbGUgd2l0aG91dFxuXHQgICAgICogY29uZmlndXJpbmcgdGhlIHByb2plY3QgY29ycmVjdGx5IGJ1dCB0aGlzIHdvdWxkIGRlbW9uc3RyYXRlIHNvbWUgdGVtcGxhdGluZyBvcHRpb25zIGF2YWlsYWJsZSk6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogKGFzeW5jICgpPT4ge1xuXHQgICAgICogICAgIHRyeSB7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuY3JlYXRlKHtcblx0ICAgICAqICAgICAgICAgICAgIG5hbWU6IGBjaGlsZC13aW5kb3ctJHtEYXRlLm5vdygpfWAsXG5cdCAgICAgKiAgICAgICAgICAgICB1cmw6ICdhYm91dDpibGFuaydcblx0ICAgICAqICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgIGNvbnN0IHRlbXBsYXRlID0gaHRtbGBcblx0ICAgICAqICAgICAgICAgICAgIDxkaXY+XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgPHNwYW4+Q2xpY2sgaGVyZTogPC9zcGFuPlxuXHQgICAgICogICAgICAgICAgICAgICAgIDxidXR0b24gQGNsaWNrPSR7KCk9PiBjb25zb2xlLmxvZygnSGVsbG8gV29ybGQhJyl9PmxvZyB0byB0aGUgY29uc29sZTwvYnV0dG9uPlxuXHQgICAgICogICAgICAgICAgICAgPC9kaXY+YDtcblx0ICAgICAqICAgICAgICAgcmVuZGVyKHRlbXBsYXRlLCB3aW4uZ2V0V2ViV2luZG93KCkuZG9jdW1lbnQuYm9keSk7XG5cdCAgICAgKlxuXHQgICAgICogICAgIH0gY2F0Y2ggKGVycikge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSkoKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBnZXRXZWJXaW5kb3coKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy1nZXQtd2ViLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0V2ViV2luZG93KHRoaXMuaWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB3aW5kb3cgaXMgYSBtYWluIHdpbmRvdy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHduZCA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqIGNvbnN0IGlzTWFpblduZCA9IHduZC5pc01haW5XaW5kb3coKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKCdJcyB0aGlzIGEgbWFpbiB3aW5kb3c/ICcgKyBpc01haW5XbmQpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGlzTWFpbldpbmRvdygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignd2luZG93LWlzLW1haW4td2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMubWUudXVpZCA9PT0gdGhpcy5tZS5uYW1lO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB3aW5kb3cgaXMgY3VycmVudGx5IHNob3dpbmcuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBpc1dpbmRvd1Nob3dpbmcoKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5pc1Nob3dpbmcuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uaXNTaG93aW5nKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogaXNXaW5kb3dTaG93aW5nKCkudGhlbihib29sID0+IGNvbnNvbGUubG9nKGJvb2wpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgaXNTaG93aW5nKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignaXMtd2luZG93LXNob3dpbmcnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTWF4aW1pemVzIHRoZSB3aW5kb3dcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIG1heFdpbmRvdygpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93Lm1heGltaXplLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLm1heGltaXplKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogbWF4V2luZG93KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnTWF4aW1pemVkIHdpbmRvdycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgbWF4aW1pemUoKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdtYXhpbWl6ZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIE1pbmltaXplcyB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gbWluV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGZpbi5XaW5kb3cuZ2V0Q3VycmVudCgpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubWluaW1pemUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtaW5XaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdNaW5pbWl6ZWQgd2luZG93JykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBtaW5pbWl6ZSgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ21pbmltaXplLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogTW92ZXMgdGhlIHdpbmRvdyBieSBhIHNwZWNpZmllZCBhbW91bnQuXG5cdCAgICAgKiBAcGFyYW0gZGVsdGFMZWZ0IFRoZSBjaGFuZ2UgaW4gdGhlIGxlZnQgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGRlbHRhVG9wIFRoZSBjaGFuZ2UgaW4gdGhlIHRvcCBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5tb3ZlQnkuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBtb3ZlQnkobGVmdCwgdG9wKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5tb3ZlQnkobGVmdCwgdG9wKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtb3ZlQnkoNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01vdmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBtb3ZlQnkoZGVsdGFMZWZ0LCBkZWx0YVRvcCwgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignbW92ZS13aW5kb3ctYnknLCB7XG5cdCAgICAgICAgICAgIGRlbHRhTGVmdCxcblx0ICAgICAgICAgICAgZGVsdGFUb3AsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIE1vdmVzIHRoZSB3aW5kb3cgdG8gYSBzcGVjaWZpZWQgbG9jYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gbGVmdCBUaGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG5cdCAgICAgKiBAcGFyYW0gdG9wIFRoZSB0b3AgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cubW92ZVRvLmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gbW92ZVRvKGxlZnQsIHRvcCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ubW92ZVRvKGxlZnQsIHRvcClcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBtb3ZlVG8oNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01vdmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIG1vdmVUbyhsZWZ0LCB0b3AsIHBvc2l0aW9uaW5nT3B0aW9ucykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ21vdmUtd2luZG93Jywge1xuXHQgICAgICAgICAgICBsZWZ0LFxuXHQgICAgICAgICAgICB0b3AsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc2l6ZXMgdGhlIHdpbmRvdyBieSBhIHNwZWNpZmllZCBhbW91bnQuXG5cdCAgICAgKiBAcGFyYW0gZGVsdGFXaWR0aCBUaGUgY2hhbmdlIGluIHRoZSB3aWR0aCBvZiB0aGUgd2luZG93XG5cdCAgICAgKiBAcGFyYW0gZGVsdGFIZWlnaHQgVGhlIGNoYW5nZSBpbiB0aGUgaGVpZ2h0IG9mIHRoZSB3aW5kb3dcblx0ICAgICAqIEBwYXJhbSBhbmNob3IgU3BlY2lmaWVzIGEgY29ybmVyIHRvIHJlbWFpbiBmaXhlZCBkdXJpbmcgdGhlIHJlc2l6ZS5cblx0ICAgICAqIENhbiB0YWtlIHRoZSB2YWx1ZXM6IFwidG9wLWxlZnRcIiwgXCJ0b3AtcmlnaHRcIiwgXCJib3R0b20tbGVmdFwiLCBvciBcImJvdHRvbS1yaWdodFwiLlxuXHQgICAgICogSWYgdW5kZWZpbmVkLCB0aGUgZGVmYXVsdCBpcyBcInRvcC1sZWZ0XCJcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnJlc2l6ZUJ5Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gcmVzaXplQnkobGVmdCwgdG9wLCBhbmNob3IpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnJlc2l6ZUJ5KGxlZnQsIHRvcCwgYW5jaG9yKVxuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlc2l6ZUJ5KDU4MCwgMzAwLCAndG9wLXJpZ2h0JykudGhlbigoKSA9PiBjb25zb2xlLmxvZygnUmVzaXplZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgcmVzaXplQnkoZGVsdGFXaWR0aCwgZGVsdGFIZWlnaHQsIGFuY2hvciwgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbigncmVzaXplLXdpbmRvdy1ieScsIHtcblx0ICAgICAgICAgICAgZGVsdGFXaWR0aDogTWF0aC5mbG9vcihkZWx0YVdpZHRoKSxcblx0ICAgICAgICAgICAgZGVsdGFIZWlnaHQ6IE1hdGguZmxvb3IoZGVsdGFIZWlnaHQpLFxuXHQgICAgICAgICAgICBhbmNob3IsXG5cdCAgICAgICAgICAgIHBvc2l0aW9uaW5nT3B0aW9ucyxcblx0ICAgICAgICAgICAgLi4udGhpcy5pZGVudGl0eVxuXHQgICAgICAgIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc2l6ZXMgdGhlIHdpbmRvdyB0byB0aGUgc3BlY2lmaWVkIGRpbWVuc2lvbnMuXG5cdCAgICAgKiBAcGFyYW0gd2lkdGggVGhlIGNoYW5nZSBpbiB0aGUgd2lkdGggb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGhlaWdodCBUaGUgY2hhbmdlIGluIHRoZSBoZWlnaHQgb2YgdGhlIHdpbmRvd1xuXHQgICAgICogQHBhcmFtIGFuY2hvciBTcGVjaWZpZXMgYSBjb3JuZXIgdG8gcmVtYWluIGZpeGVkIGR1cmluZyB0aGUgcmVzaXplLlxuXHQgICAgICogQ2FuIHRha2UgdGhlIHZhbHVlczogXCJ0b3AtbGVmdFwiLCBcInRvcC1yaWdodFwiLCBcImJvdHRvbS1sZWZ0XCIsIG9yIFwiYm90dG9tLXJpZ2h0XCIuXG5cdCAgICAgKiBJZiB1bmRlZmluZWQsIHRoZSBkZWZhdWx0IGlzIFwidG9wLWxlZnRcIlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cucmVzaXplVG8uaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiByZXNpemVUbyhsZWZ0LCB0b3AsIGFuY2hvcikge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4ucmVzaXplVG8obGVmdCwgdG9wLCBhbmNob3IpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIHJlc2l6ZVRvKDU4MCwgMzAwLCAndG9wLWxlZnQnKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdSZXNpemVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICByZXNpemVUbyh3aWR0aCwgaGVpZ2h0LCBhbmNob3IsIHBvc2l0aW9uaW5nT3B0aW9ucykge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmVcblx0ICAgICAgICAgICAgLnNlbmRBY3Rpb24oJ3Jlc2l6ZS13aW5kb3cnLCB7XG5cdCAgICAgICAgICAgIHdpZHRoOiBNYXRoLmZsb29yKHdpZHRoKSxcblx0ICAgICAgICAgICAgaGVpZ2h0OiBNYXRoLmZsb29yKGhlaWdodCksXG5cdCAgICAgICAgICAgIGFuY2hvcixcblx0ICAgICAgICAgICAgcG9zaXRpb25pbmdPcHRpb25zLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzdG9yZXMgdGhlIHdpbmRvdyB0byBpdHMgbm9ybWFsIHN0YXRlIChpLmUuLCB1bm1pbmltaXplZCwgdW5tYXhpbWl6ZWQpLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cucmVzdG9yZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHJlc3RvcmUoKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5yZXN0b3JlKCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogcmVzdG9yZSgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Jlc3RvcmVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICByZXN0b3JlKCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVzdG9yZS13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFdpbGwgYnJpbmcgdGhlIHdpbmRvdyB0byB0aGUgZnJvbnQgb2YgdGhlIGVudGlyZSBzdGFjayBhbmQgZ2l2ZSBpdCBmb2N1cy5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LnNldEFzRm9yZWdyb3VuZC5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IHRydWVcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgYXBwLmdldFdpbmRvdygpO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIHNldEFzRm9yZWdyb3VuZCgpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBjcmVhdGVXaW4oKTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgd2luLnNldEFzRm9yZWdyb3VuZCgpXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2V0QXNGb3JlZ3JvdW5kKCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnSW4gdGhlIGZvcmVncm91bmQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNldEFzRm9yZWdyb3VuZCgpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NldC1mb3JlZ3JvdW5kLXdpbmRvdycsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyB0aGUgd2luZG93J3Mgc2l6ZSBhbmQgcG9zaXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBjcmVhdGVXaW4oKSB7XG5cdCAgICAgKiAgICAgY29uc3QgYXBwID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLnN0YXJ0KHtcblx0ICAgICAqICAgICAgICAgbmFtZTogJ215QXBwJyxcblx0ICAgICAqICAgICAgICAgdXVpZDogJ2FwcC0xJyxcblx0ICAgICAqICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvc3RhYmxlL3R1dG9yaWFsLVdpbmRvdy5zZXRCb3VuZHMuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzZXRCb3VuZHMoYm91bmRzKSB7XG5cdCAgICAgKiAgICAgY29uc3Qgd2luID0gYXdhaXQgY3JlYXRlV2luKCk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHdpbi5zZXRCb3VuZHMoYm91bmRzKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzZXRCb3VuZHMoe1xuXHQgICAgICogICAgIGhlaWdodDogMTAwLFxuXHQgICAgICogICAgIHdpZHRoOiAyMDAsXG5cdCAgICAgKiAgICAgdG9wOiA0MDAsXG5cdCAgICAgKiAgICAgbGVmdDogNDAwXG5cdCAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdCb3VuZHMgc2V0IHRvIHdpbmRvdycpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgc2V0Qm91bmRzKGJvdW5kcywgcG9zaXRpb25pbmdPcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZVxuXHQgICAgICAgICAgICAuc2VuZEFjdGlvbignc2V0LXdpbmRvdy1ib3VuZHMnLCB7IC4uLmJvdW5kcywgLi4udGhpcy5pZGVudGl0eSwgcG9zaXRpb25pbmdPcHRpb25zIH0pXG5cdCAgICAgICAgICAgIC50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNob3dzIHRoZSB3aW5kb3cgaWYgaXQgaXMgaGlkZGVuLlxuXHQgICAgICogQHBhcmFtIGZvcmNlIFNob3cgd2lsbCBiZSBwcmV2ZW50ZWQgZnJvbSBzaG93aW5nIHdoZW4gZm9yY2UgaXMgZmFsc2UgYW5kXG5cdCAgICAgKiAg4oCYc2hvdy1yZXF1ZXN0ZWTigJkgaGFzIGJlZW4gc3Vic2NyaWJlZCB0byBmb3IgYXBwbGljYXRpb27igJlzIG1haW4gd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2hvdy5odG1sJyxcblx0ICAgICAqICAgICAgICAgYXV0b1Nob3c6IGZhbHNlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBhc3luYyBmdW5jdGlvbiBzaG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc2hvdygpXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogc2hvdygpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Nob3dpbmcnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNob3coZm9yY2UgPSBmYWxzZSkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignc2hvdy13aW5kb3cnLCB7IGZvcmNlLCAuLi50aGlzLmlkZW50aXR5IH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgdGhlIHdpbmRvdyBpZiBpdCBpcyBoaWRkZW4gYXQgdGhlIHNwZWNpZmllZCBsb2NhdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gbGVmdCBUaGUgbGVmdCBwb3NpdGlvbiBvZiB0aGUgd2luZG93IGluIHBpeGVsc1xuXHQgICAgICogQHBhcmFtIHRvcCBUaGUgdG9wIHBvc2l0aW9uIG9mIHRoZSB3aW5kb3cgaW4gcGl4ZWxzXG5cdCAgICAgKiBAcGFyYW0gZm9yY2UgU2hvdyB3aWxsIGJlIHByZXZlbnRlZCBmcm9tIGNsb3Npbmcgd2hlbiBmb3JjZSBpcyBmYWxzZSBhbmRcblx0ICAgICAqIOKAmHNob3ctcmVxdWVzdGVk4oCZIGhhcyBiZWVuIHN1YnNjcmliZWQgdG8gZm9yIGFwcGxpY2F0aW9u4oCZcyBtYWluIHdpbmRvd1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cuc2hvd0F0Lmh0bWwnLFxuXHQgICAgICogICAgICAgICBhdXRvU2hvdzogdHJ1ZVxuXHQgICAgICogICAgIH0pO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCBhcHAuZ2V0V2luZG93KCk7XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gc2hvd0F0KGxlZnQsIHRvcCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogICAgIHJldHVybiBhd2FpdCB3aW4uc2hvd0F0KGxlZnQsIHRvcClcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBzaG93QXQoNTgwLCAzMDApLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1Nob3dpbmcgYXQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHNob3dBdChsZWZ0LCB0b3AsIGZvcmNlID0gZmFsc2UpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdzaG93LWF0LXdpbmRvdycsIHtcblx0ICAgICAgICAgICAgZm9yY2UsXG5cdCAgICAgICAgICAgIGxlZnQ6IE1hdGguZmxvb3IobGVmdCksXG5cdCAgICAgICAgICAgIHRvcDogTWF0aC5mbG9vcih0b3ApLFxuXHQgICAgICAgICAgICAuLi50aGlzLmlkZW50aXR5XG5cdCAgICAgICAgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29sc1xuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBXaW5kb3cuc2hvd0RldmVsb3BlclRvb2xzXG5cdCAgICAgKi9cblx0ICAgIC8qKlxuXHQgICAgICogVXBkYXRlcyB0aGUgd2luZG93IHVzaW5nIHRoZSBwYXNzZWQgb3B0aW9ucy5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBWYWx1ZXMgdGhhdCBhcmUgb2JqZWN0cyBhcmUgZGVlcC1tZXJnZWQsIG92ZXJ3cml0aW5nIG9ubHkgdGhlIHZhbHVlcyB0aGF0IGFyZSBwcm92aWRlZC5cblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIENoYW5nZXMgYSB3aW5kb3cncyBvcHRpb25zIHRoYXQgd2VyZSBkZWZpbmVkIHVwb24gY3JlYXRpb24uIFNlZSB0dXRvcmlhbFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gdXBkYXRlT3B0aW9ucygpIHtcblx0ICAgICAqICAgICBjb25zdCB3aW4gPSBhd2FpdCBmaW4uV2luZG93LmdldEN1cnJlbnQoKTtcblx0ICAgICAqICAgICByZXR1cm4gd2luLnVwZGF0ZU9wdGlvbnMoe21heFdpZHRoOiAxMDB9KTtcblx0ICAgICAqIH1cblx0ICAgICAqIHVwZGF0ZU9wdGlvbnMoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdvcHRpb25zIGlzIHVwZGF0ZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgdXBkYXRlT3B0aW9ucyhvcHRpb25zKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd1cGRhdGUtd2luZG93LW9wdGlvbnMnLCB7IG9wdGlvbnMsIC4uLnRoaXMuaWRlbnRpdHkgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBQcm92aWRlcyBjcmVkZW50aWFscyB0byBhdXRoZW50aWNhdGlvbiByZXF1ZXN0c1xuXHQgICAgICogQHBhcmFtIHVzZXJOYW1lIHVzZXJOYW1lIHRvIHByb3ZpZGUgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIGNoYWxsZW5nZVxuXHQgICAgICogQHBhcmFtIHBhc3N3b3JkIHBhc3N3b3JkIHRvIHByb3ZpZGUgdG8gdGhlIGF1dGhlbnRpY2F0aW9uIGNoYWxsZW5nZVxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLkFwcGxpY2F0aW9uLndyYXAoe3V1aWQ6ICdPcGVuZmluUE9DJ30pLnRoZW4oYXBwID0+IHtcblx0ICAgICAqICAgICBhcHAub24oJ3dpbmRvdy1hdXRoLXJlcXVlc3RlZCcsIGV2dCA9PiB7XG5cdCAgICAgKiAgICAgICAgIGxldCB3aW4gPSBmaW4uV2luZG93LndyYXAoeyB1dWlkOiBldnQudXVpZCwgbmFtZTogZXZ0Lm5hbWV9KTtcblx0ICAgICAqICAgICAgICAgd2luLmF1dGhlbnRpY2F0ZSgndXNlck5hbWUnLCAnUEBhc3N3MHJkJykudGhlbigoKT0+IGNvbnNvbGUubG9nKCdhdXRoZW50aWNhdGVkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqICAgICB9KTtcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGF1dGhlbnRpY2F0ZSh1c2VyTmFtZSwgcGFzc3dvcmQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy53aXJlXG5cdCAgICAgICAgICAgIC5zZW5kQWN0aW9uKCd3aW5kb3ctYXV0aGVudGljYXRlJywgeyB1c2VyTmFtZSwgcGFzc3dvcmQsIC4uLnRoaXMuaWRlbnRpdHkgfSlcblx0ICAgICAgICAgICAgLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU2hvd3MgYSBtZW51IG9uIHRoZSB3aW5kb3cuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSB1c2VyIGhhcyBlaXRoZXIgc2VsZWN0ZWQgYW4gaXRlbSBvciBjbG9zZWQgdGhlIG1lbnUuIChUaGlzIG1heSB0YWtlIGxvbmdlciB0aGFuIG90aGVyIGFwaXMpLlxuXHQgICAgICogUmVzb2x2ZXMgdG8gYW4gb2JqZWN0IHdpdGggYHtyZXN1bHQ6ICdjbGlja2VkJywgZGF0YSB9YCB3aGVyZSBkYXRhIGlzIHRoZSBkYXRhIGZpZWxkIG9uIHRoZSBtZW51IGl0ZW0gY2xpY2tlZCwgb3IgYHtyZXN1bHQgJ2Nsb3NlZCd9YCB3aGVuIHRoZSB1c2VyIGRvZXNuJ3Qgc2VsZWN0IGFueXRoaW5nLlxuXHQgICAgICogQ2FsbGluZyB0aGlzIG1ldGhvZCB3aWxsIGNsb3NlIHByZXZpb3VzbHkgb3BlbmVkIG1lbnVzLlxuXHQgICAgICogQGV4cGVyaW1lbnRhbFxuXHQgICAgICogQHBhcmFtIG9wdGlvbnNcblx0ICAgICAqIEB0eXBlUGFyYW0gRGF0YSBVc2VyLWRlZmluZWQgc2hhcGUgZm9yIGRhdGEgcmV0dXJuZWQgdXBvbiBtZW51IGl0ZW0gY2xpY2suICBTaG91bGQgYmUgYVxuXHQgICAgICogW3VuaW9uXShodHRwczovL3d3dy50eXBlc2NyaXB0bGFuZy5vcmcvZG9jcy9oYW5kYm9vay8yL2V2ZXJ5ZGF5LXR5cGVzLmh0bWwjdW5pb24tdHlwZXMpXG5cdCAgICAgKiBvZiBhbGwgcG9zc2libGUgZGF0YSBzaGFwZXMgZm9yIHRoZSBlbnRpcmUgbWVudSwgYW5kIHRoZSBjbGljayBoYW5kbGVyIHNob3VsZCBwcm9jZXNzXG5cdCAgICAgKiB0aGVzZSB3aXRoIGEgXCJyZWR1Y2VyXCIgcGF0dGVybi5cblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gc2hvdyBhIGRyb3AgZG93biBtZW51IG92ZXIgdmlld3MgaW4gYSBwbGF0Zm9ybSB3aW5kb3c6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgdGVtcGxhdGUgPSBbXG5cdCAgICAgKiAgICAge1xuXHQgICAgICogICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgICAgICAgZGF0YTogJ2hlbGxvIGZyb20gaXRlbSAxJ1xuXHQgICAgICogICAgIH0sXG5cdCAgICAgKiAgICAgeyB0eXBlOiAnc2VwYXJhdG9yJyB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgbGFiZWw6ICdNZW51IEl0ZW0gMicsXG5cdCAgICAgKiAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICAgICAgIGNoZWNrZWQ6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIGRhdGE6ICdUaGUgdXNlciBjbGlja2VkIHRoZSBjaGVja2JveCdcblx0ICAgICAqICAgICB9LFxuXHQgICAgICogICAgIHtcblx0ICAgICAqICAgICAgICAgbGFiZWw6ICdzZWUgbW9yZScsXG5cdCAgICAgKiAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuXHQgICAgICogICAgICAgICBzdWJtZW51OiBbXG5cdCAgICAgKiAgICAgICAgICAgICB7IGxhYmVsOiAnc3VibWVudSAxJywgZGF0YTogJ2hlbGxvIGZyb20gc3VibWVudScgfVxuXHQgICAgICogICAgICAgICBdXG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogXVxuXHQgICAgICogZmluLm1lLnNob3dQb3B1cE1lbnUoeyB0ZW1wbGF0ZSB9KS50aGVuKHIgPT4ge1xuXHQgICAgICogICAgIGlmIChyLnJlc3VsdCA9PT0gJ2Nsb3NlZCcpIHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ25vdGhpbmcgaGFwcGVuZWQnKTtcblx0ICAgICAqICAgICB9IGVsc2Uge1xuXHQgICAgICogICAgICAgICBjb25zb2xlLmxvZyhyLmRhdGEpXG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIE92ZXJyaWRpbmcgdGhlIGJ1aWx0IGluIGNvbnRleHQgbWVudSAobm90ZTogdGhhdCB0aGlzIGNhbiBiZSBkb25lIHBlciBlbGVtZW50IG9yIGRvY3VtZW50IHdpZGUpOlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZSA9PiB7XG5cdCAgICAgKiAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHQgICAgICogICAgIGNvbnN0IHRlbXBsYXRlID0gW1xuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAxJyxcblx0ICAgICAqICAgICAgICAgICAgIGRhdGE6ICdoZWxsbyBmcm9tIGl0ZW0gMSdcblx0ICAgICAqICAgICAgICAgfSxcblx0ICAgICAqICAgICAgICAgeyB0eXBlOiAnc2VwYXJhdG9yJyB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ01lbnUgSXRlbSAyJyxcblx0ICAgICAqICAgICAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG5cdCAgICAgKiAgICAgICAgICAgICBjaGVja2VkOiB0cnVlLFxuXHQgICAgICogICAgICAgICAgICAgZGF0YTogJ1RoZSB1c2VyIGNsaWNrZWQgdGhlIGNoZWNrYm94J1xuXHQgICAgICogICAgICAgICB9LFxuXHQgICAgICogICAgICAgICB7XG5cdCAgICAgKiAgICAgICAgICAgICBsYWJlbDogJ3NlZSBtb3JlJyxcblx0ICAgICAqICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuXHQgICAgICogICAgICAgICAgICAgc3VibWVudTogW1xuXHQgICAgICogICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdzdWJtZW51IDEnLCBkYXRhOiAnaGVsbG8gZnJvbSBzdWJtZW51JyB9XG5cdCAgICAgKiAgICAgICAgICAgICBdXG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICBdXG5cdCAgICAgKiAgICAgZmluLm1lLnNob3dQb3B1cE1lbnUoeyB0ZW1wbGF0ZSwgeDogZS54LCB5OiBlLnkgfSkudGhlbihyID0+IHtcblx0ICAgICAqICAgICAgICAgaWYgKHIucmVzdWx0ID09PSAnY2xvc2VkJykge1xuXHQgICAgICogICAgICAgICAgICAgY29uc29sZS5sb2coJ25vdGhpbmcgaGFwcGVuZWQnKTtcblx0ICAgICAqICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKHIuZGF0YSlcblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgIH0pXG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHNob3dQb3B1cE1lbnUob3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Nob3ctcG9wdXAtbWVudScsIHsgb3B0aW9ucywgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDbG9zZXMgdGhlIHdpbmRvdydzIHBvcHVwIG1lbnUsIGlmIG9uZSBleGlzdHMuXG5cdCAgICAgKiBAZXhwZXJpbWVudGFsXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgT25seSBvbmUgcG9wdXAgbWVudSB3aWxsIGV2ZXIgYmUgc2hvd2luZyBhdCBhIHRpbWUuIENhbGxpbmcgYHNob3dQb3B1cE1lbnVgIHdpbGwgYXV0b21hdGljYWxseSBjbG9zZVxuXHQgICAgICogYW55IGV4aXN0aW5nIHBvcHVwIG1lbnUuXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBUaGlzIGNvdWxkIGJlIHVzZWQgdG8gY2xvc2UgYSBwb3B1cCBtZW51IGlmIHRoZSB1c2VyJ3MgbW91c2UgbGVhdmVzIGFuIGVsZW1lbnQgZm9yIGV4YW1wbGUuXG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5jbG9zZVBvcHVwTWVudSgpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGNsb3NlUG9wdXBNZW51KCkge1xuXHQgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xvc2UtcG9wdXAtbWVudScsIHsgLi4udGhpcy5pZGVudGl0eSB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIERpc3BhdGNoIGEgcmVzdWx0IHRvIHRoZSBjYWxsZXIgb2YgYHNob3dQb3B1cFdpbmRvd2AuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSWYgdGhpcyB3aW5kb3cgaXNuJ3QgY3VycmVudGx5IGJlaW5nIHNob3duIGFzIGEgcG9wdXAsIHRoaXMgY2FsbCB3aWxsIHNpbGVudGx5IGZhaWwuXG5cdCAgICAgKiBAcGFyYW0gZGF0YSBTZXJpYWxpemFibGUgZGF0YSB0byBzZW5kIHRvIHRoZSBjYWxsZXIgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXdhaXQgZmluLm1lLmRpc3BhdGNoUG9wdXBSZXN1bHQoe1xuXHQgICAgICogICAgIGZvbzogJ2Jhcidcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGRpc3BhdGNoUG9wdXBSZXN1bHQoZGF0YSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctZGlzcGF0Y2gtcG9wdXAtcmVzdWx0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rpc3BhdGNoLXBvcHVwLXJlc3VsdCcsIHsgZGF0YSwgLi4udGhpcy5pZGVudGl0eSB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJpbnRzIHRoZSBjb250ZW50cyBvZiB0aGUgd2luZG93LlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBwcmludCB0YXNrLlxuXHQgICAgICogQHJlbWFya3MgV2hlbiBgc2lsZW50YCBpcyBzZXQgdG8gYHRydWVgLCB0aGUgQVBJIHdpbGwgcGljayB0aGUgc3lzdGVtJ3MgZGVmYXVsdCBwcmludGVyIGlmIGRldmljZU5hbWUgaXMgZW1wdHlcblx0ICAgICAqIGFuZCB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgcHJpbnRpbmcuXG5cdCAgICAgKlxuXHQgICAgICogVXNlIHRoZSBDU1Mgc3R5bGUgYHBhZ2UtYnJlYWstYmVmb3JlOiBhbHdheXM7YCB0byBmb3JjZSBwcmludCB0byBhIG5ldyBwYWdlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3Qgd2luID0gZmluLldpbmRvdy5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICpcblx0ICAgICAqIHdpbi5wcmludCh7IHNpbGVudDogZmFsc2UsIGRldmljZU5hbWU6ICdzeXN0ZW0tcHJpbnRlci1uYW1lJyB9KS50aGVuKCgpID0+IHtcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygncHJpbnQgY2FsbCBoYXMgYmVlbiBzZW50IHRvIHRoZSBzeXN0ZW0nKTtcblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogSWYgYSB3aW5kb3cgaGFzIGVtYmVkZGVkIHZpZXdzLCB0aG9zZSB2aWV3cyB3aWxsIG5vdCBwcmludCBieSBkZWZhdWx0LiAgVG8gcHJpbnQgYSB3aW5kb3cncyBjb250ZW50cyBpbmNsdWRpbmcgZW1iZWRkZWQgdmlld3MsXG5cdCAgICAgKiB1c2UgdGhlIGBjb250ZW50YCBvcHRpb246XG5cdCAgICAgKlxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBQcmludCBlbWJlZGRlZCB2aWV3c1xuXHQgICAgICogd2luLnByaW50KHsgY29udGVudDogJ3ZpZXdzJyB9KTtcblx0ICAgICAqXG5cdCAgICAgKiAvLyBQcmludCBzY3JlZW5zaG90IG9mIGN1cnJlbnQgd2luZG93XG5cdCAgICAgKiB3aW4ucHJpbnQoeyBjb250ZW50OiAnc2NyZWVuc2hvdCcgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIFdoZW4gYGNvbnRlbnRgIGlzIHNldCB0byBgdmlld3NgLCB0aGUgZW1iZWRkZWQgdmlld3MgaW4gdGhlIHBsYXRmb3JtIHdpbmRvdyB3aWxsIGJlIGNvbmNhdGVuYXRlZCBhbmQgcHJpbnRlZCBhc1xuXHQgICAgICogaW5kaXZpZHVhbCBwYWdlcy4gIElmIGBpbmNsdWRlU2VsZmAgaXMgc2V0IHRvIGB0cnVlYCwgdGhlIHBsYXRmb3JtIHdpbmRvdyBpdHNlbGYgd2lsbCBiZSBwcmludGVkIGFzIHRoZSBmaXJzdFxuXHQgICAgICogcGFnZSAtIGJlIGF3YXJlIHRoYXQgdGhpcyBwYWdlIHdpbGwgKm5vdCogaW5jbHVkZSB0aGUgZW1iZWRkZWQgdmlld3MgLSBpdCB3aWxsIG9ubHkgaW5jbHVkZSB0aGUgY29udGVudHMgb2Zcblx0ICAgICAqIHRoZSBwbGF0Zm9ybSB3aW5kb3cgaXRzZWxmIChlLmcuIHRhYiBzdGFja3MpLCB3aXRoIGJsYW5rIHNwYWNlcyB3aGVyZSB0aGUgdmlldyBjb250ZW50cyB3b3VsZCBiZSBlbWJlZGRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBEdWUgdG8gYSBrbm93biBpc3N1ZSwgdmlldyBjb250ZW50cyB0aGF0IGFyZSBub3QgdmlzaWJsZSBhdCB0aGUgdGltZSBgcHJpbnRgIGlzIGNhbGxlZCB3aWxsIG5vdCBhcHBlYXIgd2hlblxuXHQgICAgICogcHJpbnRpbmcgYGNvbnRlbnRzOiB2aWV3c2AuICBUaGlzIGluY2x1ZGVzIHZpZXdzIHRoYXQgYXJlIG9ic2N1cmVkIGJlaGluZCBvdGhlciBhY3RpdmUgVUkgZWxlbWVudHMuXG5cdCAgICAgKlxuXHQgICAgICogVG8gcHJpbnQgdGhlIHZpZXdzIGVtYmVkZGVkIGluIHRoZWlyIHBhZ2UgY29udGV4dCwgc2V0IGBjb250ZW50YCB0byBgc2NyZWVuc2hvdGAuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHByaW50KG9wdGlvbnMgPSB7IGNvbnRlbnQ6ICdzZWxmJyB9KSB7XG5cdCAgICAgICAgc3dpdGNoIChvcHRpb25zLmNvbnRlbnQpIHtcblx0ICAgICAgICAgICAgY2FzZSB1bmRlZmluZWQ6XG5cdCAgICAgICAgICAgIGNhc2UgJ3NlbGYnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnByaW50KG9wdGlvbnMpO1xuXHQgICAgICAgICAgICBjYXNlICdzY3JlZW5zaG90Jzpcblx0ICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncHJpbnQtc2NyZWVuc2hvdCcsIHRoaXMuaWRlbnRpdHkpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcblx0ICAgICAgICAgICAgY2FzZSAndmlld3MnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwcmludC12aWV3cycsIHsgLi4udGhpcy5pZGVudGl0eSwgb3B0aW9ucyB9KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0fVxuXHRJbnN0YW5jZSQ3Ll9XaW5kb3cgPSBfV2luZG93O1xuXHRyZXR1cm4gSW5zdGFuY2UkNztcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeSQxO1xuXG5mdW5jdGlvbiByZXF1aXJlRmFjdG9yeSQxICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkRmFjdG9yeSQxKSByZXR1cm4gRmFjdG9yeSQ4O1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkkMSA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDgsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDguX1dpbmRvd01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgYmFzZV8xID0gYmFzZTtcblx0Y29uc3QgdmFsaWRhdGVfMSA9IHZhbGlkYXRlO1xuXHRjb25zdCBJbnN0YW5jZV8xID0gcmVxdWlyZUluc3RhbmNlKCk7XG5cdC8qKlxuXHQgKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIF9XaW5kb3d9IGNsYXNzLCBhdmFpbGFibGUgdW5kZXIgYGZpbi5XaW5kb3dgLlxuXHQgKi9cblx0Y2xhc3MgX1dpbmRvd01vZHVsZSBleHRlbmRzIGJhc2VfMS5CYXNlIHtcblx0ICAgIC8qKlxuXHQgICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBBUEkgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gV2luZG93IGlkZW50aXR5LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdyYXBwaW5nIGEgV2luZG93IGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG5cdCAgICAgKiByZXR1cm5zIGEgc3R1YiBvYmplY3QgdGhhdCBjYW5ub3QgeWV0IHBlcmZvcm0gcmVuZGVyaW5nIHRhc2tzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBsdW1iaW5nIGV2ZW50aW5nXG5cdCAgICAgKiBmb3IgYSBXaW5kb3cgdGhyb3VnaG91dCBpdHMgZW50aXJlIGxpZmVjeWNsZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbigpIHtcblx0ICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uQXBwbGljYXRpb24uc3RhcnQoe1xuXHQgICAgICogICAgICAgICBuYW1lOiAnbXlBcHAnLFxuXHQgICAgICogICAgICAgICB1dWlkOiAnYXBwLTEnLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LndyYXAuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGNyZWF0ZVdpbigpLnRoZW4oKCkgPT4gZmluLldpbmRvdy53cmFwKHsgdXVpZDogJ2FwcC0xJywgbmFtZTogJ215QXBwJyB9KSlcblx0ICAgICAqIC50aGVuKHdpbiA9PiBjb25zb2xlLmxvZygnd3JhcHBlZCB3aW5kb3cnKSlcblx0ICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3aW5kb3ctd3JhcCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGVycm9yTXNnID0gKDAsIHZhbGlkYXRlXzEudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuXHQgICAgICAgIGlmIChlcnJvck1zZykge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gbmV3IEluc3RhbmNlXzEuX1dpbmRvdyh0aGlzLndpcmUsIGlkZW50aXR5KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGFuIEFQSSBoYW5kbGUgZm9yIHRoZSBnaXZlbiBXaW5kb3cgaWRlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBXaW5kb3cgaWRlbnRpdHkgdGhhdCBkb2VzIG5vdCB5ZXQgZXhpc3Qgd2lsbCAqbm90KiB0aHJvdyBhbiBlcnJvciwgYW5kIGluc3RlYWRcblx0ICAgICAqIHJldHVybnMgYSBzdHViIG9iamVjdCB0aGF0IGNhbm5vdCB5ZXQgcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGx1bWJpbmcgZXZlbnRpbmdcblx0ICAgICAqIGZvciBhIFdpbmRvdyB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luKCkge1xuXHQgICAgICogICAgIGNvbnN0IGFwcCA9IGF3YWl0IGZpbi5BcHBsaWNhdGlvbi5zdGFydCh7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdteUFwcCcsXG5cdCAgICAgKiAgICAgICAgIHV1aWQ6ICdhcHAtMScsXG5cdCAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L3N0YWJsZS90dXRvcmlhbC1XaW5kb3cud3JhcFN5bmMuaHRtbCcsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGFwcC5nZXRXaW5kb3coKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGF3YWl0IGNyZWF0ZVdpbigpO1xuXHQgICAgICogbGV0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyB1dWlkOiAnYXBwLTEnLCBuYW1lOiAnbXlBcHAnIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3dpbmRvdy13cmFwLXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcblx0ICAgICAgICBpZiAoZXJyb3JNc2cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTXNnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xLl9XaW5kb3codGhpcy53aXJlLCBpZGVudGl0eSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENyZWF0ZXMgYSBuZXcgV2luZG93LlxuXHQgICAgICogQHBhcmFtIG9wdGlvbnMgLSBXaW5kb3cgY3JlYXRpb24gb3B0aW9uc1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogYXN5bmMgZnVuY3Rpb24gY3JlYXRlV2luZG93KCkge1xuXHQgICAgICogICAgIGNvbnN0IHdpbk9wdGlvbiA9IHtcblx0ICAgICAqICAgICAgICAgbmFtZTonY2hpbGQnLFxuXHQgICAgICogICAgICAgICBkZWZhdWx0V2lkdGg6IDMwMCxcblx0ICAgICAqICAgICAgICAgZGVmYXVsdEhlaWdodDogMzAwLFxuXHQgICAgICogICAgICAgICB1cmw6ICdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtV2luZG93LmNyZWF0ZS5odG1sJyxcblx0ICAgICAqICAgICAgICAgZnJhbWU6IHRydWUsXG5cdCAgICAgKiAgICAgICAgIGF1dG9TaG93OiB0cnVlXG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqICAgICByZXR1cm4gYXdhaXQgZmluLldpbmRvdy5jcmVhdGUod2luT3B0aW9uKTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjcmVhdGVXaW5kb3coKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdXaW5kb3cgaXMgY3JlYXRlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY3JlYXRlKG9wdGlvbnMpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignY3JlYXRlLXdpbmRvdycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHdpbiA9IG5ldyBJbnN0YW5jZV8xLl9XaW5kb3codGhpcy53aXJlLCB7IHV1aWQ6IHRoaXMubWUudXVpZCwgbmFtZTogb3B0aW9ucy5uYW1lIH0pO1xuXHQgICAgICAgIHJldHVybiB3aW4uY3JlYXRlV2luZG93KG9wdGlvbnMpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgV2luZG93IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgd2luZG93XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uV2luZG93LmdldEN1cnJlbnQoKVxuXHQgICAgICogLnRoZW4od25kID0+IGNvbnNvbGUubG9nKCdjdXJyZW50IHdpbmRvdycpKVxuXHQgICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcblx0ICAgICAqXG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgZ2V0Q3VycmVudCgpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWN1cnJlbnQtd2luZG93JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKCF0aGlzLndpcmUubWUuaXNXaW5kb3cpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBpbiBhIFdpbmRvdyBjb250ZXh0Jyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gdGhpcy53aXJlLm1lO1xuXHQgICAgICAgIHJldHVybiB0aGlzLndyYXAoeyB1dWlkLCBuYW1lIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYSBXaW5kb3cgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCB3aW5kb3dcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGNvbnN0IHduZCA9IGZpbi5XaW5kb3cuZ2V0Q3VycmVudFN5bmMoKTtcblx0ICAgICAqIGNvbnN0IGluZm8gPSBhd2FpdCB3bmQuZ2V0SW5mbygpO1xuXHQgICAgICogY29uc29sZS5sb2coaW5mbyk7XG5cdCAgICAgKlxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGdldEN1cnJlbnRTeW5jKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY3VycmVudC13aW5kb3ctc3luYycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICghdGhpcy53aXJlLm1lLmlzV2luZG93KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgaW4gYSBXaW5kb3cgY29udGV4dCcpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcblx0ICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQ4Ll9XaW5kb3dNb2R1bGUgPSBfV2luZG93TW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQ4O1xufVxuXG52YXIgaGFzUmVxdWlyZWRXaW5kb3c7XG5cbmZ1bmN0aW9uIHJlcXVpcmVXaW5kb3cgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRXaW5kb3cpIHJldHVybiB3aW5kb3ckMTtcblx0aGFzUmVxdWlyZWRXaW5kb3cgPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHRcdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHRcdCAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XG5cdFx0ICAgIH1cblx0XHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0XHR9KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuXHRcdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHRcdCAgICBvW2syXSA9IG1ba107XG5cdFx0fSkpO1xuXHRcdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdFx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0XHR9O1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludHMgZm9yIHRoZSBPcGVuRmluIGBXaW5kb3dgIEFQSSAoYGZpbi5XaW5kb3dgKS5cblx0XHQgKlxuXHRcdCAqICoge0BsaW5rIF9XaW5kb3dNb2R1bGV9IGNvbnRhaW5zIHN0YXRpYyBtZW1iZXJzIG9mIHRoZSBgV2luZG93YCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLldpbmRvd2AuXG5cdFx0ICogKiB7QGxpbmsgX1dpbmRvd30gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gV2luZG93LCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uV2luZG93LmdldEN1cnJlbnRgLlxuXHRcdCAqXG5cdFx0ICogVGhlc2UgYXJlIHNlcGFyYXRlIGNvZGUgZW50aXRpZXMsIGFuZCBhcmUgZG9jdW1lbnRlZCBzZXBhcmF0ZWx5LiAgSW4gdGhlIFtwcmV2aW91cyB2ZXJzaW9uIG9mIHRoZSBBUEkgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9kb2NzL2phdmFzY3JpcHQvMzIuMTE0Ljc2LjEwL2luZGV4Lmh0bWwpLFxuXHRcdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdFx0ICpcblx0XHQgKiBVbmRlcnNjb3JlIHByZWZpeGluZyBvZiBPcGVuRmluIHR5cGVzIHRoYXQgYWxpYXMgRE9NIGVudGl0aWVzIHdpbGwgYmUgZml4ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cblx0XHQgKlxuXHRcdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHRcdCAqL1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlRmFjdG9yeSQxKCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW5zdGFuY2UoKSwgZXhwb3J0cyk7IFxuXHR9ICh3aW5kb3ckMSkpO1xuXHRyZXR1cm4gd2luZG93JDE7XG59XG5cbi8qKlxuICogRW50cnkgcG9pbnQgZm9yIHRoZSBPcGVuRmluIGBTeXN0ZW1gIEFQSSAoYGZpbi5TeXN0ZW1gKS5cbiAqXG4gKiAqIHtAbGluayBTeXN0ZW19IGNvbnRhaW5zIHN0YXRpYyBtZW1iZXJzIG9mIHRoZSBgU3lzdGVtYCBBUEkgKGF2YWlsYWJsZSB1bmRlciBgZmluLlN5c3RlbWApXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzeXN0ZW0sIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3lzdGVtLlN5c3RlbSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSRpID0gYmFzZTtcbmNvbnN0IHRyYW5zcG9ydF9lcnJvcnNfMSQxID0gdHJhbnNwb3J0RXJyb3JzO1xuY29uc3Qgd2luZG93XzEgPSByZXF1aXJlV2luZG93KCk7XG5jb25zdCBldmVudHNfMSQ2ID0gcmVxdWlyZSQkMDtcbi8qKlxuICogQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY29yZSBvZiBPcGVuRmluIFJ1bnRpbWUuIEFsbG93cyB0aGUgZGV2ZWxvcGVyXG4gKiB0byBwZXJmb3JtIHN5c3RlbS1sZXZlbCBhY3Rpb25zLCBzdWNoIGFzIGFjY2Vzc2luZyBsb2dzLCB2aWV3aW5nIHByb2Nlc3NlcyxcbiAqIGNsZWFyaW5nIHRoZSBjYWNoZSBhbmQgZXhpdGluZyB0aGUgcnVudGltZSBhcyB3ZWxsIGFzIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5TeXN0ZW1FdmVudHMgc3lzdGVtIGV2ZW50c30uXG4gKlxuICovXG5jbGFzcyBTeXN0ZW0gZXh0ZW5kcyBiYXNlXzEkaS5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlLCAnc3lzdGVtJyk7XG4gICAgfVxuICAgIHNlbmRFeHRlcm5hbFByb2Nlc3NSZXF1ZXN0KGFjdGlvbiwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXhpdEV2ZW50S2V5ID0gJ2V4dGVybmFsLXByb2Nlc3MtZXhpdGVkJztcbiAgICAgICAgICAgIGxldCBwcm9jZXNzVXVpZDtcbiAgICAgICAgICAgIGxldCBleGl0UGF5bG9hZDtcbiAgICAgICAgICAgIGxldCBleHRlcm5hbFByb2Nlc3NFeGl0SGFuZGxlcjtcbiAgICAgICAgICAgIGxldCBvZldpbmRvdztcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5saXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGV4dGVybmFsUHJvY2Vzc0V4aXRIYW5kbGVyID0gKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IHBheWxvYWQgfHwge307XG4gICAgICAgICAgICAgICAgICAgIGV4aXRQYXlsb2FkID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9waWM6ICdleGl0ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXVpZDogZGF0YS5wcm9jZXNzVXVpZCB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXRDb2RlOiBkYXRhLmV4aXRDb2RlIHx8IDBcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NVdWlkID09PSBwYXlsb2FkLnByb2Nlc3NVdWlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmxpc3RlbmVyKGV4aXRQYXlsb2FkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mV2luZG93LnJlbW92ZUxpc3RlbmVyKGV4aXRFdmVudEtleSwgZXh0ZXJuYWxQcm9jZXNzRXhpdEhhbmRsZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAvLyB3aW5kb3cgY29uc3RydWN0b3IgZXhwZWN0cyB0aGUgbmFtZSBpcyBub3QgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLndpcmUubWUubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpcmUubWUubmFtZSA9IHRoaXMud2lyZS5tZS51dWlkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvZldpbmRvdyA9IG5ldyB3aW5kb3dfMS5fV2luZG93KHRoaXMud2lyZSwgdGhpcy53aXJlLm1lKTtcbiAgICAgICAgICAgICAgICBvZldpbmRvdy5vbihleGl0RXZlbnRLZXksIGV4dGVybmFsUHJvY2Vzc0V4aXRIYW5kbGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2lyZVxuICAgICAgICAgICAgICAgIC5zZW5kQWN0aW9uKGFjdGlvbiwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAudGhlbigoeyBwYXlsb2FkIH0pID0+IHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzVXVpZCA9IHBheWxvYWQuZGF0YS51dWlkO1xuICAgICAgICAgICAgICAgIHJlc29sdmUocGF5bG9hZC5kYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoZXhpdFBheWxvYWQgJiYgcHJvY2Vzc1V1aWQgPT09IGV4aXRQYXlsb2FkLnV1aWQpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5saXN0ZW5lcihleGl0UGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgICAgIG9mV2luZG93LnJlbW92ZUxpc3RlbmVyKGV4aXRFdmVudEtleSwgZXh0ZXJuYWxQcm9jZXNzRXhpdEhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAob2ZXaW5kb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgb2ZXaW5kb3cucmVtb3ZlTGlzdGVuZXIoZXhpdEV2ZW50S2V5LCBleHRlcm5hbFByb2Nlc3NFeGl0SGFuZGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoZSBydW50aW1lLiBUaGUgdmVyc2lvbiBjb250YWlucyB0aGUgbWFqb3IsIG1pbm9yLFxuICAgICAqIGJ1aWxkIGFuZCByZXZpc2lvbiBudW1iZXJzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0VmVyc2lvbigpLnRoZW4odiA9PiBjb25zb2xlLmxvZyh2KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFZlcnNpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXZlcnNpb24nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGNhY2hlZCBkYXRhIGNvbnRhaW5pbmcgYXBwbGljYXRpb24gcmVzb3VyY2VcbiAgICAgKiBmaWxlcyAoaW1hZ2VzLCBIVE1MLCBKYXZhU2NyaXB0IGZpbGVzKSwgY29va2llcywgYW5kIGl0ZW1zIHN0b3JlZCBpbiB0aGVcbiAgICAgKiBMb2NhbCBTdG9yYWdlLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gU2VlIGJlbG93IGZvciBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgRm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIGFjY2VwdGVkIG9wdGlvbnMsIHNlZSB0aGUgZm9sbG93aW5nIHBhZ2VzOlxuICAgICAqICogY2FjaGU6IGJyb3dzaW5nIGRhdGEgY2FjaGUgZm9yIGh0bWwgZmlsZXMgYW5kIGltYWdlcyAoW2NhY2hpbmddKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUVFAvQ2FjaGluZykpXG4gICAgICogKiBjb29raWVzOiBicm93c2VyIFtjb29raWVzXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Nvb2tpZXMpXG4gICAgICogKiBsb2NhbFN0b3JhZ2U6IGJyb3dzZXIgZGF0YSB0aGF0IGNhbiBiZSB1c2VkIGFjcm9zcyBzZXNzaW9ucyAoW2xvY2FsIHN0b3JhZ2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cvbG9jYWxTdG9yYWdlKSlcbiAgICAgKiAqIGFwcGNhY2hlOiBodG1sNSBbYXBwbGljYXRpb24gY2FjaGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvVXNpbmdfdGhlX2FwcGxpY2F0aW9uX2NhY2hlKVxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBjbGVhckNhY2hlT3B0aW9ucyA9IHtcbiAgICAgKiAgICAgYXBwY2FjaGU6IHRydWUsXG4gICAgICogICAgIGNhY2hlOiB0cnVlLFxuICAgICAqICAgICBjb29raWVzOiB0cnVlLFxuICAgICAqICAgICBsb2NhbFN0b3JhZ2U6IHRydWVcbiAgICAgKiB9O1xuICAgICAqIGZpbi5TeXN0ZW0uY2xlYXJDYWNoZShjbGVhckNhY2hlT3B0aW9ucykudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ2FjaGUgY2xlYXJlZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKi9cbiAgICBjbGVhckNhY2hlKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGVhci1jYWNoZScsIG9wdGlvbnMpLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGFsbCBjYWNoZWQgZGF0YSB3aGVuIE9wZW5GaW4gUnVudGltZSBleGl0cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmRlbGV0ZUNhY2hlT25FeGl0KCkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnRGVsZXRlZCBDYWNoZScpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGVsZXRlQ2FjaGVPbkV4aXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZGVsZXRlLWNhY2hlLXJlcXVlc3QnKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEV4aXRzIHRoZSBSdW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZXhpdCgpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ2V4aXQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGV4aXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZXhpdC1kZXNrdG9wJykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIGEgSlNPTiBtYW5pZmVzdCB1c2luZyB0aGUgYnJvd3NlciBwcm9jZXNzIGFuZCByZXR1cm5zIGEgSmF2YXNjcmlwdCBvYmplY3QuXG4gICAgICogQHBhcmFtIG1hbmlmZXN0VXJsIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRvIGZldGNoLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5mZXRjaE1hbmlmZXN0KCdodHRwczovL3d3dy5wYXRoLXRvLW1hbmlmZXN0LmNvbScpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBmZXRjaE1hbmlmZXN0KG1hbmlmZXN0VXJsKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZXRjaC1tYW5pZmVzdCcsIHsgbWFuaWZlc3RVcmwgfSk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgYW55IHVud3JpdHRlbiBjb29raWVzIGRhdGEgdG8gZGlzay5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmZsdXNoQ29va2llU3RvcmUoKVxuICAgICAqICAgICAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnc3VjY2VzcycpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZmx1c2hDb29raWVTdG9yZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmbHVzaC1jb29raWUtc3RvcmUnKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBkYXRhIChuYW1lLCBpZHMsIGJvdW5kcykgZm9yIGFsbCBhcHBsaWNhdGlvbiB3aW5kb3dzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0QWxsV2luZG93cygpLnRoZW4od2lucyA9PiBjb25zb2xlLmxvZyh3aW5zKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEFsbFdpbmRvd3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWFsbC13aW5kb3dzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhbiBhcnJheSBvZiBkYXRhIGZvciBhbGwgYXBwbGljYXRpb25zLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0QWxsQXBwbGljYXRpb25zKCkudGhlbihhcHBzID0+IGNvbnNvbGUubG9nKGFwcHMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0QWxsQXBwbGljYXRpb25zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1hbGwtYXBwbGljYXRpb25zJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50IHN0cmluZyB0aGF0IHN0YXJ0ZWQgT3BlbkZpbiBSdW50aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0Q29tbWFuZExpbmVBcmd1bWVudHMoKS50aGVuKGFyZ3MgPT4gY29uc29sZS5sb2coYXJncykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRDb21tYW5kTGluZUFyZ3VtZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtY29tbWFuZC1saW5lLWFyZ3VtZW50cycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGNyYXNoIHJlcG9ydGVyLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0Q3Jhc2hSZXBvcnRlclN0YXRlKCkudGhlbihzdGF0ZSA9PiBjb25zb2xlLmxvZyhzdGF0ZSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRDcmFzaFJlcG9ydGVyU3RhdGUoKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhOiB7IGRpYWdub3N0aWNNb2RlLCBpc1J1bm5pbmcgfSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWNyYXNoLXJlcG9ydGVyLXN0YXRlJyk7XG4gICAgICAgIGNvbnNvbGUud2FybignZGlhZ25vc3RpY01vZGUgcHJvcGVydHkgaXMgZGVwcmVjYXRlZC4gSXQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24nKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWNNb2RlIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uXG4gICAgICAgICAgICBkaWFnbm9zdGljTW9kZSxcbiAgICAgICAgICAgIGRpYWdub3N0aWNzTW9kZTogZGlhZ25vc3RpY01vZGUsXG4gICAgICAgICAgICBpc1J1bm5pbmdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGNyYXNoIHJlcG9ydGVyIGlmIG5vdCBhbHJlYWR5IHJ1bm5pbmcuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBjb25maWd1cmUgY3Jhc2ggcmVwb3J0ZXJcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFlvdSBjYW4gb3B0aW9uYWxseSBzcGVjaWZ5IGBkaWFnbm9zdGljc01vZGVgIHRvIGhhdmUgdGhlIGxvZ3Mgc2VudCB0b1xuICAgICAqIE9wZW5GaW4gb24gcnVudGltZSBjbG9zZS4gKE5PVEU6IGBkaWFnbm9zdGljc01vZGVgIHdpbGwgdHVybiBvbiB2ZXJib3NlIGxvZ2dpbmcgYW5kIGRpc2FibGUgdGhlIHNhbmRib3hcbiAgICAgKiBmb3IgbmV3bHkgbGF1bmNoZWQgcmVuZGVyZXIgcHJvY2Vzc2VzLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2RlYnVnZ2luZyNkaWFnbm9zdGljcy1tb2RlIGZvclxuICAgICAqIG1vcmUgZGV0YWlscy4pXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5zdGFydENyYXNoUmVwb3J0ZXIoe2RpYWdub3N0aWNzTW9kZTogdHJ1ZX0pLnRoZW4ocmVwb3J0ZXIgPT4gY29uc29sZS5sb2cocmVwb3J0ZXIpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgc3RhcnRDcmFzaFJlcG9ydGVyKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IG5ld09wdHMgPSB7IC4uLm9wdHMsIGRpYWdub3N0aWNNb2RlOiBvcHRzLmRpYWdub3N0aWNzTW9kZSB8fCBvcHRzLmRpYWdub3N0aWNNb2RlIH07XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhOiB7IGRpYWdub3N0aWNNb2RlLCBpc1J1bm5pbmcgfSB9IH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3RhcnQtY3Jhc2gtcmVwb3J0ZXInLCBuZXdPcHRzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC8vIGRpYWdub3N0aWNNb2RlIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uXG4gICAgICAgICAgICBkaWFnbm9zdGljTW9kZSxcbiAgICAgICAgICAgIGRpYWdub3N0aWNzTW9kZTogZGlhZ25vc3RpY01vZGUsXG4gICAgICAgICAgICBpc1J1bm5pbmdcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGhleCBlbmNvZGVkIGhhc2ggb2YgdGhlIG1hY2hpbmUgaWQgYW5kIHRoZSBjdXJyZW50bHkgbG9nZ2VkIGluIHVzZXIgbmFtZS5cbiAgICAgKiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCB3YXkgdG8gdW5pcXVlbHkgaWRlbnRpZnkgYSB1c2VyIC8gbWFjaGluZSBjb21iaW5hdGlvbi5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEZvciBXaW5kb3dzIHN5c3RlbXMgdGhpcyBpcyBhIHNoYTI1NiBoYXNoIG9mIHRoZSBtYWNoaW5lIElEIHNldCBpbiB0aGUgcmVnaXN0cnkga2V5OlxuICAgICAqIGBIS0VZX0xPQ0FMX01BQ0hJTkVcXFNPRlRXQVJFXFxNaWNyb3NvZnRcXENyeXB0b2dyYXBoeVxcTWFjaGluZUd1aWRgIGFuZCBgVVNFUk5BTUVgLlxuICAgICAqXG4gICAgICogRm9yIE9TWCBzeXN0ZW1zLCBhIG5hdGl2ZS1sZXZlbCBjYWxsIGlzIHVzZWQgdG8gZ2V0IHRoZSBtYWNoaW5lIElELlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0VW5pcXVlVXNlcklkKCkudGhlbihpZCA9PiBjb25zb2xlLmxvZyhpZCkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRVbmlxdWVVc2VySWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXVuaXF1ZS11c2VyLWlkJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBhIGZyYW1lIGluZm8gb2JqZWN0IGZvciB0aGUgdXVpZCBhbmQgbmFtZSBwYXNzZWQgaW5cbiAgICAgKiBAcGFyYW0gdXVpZCAtIFRoZSBVVUlEIG9mIHRoZSB0YXJnZXQuXG4gICAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFyZ2V0LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlIHBvc3NpYmxlIHR5cGVzIGFyZSAnd2luZG93JywgJ2lmcmFtZScsICdleHRlcm5hbCBjb25uZWN0aW9uJyBvciAndW5rbm93bicuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGVudGl0eVV1aWQgPSAnT3BlbmZpblBPQyc7XG4gICAgICogY29uc3QgZW50aXR5TmFtZSA9ICc0MGM3NGI1ZC1lZDk4LTQwZjctODUzZi1lM2QzYzI2OTkxNzUnO1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0RW50aXR5SW5mbyhlbnRpdHlVdWlkLCBlbnRpdHlOYW1lKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIC8vIGV4YW1wbGUgaW5mbyBzaGFwZVxuICAgICAqIHtcbiAgICAgKiAgICAgXCJ1dWlkXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICBcIm5hbWVcIjogXCI0MGM3NGI1ZC1lZDk4LTQwZjctODUzZi1lM2QzYzI2OTkxNzVcIixcbiAgICAgKiAgICAgXCJwYXJlbnRcIjoge1xuICAgICAqICAgICAgICAgXCJ1dWlkXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICAgICAgXCJuYW1lXCI6IFwiT3BlbmZpblBPQ1wiXG4gICAgICogICAgIH0sXG4gICAgICogICAgIFwiZW50aXR5VHlwZVwiOiBcImlmcmFtZVwiXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEVudGl0eUluZm8odXVpZCwgbmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1lbnRpdHktaW5mbycsIHsgdXVpZCwgbmFtZSB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWUgb2YgYSBnaXZlbiBlbnZpcm9ubWVudCB2YXJpYWJsZSBvbiB0aGUgY29tcHV0ZXIgb24gd2hpY2ggdGhlIHJ1bnRpbWUgaXMgaW5zdGFsbGVkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRFbnZpcm9ubWVudFZhcmlhYmxlKCdIT01FJykudGhlbihlbnYgPT4gY29uc29sZS5sb2coZW52KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEVudmlyb25tZW50VmFyaWFibGUoZW52TmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlXG4gICAgICAgICAgICAuc2VuZEFjdGlvbignZ2V0LWVudmlyb25tZW50LXZhcmlhYmxlJywge1xuICAgICAgICAgICAgZW52aXJvbm1lbnRWYXJpYWJsZXM6IGVudk5hbWVcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGN1cnJlbnRseSBmb2N1c2VkIFdpbmRvdy5cbiAgICAgKiBJZiBhIFZpZXcgY3VycmVudGx5IGhhcyBmb2N1cywgcmV0dXJucyB0aGUgaWRlbnRpdHkgb2YgVmlldydzIHBhcmVudCBXaW5kb3cuXG4gICAgICogVXNlIHtAbGluayBXaW5kb3cuX1dpbmRvdyNnZXRGb2N1c2VkQ29udGVudCBXaW5kb3cuZ2V0Rm9jdXNlZENvbnRlbnR9IHRvIGRpcmVjdGx5IGFjY2VzcyBjdXJyZW50bHkgZm9jdXNlZCBXaW5kb3cgb3IgVmlldy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldEZvY3VzZWRXaW5kb3coKS50aGVuKHdpbkluZm8gPT4gY29uc29sZS5sb2cod2luSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRGb2N1c2VkV2luZG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1mb2N1c2VkLXdpbmRvdycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgY3VycmVudGx5IGZvY3VzZWQgY29udGVudC4gUmV0dXJucyBpZGVudGl0eSBvZiBlbnRpdHkgd2l0aCBgZW50aXR5VHlwZWAuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRGb2N1c2VkQ29udGVudCgpLnRoZW4oY29udGVudElkZW50aXR5ID0+IGNvbnNvbGUubG9nKGNvbnRlbnRJZGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRGb2N1c2VkQ29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZm9jdXNlZC1jb250ZW50JykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGdpdmVuIGFwcCdzIGNlcnRpZmljYXRpb24gc3RhdHVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3RVcmwgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6MTIzNC9hcHAuanNvblwiXG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgY2VydGlmaWNhdGlvbkluZm8gPSBhd2FpdCBmaW4uU3lzdGVtLmlzQXBwQ2VydGlmaWVkKG1hbmlmZXN0VXJsKTtcbiAgICAgKiB9IGNhdGNoKGVycikge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgaXNBcHBDZXJ0aWZpZWQobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGE6IHsgY2VydGlmaWVkSW5mbyB9IH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpcy1hcHAtY2VydGlmaWVkJywgeyBtYW5pZmVzdFVybCB9KTtcbiAgICAgICAgcmV0dXJuIGNlcnRpZmllZEluZm87XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIHRoZSBpbnN0YWxsZWQgcnVudGltZSB2ZXJzaW9ucyBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRJbnN0YWxsZWRSdW50aW1lcygpLnRoZW4ocnVudGltZXMgPT4gY29uc29sZS5sb2cocnVudGltZXMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gaW5jb21wYXRpYmxlIHdpdGggc3RhbmRhbG9uZSBub2RlIHByb2Nlc3MuXG4gICAgZ2V0SW5zdGFsbGVkUnVudGltZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWluc3RhbGxlZC1ydW50aW1lcycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEucnVudGltZXMpO1xuICAgIH1cbiAgICAvLyBpbmNvbXBhdGlibGUgd2l0aCBzdGFuZGFsb25lIG5vZGUgcHJvY2Vzcy5cbiAgICBhc3luYyBnZXRJbnN0YWxsZWRBcHBzKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgZGF0YTogeyBpbnN0YWxsZWRBcHBzIH0gfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1pbnN0YWxsZWQtYXBwcycpO1xuICAgICAgICByZXR1cm4gaW5zdGFsbGVkQXBwcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBjb250ZW50cyBvZiB0aGUgbG9nIHdpdGggdGhlIHNwZWNpZmllZCBmaWxlbmFtZS5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIG9iamVjdCB0aGF0IGlkIGRlZmluZWQgYnkgdGhlIEdldExvZ1JlcXVlc3RUeXBlIGludGVyZmFjZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGdldExvZygpIHtcbiAgICAgKiAgICAgY29uc3QgbG9ncyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0TG9nTGlzdCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZmluLlN5c3RlbS5nZXRMb2cobG9nc1swXSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogZ2V0TG9nKCkudGhlbihsb2cgPT4gY29uc29sZS5sb2cobG9nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldExvZyhvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndmlldy1sb2cnLCBvcHRpb25zKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHVuaXF1ZSBpZGVudGlmaWVyIChVVUlEKSBwcm92aWRlZCBieSB0aGUgbWFjaGluZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldE1hY2hpbmVJZCgpLnRoZW4oaWQgPT4gY29uc29sZS5sb2coaWQpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TWFjaGluZUlkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1tYWNoaW5lLWlkJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIG1pbmltdW0gKGluY2x1c2l2ZSkgbG9nZ2luZyBsZXZlbCB0aGF0IGlzIGN1cnJlbnRseSBiZWluZyB3cml0dGVuIHRvIHRoZSBsb2cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRNaW5Mb2dMZXZlbCgpLnRoZW4obGV2ZWwgPT4gY29uc29sZS5sb2cobGV2ZWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TWluTG9nTGV2ZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LW1pbi1sb2ctbGV2ZWwnKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gZm9yIGVhY2ggbG9nIGZpbGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRMb2dMaXN0KCkudGhlbihsb2dMaXN0ID0+IGNvbnNvbGUubG9nKGxvZ0xpc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TG9nTGlzdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsaXN0LWxvZ3MnKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIG9iamVjdCB0aGF0IGNvbnRhaW5zIGRhdGEgYWJvdXQgdGhlIG1vbml0b3Igc2V0dXAgb2YgdGhlXG4gICAgICogY29tcHV0ZXIgdGhhdCB0aGUgcnVudGltZSBpcyBydW5uaW5nIG9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0TW9uaXRvckluZm8oKS50aGVuKG1vbml0b3JJbmZvID0+IGNvbnNvbGUubG9nKG1vbml0b3JJbmZvKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldE1vbml0b3JJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1tb25pdG9yLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbW91c2UgaW4gdmlydHVhbCBzY3JlZW4gY29vcmRpbmF0ZXMgKGxlZnQsIHRvcCkuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRNb3VzZVBvc2l0aW9uKCkudGhlbihtb3VzZVBvc2l0aW9uID0+IGNvbnNvbGUubG9nKG1vdXNlUG9zaXRpb24pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0TW91c2VQb3NpdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtbW91c2UtcG9zaXRpb24nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGFsbCBvZiB0aGUgcnVudGltZSBwcm9jZXNzZXMgdGhhdCBhcmUgY3VycmVudGx5XG4gICAgICogcnVubmluZy4gRWFjaCBlbGVtZW50IGluIHRoZSBhcnJheSBpcyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgdXVpZFxuICAgICAqIGFuZCB0aGUgbmFtZSBvZiB0aGUgYXBwbGljYXRpb24gdG8gd2hpY2ggdGhlIHByb2Nlc3MgYmVsb25ncy5cbiAgICAgKiBAZGVwcmVjYXRlZCBQbGVhc2UgdXNlIG91ciBuZXcgc2V0IG9mIHByb2Nlc3MgQVBJczpcbiAgICAgKiB7QGxpbmsgV2luZG93Ll9XaW5kb3cjZ2V0UHJvY2Vzc0luZm8gV2luZG93LmdldFByb2Nlc3NJbmZvfVxuICAgICAqIHtAbGluayBWaWV3LlZpZXcjZ2V0UHJvY2Vzc0luZm8gVmlldy5nZXRQcm9jZXNzSW5mb31cbiAgICAgKiB7QGxpbmsgQXBwbGljYXRpb24uQXBwbGljYXRpb24jZ2V0UHJvY2Vzc0luZm8gQXBwbGljYXRpb24uZ2V0UHJvY2Vzc0luZm99XG4gICAgICoge0BsaW5rIFN5c3RlbSNnZXRBbGxQcm9jZXNzSW5mbyBTeXN0ZW0uZ2V0QWxsUHJvY2Vzc0luZm99XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRQcm9jZXNzTGlzdCgpLnRoZW4oUHJvY2Vzc0xpc3QgPT4gY29uc29sZS5sb2coUHJvY2Vzc0xpc3QpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0UHJvY2Vzc0xpc3QoKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUud2FybignU3lzdGVtLmdldFByb2Nlc3NMaXN0IGhhcyBiZWVuIGRlcHJlY2F0ZWQuIFBsZWFzZSBjb25zaWRlciB1c2luZyBvdXIgbmV3IHByb2Nlc3MgQVBJczogV2luZG93LmdldFByb2Nlc3NJbmZvLCBWaWV3LmdldFByb2Nlc3NJbmZvLCBBcHBsaWNhdGlvbi5nZXRQcm9jZXNzSW5mbywgU3lzdGVtLmdldEFsbFByb2Nlc3NJbmZvJyk7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncHJvY2Vzcy1zbmFwc2hvdCcpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYWxsIHByb2Nlc3MgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGlzIGluY2x1ZGVzIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIGV2ZXJ5IHByb2Nlc3MgYXNzb2NpYXRlZCB0byBhbGwgZW50aXRpZXMgKHdpbmRvd3MgYW5kIHZpZXdzKS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBhbGxQcm9jZXNzSW5mbyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0QWxsUHJvY2Vzc0luZm8oKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QWxsUHJvY2Vzc0luZm8oKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLXByb2Nlc3MtaW5mbycsIHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBQcm94eSBzZXR0aW5ncy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmdldFByb3h5U2V0dGluZ3MoKS50aGVuKFByb3h5U2V0dGluZyA9PiBjb25zb2xlLmxvZyhQcm94eVNldHRpbmcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICpcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICBjb25maWc6IHtcbiAgICAgKiAgICAgICAgIHByb3h5QWRkcmVzczogXCJwcm94eUFkZHJlc3NcIiwgLy90aGUgY29uZmlndXJlZCBQcm94eSBBZGRyZXNzXG4gICAgICogICAgICAgICBwcm94eVBvcnQ6IDAsIC8vdGhlIGNvbmZpZ3VyZWQgUHJveHkgcG9ydFxuICAgICAqICAgICAgICAgdHlwZTogXCJzeXN0ZW1cIiAvL1Byb3h5IFR5cGVcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgc3lzdGVtOiB7XG4gICAgICogICAgICAgICBhdXRvQ29uZmlnVXJsOiBcIlwiLFxuICAgICAqICAgICAgICAgYnlwYXNzOiBcIlwiLFxuICAgICAqICAgICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICogICAgICAgICBwcm94eTogXCJcIlxuICAgICAqICAgICB9XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFByb3h5U2V0dGluZ3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXByb3h5LXNldHRpbmdzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJ1bm5pbmcgUnVudGltZSBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRSdW50aW1lSW5mbygpLnRoZW4oUnVudGltZUluZm8gPT4gY29uc29sZS5sb2coUnVudGltZUluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0UnVudGltZUluZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXJ1bnRpbWUtaW5mbycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBydW5uaW5nIFJWTSBpbiBhbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRSdm1JbmZvKCkudGhlbihSdm1JbmZvID0+IGNvbnNvbGUubG9nKFJ2bUluZm8pKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgLy8gaW5jb21wYXRpYmxlIHdpdGggc3RhbmRhbG9uZSBub2RlIHByb2Nlc3MuXG4gICAgZ2V0UnZtSW5mbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtcnZtLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGdlbmVyYWwgc3lzdGVtIGluZm9ybWF0aW9uLiBJZiB5b3UgbmVlZCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uIGFib3V0IHRoZVxuICAgICAqIE9TIGFuZCB0aGUgY3VycmVudGx5IGxvZ2dlZCBpbiB1c2VyLCB1c2UgYGZpbi5TeXN0ZW0uZ2V0T1NJbmZvKClgIGluc3RlYWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRIb3N0U3BlY3MoKS50aGVuKHNwZWNzID0+IGNvbnNvbGUubG9nKHNwZWNzKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEhvc3RTcGVjcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtaG9zdC1zcGVjcycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIE9TIGFuZCB0aGUgY3VycmVudGx5IGxvZ2dlZCBpbiB1c2VyLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0T1NJbmZvKCkudGhlbihzcGVjcyA9PiBjb25zb2xlLmxvZyhzcGVjcykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRPU0luZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LW9zLWluZm8nKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUnVucyBhbiBleGVjdXRhYmxlIG9yIGJhdGNoIGZpbGUuIEEgcGF0aCB0byB0aGUgZmlsZSBtdXN0IGJlIGluY2x1ZGVkIGluIG9wdGlvbnMuXG4gICAgICogPGJyPiBBIHV1aWQgbWF5IGJlIG9wdGlvbmFsbHkgcHJvdmlkZWQuIElmIG5vdCBwcm92aWRlZCwgT3BlbkZpbiB3aWxsIGNyZWF0ZSBhIHV1aWQgZm9yIHRoZSBuZXcgcHJvY2Vzcy5cbiAgICAgKiA8YnI+IE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIDxhIGhyZWY9XCJodHRwczovL2RldmVsb3BlcnMub3BlbmZpbi5jby9kb2NzL2FwaS1zZWN1cml0eVwiPkFQSSBzZWN1cml0eSBzZXR0aW5nczwvYT4uIEFsc28sIHRoaXMgYXBpIGhhcyBhbiBlbmhhbmNlZCBwZXJtaXNzaW9uIHNldCB0byBtYWtlIGl0IGxlc3MgZGFuZ2Vyb3VzLiBTbyBhcHBsaWNhdGlvbiBvd25lcnMgY2FuIG9ubHkgYWxsb3cgdG8gbGF1bmNoIHRoZSBhc3NldHMgb3duZWQgYnkgdGhlIGFwcGxpY2F0aW9uLCB0aGUgZW5hYmxlZCBkb3dubG9hZGVkIGZpbGVzIG9yIHRoZSByZXN0cmljdGVkIGV4ZWN1dGFibGVzLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEEgb2JqZWN0IHRoYXQgaXMgZGVmaW5lZCBpbiB0aGUgRXh0ZXJuYWxQcm9jZXNzUmVxdWVzdFR5cGUgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJZiBhbiB1bnVzZWQgVVVJRCBpcyBwcm92aWRlZCBpbiBvcHRpb25zLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vIFVVSUQgaXMgcHJvdmlkZWQsIE9wZW5GaW4gd2lsbCBhc3NpZ24gb25lLlxuICAgICAqIFRoaXMgYXBpIGhhcyBhbiBlbmhhbmNlZCBwZXJtaXNzaW9uIHNldCB0byBtYWtlIGl0IGxlc3MgZGFuZ2Vyb3VzLiBTbyBhcHBsaWNhdGlvbiBvd25lcnMgY2FuIG9ubHkgYWxsb3cgdG8gbGF1bmNoIHRoZVxuICAgICAqIGFzc2V0cyBvd25lZCBieSB0aGUgYXBwbGljYXRpb24sIHRoZSBlbmFibGVkIGRvd25sb2FkZWQgZmlsZXMgb3IgdGhlIHJlc3RyaWN0ZWQgZXhlY3V0YWJsZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogU2luY2UgX2FwcEFzc2V0c18gcmVsaWVzIG9uIHRoZSBSVk0sIHdoaWNoIGlzIG1pc3Npbmcgb24gTUFDX09TLCAnYWxpYXMnIGlzIG5vdCBhdmFpbGFibGUuIEluc3RlYWQgcHJvdmlkZVxuICAgICAqIHRoZSBmdWxsIHBhdGggZS5nLiBfL0FwcGxpY2F0aW9ucy9DYWxjdWxhdG9yLmFwcC9Db250ZW50cy9NYWNPUy9DYWxjdWxhdG9yXy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogQmFzaWMgRXhhbXBsZTpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ25vdGVwYWQnLFxuICAgICAqICAgICBhcmd1bWVudHM6ICcnLFxuICAgICAqICAgICBsaXN0ZW5lcjogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUHJvbWlzZSByZXNvbHV0aW9uOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICB1dWlkOiBcIkZCM0U2RTM2LTA5NzYtNEMyQi05QTA5LUZCMkU1NEQyRjFCQlwiIC8vIFRoZSBtYXBwZWQgVVVJRCB3aGljaCBpZGVudGlmaWVzIHRoZSBsYXVuY2hlZCBwcm9jZXNzXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTGlzdGVuZXIgY2FsbGJhY2s6XG4gICAgICogYGBganNcbiAgICAgKiAvL1RoaXMgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGU6XG4gICAgICoge1xuICAgICAqICAgICB0b3BpYzogXCJleGl0ZWRcIiwgLy8gT3IgXCJyZWxlYXNlZFwiIG9uIGEgY2FsbCB0byByZWxlYXNlRXh0ZXJuYWxQcm9jZXNzXG4gICAgICogICAgIHV1aWQ6IFwiRkIzRTZFMzYtMDk3Ni00QzJCLTlBMDktRkIyRTU0RDJGMUJCXCIsIC8vIFRoZSBtYXBwZWQgVVVJRCB3aGljaCBpZGVudGlmaWVzIHRoZSBsYXVuY2hlZCBwcm9jZXNzXG4gICAgICogICAgIGV4aXRDb2RlOiAwIC8vIFByb2Nlc3MgZXhpdCBjb2RlXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQnkgc3BlY2lmeWluZyBhIGxpZmV0aW1lLCBhbiBleHRlcm5hbCBwcm9jZXNzIGNhbiBsaXZlIGFzIGxvbmcgdGhlIHdpbmRvdy9hcHBsaWNhdGlvbiB0aGF0IGxhdW5jaGVkIGl0IG9yXG4gICAgICogcGVyc2lzdCBhZnRlciB0aGUgYXBwbGljYXRpb24gZXhpdHMuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIG51bGwsIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gJ3BlcnNpc3QnLCBtZWFuaW5nXG4gICAgICogdGhlIHByb2Nlc3MgbGl2ZXMgb24gYWZ0ZXIgdGhlIGFwcGxpY2F0aW9uIGV4aXRzOlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLmxhdW5jaEV4dGVybmFsUHJvY2Vzcyh7XG4gICAgICogICAgIHBhdGg6ICdub3RlcGFkJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnJyxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbGlmZXRpbWU6ICd3aW5kb3cnXG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTm90ZTogQSBwcm9jZXNzIHRoYXQgZXhpdHMgd2hlbiB0aGUgd2luZG93L2FwcGxpY2F0aW9uIGV4aXRzIGNhbm5vdCBiZSByZWxlYXNlZCB2aWEgZmluLmRlc2t0b3AuU3lzdGVtLnJlbGVhc2VFeHRlcm5hbFByb2Nlc3MuXG4gICAgICpcbiAgICAgKiBCeSBzcGVjaWZ5aW5nIGEgY3dkLCBpdCB3aWxsIHNldCBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IHdoZW4gbGF1bmNoaW5nIGFuIGV4dGVybmFsIHByb2Nlc3M6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ2NtZC5leGUnLFxuICAgICAqICAgICBjd2Q6ICdjOlxcXFx0ZW1wJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnJyxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvY2Vzc0lkZW50aXR5KTtcbiAgICAgKiB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEV4YW1wbGUgdXNpbmcgYW4gYWxpYXMgZnJvbSBhcHAuanNvbiBhcHBBc3NldHMgcHJvcGVydHk6XG4gICAgICpcbiAgICAgKiBgYGBqc29uXG4gICAgICogXCJhcHBBc3NldHNcIjogW1xuICAgICAqICAgICB7XG4gICAgICogICAgICAgICBcInNyY1wiOiBcImV4ZS56aXBcIixcbiAgICAgKiAgICAgICAgIFwiYWxpYXNcIjogXCJteUFwcFwiLFxuICAgICAqICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNC4xMi44XCIsXG4gICAgICogICAgICAgICBcInRhcmdldFwiOiBcIm15QXBwLmV4ZVwiLFxuICAgICAqICAgICAgICAgXCJhcmdzXCI6IFwiYSBiIGMgZFwiXG4gICAgICogICAgIH0sXG4gICAgICogXVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvLyAgV2hlbiBjYWxsZWQsIGlmIG5vIGFyZ3VtZW50cyBhcmUgcGFzc2VkIHRoZW4gdGhlIGFyZ3VtZW50cyAoaWYgYW55KVxuICAgICAqIC8vICBhcmUgdGFrZW4gZnJvbSB0aGUgJ2FwcC5qc29uJyBmaWxlLCBmcm9tIHRoZSAgJ2FyZ3MnIHBhcmFtZXRlclxuICAgICAqIC8vICBvZiB0aGUgJ2FwcEFzc2V0cycgT2JqZWN0IHdpdGggdGhlIHJlbGV2YW50ICdhbGlhcycuXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICAvL0FkZGl0aW9uYWxseSBub3RlIHRoYXQgdGhlIGV4ZWN1dGFibGUgZm91bmQgaW4gdGhlIHppcCBmaWxlIHNwZWNpZmllZCBpbiBhcHBBc3NldHNcbiAgICAgKiAgICAgLy93aWxsIGRlZmF1bHQgdG8gdGhlIG9uZSBtZW50aW9uZWQgYnkgYXBwQXNzZXRzLnRhcmdldFxuICAgICAqICAgICAvL0lmIHRoZSB0aGUgcGF0aCBiZWxvdyByZWZlcnMgdG8gYSBzcGVjaWZpYyBwYXRoIGl0IHdpbGwgb3ZlcnJpZGUgdGhpcyBkZWZhdWx0XG4gICAgICogICAgIGFsaWFzOiAnbXlBcHAnLFxuICAgICAqICAgICBsaXN0ZW5lcjogKHJlc3VsdCkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogRXhhbXBsZSB1c2luZyBhbiBhbGlhcyBidXQgb3ZlcnJpZGluZyB0aGUgYXJndW1lbnRzOlxuICAgICAqXG4gICAgICogYGBganNvblxuICAgICAqIFwiYXBwQXNzZXRzXCI6IFtcbiAgICAgKiAgICAge1xuICAgICAqICAgICAgICAgXCJzcmNcIjogXCJleGUuemlwXCIsXG4gICAgICogICAgICAgICBcImFsaWFzXCI6IFwibXlBcHBcIixcbiAgICAgKiAgICAgICAgIFwidmVyc2lvblwiOiBcIjQuMTIuOFwiLFxuICAgICAqICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcC5leGVcIixcbiAgICAgKiAgICAgICAgIFwiYXJnc1wiOiBcImEgYiBjIGRcIlxuICAgICAqICAgICB9LFxuICAgICAqIF1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogLy8gIElmICdhcmd1bWVudHMnIGlzIHBhc3NlZCBhcyBhIHBhcmFtZXRlciBpdCB0YWtlcyBwcmVjZWRlbmNlXG4gICAgICogLy8gIG92ZXIgYW55ICdhcmdzJyBzZXQgaW4gdGhlICdhcHAuanNvbicuXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICBhbGlhczogJ215QXBwJyxcbiAgICAgKiAgICAgYXJndW1lbnRzOiAnZSBmIGcnLFxuICAgICAqICAgICBsaXN0ZW5lcjogKHJlc3VsdCkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSkudGhlbihwcm9jZXNzSWRlbnRpdHkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqIH0pLmNhdGNoKGVycm9yID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSXQgaXMgbm93IHBvc3NpYmxlIHRvIG9wdGlvbmFsbHkgcGVyZm9ybSBhbnkgY29tYmluYXRpb24gb2YgdGhlIGZvbGxvd2luZyBjZXJ0aWZpY2F0ZSBjaGVja3NcbiAgICAgKiBhZ2FpbnN0IGFuIGFic29sdXRlIHRhcmdldCB2aWEgYGZpbi5kZXNrdG9wLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKWA6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIFwiY2VydGlmaWNhdGVcIjoge1xuICAgICAqICAgICBcInNlcmlhbFwiOiBcIjNjIGE1IC4uLlwiLCAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgaGV4IHN0cmluZyB3aXRoIG9yIHdpdGhvdXQgc3BhY2VzXG4gICAgICogICAgIFwic3ViamVjdFwiOiBcIk89T3BlbkZpbiBJTkMuLCBMPU5ldyBZb3JrLCAuLi5cIiwgLy8gQW4gaW50ZXJuYWxseSB0b2tlbml6ZWQgYW5kIGNvbW1hIGRlbGltaXRlZCBzdHJpbmcgYWxsb3dpbmcgcGFydGlhbCBvciBmdWxsIGNoZWNrcyBvZiB0aGUgc3ViamVjdCBmaWVsZHNcbiAgICAgKiAgICAgXCJwdWJsaWNrZXlcIjogXCIzYyBhNSAuLi5cIiwgICAgICAgICAgICAgICAgICAgICAvLyBBIGhleCBzdHJpbmcgd2l0aCBvciB3aXRob3V0IHNwYWNlc1xuICAgICAqICAgICBcInRodW1icHJpbnRcIjogXCIzYyBhNSAuLi5cIiwgICAgICAgICAgICAgICAgICAgIC8vIEEgaGV4IHN0cmluZyB3aXRoIG9yIHdpdGhvdXQgc3BhY2VzXG4gICAgICogICAgIFwidHJ1c3RlZFwiOiB0cnVlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHRoYXQgdGhlIGNlcnRpZmljYXRlIGlzIHRydXN0ZWQgYW5kIG5vdCByZXZva2VkXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUHJvdmlkaW5nIHRoaXMgaW5mb3JtYXRpb24gYXMgcGFydCBvZiB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9ucyBmb3IgYXNzZXRzIGluIGFuIGFwcGxpY2F0aW9uJ3MgbWFuaWZlc3RcbiAgICAgKiB3aWxsIGJlIGFkZGVkIGluIGEgZnV0dXJlIFJWTSB1cGRhdGU6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogJ0M6XFxcXFVzZXJzXFxcXEV4YW1wbGVVc2VyXFxcXEFwcERhdGFcXFxcTG9jYWxcXFxcT3BlbkZpblxcXFxPcGVuRmluUlZNLmV4ZScsXG4gICAgICogICAgIGFyZ3VtZW50czogJy0tdmVyc2lvbicsXG4gICAgICogICAgIGNlcnRpZmljYXRlOiB7XG4gICAgICogICAgICAgICB0cnVzdGVkOiB0cnVlLFxuICAgICAqICAgICAgICAgc3ViamVjdDogJ089T3BlbkZpbiBJTkMuLCBMPU5ldyBZb3JrLCBTPU5ZLCBDPVVTJyxcbiAgICAgKiAgICAgICAgIHRodW1icHJpbnQ6ICfigI4zYyBhNSAyOCAxOSA4MyAwNSBmZSA2OSA4OCBlNiA4ZiA0YiAzYSBhZiBjNSBjNSAxYiAwNyA4MCA1YidcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvY2Vzc0lkZW50aXR5KTtcbiAgICAgKiB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEl0IGlzIHBvc3NpYmxlIHRvIGxhdW5jaCBmaWxlcyB0aGF0IGhhdmUgYmVlbiBkb3dubG9hZGVkIGJ5IHRoZSB1c2VyIGJ5IGxpc3RlbmluZyB0byB0aGUgd2luZG93XG4gICAgICogYGZpbGUtZG93bmxvYWQtY29tcGxldGVkYCBldmVudCBhbmQgdXNpbmcgdGhlIGBmaWxlVXVpZGAgcHJvdmlkZWQgYnkgdGhlIGV2ZW50OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3aW4gPSBmaW4uV2luZG93LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogd2luLmFkZExpc3RlbmVyKCdmaWxlLWRvd25sb2FkLWNvbXBsZXRlZCcsIChldnQpID0+IHtcbiAgICAgKiAgICAgaWYgKGV2dC5zdGF0ZSA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgKiAgICAgICAgIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgICAgICAgICBmaWxlVXVpZDogZXZ0LmZpbGVVdWlkLFxuICAgICAqICAgICAgICAgICAgIGFyZ3VtZW50czogJycsXG4gICAgICogICAgICAgICAgICAgbGlzdGVuZXI6IChyZXN1bHQpID0+IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ3RoZSBleGl0IGNvZGUnLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IHtcbiAgICAgKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhwcm9jZXNzSWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgfSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgKiAgICAgICAgIH0pO1xuICAgICAqICAgICB9XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgYXNzZXRzIHNwZWNpZmllZCBpbiB0aGUgYXBwIG1hbmlmZXN0OlxuICAgICAqXG4gICAgICogU2FtcGxlIGFwcEFzc2V0cyBzZWN0aW9uIGluIGFwcC5qc29uXG4gICAgICogYGBganNcbiAgICAgKiAgICAgXCJhcHBBc3NldHNcIjogW1xuICAgICAqICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgIFwic3JjXCI6IFwiaHR0cDovL2ZpbGVzYW1wbGVzLmNvbS9leGUuemlwXCIsXG4gICAgICogICAgICAgICAgICAgXCJhbGlhc1wiOiBcIm15QXBwXCIsXG4gICAgICogICAgICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNC4xMi44XCIsXG4gICAgICogICAgICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcC5leGVcIixcbiAgICAgKiAgICAgICAgICAgICBcImFyZ3NcIjogXCJhIGIgYyBkXCJcbiAgICAgKiAgICAgICAgIH0sXG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgXCJzcmNcIjogXCJodHRwOi8vZXhhbXBsZXMuY29tL2V4ZS56aXBcIixcbiAgICAgKiAgICAgICAgICAgICBcImFsaWFzXCI6IFwibXlBcHAyXCIsXG4gICAgICogICAgICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiNS4xMi44XCIsXG4gICAgICogICAgICAgICAgICAgXCJ0YXJnZXRcIjogXCJteUFwcDIuZXhlXCIsXG4gICAgICogICAgICAgICAgICAgXCJhcmdzXCI6IFwiYSBiIGNcIlxuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICBdXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBUaGlzIHBlcm1pc3Npb24gYWxsb3dzIGZvciBsYXVuY2hpbmcgb2YgYWxsIGFzc2V0cyBzcGVjaWZpZWQgaW4gdGhlIGFib3ZlIGFwcEFzc2V0cyBzZWN0aW9uLiAoXCJteUFwcFwiIGFuZCBcIm15QXBwMlwiKTpcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIFwicGVybWlzc2lvbnNcIjoge1xuICAgICAqICAgICAgICBcIlN5c3RlbVwiOiB7XG4gICAgICogICAgICAgICAgICBcImxhdW5jaEV4dGVybmFsUHJvY2Vzc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgICAgICBcImFzc2V0c1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZVxuICAgICAqICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRoaXMgcGVybWlzc2lvbiBhbGxvd3MgZm9yIGxhdW5jaGluZyBvZiBfb25seV8gdGhlIFwibXlBcHBcIiBhc3NldCBpbiB0aGUgYWJvdmUgYXBwQXNzZXRzIHNlY3Rpb24sIGFzIGRlZmluZWQgaW4gYHNyY1J1bGVzYDpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJsYXVuY2hFeHRlcm5hbFByb2Nlc3NcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJhc3NldHNcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgXCJlbmFibGVkXCI6IHRydWVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwic3JjUnVsZXNcIjogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIio6Ly9maWxlc2FtcGxlcy5jb20vKlwiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYmVoYXZpb3JcIjogXCJhbGxvd1wiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibWF0Y2hcIjogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI8YWxsX3VybHM+XCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJiZWhhdmlvclwiOiBcImJsb2NrXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTGF1bmNoaW5nIGRvd25sb2FkZWQgZmlsZXM6XG4gICAgICogYGBganNcbiAgICAgKiAgICAgXCJwZXJtaXNzaW9uc1wiOiB7XG4gICAgICogICAgICAgIFwiU3lzdGVtXCI6IHtcbiAgICAgKiAgICAgICAgICAgIFwibGF1bmNoRXh0ZXJuYWxQcm9jZXNzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJlbmFibGVkXCI6IHRydWUsXG4gICAgICogICAgICAgICAgICAgICAgIFwiZG93bmxvYWRzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgIH1cbiAgICAgKiAgICAgfVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVGhpcyBwZXJtaXNzaW9uIGFsbG93cyB0byBsYXVuY2ggYWxsIHRoZSBleGVjdXRhYmxlczpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJsYXVuY2hFeHRlcm5hbFByb2Nlc3NcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJleGVjdXRhYmxlc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZVxuICAgICAqICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqXG4gICAgICogVGhpcyBwZXJtaXNzaW9uIG9ubHkgYWxsb3dzIGxhdW5jaGluZyBvZiBleGVjdXRhYmxlcyB3aG9zZSBmaWxlIHBhdGhzIG1hdGNoIHRoZSBjb3JyZXNwb25kaW5nIGBwYXRoUnVsZXNgOlxuICAgICAqIGBgYGpzXG4gICAgICogICAgIFwicGVybWlzc2lvbnNcIjoge1xuICAgICAqICAgICAgICBcIlN5c3RlbVwiOiB7XG4gICAgICogICAgICAgICAgICBcImxhdW5jaEV4dGVybmFsUHJvY2Vzc1wiOiB7XG4gICAgICogICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgICAgICBcImV4ZWN1dGFibGVzXCI6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiOiB0cnVlXG4gICAgICogICAgICAgICAgICAgICAgICAgICBcInBhdGhSdWxlc1wiOiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiL1dpbmRvd3MvU3lzdGVtMzIvKi5leGVcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwiYWxsb3dcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiKi5leGVcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwiYmxvY2tcIlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgbGF1bmNoRXh0ZXJuYWxQcm9jZXNzKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZEV4dGVybmFsUHJvY2Vzc1JlcXVlc3QoJ2xhdW5jaC1leHRlcm5hbC1wcm9jZXNzJywgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1vbml0b3JzIGEgcnVubmluZyBwcm9jZXNzLiBBIHBpZCBmb3IgdGhlIHByb2Nlc3MgbXVzdCBiZSBpbmNsdWRlZCBpbiBvcHRpb25zLlxuICAgICAqIDxicj4gQSB1dWlkIG1heSBiZSBvcHRpb25hbGx5IHByb3ZpZGVkLiBJZiBub3QgcHJvdmlkZWQsIE9wZW5GaW4gd2lsbCBjcmVhdGUgYSB1dWlkIGZvciB0aGUgbmV3IHByb2Nlc3MuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJZiBhbiB1bnVzZWQgdXVpZCBpcyBwcm92aWRlZCBpbiBvcHRpb25zLCBpdCB3aWxsIGJlIHVzZWQuIElmIG5vIHV1aWQgaXMgcHJvdmlkZWQsIE9wZWZpbkZpbiB3aWxsIGFzc2lnbiBhIHV1aWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubW9uaXRvckV4dGVybmFsUHJvY2Vzcyh7XG4gICAgICogICAgIHBpZDogMTAyMDgsXG4gICAgICogICAgIHV1aWQ6ICdteS1leHRlcm5hbC1wcm9jZXNzJywgLy8gb3B0aW9uYWxcbiAgICAgKiAgICAgbGlzdGVuZXI6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKCd0aGUgZXhpdCBjb2RlJywgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4ocHJvY2Vzc0lkZW50aXR5ID0+IGNvbnNvbGUubG9nKHByb2Nlc3NJZGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBtb25pdG9yRXh0ZXJuYWxQcm9jZXNzKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZEV4dGVybmFsUHJvY2Vzc1JlcXVlc3QoJ21vbml0b3ItZXh0ZXJuYWwtcHJvY2VzcycsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcml0ZXMgdGhlIHBhc3NlZCBtZXNzYWdlIGludG8gYm90aCB0aGUgbG9nIGZpbGUgYW5kIHRoZSBjb25zb2xlLlxuICAgICAqIEBwYXJhbSBsZXZlbCBUaGUgbG9nIGxldmVsIGZvciB0aGUgZW50cnkuIENhbiBiZSBlaXRoZXIgXCJpbmZvXCIsIFwid2FybmluZ1wiIG9yIFwiZXJyb3JcIlxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFRoZSBsb2cgbWVzc2FnZSB0ZXh0XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sb2coXCJpbmZvXCIsIFwiQW4gZXhhbXBsZSBsb2cgbWVzc2FnZVwiKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdMb2cgaW5mbyBtZXNzYWdlJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBsb2cobGV2ZWwsIG1lc3NhZ2UpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCd3cml0ZS10by1sb2cnLCB7IGxldmVsLCBtZXNzYWdlIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3BlbnMgdGhlIHBhc3NlZCBVUkwgaW4gdGhlIGRlZmF1bHQgd2ViIGJyb3dzZXIuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBJdCBvbmx5IHN1cHBvcnRzIGh0dHAocykgYW5kIGZpbihzKSBwcm90b2NvbHMgYnkgZGVmYXVsdC5cbiAgICAgKiBJbiBvcmRlciB0byB1c2Ugb3RoZXIgY3VzdG9tIHByb3RvY29scywgdGhleSBoYXZlIHRvIGJlIGVuYWJsZWQgdmlhXG4gICAgICogW0FQSSBzZWN1cml0eSBzZXR0aW5nc10oaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9hcGktc2VjdXJpdHkpLlxuICAgICAqIEZpbGUgcHJvdG9jb2wgYW5kIGZpbGUgcGF0aCBhcmUgbm90IHN1cHBvcnRlZC5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSBVUkwgdG8gb3BlblxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ub3BlblVybFdpdGhCcm93c2VyKCdodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9zdGFibGUvdHV0b3JpYWwtU3lzdGVtLm9wZW5VcmxXaXRoQnJvd3Nlci5odG1sJylcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnT3BlbmVkIFVSTCcpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBFeGFtcGxlIG9mIHBlcm1pc3Npb24gZGVmaW5pdGlvbiB0byBlbmFibGUgbm9uLWRlZmF1bHQgcHJvdG9jb2xzOlxuICAgICAqXG4gICAgICogTm90ZTogcGVybWlzc2lvbiBkZWZpbml0aW9uIHNob3VsZCBiZSBzcGVjaWZpZWQgaW4gYW4gYXBwIG1hbmlmZXN0IGZpbGUgaWYgdGhlcmUgaXMgbm8gRE9TIHNldHRpbmdzLlxuICAgICAqIE90aGVyd2lzZSBpdCBoYXMgdG8gYmUgc3BlY2lmaWVkIGluIGJvdGggRE9TIGFuZCBhcHAgbWFuaWZlc3QgZmlsZXMuXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqICAgICBcInBlcm1pc3Npb25zXCI6IHtcbiAgICAgKiAgICAgICAgXCJTeXN0ZW1cIjoge1xuICAgICAqICAgICAgICAgICAgXCJvcGVuVXJsV2l0aEJyb3dzZXJcIjoge1xuICAgICAqICAgICAgICAgICAgICAgICBcImVuYWJsZWRcIjogdHJ1ZSxcbiAgICAgKiAgICAgICAgICAgICAgICAgXCJwcm90b2NvbHNcIjogWyBcIm1zdGVhbXNcIiwgXCJzbGFja1wiXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgb3BlblVybFdpdGhCcm93c2VyKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ29wZW4tdXJsLXdpdGgtYnJvd3NlcicsIHsgdXJsIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyByZWdpc3RyeSBlbnRyeSB1bmRlciB0aGUgSEtDVSByb290IFdpbmRvd3MgcmVnaXN0cnkga2V5IGlmIHRoZSBnaXZlbiBjdXN0b20gcHJvdG9jb2wgbmFtZSBkb2Vzbid0IGV4aXN0IG9yXG4gICAgICogb3ZlcndyaXRlcyB0aGUgZXhpc3RpbmcgcmVnaXN0cnkgZW50cnkgaWYgdGhlIGdpdmVuIGN1c3RvbSBwcm90b2NvbCBuYW1lIGFscmVhZHkgZXhpc3RzLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5IEFQSSBzZWN1cml0eSBzZXR0aW5nc30uIEl0IHJlcXVpcmVzIFJWTSAxMiBvciBoaWdoZXIgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlc2UgcHJvdG9jb2xzIGFyZSByZXNlcnZlZCBhbmQgY2Fubm90IGJlIHJlZ2lzdGVyZWQ6XG4gICAgICogLSBmaW5cbiAgICAgKiAtIGZpbnNcbiAgICAgKiAtIG9wZW5maW5cbiAgICAgKiAtIFVSSSBTY2hlbWVzIHJlZ2lzdGVyZWQgd2l0aCB7QGxpbmsgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGlzdF9vZl9VUklfc2NoZW1lcyNPZmZpY2lhbF9JQU5BLXJlZ2lzdGVyZWRfc2NoZW1lcyBJQU5BfVxuICAgICAqXG4gICAgICogQHRocm93cyBpZiBhIGdpdmVuIGN1c3RvbSBwcm90b2NvbCBmYWlsZWQgdG8gYmUgcmVnaXN0ZXJlZC5cbiAgICAgKiBAdGhyb3dzIGlmIGEgbWFuaWZlc3QgVVJMIGNvbnRhaW5zIHRoZSAnJTEnIHN0cmluZy5cbiAgICAgKiBAdGhyb3dzIGlmIGEgbWFuaWZlc3QgVVJMIGNvbnRhaW5zIGEgcXVlcnkgc3RyaW5nIHBhcmFtZXRlciB3aGljaCBuYW1lIGVxdWFscyB0byB0aGUgUHJvdG9jb2wgTGF1bmNoIFJlcXVlc3QgUGFyYW1ldGVyIE5hbWUuXG4gICAgICogQHRocm93cyBpZiB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIGNvbW1hbmQgc3RyaW5nIHRoYXQgaXMgdG8gYmUgd3JpdHRlbiB0byB0aGUgcmVnaXN0cnkgZXhjZWVkcyAyMDQ4IGJ5dGVzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ucmVnaXN0ZXJDdXN0b21Qcm90b2NvbCh7cHJvdG9jb2xOYW1lOidwcm90b2NvbDEnfSkudGhlbihjb25zb2xlLmxvZykuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXJDdXN0b21Qcm90b2NvbChvcHRpb25zKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTXVzdCBwcm92aWRlIGFuIG9iamVjdCB3aXRoIGEgYHByb3RvY29sTmFtZWAgcHJvcGVydHkgaGF2aW5nIGEgc3RyaW5nIHZhbHVlLicpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdyZWdpc3Rlci1jdXN0b20tcHJvdG9jb2wnLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcmVnaXN0cnkgZW50cnkgZm9yIGEgZ2l2ZW4gY3VzdG9tIHByb3RvY29sLlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5IEFQSSBzZWN1cml0eSBzZXR0aW5nc30uIEl0IHJlcXVpcmVzIFJWTSAxMiBvciBoaWdoZXIgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhlc2UgcHJvdG9jb2xzIGFyZSByZXNlcnZlZCBhbmQgY2Fubm90IGJlIHVucmVnaXN0ZXJlZDpcbiAgICAgKiAtIGZpblxuICAgICAqIC0gZmluc1xuICAgICAqIC0gb3BlbmZpblxuICAgICAqIC0gVVJJIFNjaGVtZXMgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX1VSSV9zY2hlbWVzI09mZmljaWFsX0lBTkEtcmVnaXN0ZXJlZF9zY2hlbWVzIElBTkF9XG4gICAgICpcbiAgICAgKiBAdGhyb3dzIGlmIGEgcHJvdG9jb2wgZW50cnkgZmFpbGVkIHRvIGJlIHJlbW92ZWQgaW4gcmVnaXN0cnkuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXdhaXQgZmluLlN5c3RlbS51bnJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2woJ3Byb3RvY29sMScpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXJDdXN0b21Qcm90b2NvbChwcm90b2NvbE5hbWUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3VucmVnaXN0ZXItY3VzdG9tLXByb3RvY29sJywgeyBwcm90b2NvbE5hbWUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgcmVnaXN0cmF0aW9uIHN0YXRlIGZvciBhIGdpdmVuIGN1c3RvbSBwcm90b2NvbC5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIHtAbGluayBodHRwczovL2RldmVsb3BlcnMub3BlbmZpbi5jby9kb2NzL2FwaS1zZWN1cml0eSBBUEkgc2VjdXJpdHkgc2V0dGluZ3N9LiBJdCByZXF1aXJlcyBSVk0gMTIgb3IgaGlnaGVyIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGVzZSBwcm90b2NvbHMgYXJlIHJlc2VydmVkIGFuZCBjYW5ub3QgZ2V0IHN0YXRlcyBmb3IgdGhlbTpcbiAgICAgKiAtIGZpblxuICAgICAqIC0gZmluc1xuICAgICAqIC0gb3BlbmZpblxuICAgICAqIC0gVVJJIFNjaGVtZXMgcmVnaXN0ZXJlZCB3aXRoIHtAbGluayBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MaXN0X29mX1VSSV9zY2hlbWVzI09mZmljaWFsX0lBTkEtcmVnaXN0ZXJlZF9zY2hlbWVzIElBTkF9XG4gICAgICpcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwcm90b2NvbFN0YXRlID0gYXdhaXQgZmluLlN5c3RlbS5nZXRDdXN0b21Qcm90b2NvbFN0YXRlKCdwcm90b2NvbDEnKTtcbiAgICAgKi9cbiAgICBhc3luYyBnZXRDdXN0b21Qcm90b2NvbFN0YXRlKHByb3RvY29sTmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1jdXN0b20tcHJvdG9jb2wtc3RhdGUnLCB7IHByb3RvY29sTmFtZSB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyB0aGUgcHJvY2VzcyBlbnRyeSBmb3IgdGhlIHBhc3NlZCBVVUlEIG9idGFpbmVkIGZyb20gYSBwcmlvciBjYWxsXG4gICAgICogb2YgZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKS5cbiAgICAgKiBAcGFyYW0gdXVpZCBUaGUgVVVJRCBmb3IgYSBwcm9jZXNzIG9idGFpbmVkIGZyb20gYSBwcmlvciBjYWxsIHRvIGZpbi5kZXNrdG9wLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3MoKVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzKHtcbiAgICAgKiAgICAgcGF0aDogXCJub3RlcGFkXCIsXG4gICAgICogICAgIGxpc3RlbmVyOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhcIlRoZSBleGl0IGNvZGVcIiwgcmVzdWx0LmV4aXRDb2RlKTtcbiAgICAgKiAgICAgfVxuICAgICAqIH0pXG4gICAgICogLnRoZW4oaWRlbnRpdHkgPT4gZmluLlN5c3RlbS5yZWxlYXNlRXh0ZXJuYWxQcm9jZXNzKGlkZW50aXR5LnV1aWQpKVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQcm9jZXNzIGhhcyBiZWVuIHVubWFwcGVkIScpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVsZWFzZUV4dGVybmFsUHJvY2Vzcyh1dWlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVsZWFzZS1leHRlcm5hbC1wcm9jZXNzJywgeyB1dWlkIH0pLnRoZW4oKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2hvd3MgdGhlIENocm9taXVtIERldmVsb3BlciBUb29scyBmb3IgdGhlIHNwZWNpZmllZCB3aW5kb3dcbiAgICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhpcyBpcyBhIG9iamVjdCB0aGF0IGlzIGRlZmluZWQgYnkgdGhlIElkZW50aXR5IGludGVyZmFjZVxuICAgICAqXG4gICAgICogQHR1dG9yaWFsIFN5c3RlbS5zaG93RGV2ZWxvcGVyVG9vbHNcbiAgICAgKi9cbiAgICBzaG93RGV2ZWxvcGVyVG9vbHMoaWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzaG93LWRldmVsb3Blci10b29scycsIGlkZW50aXR5KS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEF0dGVtcHQgdG8gY2xvc2UgYW4gZXh0ZXJuYWwgcHJvY2Vzcy4gVGhlIHByb2Nlc3Mgd2lsbCBiZSB0ZXJtaW5hdGVkIGlmIGl0XG4gICAgICogaGFzIG5vdCBjbG9zZWQgYWZ0ZXIgdGhlIGVsYXBzZWQgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUaGlzIG1ldGhvZCBpcyByZXN0cmljdGVkIGJ5IGRlZmF1bHQgYW5kIG11c3QgYmUgZW5hYmxlZCB2aWFcbiAgICAgKiA8YSBocmVmPVwiaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9hcGktc2VjdXJpdHlcIj5BUEkgc2VjdXJpdHkgc2V0dGluZ3M8L2E+LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEEgb2JqZWN0IGRlZmluZWQgaW4gdGhlIFRlcm1pbmF0ZUV4dGVybmFsUmVxdWVzdFR5cGUgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hFeHRlcm5hbFByb2Nlc3Moe1xuICAgICAqICAgICBwYXRoOiBcIm5vdGVwYWRcIixcbiAgICAgKiAgICAgbGlzdGVuZXI6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKFwiVGhlIGV4aXQgY29kZVwiLCByZXN1bHQuZXhpdENvZGUpO1xuICAgICAqICAgICB9XG4gICAgICogfSlcbiAgICAgKiAudGhlbihpZGVudGl0eSA9PiBmaW4uU3lzdGVtLnRlcm1pbmF0ZUV4dGVybmFsUHJvY2Vzcyh7dXVpZDogaWRlbnRpdHkudXVpZCwgdGltZW91dDoyMDAwLCBraWxsVHJlZTogZmFsc2V9KSlcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnVGVybWluYXRlIHRoZSBwcm9jZXNzJykpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB0ZXJtaW5hdGVFeHRlcm5hbFByb2Nlc3Mob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Rlcm1pbmF0ZS1leHRlcm5hbC1wcm9jZXNzJywgb3B0aW9ucykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIE9wZW5GaW4gUnVudGltZSBQcm94eSBzZXR0aW5ncy5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBIGNvbmZpZyBvYmplY3QgZGVmaW5lZCBpbiB0aGUgUHJveHlDb25maWcgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS51cGRhdGVQcm94eVNldHRpbmdzKHtwcm94eUFkZHJlc3M6JzEyNy4wLjAuMScsIHByb3h5UG9ydDo4MDgwLCB0eXBlOidodHRwJ30pXG4gICAgICogLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1VwZGF0ZSBwcm94eSBzdWNjZXNzZnVsbHknKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgdXBkYXRlUHJveHlTZXR0aW5ncyhvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigndXBkYXRlLXByb3h5Jywgb3B0aW9ucykudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgdGhlIGdpdmVuIGFwcGxpY2F0aW9uIGFzc2V0LlxuICAgICAqXG4gICAgICogTm90ZTogVGhpcyBtZXRob2QgaXMgcmVzdHJpY3RlZCBieSBkZWZhdWx0IGFuZCBtdXN0IGJlIGVuYWJsZWQgdmlhXG4gICAgICogPGEgaHJlZj1cImh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5XCI+QVBJIHNlY3VyaXR5IHNldHRpbmdzPC9hPi5cbiAgICAgKiBAcGFyYW0gYXBwQXNzZXQgQXBwIGFzc2V0IG9iamVjdFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkQXNzZXQoKSB7XG4gICAgICogICAgIGNvbnN0IGFwcEFzc2V0ID0ge1xuICAgICAqICAgICAgICAgc3JjOiBgJHsgbG9jYXRpb24ub3JpZ2luIH0vYXNzZXRzLnppcGAsXG4gICAgICogICAgICAgICBhbGlhczogJ2RpckFwcCcsXG4gICAgICogICAgICAgICB2ZXJzaW9uOiAnMS4yMy4yNCcsXG4gICAgICogICAgICAgICB0YXJnZXQ6ICdhc3NldHMvcnVuLmJhdCdcbiAgICAgKiAgICAgfTtcbiAgICAgKlxuICAgICAqICAgICByZXR1cm4gZmluLlN5c3RlbS5kb3dubG9hZEFzc2V0KGFwcEFzc2V0LCAocHJvZ3Jlc3MgPT4ge1xuICAgICAqICAgICAvL1ByaW50IHByb2dyZXNzIGFzIHdlIGRvd25sb2FkIHRoZSBhc3NldC5cbiAgICAgKiAgICAgICAgIGNvbnN0IGRvd25sb2FkZWRQZXJjZW50ID0gTWF0aC5mbG9vcigocHJvZ3Jlc3MuZG93bmxvYWRlZEJ5dGVzIC8gcHJvZ3Jlc3MudG90YWxCeXRlcykgKiAxMDApO1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coYERvd25sb2FkZWQgJHtkb3dubG9hZGVkUGVyY2VudH0lYCk7XG4gICAgICogICAgIH0pKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBkb3dubG9hZEFzc2V0KClcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3VjY2VzcycpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpKTtcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIC8vIGluY29tcGF0aWJsZSB3aXRoIHN0YW5kYWxvbmUgbm9kZSBwcm9jZXNzLlxuICAgIGFzeW5jIGRvd25sb2FkQXNzZXQoYXBwQXNzZXQsIHByb2dyZXNzTGlzdGVuZXIpIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1mdW5jdGlvbi1yZXR1cm4tdHlwZSwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uXG4gICAgICAgIGNvbnN0IG5vb3AgPSAoKSA9PiB7IH07XG4gICAgICAgIGxldCByZXNvbHZlID0gbm9vcDtcbiAgICAgICAgbGV0IHJlamVjdCA9IG5vb3A7XG4gICAgICAgIGNvbnN0IGRvd25sb2FkQ29tcGxldGVQcm9taXNlID0gbmV3IFByb21pc2UoKHksIG4pID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUgPSB5O1xuICAgICAgICAgICAgcmVqZWN0ID0gbjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG5vZGUuanMgZW52aXJvbm1lbnQgbm90IHN1cHBvcnRlZFxuICAgICAgICBpZiAodGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgIT09ICdvcGVuZmluJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLk5vdFN1cHBvcnRlZEVycm9yKCdkb3dubG9hZEFzc2V0IG9ubHkgc3VwcG9ydGVkIGluIGFuIE9wZW5GaW4gUmVuZGVyIHByb2Nlc3MnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjYWxsU2l0ZSA9IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgpO1xuICAgICAgICBjb25zdCBkb3dubG9hZElkID0gdGhpcy53aXJlLmVudmlyb25tZW50LmdldE5leHRNZXNzYWdlSWQoKS50b1N0cmluZygpO1xuICAgICAgICBjb25zdCBkbFByb2dyZXNzS2V5ID0gYGFzc2V0LWRvd25sb2FkLXByb2dyZXNzLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbEVycm9yS2V5ID0gYGFzc2V0LWRvd25sb2FkLWVycm9yLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbENvbXBsZXRlS2V5ID0gYGFzc2V0LWRvd25sb2FkLWNvbXBsZXRlLSR7ZG93bmxvYWRJZH1gO1xuICAgICAgICBjb25zdCBkbFByb2dyZXNzID0gKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwID0ge1xuICAgICAgICAgICAgICAgIGRvd25sb2FkZWRCeXRlczogcHJvZ3Jlc3MuZG93bmxvYWRlZEJ5dGVzLFxuICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXM6IHByb2dyZXNzLnRvdGFsQnl0ZXNcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBwcm9ncmVzc0xpc3RlbmVyKHApO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjbGVhbkxpc3RlbmVycyA9ICgpID0+IHtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihkbFByb2dyZXNzS2V5LCBkbFByb2dyZXNzKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGxFcnJvciA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgY29uc3QgeyByZWFzb24sIGVycjogZXJyb3IgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICByZWplY3QobmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvcih7IHJlYXNvbiwgZXJyb3IgfSwgY2FsbFNpdGUpKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGxDb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGNsZWFuTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbihkbFByb2dyZXNzS2V5LCBkbFByb2dyZXNzKSxcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbmNlKGRsRXJyb3JLZXksIGRsRXJyb3IpLFxuICAgICAgICAgICAgLy8gVE9ETzogZml4IGludGVybmFsIHR5cGVzXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICB0aGlzLm9uY2UoZGxDb21wbGV0ZUtleSwgZGxDb21wbGV0ZSlcbiAgICAgICAgXSk7XG4gICAgICAgIGNvbnN0IGRvd25sb2FkT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oYXBwQXNzZXQsIHsgZG93bmxvYWRJZCB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rvd25sb2FkLWFzc2V0JywgZG93bmxvYWRPcHRpb25zKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGRvd25sb2FkQ29tcGxldGVQcm9taXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgYSB2ZXJzaW9uIG9mIHRoZSBydW50aW1lLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gRG93bmxvYWQgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gcHJvZ3Jlc3NMaXN0ZW5lciAtIGNhbGxlZCBhcyB0aGUgcnVudGltZSBpcyBkb3dubG9hZGVkIHdpdGggcHJvZ3Jlc3MgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBPbmx5IHN1cHBvcnRlZCBpbiBhbiBPcGVuRmluIFJlbmRlciBwcm9jZXNzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIHZhciBkb3dubG9hZE9wdGlvbnMgPSB7XG4gICAgICogICAgIC8vU3BlY2lmaWMgdmVyc2lvbiBudW1iZXIgcmVxdWlyZWQsIGlmIGdpdmVuIGEgcmVsZWFzZSBjaGFubmVsIHRoZSBjYWxsIHdpbGwgcHJvZHVjZSBhbiBlcnJvci5cbiAgICAgKiAgICAgdmVyc2lvbjogJzkuNjEuMzAuMSdcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZnVuY3Rpb24gb25Qcm9ncmVzcyhwcm9ncmVzcykge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgJHtNYXRoLmZsb29yKChwcm9ncmVzcy5kb3dubG9hZGVkQnl0ZXMgLyBwcm9ncmVzcy50b3RhbEJ5dGVzKSAqIDEwMCl9JWApO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZpbi5TeXN0ZW0uZG93bmxvYWRSdW50aW1lKGRvd25sb2FkT3B0aW9ucywgb25Qcm9ncmVzcykudGhlbigoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdEb3dubG9hZCBjb21wbGV0ZScpO1xuICAgICAqIH0pLmNhdGNoKGVyciA9PiAgICB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBEb3dubG9hZCBGYWlsZWQsIHdlIGNvdWxkIHJldHJ5OiAke2Vyci5tZXNzYWdlfWApO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGRvd25sb2FkUnVudGltZShvcHRpb25zLCBwcm9ncmVzc0xpc3RlbmVyKSB7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlcyA9IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgpO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgLy8gbm9kZS5qcyBlbnZpcm9ubWVudCBub3Qgc3VwcG9ydGVkXG4gICAgICAgICAgICBpZiAodGhpcy53aXJlLmVudmlyb25tZW50LnR5cGUgIT09ICdvcGVuZmluJykge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgdHJhbnNwb3J0X2Vycm9yc18xJDEuTm90U3VwcG9ydGVkRXJyb3IoJ2Rvd25sb2FkUnVudGltZSBvbmx5IHN1cHBvcnRlZCBpbiBhbiBPcGVuRmluIFJlbmRlciBwcm9jZXNzJykpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRvd25sb2FkSWQgPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBjb25zdCBkbFByb2dyZXNzS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtcHJvZ3Jlc3MtJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbEVycm9yS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtZXJyb3ItJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbENvbXBsZXRlS2V5ID0gYHJ1bnRpbWUtZG93bmxvYWQtY29tcGxldGUtJHtkb3dubG9hZElkfWA7XG4gICAgICAgICAgICBjb25zdCBkbFByb2dyZXNzID0gKHByb2dyZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZG93bmxvYWRlZEJ5dGVzOiBwcm9ncmVzcy5kb3dubG9hZGVkQnl0ZXMsXG4gICAgICAgICAgICAgICAgICAgIHRvdGFsQnl0ZXM6IHByb2dyZXNzLnRvdGFsQnl0ZXNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHByb2dyZXNzTGlzdGVuZXIocCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY2xlYW5MaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogZml4IGludGVybmFsIHR5cGVzXG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZGxQcm9ncmVzc0tleSwgZGxQcm9ncmVzcyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZGxFcnJvciA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgY2xlYW5MaXN0ZW5lcnMoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHJlYXNvbiwgZXJyOiBlcnJvciB9ID0gcGF5bG9hZDtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IHRyYW5zcG9ydF9lcnJvcnNfMSQxLlJ1bnRpbWVFcnJvcih7IHJlYXNvbiwgZXJyb3IgfSwgY2FsbHNpdGVzKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZGxDb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBjbGVhbkxpc3RlbmVycygpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggaW50ZXJuYWwgdHlwZXNcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHRoaXMub24oZGxQcm9ncmVzc0tleSwgZGxQcm9ncmVzcyk7XG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggaW50ZXJuYWwgdHlwZXNcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgICAgIHRoaXMub25jZShkbEVycm9yS2V5LCBkbEVycm9yKTtcbiAgICAgICAgICAgIC8vIFRPRE86IGZpeCBpbnRlcm5hbCB0eXBlc1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICAgICAgdGhpcy5vbmNlKGRsQ29tcGxldGVLZXksIGRsQ29tcGxldGUpO1xuICAgICAgICAgICAgY29uc3QgZG93bmxvYWRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7IGRvd25sb2FkSWQgfSk7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZG93bmxvYWQtcnVudGltZScsIGRvd25sb2FkT3B0aW9ucykuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFuTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERvd25sb2FkIHByZWxvYWQgc2NyaXB0cyBmcm9tIGdpdmVuIFVSTHNcbiAgICAgKiBAcGFyYW0gc2NyaXB0cyAtIFVSTHMgb2YgcHJlbG9hZCBzY3JpcHRzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHNjcmlwdHMgPSBbXG4gICAgICogICAgIHsgdXJsOiAnaHR0cDovLy4uLi9wcmVsb2FkLmpzJyB9LFxuICAgICAqICAgICB7IHVybDogJ2h0dHA6Ly8uLi4vcHJlbG9hZDIuanMnIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogZmluLlN5c3RlbS5kb3dubG9hZFByZWxvYWRTY3JpcHRzKHNjcmlwdHMpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICogICAgIHJlc3VsdHMuZm9yRWFjaCgoe3VybCwgc3VjY2VzcywgZXJyb3J9KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhgVVJMOiAke3VybH1gKTtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzOiAke3N1Y2Nlc3N9YCk7XG4gICAgICogICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRXJyb3I6ICR7ZXJyb3J9YCk7XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGRvd25sb2FkUHJlbG9hZFNjcmlwdHMoc2NyaXB0cykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2Rvd25sb2FkLXByZWxvYWQtc2NyaXB0cycsIHsgc2NyaXB0cyB9KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGRhdGEgKG5hbWUsIGlkcywgYm91bmRzKSBmb3IgYWxsIGFwcGxpY2F0aW9uIHdpbmRvd3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRBbGxFeHRlcm5hbEFwcGxpY2F0aW9ucygpXG4gICAgICogLnRoZW4oZXh0ZXJuYWxBcHBzID0+IGNvbnNvbGUubG9nKCdUb3RhbCBleHRlcm5hbCBhcHBzOiAnICsgZXh0ZXJuYWxBcHBzLmxlbmd0aCkpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRBbGxFeHRlcm5hbEFwcGxpY2F0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWV4dGVybmFsLWFwcGxpY2F0aW9ucycpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYXBwIGFzc2V0IGluZm9ybWF0aW9uLlxuICAgICAqIEBwYXJhbSBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRBcHBBc3NldEluZm8oe2FsaWFzOidwcm9jZXhwJ30pLnRoZW4oYXNzZXRJbmZvID0+IGNvbnNvbGUubG9nKGFzc2V0SW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRBcHBBc3NldEluZm8ob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1hcHAtYXNzZXQtaW5mbycsIG9wdGlvbnMpLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWRkaXRpb25hbCBpbmZvIG9mIGNvb2tpZXMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5nZXRDb29raWVzKHtuYW1lOiAnbXlDb29raWUnfSkudGhlbihjb29raWVzID0+IGNvbnNvbGUubG9nKGNvb2tpZXMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q29va2llcyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IHVybCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXRVcmwoKTtcbiAgICAgICAgY29uc3QgbmV3T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgeyB1cmwgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWNvb2tpZXMnLCBuZXdPcHRpb25zKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBtaW5pbXVtIGxvZyBsZXZlbCBhYm92ZSB3aGljaCBsb2dzIHdpbGwgYmUgd3JpdHRlbiB0byB0aGUgT3BlbkZpbiBsb2dcbiAgICAgKiBAcGFyYW0gVGhlIG1pbmltdW0gbGV2ZWwgKGluY2x1c2l2ZSkgYWJvdmUgd2hpY2ggYWxsIGNhbGxzIHRvIGxvZyB3aWxsIGJlIHdyaXR0ZW5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnNldE1pbkxvZ0xldmVsKFwidmVyYm9zZVwiKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKFwibG9nIGxldmVsIGlzIHNldCB0byB2ZXJib3NlXCIpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgc2V0TWluTG9nTGV2ZWwobGV2ZWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtbWluLWxvZy1sZXZlbCcsIHsgbGV2ZWwgfSkudGhlbigoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIFVVSUQgb2YgdGhlIGNvbXB1dGVyIG9uIHdoaWNoIHRoZSBydW50aW1lIGlzIGluc3RhbGxlZFxuICAgICAqIEBwYXJhbSB1dWlkIFRoZSB1dWlkIG9mIHRoZSBydW5uaW5nIGFwcGxpY2F0aW9uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5yZXNvbHZlVXVpZCgnT3BlbmZpblBPQycpLnRoZW4oZW50aXR5ID0+IGNvbnNvbGUubG9nKGVudGl0eSkpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICByZXNvbHZlVXVpZCh1dWlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmVcbiAgICAgICAgICAgIC5zZW5kQWN0aW9uKCdyZXNvbHZlLXV1aWQnLCB7XG4gICAgICAgICAgICBlbnRpdHlLZXk6IHV1aWRcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGFuIGFycmF5IG9mIGRhdGEgZm9yIGFsbCBleHRlcm5hbCBhcHBsaWNhdGlvbnNcbiAgICAgKiBAcGFyYW0gcmVxdWVzdGluZ0lkZW50aXR5IFRoaXMgb2JqZWN0IGlzIGRlc2NyaWJlZCBpbiB0aGUgSWRlbnRpdHkgdHlwZWRlZlxuICAgICAqIEBwYXJhbSBkYXRhIEFueSBkYXRhIHR5cGUgdG8gcGFzcyB0byB0aGUgbWV0aG9kXG4gICAgICpcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgZXhlY3V0ZU9uUmVtb3RlKHJlcXVlc3RpbmdJZGVudGl0eSwgZGF0YSkge1xuICAgICAgICBkYXRhLnJlcXVlc3RpbmdJZGVudGl0eSA9IHJlcXVlc3RpbmdJZGVudGl0eTtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5mZXJyeUFjdGlvbihkYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZHMgdGhlIHNwZWNpZmVkIHZhbHVlIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIGlzIHJlc3RyaWN0ZWQgYnkgZGVmYXVsdCBhbmQgbXVzdCBiZSBlbmFibGVkIHZpYVxuICAgICAqIFtBUEkgc2VjdXJpdHkgc2V0dGluZ3NdKGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvYXBpLXNlY3VyaXR5KS5cbiAgICAgKiBAcGFyYW0gcm9vdEtleSAtIFRoZSByZWdpc3RyeSByb290IGtleS5cbiAgICAgKiBAcGFyYW0gc3Via2V5IC0gVGhlIHJlZ2lzdHJ5IGtleS5cbiAgICAgKiBAcGFyYW0gdmFsdWUgLSBUaGUgcmVnaXN0cnkgdmFsdWUgbmFtZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnJlYWRSZWdpc3RyeVZhbHVlKFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsIFwiSEFSRFdBUkVcXFxcREVTQ1JJUFRJT05cXFxcU3lzdGVtXCIsIFwiQm9vdEFyY2hpdGVjdHVyZVwiKS50aGVuKHZhbCA9PiBjb25zb2xlLmxvZyh2YWwpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvd2luZG93cy9kZXNrdG9wL21zNjgxMzgyKHY9dnMuODUpLmFzcHggaGVyZX0gZm9yIFdpbmRvdydzIGVycm9yIGNvZGUgZGVmaW5pdGlvbnMuXG4gICAgICpcbiAgICAgKiBFeGFtcGxlIHBheWxvYWRzIG9mIGRpZmZlcmVudCByZWdpc3RyeSB0eXBlczpcbiAgICAgKlxuICAgICAqIFNlZSBsaXN0IG9mIHR5cGVzIHtAbGluayBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L3dpbmRvd3MvZGVza3RvcC9tczcyNDg4NCh2PXZzLjg1KS5hc3B4IGhlcmV9LlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAvLyBSRUdfRFdPUkRcbiAgICAgKiB7XG4gICAgICogICAgIGRhdGE6IDEsXG4gICAgICogICAgIHJvb3RLZXk6IFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19EV09SRFwiLFxuICAgICAqICAgICB2YWx1ZTogXCJCYXpcIlxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIFJFR19RV09SRFxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogMTMxMDgxNDY2NzEzMzQxMTIsXG4gICAgICogICAgIHJvb3RLZXk6IFwiSEtFWV9MT0NBTF9NQUNISU5FXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19RV09SRFwiLFxuICAgICAqICAgICB2YWx1ZTogXCJCYXpcIlxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIFJFR19TWlxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogXCJGb29CYXJCYXpcIixcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0xPQ0FMX01BQ0hJTkVcIixcbiAgICAgKiAgICAgc3Via2V5OiBcIkZvb1xcQmFyXCIsXG4gICAgICogICAgIHR5cGU6IFwiUkVHX1NaXCIsXG4gICAgICogICAgIHZhbHVlOiBcIkJhelwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogLy8gUkVHX0VYUEFORF9TWlxuICAgICAqIHtcbiAgICAgKiAgICAgZGF0YTogXCJDOlxcVXNlclxcSm9obkRvZVxcQXBwRGF0YVxcTG9jYWxcIixcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0NVUlJFTlRfVVNFUlwiLFxuICAgICAqICAgICBzdWJrZXk6IFwiRm9vXFxCYXJcIixcbiAgICAgKiAgICAgdHlwZTogXCJSRUdfRVhQQU5EX1NaXCIsXG4gICAgICogICAgIHZhbHVlOiBcIkJhelwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogLy8gUkVHX01VTFRJX1NaXG4gICAgICoge1xuICAgICAqICAgICBkYXRhOiBbXG4gICAgICogICAgICAgICBcIkZvb1wiLFxuICAgICAqICAgICAgICAgXCJCYXJcIixcbiAgICAgKiAgICAgICAgIFwiQmF6XCJcbiAgICAgKiAgICAgXSxcbiAgICAgKiAgICAgcm9vdEtleTogXCJIS0VZX0NVUlJFTlRfVVNFUlwiLFxuICAgICAqICAgICBzdWJrZXk6IFwiRm9vXFxCYXJcIixcbiAgICAgKiAgICAgdHlwZTogXCJSRUdfTVVMVElfU1pcIixcbiAgICAgKiAgICAgdmFsdWU6IFwiQmF6XCJcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiAvLyBSRUdfQklOQVJZXG4gICAgICoge1xuICAgICAqICAgICBkYXRhOiB7XG4gICAgICogICAgICAgICBkYXRhOiBbXG4gICAgICogICAgICAgICAgICAgMjU1LFxuICAgICAqICAgICAgICAgICAgIDI1NSxcbiAgICAgKiAgICAgICAgICAgICAwLFxuICAgICAqICAgICAgICAgICAgIDQzLFxuICAgICAqICAgICAgICAgICAgIDU1LFxuICAgICAqICAgICAgICAgICAgIDAsXG4gICAgICogICAgICAgICAgICAgMCxcbiAgICAgKiAgICAgICAgICAgICAyNTUsXG4gICAgICogICAgICAgICAgICAgMjU1XG4gICAgICogICAgICAgICBdLFxuICAgICAqICAgICAgICAgdHlwZTogXCJCdWZmZXJcIlxuICAgICAqICAgICB9LFxuICAgICAqICAgICByb290S2V5OiBcIkhLRVlfQ1VSUkVOVF9VU0VSXCIsXG4gICAgICogICAgIHN1YmtleTogXCJGb29cXEJhclwiLFxuICAgICAqICAgICB0eXBlOiBcIlJFR19CSU5BUllcIixcbiAgICAgKiAgICAgdmFsdWU6IFwiQmF6XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVhZFJlZ2lzdHJ5VmFsdWUocm9vdEtleSwgc3Via2V5LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlXG4gICAgICAgICAgICAuc2VuZEFjdGlvbigncmVhZC1yZWdpc3RyeS12YWx1ZScsIHtcbiAgICAgICAgICAgIHJvb3RLZXksXG4gICAgICAgICAgICBzdWJrZXksXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNhbGwgd2lsbCByZWdpc3RlciBhIHVuaXF1ZSBpZCBhbmQgcHJvZHVjZSBhIHRva2VuLlxuICAgICAqIFRoZSB0b2tlbiBjYW4gYmUgdXNlZCB0byBicm9rZXIgYW4gZXh0ZXJuYWwgY29ubmVjdGlvbi5cbiAgICAgKiBAcGFyYW0gdXVpZCAtIEEgVVVJRCBmb3IgdGhlIHJlbW90ZSBjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0ucmVnaXN0ZXJFeHRlcm5hbENvbm5lY3Rpb24oXCJyZW1vdGUtY29ubmVjdGlvbi11dWlkXCIpLnRoZW4oY29ubiA9PiBjb25zb2xlLmxvZyhjb25uKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICpcbiAgICAgKiAvLyBvYmplY3QgY29tZXMgYmFjayB3aXRoXG4gICAgICogLy8gICAgIHRva2VuOiBcIjA0ODlFQUM1LTY0MDQtNEYwRC05OTNCLTkyQkI4RUFCNDQ1RFwiLCAvLyB0aGlzIHdpbGwgYmUgdW5pcXVlIGVhY2ggdGltZVxuICAgICAqIC8vICAgICB1dWlkOiBcInJlbW90ZS1jb25uZWN0aW9uLXV1aWRcIlxuICAgICAqXG4gICAgICogYGBgXG4gICAgICovXG4gICAgcmVnaXN0ZXJFeHRlcm5hbENvbm5lY3Rpb24odXVpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlZ2lzdGVyLWV4dGVybmFsLWNvbm5lY3Rpb24nLCB7IHV1aWQgfSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGpzb24gYmxvYiBmb3VuZCBpbiB0aGUgW2Rlc2t0b3Agb3duZXIgc2V0dGluZ3NdKGh0dHBzOi8vb3BlbmZpbi5jby9kb2N1bWVudGF0aW9uL2Rlc2t0b3Atb3duZXItc2V0dGluZ3MvKVxuICAgICAqIGZvciB0aGUgc3BlY2lmaWVkIHNlcnZpY2UuXG4gICAgICogQHBhcmFtIHNlcnZpY2VJZGVudGlmaWVyIEFuIG9iamVjdCBjb250YWluaW5nIGEgbmFtZSBrZXkgdGhhdCBpZGVudGlmaWVzIHRoZSBzZXJ2aWNlLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgTW9yZSBpbmZvcm1hdGlvbiBhYm91dCBkZXNrdG9wIHNlcnZpY2VzIGNhbiBiZSBmb3VuZCBbaGVyZV0oaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9kZXNrdG9wLXNlcnZpY2VzKS5cbiAgICAgKiBUaGlzIGNhbGwgd2lsbCByZWplY3QgaWYgdGhlIGRlc2t0b3Agb3duZXIgc2V0dGluZ3MgZmlsZSBpcyBub3QgcHJlc2VudCwgbm90IGNvcnJlY3RseSBmb3JtYXR0ZWQsIG9yIGlmIHRoZSBzZXJ2aWNlIHJlcXVlc3RlZCBpcyBub3QgY29uZmlndXJlZCBvciBjb25maWd1cmVkIGluY29ycmVjdGx5LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEhlcmUgd2UgYXJlIHVzaW5nIHRoZSBbbGF5b3V0c10oaHR0cHM6Ly9naXRodWIuY29tL0hhZG91a2VuSU8vbGF5b3V0cy1zZXJ2aWNlKSBzZXJ2aWNlLlxuICAgICAqIGZpbi5TeXN0ZW0uZ2V0U2VydmljZUNvbmZpZ3VyYXRpb24oe25hbWU6J2xheW91dHMnfSkudGhlbihjb25zb2xlLmxvZykuY2F0Y2goY29uc29sZS5lcnJvcik7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U2VydmljZUNvbmZpZ3VyYXRpb24oc2VydmljZUlkZW50aWZpZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXJ2aWNlSWRlbnRpZmllci5uYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdXN0IHByb3ZpZGUgYW4gb2JqZWN0IHdpdGggYSBgbmFtZWAgcHJvcGVydHkgaGF2aW5nIGEgc3RyaW5nIHZhbHVlJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBzZXJ2aWNlSWRlbnRpZmllcjtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtc2VydmljZS1jb25maWd1cmF0aW9uJywgeyBuYW1lIH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICBhc3luYyBnZXRTeXN0ZW1BcHBDb25maWcobmFtZSkge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ011c3QgcHJvdmlkZSBhIHN0cmluZyB2YWx1ZSBmb3IgbmFtZSBvZiBzeXN0ZW0gYXBwJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtc3lzdGVtLWFwcC1jb25maWd1cmF0aW9uJywgeyBuYW1lIH0pLnRoZW4oKHsgcGF5bG9hZCB9KSA9PiBwYXlsb2FkLmRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSBzeXN0ZW0gc2h1dGRvd24gaGFuZGxlciBzbyB1c2VyIGNhbiBkbyBzb21lIGNsZWFudXAgYmVmb3JlIHN5c3RlbSBpcyBzaHV0dGluZyBkb3duLlxuICAgICAqIEByZW1hcmtzIE9uY2Ugc3lzdGVtIHNodXRkb3duIHN0YXJ0cywgeW91IGFyZSB1bmFibGUgdG8gY2FuY2VsIGl0LlxuICAgICAqIEBwYXJhbSBoYW5kbGVyIHN5c3RlbSBzaHV0ZG93biBoYW5kbGVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5yZWdpc3RlclNodXRkb3duSGFuZGxlcigoc2h1dGRvd25FdmVudCkgPT4ge1xuICAgICAqICAgICAgICAgLy8gc2F2ZSBzdGF0ZSBvciBjbGVhbnVwXG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnZG8gc29tZSBjbGVhbnVwIGJlZm9yZSBzaHV0ZG93bicpO1xuICAgICAqICAgICAgICAgLy8gTm90aWZ5IGFwcCBpcyByZWFkeSBmb3IgdGVybWluYXRpb24uXG4gICAgICogICAgICAgICBzaHV0ZG93bkV2ZW50LnByb2NlZWQoKTtcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTaHV0ZG93biBoYW5kbGVyIHJlZ2lzdGVyZWQhJykpXG4gICAgICogLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXJTaHV0ZG93bkhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLXJlZ2lzdGVyLXNodXRkb3duLWhhbmRsZXInKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBTeXN0ZW1TaHV0ZG93bkV2ZW50TmFtZSA9ICdzeXN0ZW0tc2h1dGRvd24nO1xuICAgICAgICBjb25zdCBTeXN0ZW1TaHV0ZG93bkhhbmRsZWRFdmVudE5hbWUgPSAnc3lzdGVtLXNodXRkb3duLWhhbmRsZWQnO1xuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMud2lyZS5tZTtcbiAgICAgICAgY29uc3Qgc2h1dGRvd25IYW5kbGVyID0gKHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb2NlZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gbm90aWZ5IGNvcmUgdGhhdCB0aGUgYXBwIGlzIHJlYWR5IGZvciBzaHV0ZG93blxuICAgICAgICAgICAgICAgIHRoaXMud2lyZS5lbnZpcm9ubWVudC5yYWlzZUV2ZW50KGBhcHBsaWNhdGlvbi8ke1N5c3RlbVNodXRkb3duSGFuZGxlZEV2ZW50TmFtZX1gLCB7XG4gICAgICAgICAgICAgICAgICAgIHV1aWQsXG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHRvcGljOiAnYXBwbGljYXRpb24nXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaGFuZGxlcih7IHByb2NlZWQgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMub24oU3lzdGVtU2h1dGRvd25FdmVudE5hbWUsIHNodXRkb3duSGFuZGxlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNpZ25hbHMgdGhlIFJWTSB0byBwZXJmb3JtIGEgaGVhbHRoIGNoZWNrIGFuZCByZXR1cm5zIHRoZSByZXN1bHRzIGFzIGpzb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBSZXF1aXJlcyBSVk0gNS41K1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIHRyeSB7XG4gICAgICogICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBmaW4uU3lzdGVtLnJ1blJ2bUhlYWx0aENoZWNrKCk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcnVuUnZtSGVhbHRoQ2hlY2soKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbigncnVuLXJ2bS1oZWFsdGgtY2hlY2snKS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGF1bmNoIGFwcGxpY2F0aW9uIHVzaW5nIGEgbWFuaWZlc3QgVVJML3BhdGguIEl0IGRpZmZlcnMgZnJvbSBBcHBsaWNhdGlvbi5zdGFydEZyb21NYW5pZmVzdCBpbiB0aGF0IHRoaXMgQVBJIGNhbiBhY2NlcHQgYSBtYW5pZmVzdCB1c2luZyB0aGUgZmluIHByb3RvY29sLlxuICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBtYW5pZmVzdCdzIFVSTCBvciBwYXRoLlxuICAgICAqIEBwYXJhbSBvcHRzIC0gUGFyYW1ldGVycyB0aGF0IHRoZSBSVk0gd2lsbCB1c2UuXG4gICAgICpcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICogQHJlbWFya3MgU3VwcG9ydHMgcHJvdG9jb2xzIGh0dHAvcyBhbmQgZmluL3MsIGFuZCBhbHNvIGEgbG9jYWwgcGF0aC5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoaXMgQVBJIGlzIFdpbmRvd3Mgb25seS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBUaGlzIEFQSSBjYW4gaGFuZGxlIG1vc3QgbWFuaWZlc3QgdHlwZXMuIFNvbWUgZXhhbXBsZXMgYmVsb3cuXG4gICAgICpcbiAgICAgKiBUcmFkaXRpb25hbDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdChcbiAgICAgKiAgICdodHRwczovL2RlbW9hcHBkaXJlY3Rvcnkub3BlbmYuaW4vZGVza3RvcC9jb25maWcvYXBwcy9PcGVuRmluL0hlbGxvT3BlbkZpbi9hcHAuanNvbicpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFBsYXRmb3JtOlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3QgPSBhd2FpdCBmaW4uU3lzdGVtLmxhdW5jaE1hbmlmZXN0KCdodHRwczovL29wZW5maW4uZ2l0aHViLmlvL3BsYXRmb3JtLWFwaS1wcm9qZWN0LXNlZWQvcHVibGljLmpzb24nKTtcbiAgICAgKiBjb25zb2xlLmxvZyhtYW5pZmVzdCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgdHJhZGl0aW9uYWwgbWFuaWZlc3QgaW50byBhIHBsYXRmb3JtOlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbWFuaWZlc3QgPSBhd2FpdCBmaW4uU3lzdGVtLmxhdW5jaE1hbmlmZXN0KFxuICAgICAqICAgJ2h0dHBzOi8vb3BlbmZpbi5naXRodWIuaW8vcGxhdGZvcm0tYXBpLXByb2plY3Qtc2VlZC9wdWJsaWMuanNvbj9cXFxuICAgICAqICAgJCRhcHBNYW5pZmVzdFVybD1odHRwczovL2RlbW9hcHBkaXJlY3Rvcnkub3BlbmYuaW4vZGVza3RvcC9jb25maWcvXFxcbiAgICAgKiAgIGFwcHMvT3BlbkZpbi9IZWxsb09wZW5GaW4vYXBwLmpzb24nKTtcbiAgICAgKiBjb25zb2xlLmxvZyhtYW5pZmVzdCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBMYXVuY2hpbmcgd2l0aCBSVk0gb3B0aW9uczpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdCgnaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9wbGF0Zm9ybS1hcGktcHJvamVjdC1zZWVkL3B1YmxpYy5qc29uJyxcbiAgICAgKiAgICAgeyBub1VpOiB0cnVlLCB1c2VyQXBwQ29uZmlnQXJnczogeyBhYmM6ICcxMjMnLCB4eXo6ICc3ODknIH0gfSk7XG4gICAgICogY29uc29sZS5sb2cobWFuaWZlc3QpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogTG9jYWwgUGF0aDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG1hbmlmZXN0ID0gIGF3YWl0IGZpbi5TeXN0ZW0ubGF1bmNoTWFuaWZlc3QoJ2ZpbGU6Ly9jOlxcXFxwYXRoXFxcXHRvXFxcXG1hbmlmZXN0XFxcXGZpbGUuanNvbicpO1xuICAgICAqIGNvbnNvbGUubG9nKG1hbmlmZXN0KTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIExhdW5jaGluZyB3aXRoIFJWTSAnc3Vic2NyaWJlJyBvcHRpb246XG4gICAgICpcbiAgICAgKiBUaGlzIG9wdGlvbiBhbGxvd3MgdXNlcnMgdG8gc3Vic2NyaWJlIHRvIGFwcCB2ZXJzaW9uIHJlc29sdmVyIGV2ZW50cyB3aGVuXG4gICAgICogY2FsbGluZyBsYXVuY2hNYW5pZmVzdCB3aXRoIGZhbGxiYWNrTWFuaWZlc3RzIHNwZWNpZmllZC5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogZmluLlN5c3RlbS5sYXVuY2hNYW5pZmVzdCgnZmluczovL3N5c3RlbS1hcHBzL25vdGlmaWNhdGlvbnMvYXBwLmpzb24nLCB7IHN1YnNjcmliZTogKGxhdW5jaCkgPT4ge1xuICAgICAqIFx0XHRsYXVuY2gub24oJ2FwcC12ZXJzaW9uLXByb2dyZXNzJywgKHByb2dyZXNzKSA9PiB7XG4gICAgICogXHRcdFx0Y29uc29sZS5sb2coXCJUcnlpbmcgbWFuaWZlc3QgXCIgKyBwcm9ncmVzcy5tYW5pZmVzdClcbiAgICAgKiBcdFx0fSk7XG4gICAgICpcbiAgICAgKiBcdFx0bGF1bmNoLm9uKCdydW50aW1lLXN0YXR1cycsIChzdGF0dXMpID0+IHtcbiAgICAgKiBcdFx0XHRjb25zb2xlLmxvZyhcIlJ1bnRpbWUgc3RhdHVzOiBcIiArIEpTT04uc3RyaW5naWZ5KHN0YXR1cykpO1xuICAgICAqIFx0XHR9KTtcbiAgICAgKlxuICAgICAqIFx0XHQvLyBSVk0gaGFzIHN1Y2Nlc3NmdWxseSBmb3VuZCB0aGUgdGFyZ2V0IHJ1bnRpbWUgdmVyc2lvblxuICAgICAqIFx0XHRsYXVuY2gub24oJ2FwcC12ZXJzaW9uLWNvbXBsZXRlJywgKGNvbXBsZXRlKSA9PiB7XG4gICAgICogXHRcdFx0Y29uc29sZS5sb2coXCJQYXJlbnQgYXBwIFwiICsgY29tcGxldGUuc3JjTWFuaWZlc3QgKyBcIiByZXNvbHZlZCB0byBcIiArIGNvbXBsZXRlLm1hbmlmZXN0KTtcbiAgICAgKiBcdFx0XHRsYXVuY2gucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICogXHRcdH0pO1xuICAgICAqXG4gICAgICogXHRcdC8vIFJWTSBmYWlsZWQgdG8gZmluZCBhbiBhdmFpbGFibGUgcnVudGltZSB2ZXJzaW9uXG4gICAgICogXHRcdGxhdW5jaC5vbignYXBwLXZlcnNpb24tZXJyb3InLCAoZXJyb3IpID0+IHtcbiAgICAgKiBcdFx0XHRjb25zb2xlLmxvZyhcIkZhaWxlZCB0byByZXNvbHZlIFwiICsgZXJyb3Iuc3JjTWFuaWZlc3QgKyBcIiBmcm9tIHRoZSBmYWxsYmFja01hbmlmZXN0c1wiKTtcbiAgICAgKiBcdFx0XHRsYXVuY2gucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICogXHRcdH0pO1xuICAgICAqIFx0fVxuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGxhdW5jaE1hbmlmZXN0KG1hbmlmZXN0VXJsLCBvcHRzID0ge30pIHtcbiAgICAgICAgY29uc3QgeyBzdWJzY3JpYmUsIC4uLl9zZW5kT3B0cyB9ID0gb3B0cztcbiAgICAgICAgY29uc3Qgc2VuZE9wdHMgPSBfc2VuZE9wdHM7XG4gICAgICAgIGlmIChzdWJzY3JpYmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhdW5jaEVtaXR0ZXIgPSBuZXcgZXZlbnRzXzEkNi5FdmVudEVtaXR0ZXIoKTtcbiAgICAgICAgICAgIHN1YnNjcmliZShsYXVuY2hFbWl0dGVyKTtcbiAgICAgICAgICAgIGNvbnN0IEFwcFZlcnNpb25Qcm9ncmVzc0V2ZW50TmFtZSA9ICdhcHAtdmVyc2lvbi1wcm9ncmVzcyc7XG4gICAgICAgICAgICBjb25zdCBSdW50aW1lU3RhdHVzRXZlbnROYW1lID0gJ3J1bnRpbWUtc3RhdHVzJztcbiAgICAgICAgICAgIGNvbnN0IEFwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZSA9ICdhcHAtdmVyc2lvbi1jb21wbGV0ZSc7XG4gICAgICAgICAgICBjb25zdCBBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWUgPSAnYXBwLXZlcnNpb24tZXJyb3InO1xuICAgICAgICAgICAgLy8gYWRkIGlkIHRvIGF2b2lkIG11bHRpcGxlIGFwaSBjYWxscyBnZXR0aW5nIGR1cGxpY2F0ZWQgZXZlbnRzXG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCkudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHNlbmRPcHRzLmFwcFZlcnNpb25JZCA9IGlkO1xuICAgICAgICAgICAgY29uc3Qgc3VwcG9ydGVkRXZlbnRzID0gW1xuICAgICAgICAgICAgICAgIEFwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZSxcbiAgICAgICAgICAgICAgICBBcHBWZXJzaW9uUHJvZ3Jlc3NFdmVudE5hbWUsXG4gICAgICAgICAgICAgICAgUnVudGltZVN0YXR1c0V2ZW50TmFtZSxcbiAgICAgICAgICAgICAgICBBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWVcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBjb25zdCBjbGVhbkV2ZW50UGF5bG9hZCA9IChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBkbyB0eXBlIGNhc3RpbmdzIGJlbG93IHRvIG1ha2Ugc3VyZSB0aGUgcmV0dXJuIHR5cGUgaXMgY29ycmVjdC5cbiAgICAgICAgICAgICAgICBjb25zdCB7IGFwcFZlcnNpb25JZCwgdG9waWMsIHR5cGU6IHR5cGVXaXRoSWQsIC4uLnJlc3QgfSA9IHBheWxvYWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IHN1cHBvcnRlZEV2ZW50cy5maW5kKCh4KSA9PiB0eXBlV2l0aElkLmluY2x1ZGVzKHgpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAuLi5yZXN0LFxuICAgICAgICAgICAgICAgICAgICB0eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBhcHBWZXJzaW9uTGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuUGF5bG9hZCA9IGNsZWFuRXZlbnRQYXlsb2FkKHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGxhdW5jaEVtaXR0ZXIuZW1pdChjbGVhblBheWxvYWQudHlwZSwgY2xlYW5QYXlsb2FkKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCByZW1vdmVBbGxMaXN0ZW5lcnMgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihgJHtBcHBWZXJzaW9uUHJvZ3Jlc3NFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke1J1bnRpbWVTdGF0dXNFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke0FwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoYCR7QXBwVmVyc2lvbkVycm9yRXZlbnROYW1lfS4ke2lkfWAsIGFwcFZlcnNpb25MaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihgJHtBcHBWZXJzaW9uQ29tcGxldGVFdmVudE5hbWV9LiR7aWR9YCwgcmVtb3ZlQWxsTGlzdGVuZXJzKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGAke0FwcFZlcnNpb25FcnJvckV2ZW50TmFtZX0uJHtpZH1gLCByZW1vdmVBbGxMaXN0ZW5lcnMpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICB0aGlzLm9uKGAke0FwcFZlcnNpb25Qcm9ncmVzc0V2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpLFxuICAgICAgICAgICAgICAgIHRoaXMub24oYCR7UnVudGltZVN0YXR1c0V2ZW50TmFtZX0uJHtpZH1gLCBhcHBWZXJzaW9uTGlzdGVuZXIpLFxuICAgICAgICAgICAgICAgIHRoaXMub25jZShgJHtBcHBWZXJzaW9uQ29tcGxldGVFdmVudE5hbWV9LiR7aWR9YCwgYXBwVmVyc2lvbkxpc3RlbmVyKSxcbiAgICAgICAgICAgICAgICB0aGlzLm9uY2UoYCR7QXBwVmVyc2lvbkVycm9yRXZlbnROYW1lfS4ke2lkfWAsIGFwcFZlcnNpb25MaXN0ZW5lciksXG4gICAgICAgICAgICAgICAgdGhpcy5vbmNlKGAke0FwcFZlcnNpb25Db21wbGV0ZUV2ZW50TmFtZX0uJHtpZH1gLCByZW1vdmVBbGxMaXN0ZW5lcnMpLFxuICAgICAgICAgICAgICAgIHRoaXMub25jZShgJHtBcHBWZXJzaW9uRXJyb3JFdmVudE5hbWV9LiR7aWR9YCwgcmVtb3ZlQWxsTGlzdGVuZXJzKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF1bmNoLW1hbmlmZXN0Jywge1xuICAgICAgICAgICAgbWFuaWZlc3RVcmwsXG4gICAgICAgICAgICBvcHRzOiBzZW5kT3B0c1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnBheWxvYWQuZGF0YS5tYW5pZmVzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUXVlcnkgcGVybWlzc2lvbiBvZiBhIHNlY3VyZWQgYXBpIGluIGN1cnJlbnQgY29udGV4dC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhcGlOYW1lIC0gVGhlIGZ1bGwgbmFtZSBvZiBhIHNlY3VyZWQgQVBJLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgYSBmdW5jdGlvbiBoYXMgYSBzdHJ1Y3R1cmVkIHBlcm1pc3Npb24gdmFsdWUsIHRoZSB2YWx1ZSBvZiBgZ3JhbnRlZGAgd2lsbCByZWZsZWN0IHRoZSBgZW5hYmxlZGAga2V5XG4gICAgICogb2YgdGhlIGNhbGwncyBwZXJtaXNzaW9ucyBsaXRlcmFsLiAgSW4gdGhpcyBjYXNlLCAqcGVybWlzc2lvbiBtYXkgc3RpbGwgYmUgZGVuaWVkIHRvIGEgY2FsbCogcGVuZGluZyBhcmd1bWVudHMgb3Igb3RoZXJcbiAgICAgKiBydW50aW1lIHN0YXRlLiAgVGhpcyBpcyBpbmRpY2F0ZWQgd2l0aCBgc3RhdGU6IHVuYXZhaWxhYmxlYC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uU3lzdGVtLnF1ZXJ5UGVybWlzc2lvbkZvckN1cnJlbnRDb250ZXh0KCdTeXN0ZW0ubGF1bmNoRXh0ZXJuYWxQcm9jZXNzJykudGhlbihyZXN1bHQgPT4gY29uc29sZS5sb2cocmVzdWx0KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogLy9UaGlzIHJlc3BvbnNlIGhhcyB0aGUgZm9sbG93aW5nIHNoYXBlOlxuICAgICAqIHtcbiAgICAgKiAgICBwZXJtaXNzaW9uOiAnU3lzdGVtLmxhdW5jaEV4dGVybmFsUHJvY2VzcycsIC8vIGFwaSBmdWxsIG5hbWVcbiAgICAgKiAgICBzdGF0ZTogJ2dyYW50ZWQnLCAvLyBzdGF0ZSBvZiBwZXJtaXNzaW9uXG4gICAgICogICAgZ3JhbnRlZDogdHJ1ZVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBxdWVyeVBlcm1pc3Npb25Gb3JDdXJyZW50Q29udGV4dChhcGlOYW1lKSB7XG4gICAgICAgIGNvbnN0IGlkZW50aXR5ID0geyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCwgbmFtZTogdGhpcy53aXJlLm1lLm5hbWUgfTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncXVlcnktcGVybWlzc2lvbi1mb3ItY3VycmVudC1jb250ZXh0Jywge1xuICAgICAgICAgICAgYXBpTmFtZSxcbiAgICAgICAgICAgIGlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UucGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvLyBOb3QgZG9jdW1lbnRpbmcsIGludGVybmFsIHVzZSBvbmx5LlxuICAgIGFzeW5jIGVuYWJsZU5hdGl2ZVdpbmRvd0ludGVncmF0aW9uUHJvdmlkZXIocGVybWlzc2lvbnMpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZW5hYmxlLW5hdGl2ZS13aW5kb3ctaW50ZWdyYXRpb24tcHJvdmlkZXInLCB7IHBlcm1pc3Npb25zIH0pO1xuICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAoSW50ZXJuYWwpIFJlZ2lzdGVyIHRoZSB1c2FnZSBvZiBhIGNvbXBvbmVudCB3aXRoIGEgcGxhdGZvcm1cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIE9iamVjdCB3aXRoIGRhdGEgYW5kIHR5cGVcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWdpc3RlclVzYWdlKCkge1xuICAgICAqICAgICBjb25zdCBhcHAgPSBhd2FpdCBmaW4uU3lzdGVtLmdldEN1cnJlbnQoKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGZpbi5TeXN0ZW0ucmVnaXN0ZXJVc2FnZSh7XG4gICAgICogICAgICAgICB0eXBlOiAnd29ya3NwYWNlLWxpY2Vuc2luZycsXG4gICAgICogICAgICAgICAvLyBleGFtcGxlIHZhbHVlcyBmb3IgdGhlIGZvbGxvd2luZyBkYXRhIG9iamVjdFxuICAgICAqICAgICAgICAgZGF0YToge1xuICAgICAqICAgICAgICAgICAgIGFwaVZlcnNpb246ICcxLjAnLFxuICAgICAqICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdob21lJyxcbiAgICAgKiAgICAgICAgICAgICBjb21wb25lbnRWZXJzaW9uOiAnMS4wJyxcbiAgICAgKiAgICAgICAgICAgICBhbGxvd2VkOiB0cnVlLFxuICAgICAqICAgICAgICAgICAgIHJlamVjdGlvbkNvZGU6ICcnXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHJlZ2lzdGVyVXNhZ2UoKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTdWNjZXNzZnVsbHkgcmVnaXN0ZXJlZCBjb21wb25lbnQgYXBwbGljYXRpb24nKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlZ2lzdGVyVXNhZ2UoeyBkYXRhLCB0eXBlIH0pIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3JlZ2lzdGVyLXVzYWdlJywgeyBkYXRhLCB0eXBlIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggYWxsIHByaW50ZXJzIG9mIHRoZSBjYWxsZXIgYW5kIG5vdCBhbGwgdGhlIHByaW50ZXJzIG9uIHRoZSBkZXNrdG9wLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5TeXN0ZW0uZ2V0UHJpbnRlcnMoKVxuICAgICAqICAgICAudGhlbigocHJpbnRlcnMpID0+IHtcbiAgICAgKiAgICAgICAgIHByaW50ZXJzLmZvckVhY2goKHByaW50ZXIpID0+IHtcbiAgICAgKiAgICAgICAgICAgICBpZiAocHJpbnRlci5pc0RlZmF1bHQpIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocHJpbnRlcik7XG4gICAgICogICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgfSk7XG4gICAgICogICAgIH0pXG4gICAgICogICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRQcmludGVycygpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLWdldC1wcmludGVycycpO1xuICAgICAgICByZXR1cm4gcGF5bG9hZC5kYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIFByb2Nlc3MgTG9nZ2luZyB2YWx1ZXM6IHBlcmlvZGljIGludGVydmFsIGFuZCBvdXRsaWVyIGRldGVjdGlvbiBlbnRyaWVzIGFuZCBpbnRlcnZhbC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBQcm9jZXNzIExvZ2dpbmcgdXBkYXRhYmxlIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXaGVuIGVuYWJsaW5nIHZlcmJvc2UgbW9kZSwgYWRkaXRpb25hbCBwcm9jZXNzIGluZm9ybWF0aW9uIGlzIGxvZ2dlZCB0byB0aGUgZGVidWcubG9nOlxuICAgICAqXG4gICAgICogMS4gUGVyaW9kaWNhbGx5IHByb2Nlc3MgdXNhZ2UgKG1lbW9yeSwgY3B1LCBldGMpIHdpbGwgYmUgbG9nZ2VkIGZvciBlYWNoIFBJRCBhbG9uZyB3aXRoIHRoZSB3aW5kb3dzLCB2aWV3cyBhbmRcbiAgICAgKiBpZnJhbWVzIHRoYXQgYmVsb25nIHRvIHRoZW0uIFRoZSBkZWZhdWx0IGlzIGV2ZXJ5IDMwIHNlY29uZHMuIFVwZGF0YWJsZSBieSBwYXNzaW5nIHRoZSBpbnRlcnZhbCBvcHRpb24uXG4gICAgICogMi4gV2hlbiBXaW5kb3dzIGFuZCBWaWV3cyBhcmUgY3JlYXRlZCBvciBuYXZpZ2F0ZWQgdGhlIFBJRCB0aGV5IGJlbG9uZyB0byBhbmQgdGhlaXIgb3B0aW9ucyB3aWxsIGJlIGxvZ2dlZC5cbiAgICAgKiAzLiBXaGVuIFdpbmRvd3MgYW5kIFZpZXdzIGFyZSBkZXN0cm95ZWQgdGhlaXIgbGFzdCBrbm93biBwcm9jZXNzIHVzYWdlIHdpbGwgYmUgbG9nZ2VkLlxuICAgICAqIDQuIFdoZW5ldmVyIGFuIG91dGxpZXIgbWVtb3J5IHVzYWdlIGlzIGRldGVjdGVkIGl0IHdpbGwgYmUgbG9nZ2VkLiBCeSBkZWZhdWx0LCBvbiBhbiBpbnRlcnZhbCBvZiA1IHNlY29uZHMgd2Ugd2lsbFxuICAgICAqIGNvbGxlY3QgcHJvY2VzcyB1c2FnZSBmb3IgYWxsIFBJRHMgYW5kIHdoZW4gMTQ0IHN1Y2ggZW50cmllcyBhcmUgY29sbGVjdGVkLCB3ZSB3aWxsIHN0YXJ0IGFuYWx5emluZyB0aGUgZGF0YSBmb3IgYW55XG4gICAgICogcG9zc2libGUgb3V0bGllcnMgaW4gdGhlIGZvbGxvd2luZyBlbnRyaWVzLiBUaGUgaW50ZXJ2YWwgYW5kIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgc3RvcmVkIGluIHRoZSBydW5uaW5nIGJ1ZmZlclxuICAgICAqIGNhbiBiZSB1cGRhdGFibGUgYnkgcGFzc2luZyB0aGUgb3V0bGllckRldGVjdGlvbi5pbnRlcnZhbCBhbmQgb3V0bGllckRldGVjdGlvbi5lbnRyaWVzIG9wdGlvbnMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBhd2FpdCBmaW4uU3lzdGVtLnVwZGF0ZVByb2Nlc3NMb2dnaW5nT3B0aW9ucyh7XG4gICAgICogICAgIGludGVydmFsOiAxMCxcbiAgICAgKiAgICAgb3V0bGllckRldGVjdGlvbjoge1xuICAgICAqICAgICAgICAgaW50ZXJ2YWw6IDE1LFxuICAgICAqICAgICAgICAgZW50cmllczogMjAwXG4gICAgICogICAgIH1cbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVQcm9jZXNzTG9nZ2luZ09wdGlvbnMob3B0aW9ucykge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3lzdGVtLXVwZGF0ZS1wcm9jZXNzLWxvZ2dpbmctb3B0aW9ucycsIHsgb3B0aW9ucyB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBkb21haW4gc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLlxuICAgICAqIEluaXRpYWwgc2V0dGluZ3MgYXJlIGNvbmZpZ3VyZWQgd2l0aCB0aGUgZGVmYXVsdERvbWFpblNldHRpbmdzIGFwcGxpY2F0aW9uIG9wdGlvbiB2aWEgbWFuaWZlc3QuXG4gICAgICogRG9tYWluIHNldHRpbmdzIGNhbiBiZSBvdmVyd3JpdHRlbiBkdXJpbmcgcnVudGltZSB3aXRoIFN5c3RlbS5zZXREb21haW5TZXR0aW5ncy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZG9tYWluU2V0dGluZ3MgPSBhd2FpdCBmaW4uU3lzdGVtLmdldERvbWFpblNldHRpbmdzKCk7XG4gICAgICogLy8ge1xuICAgICAqIC8vICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJodHRwczovL29wZW5maW4uY29cIlxuICAgICAqIC8vICAgICAgICAgICAgIF0sXG4gICAgICogLy8gICAgICAgICAgICAgXCJvcHRpb25zXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJkb3dubG9hZFNldHRpbmdzXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgIFwicnVsZXNcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjxhbGxfdXJscz5cIlxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwicHJvbXB0XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgKiAvLyAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICB9XG4gICAgICogLy8gICAgIF1cbiAgICAgKiAvLyB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0RG9tYWluU2V0dGluZ3MoKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBkYXRhIH0gfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtZG9tYWluLXNldHRpbmdzJywgdGhpcy5pZGVudGl0eSk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBkb21haW4gc2V0dGluZ3MgZm9yIHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uLlxuICAgICAqIEBwYXJhbSBkb21haW5TZXR0aW5ncyAtIGRvbWFpbiBzZXR0aW5ncyBvYmplY3RcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZG9tYWluU2V0dGluZ3MgPSBhd2FpdCBmaW4uU3lzdGVtLmdldERvbWFpblNldHRpbmdzKCk7XG4gICAgICogLy8ge1xuICAgICAqIC8vICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICBcIm1hdGNoXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJodHRwczovL29wZW5maW4uY29cIlxuICAgICAqIC8vICAgICAgICAgICAgIF0sXG4gICAgICogLy8gICAgICAgICAgICAgXCJvcHRpb25zXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgXCJkb3dubG9hZFNldHRpbmdzXCI6IHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgIFwicnVsZXNcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjxhbGxfdXJscz5cIlxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImJlaGF2aW9yXCI6IFwicHJvbXB0XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogLy8gICAgICAgICAgICAgICAgIH1cbiAgICAgKiAvLyAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICB9XG4gICAgICogLy8gICAgIF1cbiAgICAgKiAvLyB9XG4gICAgICpcbiAgICAgKiAvLyBWYWxpZCBydWxlIGJlaGF2aW9ycyBhcmUgJ3Byb21wdCcgYW5kICduby1wcm9tcHQnXG4gICAgICogZG9tYWluU2V0dGluZ3MucnVsZXNbMF0ub3B0aW9ucy5kb3dubG9hZFNldHRpbmdzLnJ1bGVzWzBdLmJlaGF2aW9yID0gJ25vLXByb21wdCc7XG4gICAgICpcbiAgICAgKiBhd2FpdCBmaW4uU3lzdGVtLnNldERvbWFpblNldHRpbmdzKGRvbWFpblNldHRpbmdzKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IG5ld0RvbWFpblNldHRpbmdzID0gYXdhaXQgZmluLlN5c3RlbS5nZXREb21haW5TZXR0aW5ncygpO1xuICAgICAqIC8vIHtcbiAgICAgKiAvLyAgICAgXCJydWxlc1wiOiBbXG4gICAgICogLy8gICAgICAgICB7XG4gICAgICogLy8gICAgICAgICAgICAgXCJtYXRjaFwiOiBbXG4gICAgICogLy8gICAgICAgICAgICAgICAgIFwiaHR0cHM6Ly9vcGVuZmluLmNvXCJcbiAgICAgKiAvLyAgICAgICAgICAgICBdLFxuICAgICAqIC8vICAgICAgICAgICAgIFwib3B0aW9uc1wiOiB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgIFwiZG93bmxvYWRTZXR0aW5nc1wiOiB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICBcInJ1bGVzXCI6IFtcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibWF0Y2hcIjogW1xuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCI8YWxsX3VybHM+XCJcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgKiAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJiZWhhdmlvclwiOiBcIm5vLXByb21wdFwiXG4gICAgICogLy8gICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAqIC8vICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAqIC8vICAgICAgICAgICAgICAgICB9XG4gICAgICogLy8gICAgICAgICAgICAgfVxuICAgICAqIC8vICAgICAgICAgfVxuICAgICAqIC8vICAgICBdXG4gICAgICogLy8gfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHNldERvbWFpblNldHRpbmdzKGRvbWFpblNldHRpbmdzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZXQtZG9tYWluLXNldHRpbmdzJywgeyBkb21haW5TZXR0aW5ncywgLi4udGhpcy5pZGVudGl0eSB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0ZW1wdHMgdG8gaW5zdGFsbCBhbmQgZW5hYmxlIGV4dGVuc2lvbnMgZm9yIHRoZSBzZWN1cml0eSByZWFsbS4gIFVzZXJzIG1heSB3YW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbiBpbiByZXNwb25zZVxuICAgICAqIHRvIGFuIGBleHRlbnNpb25zLWluc3RhbGwtZmFpbGVkYCBldmVudC4gIE9ubHkgZXh0ZW5zaW9ucyBhbGxvd2VkIGJ5IGV2ZXJ5IGFwcGxpY2F0aW9uIG9uIHRoZSBjdXJyZW50IHNlY3VyaXR5IHJlYWxtXG4gICAgICogd2lsbCBiZSBpbnN0YWxsZWQvZW5hYmxlZC5cbiAgICAgKi9cbiAgICBhc3luYyByZWZyZXNoRXh0ZW5zaW9ucygpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbigncmVmcmVzaC1leHRlbnNpb25zJyk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGN1cnJlbnRseS1pbnN0YWxsZWRcbiAgICAgKi9cbiAgICBhc3luYyBnZXRJbnN0YWxsZWRFeHRlbnNpb25zKCkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtaW5zdGFsbGVkLWV4dGVuc2lvbnMnKTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG59XG5zeXN0ZW0uU3lzdGVtID0gU3lzdGVtO1xuXG52YXIgaW50ZXJhcHBidXMgPSB7fTtcblxudmFyIHJlZkNvdW50ZXIgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlZkNvdW50ZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xucmVmQ291bnRlci5SZWZDb3VudGVyID0gdm9pZCAwO1xuY2xhc3MgUmVmQ291bnRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMudG9waWNSZWZNYXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIC8vIHJldHVybnMgdGhlIHJlZiBjb3VudCBhZnRlciBpbmNyZW1lbnRpbmdcbiAgICBpbmNSZWZDb3VudChrZXkpIHtcbiAgICAgICAgY29uc3QgcmVmQ291bnQgPSB0aGlzLnRvcGljUmVmTWFwLmdldChrZXkpO1xuICAgICAgICBsZXQgcmV0dXJuQ291bnQ7XG4gICAgICAgIGlmICghcmVmQ291bnQpIHtcbiAgICAgICAgICAgIHRoaXMudG9waWNSZWZNYXAuc2V0KGtleSwgMSk7XG4gICAgICAgICAgICByZXR1cm5Db3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWZDb3VudCA9IHJlZkNvdW50ICsgMTtcbiAgICAgICAgICAgIHJldHVybkNvdW50ID0gbmV3UmVmQ291bnQ7XG4gICAgICAgICAgICB0aGlzLnRvcGljUmVmTWFwLnNldChrZXksIG5ld1JlZkNvdW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuQ291bnQ7XG4gICAgfVxuICAgIC8vIHJldHVybnMgdGhlIHJlZiBjb3VudCBhZnRlciBkZWNyZW1lbnRpbmcsIG9yIC0xIGlmIHRoZSBrZXkgYWxyZWFkeSBoYWQgbm8gcmVmZXJlbmNlc1xuICAgIGRlY1JlZkNvdW50KGtleSkge1xuICAgICAgICBjb25zdCByZWZDb3VudCA9IHRoaXMudG9waWNSZWZNYXAuZ2V0KGtleSk7XG4gICAgICAgIGxldCByZXR1cm5Db3VudDtcbiAgICAgICAgaWYgKHJlZkNvdW50KSB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWZDb3VudCA9IHJlZkNvdW50IC0gMTtcbiAgICAgICAgICAgIHRoaXMudG9waWNSZWZNYXAuc2V0KGtleSwgbmV3UmVmQ291bnQpO1xuICAgICAgICAgICAgcmV0dXJuQ291bnQgPSBuZXdSZWZDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybkNvdW50ID0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldHVybkNvdW50O1xuICAgIH1cbiAgICAvLyBFeGVjdXRlIGZpcnN0QWN0aW9uIGlmIGl0IGlzIHRoZSBmaXJzdCBzdWNoIHJlZiwgZWxzZSBleGVjdXRlIG5vbkZpcnN0QWN0aW9uLlxuICAgIC8vIEluIGVpdGhlciBjYXNlIHRoZSByZXR1cm4gdmFsdWUgaXMgdGhhdCBvZiB0aGUgYWN0aW9uIGV4ZWN1dGVkXG4gICAgYWN0T25GaXJzdChrZXksIGZpcnN0QWN0aW9uLCBub25GaXJzdEFjdGlvbikge1xuICAgICAgICBjb25zdCBudW1SZWZzID0gdGhpcy5pbmNSZWZDb3VudChrZXkpO1xuICAgICAgICBjb25zdCBpc0ZpcnN0UmVmID0gbnVtUmVmcyA9PT0gMTtcbiAgICAgICAgcmV0dXJuIGlzRmlyc3RSZWYgPyBmaXJzdEFjdGlvbigpIDogbm9uRmlyc3RBY3Rpb24oKTtcbiAgICB9XG4gICAgLy8gRXhlY3V0ZSBsYXN0QWN0aW9uIGlmIGl0IGlzIHRoZSBmaXJzdCBzdWNoIHJlZiwgZWxzZSBleGVjdXRlIG5vbkxhc3RBY3Rpb24uXG4gICAgLy8gSW4gZWl0aGVyIGNhc2UgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGF0IG9mIHRoZSBhY3Rpb24gZXhlY3V0ZWRcbiAgICBhY3RPbkxhc3Qoa2V5LCBsYXN0QWN0aW9uLCBub25MYXN0QWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IG51bVJlZnMgPSB0aGlzLmRlY1JlZkNvdW50KGtleSk7XG4gICAgICAgIGNvbnN0IGlzTGFzdFJlZiA9IG51bVJlZnMgPT09IDA7XG4gICAgICAgIHJldHVybiBpc0xhc3RSZWYgPyBsYXN0QWN0aW9uKCkgOiBub25MYXN0QWN0aW9uKCk7XG4gICAgfVxufVxucmVmQ291bnRlci5SZWZDb3VudGVyID0gUmVmQ291bnRlcjtcblxudmFyIGNoYW5uZWwkMSA9IHt9O1xuXG52YXIgY2xpZW50ID0ge307XG5cbnZhciBjaGFubmVsID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNoYW5uZWwuQ2hhbm5lbEJhc2UgPSBjaGFubmVsLlByb3RlY3RlZEl0ZW1zID0gdm9pZCAwO1xuY29uc3QgcmVzdWx0T3JQYXlsb2FkID0gKGZ1bmMpID0+IGFzeW5jICh0b3BpYywgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpID0+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCBmdW5jKHRvcGljLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSk7XG4gICAgcmV0dXJuIHJlcyA9PT0gdW5kZWZpbmVkID8gcGF5bG9hZCA6IHJlcztcbn07XG5jbGFzcyBQcm90ZWN0ZWRJdGVtcyB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY29uc3RydWN0b3JcbiAgICBjb25zdHJ1Y3Rvcihwcm92aWRlcklkZW50aXR5LCBjbG9zZSkge1xuICAgICAgICB0aGlzLnByb3ZpZGVySWRlbnRpdHkgPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICB0aGlzLmNsb3NlID0gY2xvc2U7XG4gICAgfVxufVxuY2hhbm5lbC5Qcm90ZWN0ZWRJdGVtcyA9IFByb3RlY3RlZEl0ZW1zO1xuY2xhc3MgQ2hhbm5lbEJhc2Uge1xuICAgIHN0YXRpYyBkZWZhdWx0QWN0aW9uKHRvcGljKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gYWN0aW9uIHJlZ2lzdGVyZWQgYXQgdGFyZ2V0IGZvciAke3RvcGljfWApO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBhc3luYyBwcm9jZXNzQWN0aW9uKHRvcGljLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbWFpbkFjdGlvbiA9IHRoaXMuc3Vic2NyaXB0aW9ucy5oYXModG9waWMpXG4gICAgICAgICAgICAgICAgPyB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KHRvcGljKVxuICAgICAgICAgICAgICAgIDogKGN1cnJlbnRQYXlsb2FkLCBpZCkgPT4gKHRoaXMuZGVmYXVsdEFjdGlvbiA/PyBDaGFubmVsQmFzZS5kZWZhdWx0QWN0aW9uKSh0b3BpYywgY3VycmVudFBheWxvYWQsIGlkKTtcbiAgICAgICAgICAgIGNvbnN0IHByZUFjdGlvblByb2Nlc3NlZCA9IHRoaXMucHJlQWN0aW9uID8gYXdhaXQgdGhpcy5wcmVBY3Rpb24odG9waWMsIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KSA6IHBheWxvYWQ7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb25Qcm9jZXNzZWQgPSBhd2FpdCBtYWluQWN0aW9uKHByZUFjdGlvblByb2Nlc3NlZCwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucG9zdEFjdGlvbiA/IGF3YWl0IHRoaXMucG9zdEFjdGlvbih0b3BpYywgYWN0aW9uUHJvY2Vzc2VkLCBzZW5kZXJJZGVudGl0eSkgOiBhY3Rpb25Qcm9jZXNzZWQ7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmVycm9yTWlkZGxld2FyZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yTWlkZGxld2FyZSh0b3BpYywgZSwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBtaWRkbGV3YXJlIHRoYXQgZmlyZXMgYmVmb3JlIHRoZSBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZnVuY1xuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIENoYW5uZWwgUHJvdmlkZXI6XG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBwcm92aWRlci5iZWZvcmVBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vVGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBiZWZvcmUgaGFuZGxpbmcgdGhlIGFjdGlvbi5cbiAgICAgKiAgICAgICAgIHBheWxvYWQucmVjZWl2ZWQgPSBEYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNsaWVudC5iZWZvcmVBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vVGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBiZWZvcmUgaGFuZGxpbmcgdGhlIGFjdGlvbi5cbiAgICAgKiAgICAgICAgIHBheWxvYWQucmVjZWl2ZWQgPSBEYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3Byb3ZpZGVyLWFjdGlvbicsIHsgbWVzc2FnZTogJ0hlbGxvIEZyb20gdGhlIGNsaWVudCcgfSk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKHByb3ZpZGVyUmVzcG9uc2UpO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYmVmb3JlQWN0aW9uKGZ1bmMpIHtcbiAgICAgICAgaWYgKHRoaXMucHJlQWN0aW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FscmVhZHkgcmVnaXN0ZXJlZCBiZWZvcmVBY3Rpb24gbWlkZGxld2FyZScpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJlQWN0aW9uID0gcmVzdWx0T3JQYXlsb2FkKGZ1bmMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBlcnJvciBoYW5kbGVyLiBUaGlzIGlzIGNhbGxlZCBiZWZvcmUgcmVzcG9uZGluZyBvbiBhbnkgZXJyb3IuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZnVuY1xuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAgICAgKiAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGVycm9yJyk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uRXJyb3IoKGFjdGlvbiwgZXJyb3IsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygndW5jYXVnaHQgRXhjZXB0aW9uIGluIGFjdGlvbjonLCBhY3Rpb24pO1xuICAgICAqICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAgICAgKiAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWN0aW9uIGVycm9yJyk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNsaWVudC5vbkVycm9yKChhY3Rpb24sIGVycm9yLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ3VuY2F1Z2h0IEV4Y2VwdGlvbiBpbiBhY3Rpb246JywgYWN0aW9uKTtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAqICAgICB9KTtcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIG9uRXJyb3IoZnVuYykge1xuICAgICAgICBpZiAodGhpcy5lcnJvck1pZGRsZXdhcmUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWxyZWFkeSByZWdpc3RlcmVkIGVycm9yIG1pZGRsZXdhcmUnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVycm9yTWlkZGxld2FyZSA9IGZ1bmM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVyIG1pZGRsZXdhcmUgdGhhdCBmaXJlcyBhZnRlciB0aGUgYWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZ1bmNcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIElmIHRoZSBhY3Rpb24gZG9lcyBub3QgcmV0dXJuIHRoZSBwYXlsb2FkLCB0aGVuIHRoZSBhZnRlckFjdGlvbiB3aWxsIG5vdCBoYXZlIGFjY2VzcyB0byB0aGUgcGF5bG9hZCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHByb3ZpZGVyLmFmdGVyQWN0aW9uKChhY3Rpb24sIHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICAvL3RoZSBwYXlsb2FkIGNhbiBiZSBhbHRlcmVkIGhlcmUgYWZ0ZXIgaGFuZGxpbmcgdGhlIGFjdGlvbiBidXQgYmVmb3JlIHNlbmRpbmcgYW4gYWNrbm93bGVkZ2VtZW50LlxuICAgICAqICAgICAgICAgcGF5bG9hZC5zZW50ID0gZGF0ZS5ub3coKTtcbiAgICAgKiAgICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBDaGFubmVsIENsaWVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IGNsaWVudC5yZWdpc3RlcignY2xpZW50LWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBjbGllbnQuYWZ0ZXJBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIC8vdGhlIHBheWxvYWQgY2FuIGJlIGFsdGVyZWQgaGVyZSBhZnRlciBoYW5kbGluZyB0aGUgYWN0aW9uIGJ1dCBiZWZvcmUgc2VuZGluZyBhbiBhY2tub3dsZWRnZW1lbnQuXG4gICAgICogICAgICAgICBwYXlsb2FkLnNlbnQgPSBkYXRlLm5vdygpO1xuICAgICAqICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhZnRlckFjdGlvbihmdW5jKSB7XG4gICAgICAgIGlmICh0aGlzLnBvc3RBY3Rpb24pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQWxyZWFkeSByZWdpc3RlcmVkIGFmdGVyQWN0aW9uIG1pZGRsZXdhcmUnKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBvc3RBY3Rpb24gPSByZXN1bHRPclBheWxvYWQoZnVuYyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBhY3Rpb24gYnkgYWN0aW9uIG5hbWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IHByb3ZpZGVyLnJlbW92ZSgncHJvdmlkZXItYWN0aW9uJyk7XG4gICAgICpcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHJlbW92ZShhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShhY3Rpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgYSBkZWZhdWx0IGFjdGlvbi4gVGhpcyBpcyB1c2VkIGFueSB0aW1lIGFuIGFjdGlvbiB0aGF0IGhhcyBub3QgYmVlbiByZWdpc3RlcmVkIGlzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5zZXREZWZhdWx0QWN0aW9uKChhY3Rpb24sIHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhgQ2xpZW50IHdpdGggaWRlbnRpdHkgJHtKU09OLnN0cmluZ2lmeShpZGVudGl0eSl9IGhhcyBhdHRlbXB0ZWQgdG8gZGlzcGF0Y2ggdW5yZWdpc3RlcmVkIGFjdGlvbjogJHthY3Rpb259LmApO1xuICAgICAqXG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIENoYW5uZWwgQ2xpZW50OlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50LnNldERlZmF1bHRBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGBQcm92aWRlciB3aXRoIGlkZW50aXR5ICR7SlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpfSBoYXMgYXR0ZW1wdGVkIHRvIGRpc3BhdGNoIHVucmVnaXN0ZXJlZCBhY3Rpb246ICR7YWN0aW9ufS5gKTtcbiAgICAgKlxuICAgICAqICAgICAgICAgcmV0dXJuIHtcbiAgICAgKiAgICAgICAgICAgICBlY2hvOiBwYXlsb2FkXG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICB9KTtcbiAgICAgKlxuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICogQHBhcmFtIGZ1bmNcbiAgICAgKi9cbiAgICBzZXREZWZhdWx0QWN0aW9uKGZ1bmMpIHtcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdEFjdGlvbikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZWZhdWx0IGFjdGlvbiBjYW4gb25seSBiZSBzZXQgb25jZScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0QWN0aW9uID0gZnVuYztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBhY3Rpb24gdG8gYmUgY2FsbGVkIGJ5IGRpc3BhdGNoaW5nIGZyb20gYW55IGNoYW5uZWxDbGllbnQgb3IgY2hhbm5lbFByb3ZpZGVyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRvcGljXG4gICAgICogQHBhcmFtIGxpc3RlbmVyXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgYmUgc2VudCBiYWNrIGFzIGFuIGFja25vd2xlZGdlbWVudCB0byB0aGUgb3JpZ2luYWwgY2FsbGVyLiBZb3UgY2FuIHRocm93IGFuXG4gICAgICogZXJyb3IgdG8gc2VuZCBhIG5lZ2F0aXZlLWFja25vd2xlZGdlbWVudCBhbmQgdGhlIGVycm9yIHdpbGwgcmVqZWN0IHRoZSBwcm9taXNlIHJldHVybmVkIHRvIHRoZSBzZW5kZXIgYnkgdGhlXG4gICAgICogZGlzcGF0Y2ggY2FsbC4gIE9uY2UgYSBsaXN0ZW5lciBpcyByZWdpc3RlcmVkIGZvciBhIHBhcnRpY3VsYXIgYWN0aW9uLCBpdCBzdGF5cyBpbiBwbGFjZSByZWNlaXZpbmcgYW5kIHJlc3BvbmRpbmdcbiAgICAgKiB0byBpbmNvbWluZyBtZXNzYWdlcyB1bnRpbCBpdCBpcyByZW1vdmVkLiAgVGhpcyBtZXNzYWdpbmcgbWVjaGFuaXNtIHdvcmtzIGV4YWN0bHkgdGhlIHNhbWUgd2hlbiBtZXNzYWdlcyBhcmVcbiAgICAgKiBkaXNwYXRjaGVkIGZyb20gdGhlIHByb3ZpZGVyIHRvIGEgY2xpZW50LiAgSG93ZXZlciwgdGhlIHByb3ZpZGVyIGhhcyBhbiBhZGRpdGlvbmFsIHB1Ymxpc2ggbWV0aG9kIHRoYXQgc2VuZHMgbWVzc2FnZXNcbiAgICAgKiB0byBhbGwgY29ubmVjdGVkIGNsaWVudHMuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIG11bHRpcGxlIGNsaWVudHMgY2FuIHNoYXJlIHRoZSBzYW1lIGBuYW1lYCBhbmQgYHV1aWRgLCBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGluZGl2aWR1YWwgY2xpZW50cyxcbiAgICAgKiB0aGUgYGlkZW50aXR5YCBhcmd1bWVudCBpbiBhIHByb3ZpZGVyJ3MgcmVnaXN0ZXJlZCBhY3Rpb24gY2FsbGJhY2sgY29udGFpbnMgYW4gYGVuZHBvaW50SWRgIHByb3BlcnR5LiBXaGVuIGRpc3BhdGNoaW5nXG4gICAgICogZnJvbSBhIHByb3ZpZGVyIHRvIGEgY2xpZW50LCB0aGUgYGVuZHBvaW50SWRgIHByb3BlcnR5IG11c3QgYmUgcHJvdmlkZWQgaW4gb3JkZXIgdG8gc2VuZCBhbiBhY3Rpb24gdG8gYSBzcGVjaWZpYyBjbGllbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogQ2hhbm5lbCBQcm92aWRlcjpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5yZWdpc3RlcigncHJvdmlkZXItYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdBY3Rpb24gZGlzcGF0Y2hlZCBieSBjbGllbnQ6ICcsIGlkZW50aXR5KTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgcGF5bG9hZCk7XG4gICAgICpcbiAgICAgKiAgICAgICAgcmV0dXJuIHsgZWNobzogcGF5bG9hZCB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBDaGFubmVsIENsaWVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIGF3YWl0IGNsaWVudC5yZWdpc3RlcignY2xpZW50LWFjdGlvbicsIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICBjb25zb2xlLmxvZygnQWN0aW9uIGRpc3BhdGNoZWQgYnkgY2xpZW50OiAnLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdQYXlsb2FkIHNlbnQgaW4gZGlzcGF0Y2g6ICcsIHBheWxvYWQpO1xuICAgICAqXG4gICAgICogICAgICAgIHJldHVybiB7IGVjaG86IHBheWxvYWQgfTtcbiAgICAgKiAgICB9KTtcbiAgICAgKiB9KSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHJlZ2lzdGVyKHRvcGljLCBsaXN0ZW5lcikge1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25zLmhhcyh0b3BpYykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3Vic2NyaXB0aW9uIGFscmVhZHkgcmVnaXN0ZXJlZCBmb3IgYWN0aW9uOiAke3RvcGljfS4gVW5zdWJzY3JpYmUgYmVmb3JlIGFkZGluZyBuZXcgc3Vic2NyaXB0aW9uYCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KHRvcGljLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmNoYW5uZWwuQ2hhbm5lbEJhc2UgPSBDaGFubmVsQmFzZTtcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkYSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgX0NoYW5uZWxDbGllbnRfY2xvc2U7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoY2xpZW50LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNsaWVudC5DaGFubmVsQ2xpZW50ID0gdm9pZCAwO1xuY29uc3QgY2hhbm5lbF8xJDEgPSBjaGFubmVsO1xuY29uc3QgY2hhbm5lbENsaWVudHNCeUVuZHBvaW50SWQgPSBuZXcgTWFwKCk7XG4vKipcbiAqIEluc3RhbmNlIGNyZWF0ZWQgdG8gZW5hYmxlIHVzZSBvZiBhIGNoYW5uZWwgYXMgYSBjbGllbnQuICBBbGxvd3MgZm9yIGNvbW11bmljYXRpb24gd2l0aCB0aGVcbiAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIgQ2hhbm5lbFByb3ZpZGVyfSBieSBpbnZva2luZyBhbiBhY3Rpb24gb24gdGhlXG4gKiBwcm92aWRlciB2aWEge0BsaW5rIENoYW5uZWxDbGllbnQjZGlzcGF0Y2ggZGlzcGF0Y2h9IGFuZCB0byBsaXN0ZW4gZm9yIGNvbW11bmljYXRpb25cbiAqIGZyb20gdGhlIHByb3ZpZGVyIGJ5IHJlZ2lzdGVyaW5nIGFuIGFjdGlvbiB2aWEge0BsaW5rIENoYW5uZWxDbGllbnQjcmVnaXN0ZXIgcmVnaXN0ZXJ9LlxuICpcbiAqICMjIyBTeW5jaHJvbm91cyBNZXRob2RzOlxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjb25EaXNjb25uZWN0aW9uIG9uRGlzY29ubmVjdGlvbihsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbENsaWVudCNyZWdpc3RlciByZWdpc3RlcihhY3Rpb24sIGxpc3RlbmVyKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I3JlbW92ZSByZW1vdmUoYWN0aW9uKX1cbiAqXG4gKiAjIyMgQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbENsaWVudCNkaXNjb25uZWN0IGRpc2Nvbm5lY3QoKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I2Rpc3BhdGNoIGRpc3BhdGNoKGFjdGlvbiwgcGF5bG9hZCl9XG4gKlxuICogIyMjIE1pZGRsZXdhcmU6XG4gKiBNaWRkbGV3YXJlIGZ1bmN0aW9ucyByZWNlaXZlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOiAoYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZCkuXG4gKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIG9uIGFzIHRoZSBwYXlsb2FkIGZyb20gYmVmb3JlQWN0aW9uLCB0byB0aGUgYWN0aW9uIGxpc3RlbmVyLCB0byBhZnRlckFjdGlvblxuICogdW5sZXNzIGl0IGlzIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB0aGUgb3JpZ2luYWwgcGF5bG9hZCBpcyB1c2VkLiAgTWlkZGxld2FyZSBjYW4gYmUgdXNlZCBmb3Igc2lkZSBlZmZlY3RzLlxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjc2V0RGVmYXVsdEFjdGlvbiBzZXREZWZhdWx0QWN0aW9uKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjb25FcnJvciBvbkVycm9yKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxDbGllbnQjYmVmb3JlQWN0aW9uIGJlZm9yZUFjdGlvbihtaWRkbGV3YXJlKX1cbiAqICAqIHtAbGluayBDaGFubmVsQ2xpZW50I2FmdGVyQWN0aW9uIGFmdGVyQWN0aW9uKG1pZGRsZXdhcmUpfVxuICovXG5jbGFzcyBDaGFubmVsQ2xpZW50IGV4dGVuZHMgY2hhbm5lbF8xJDEuQ2hhbm5lbEJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHN0YXRpYyBjbG9zZUNoYW5uZWxCeUVuZHBvaW50SWQoaWQpIHtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IGNoYW5uZWxDbGllbnRzQnlFbmRwb2ludElkLmdldChpZCk7XG4gICAgICAgIGlmIChjaGFubmVsKSB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGMoY2hhbm5lbCwgX0NoYW5uZWxDbGllbnRfY2xvc2UsIFwiZlwiKS5jYWxsKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqIGNsb3NlcyB0aGUgY29ycmVzcG9uZGluZyBjaGFubmVsIGFuZCBpbnZva2VzIHRoZSBkaXNjb25uZWN0IGxpc3RlbmVyIGlmIGFuIGV2ZW50IHBheWxvYWQgaXMgcGFzc2VkLlxuICAgICAqL1xuICAgIHN0YXRpYyBoYW5kbGVQcm92aWRlckRpc2Nvbm5lY3QoZXZlbnRQYXlsb2FkKSB7XG4gICAgICAgIGZvciAoY29uc3QgY2hhbm5lbENsaWVudCBvZiBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxDbGllbnQucHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQgPT09IGV2ZW50UGF5bG9hZC5jaGFubmVsSWQpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ2xpZW50LmRpc2Nvbm5lY3RMaXN0ZW5lcihldmVudFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyhjaGFubmVsQ2xpZW50LCBfQ2hhbm5lbENsaWVudF9jbG9zZSwgXCJmXCIpLmNhbGwoY2hhbm5lbENsaWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iocm91dGluZ0luZm8sIGNsb3NlLCBzdHJhdGVneSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBfQ2hhbm5lbENsaWVudF9wcm90ZWN0ZWRPYmouc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIF9DaGFubmVsQ2xpZW50X3N0cmF0ZWd5LnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICAvLyBuZWVkcyB0byBiZSBib3VuZDtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWN0aW9uID0gKGFjdGlvbiwgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpID0+IHN1cGVyLnByb2Nlc3NBY3Rpb24oYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZGVudGl0eSk7XG4gICAgICAgIF9DaGFubmVsQ2xpZW50X2Nsb3NlLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC5kZWxldGUodGhpcy5lbmRwb2ludElkKTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyh0aGlzLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgXCJmXCIpLmNsb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JGEodGhpcywgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBuZXcgY2hhbm5lbF8xJDEuUHJvdGVjdGVkSXRlbXMocm91dGluZ0luZm8sIGNsb3NlKSwgXCJmXCIpO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RMaXN0ZW5lciA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5lbmRwb2ludElkID0gcm91dGluZ0luZm8uZW5kcG9pbnRJZDtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCRhKHRoaXMsIF9DaGFubmVsQ2xpZW50X3N0cmF0ZWd5LCBzdHJhdGVneSwgXCJmXCIpO1xuICAgICAgICBjaGFubmVsQ2xpZW50c0J5RW5kcG9pbnRJZC5zZXQodGhpcy5lbmRwb2ludElkLCB0aGlzKTtcbiAgICAgICAgc3RyYXRlZ3kucmVjZWl2ZSh0aGlzLnByb2Nlc3NBY3Rpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBhIHJlYWQtb25seSBwcm92aWRlciBpZGVudGl0eVxuICAgICAqL1xuICAgIGdldCBwcm92aWRlcklkZW50aXR5KCkge1xuICAgICAgICBjb25zdCBwcm90ZWN0ZWRPYmogPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqLCBcImZcIik7XG4gICAgICAgIHJldHVybiBwcm90ZWN0ZWRPYmoucHJvdmlkZXJJZGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2ggdGhlIGdpdmVuIGFjdGlvbiB0byB0aGUgY2hhbm5lbCBwcm92aWRlci4gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSByZXNwb25zZSBmcm9tXG4gICAgICogdGhlIHByb3ZpZGVyIGZvciB0aGF0IGFjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBhY3Rpb25cbiAgICAgKiBAcGFyYW0gcGF5bG9hZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50LnJlZ2lzdGVyKCdjbGllbnQtYWN0aW9uJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZyhwYXlsb2FkLCBpZGVudGl0eSk7XG4gICAgICogICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgIGVjaG86IHBheWxvYWRcbiAgICAgKiAgICAgICAgIH07XG4gICAgICogICAgIH0pO1xuICAgICAqXG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyUmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3Byb3ZpZGVyLWFjdGlvbicsIHsgbWVzc2FnZTogJ0hlbGxvIEZyb20gdGhlIGNsaWVudCd9KTtcbiAgICAgKiAgICAgY29uc29sZS5sb2cocHJvdmlkZXJSZXNwb25zZSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBkaXNwYXRjaChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYyh0aGlzLCBfQ2hhbm5lbENsaWVudF9zdHJhdGVneSwgXCJmXCIpLmlzRW5kcG9pbnRDb25uZWN0ZWQodGhpcy5wcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfc3RyYXRlZ3ksIFwiZlwiKS5zZW5kKHRoaXMucHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQsIGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY2xpZW50IHlvdSBhcmUgdHJ5aW5nIHRvIGRpc3BhdGNoIGZyb20gaXMgZGlzY29ubmVjdGVkIGZyb20gdGhlIHRhcmdldCBwcm92aWRlci4nKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCBvbiBwcm92aWRlciBkaXNjb25uZWN0aW9uLiBJdCBpcyBwYXNzZWQgdGhlIGRpc2Nvbm5lY3Rpb24gZXZlbnQgb2YgdGhlXG4gICAgICogZGlzY29ubmVjdGluZyBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsaXN0ZW5lclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgY2xpZW50Lm9uRGlzY29ubmVjdGlvbihldnQgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2coJ1Byb3ZpZGVyIGRpc2Nvbm5lY3RlZCcsIGB1dWlkOiAke2V2dC51dWlkfSwgbmFtZTogJHtldnQubmFtZX1gKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0TGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcihwYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIHdoaWxlIGNhbGxpbmcgdGhlIG9uRGlzY29ubmVjdGlvbiBjYWxsYmFjazogJHtlcnIubWVzc2FnZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEaXNjb25uZWN0cyB0aGUgY2xpZW50IGZyb20gdGhlIGNoYW5uZWwuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdCgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBjbGllbnQuZGlzY29ubmVjdCgpO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZGlzY29ubmVjdCgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zZW5kRGlzY29ubmVjdEFjdGlvbigpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGModGhpcywgX0NoYW5uZWxDbGllbnRfY2xvc2UsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICBhc3luYyBzZW5kRGlzY29ubmVjdEFjdGlvbigpIHtcbiAgICAgICAgY29uc3QgcHJvdGVjdGVkT2JqID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRjKHRoaXMsIF9DaGFubmVsQ2xpZW50X3Byb3RlY3RlZE9iaiwgXCJmXCIpO1xuICAgICAgICBhd2FpdCBwcm90ZWN0ZWRPYmouY2xvc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICogV3JpdGluZyB0aGlzIGFzIGEgc3RhdGljIHRvIGtlZXAgY29kZSB0b2dldGhlciwgYnV0IGluIGVudmlyb25tZW50cyB3aXRoIGEgd2lyZSwgdGhpcyB3aWxsIGJlIERJJ2QgaW50byB0aGUgcHJvdGVjdGVkT2JqZWN0IGNsYXNzIGFzIGNsb3NlLlxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyB3aXJlQ2xvc2Uod2lyZSwgcHJvdmlkZXJJZGVudGl0eSwgZW5kcG9pbnRJZCkge1xuICAgICAgICBjb25zdCB7IGNoYW5uZWxOYW1lLCB1dWlkLCBuYW1lIH0gPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICBhd2FpdCB3aXJlLnNlbmRBY3Rpb24oJ2Rpc2Nvbm5lY3QtZnJvbS1jaGFubmVsJywge1xuICAgICAgICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICAgICAgICB1dWlkLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGVuZHBvaW50SWRcbiAgICAgICAgfSk7XG4gICAgfVxufVxuY2xpZW50LkNoYW5uZWxDbGllbnQgPSBDaGFubmVsQ2xpZW50O1xuX0NoYW5uZWxDbGllbnRfcHJvdGVjdGVkT2JqID0gbmV3IFdlYWtNYXAoKSwgX0NoYW5uZWxDbGllbnRfc3RyYXRlZ3kgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbENsaWVudF9jbG9zZSA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBjb25uZWN0aW9uTWFuYWdlciA9IHt9O1xuXG52YXIgZXhoYXVzdGl2ZSA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhoYXVzdGl2ZSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leGhhdXN0aXZlLmV4aGF1c3RpdmVDaGVjayA9IHZvaWQgMDtcbmZ1bmN0aW9uIGV4aGF1c3RpdmVDaGVjayh2YWx1ZSwgYWxsb3dlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdmFsdWU6ICR7dmFsdWV9JHthbGxvd2VkID8gYFxcbiBTdXBwb3J0ZWQgdmFsdWVzIGFyZTogJHthbGxvd2VkLmpvaW4oJycpfWAgOiAnJ31gKTtcbn1cbmV4aGF1c3RpdmUuZXhoYXVzdGl2ZUNoZWNrID0gZXhoYXVzdGl2ZUNoZWNrO1xuXG52YXIgc3RyYXRlZ3kkMyA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ5ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfQ2xhc3NpY1N0cmF0ZWd5X3dpcmUsIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCwgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQ7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoc3RyYXRlZ3kkMywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5zdHJhdGVneSQzLkNsYXNzaWNJbmZvID0gc3RyYXRlZ3kkMy5DbGFzc2ljU3RyYXRlZ3kgPSB2b2lkIDA7XG4vKlxuVGhpcyBpcyB1c2VkIHRvIGFic3RyYWN0IG91dCBpcGMgbWVzc2FnaW5nIGZyb20gdGhlIGNoYW5uZWxzIGltcGxlbWVudGF0aW9uLiBJdCBpcyBvbmx5IGNvbmNlcm5lZCB3aXRoIHNlbmRpbmcgbWVzc2FnZXMgYW5kIHJlZ2lzdHJhdGlvbiB3aXRoIHRoZSBNZXNzYWdlUmVjZWl2ZXJcbiovXG5jbGFzcyBDbGFzc2ljU3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIG1lc3NhZ2VSZWNlaXZlciwgZW5kcG9pbnRJZCwgLy8gUHJvdmlkZXIgZW5kcG9pbnRJZCBpcyBjaGFubmVsSWRcbiAgICBwcm92aWRlcklkZW50aXR5KSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVyID0gbWVzc2FnZVJlY2VpdmVyO1xuICAgICAgICB0aGlzLmVuZHBvaW50SWQgPSBlbmRwb2ludElkO1xuICAgICAgICB0aGlzLnByb3ZpZGVySWRlbnRpdHkgPSBwcm92aWRlcklkZW50aXR5O1xuICAgICAgICBfQ2xhc3NpY1N0cmF0ZWd5X3dpcmUuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8vIFN0b3JlIGZ1bGwgZW5kcG9pbnRJZGVudGl0eSBieSBlbmRwb2ludElkIG9mIGFsbCBrbm93biBlbmRwb2ludHMgZm9yIHRoaXMgc3RyYXRlZ3kgaW5zdGFuY2UuXG4gICAgICAgIC8vIChjbGllbnRzIHdpbGwgb25seSBoYXZlIDE6IHRoZSBwcm92aWRlciwgdGhlIHByb3ZpZGVyIHdpbGwgaGF2ZSBhbGwgY2xpZW50cylcbiAgICAgICAgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLnNldCh0aGlzLCBuZXcgTWFwKCkpO1xuICAgICAgICAvLyBTdG9yZSBhIHNldCBvZiBjYW5jZWxsYWJsZSBwcm9taXNlcyB0byBiZSBhYmxlIHRvIHJlamVjdCB0aGVtIHdoZW4gY2xpZW50XG4gICAgICAgIC8vIGNvbm5lY3Rpb24gcHJvYmxlbXMgb2NjdXJcbiAgICAgICAgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQuc2V0KHRoaXMsIG5ldyBNYXApO1xuICAgICAgICB0aGlzLnNlbmQgPSBhc3luYyAoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0byA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYih0aGlzLCBfQ2xhc3NpY1N0cmF0ZWd5X2VuZHBvaW50SWRlbnRpdHlNYXAsIFwiZlwiKS5nZXQoZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBpZiAoIXRvKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgbG9jYXRlIHJvdXRpbmcgaW5mbyBmb3IgZW5kcG9pbnQgJHtlbmRwb2ludElkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gYXMgY2FzdGluZyB0byBhbnkgYmVjYXVzZSB0eXBlc2NyaXB0IGNvbXBsYWlucy4gVGhlIGZvbGxvd2luZyBpcyBvbmx5IHJlbGV2YW50IGlmIHRoaXMgaXMgYSBsb2NhbGx5IHNldCBlbmRwb2ludElkIG9uIGEgQ2xpZW50SWRlbnRpdHkuXG4gICAgICAgICAgICAvLyBXZSBkZWxldGUgdGhlc2UgcHJvcGVydGllcyB0byBub3QgY2hhbmdlIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuICAgICAgICAgICAgY29uc3QgY2xlYW5JZCA9IHsgLi4udG8gfTtcbiAgICAgICAgICAgIGlmIChjbGVhbklkLmlzTG9jYWxFbmRwb2ludElkKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNsZWFuSWQuZW5kcG9pbnRJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBjbGVhbklkLmlzTG9jYWxFbmRwb2ludElkO1xuICAgICAgICAgICAgLy8gZ3JhYiB0aGUgcHJvbWlzZSBiZWZvcmUgYXdhaXRpbmcgaXQgdG8gc2F2ZSBpbiBvdXIgcGVuZGluZyBtZXNzYWdlcyBtYXBcbiAgICAgICAgICAgIGNvbnN0IHAgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV93aXJlLCBcImZcIilcbiAgICAgICAgICAgICAgICAuc2VuZEFjdGlvbignc2VuZC1jaGFubmVsLW1lc3NhZ2UnLCB7XG4gICAgICAgICAgICAgICAgLi4uY2xlYW5JZCxcbiAgICAgICAgICAgICAgICBwcm92aWRlcklkZW50aXR5OiB0aGlzLnByb3ZpZGVySWRlbnRpdHksXG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIHBheWxvYWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpPy5hZGQocCk7XG4gICAgICAgICAgICBjb25zdCByYXcgPSBhd2FpdCBwLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICAgIH0pLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGNsZWFuIHVwIHRoZSBwZW5kaW5nIHByb21pc2VcbiAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9wZW5kaW5nTWVzc2FnZXNCeUVuZHBvaW50SWQsIFwiZlwiKS5nZXQoZW5kcG9pbnRJZCk/LmRlbGV0ZShwKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJhdy5wYXlsb2FkLmRhdGEucmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNsb3NlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlUmVjZWl2ZXIucmVtb3ZlRW5kcG9pbnQodGhpcy5wcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCwgdGhpcy5lbmRwb2ludElkKTtcbiAgICAgICAgICAgIFsuLi5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikua2V5cygpXS5mb3JFYWNoKChpZCkgPT4gdGhpcy5jbG9zZUVuZHBvaW50KGlkKSk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDkodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBuZXcgTWFwKCksIFwiZlwiKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ5KHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfd2lyZSwgd2lyZSwgXCJmXCIpO1xuICAgIH1cbiAgICBvbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCBsaXN0ZW5lcikge1xuICAgICAgICAvLyBOZXZlciBmaXJlcyBmb3IgJ2NsYXNzaWMnLlxuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVyLmFkZEVuZHBvaW50KGxpc3RlbmVyLCB0aGlzLnByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkLCB0aGlzLmVuZHBvaW50SWQpO1xuICAgIH1cbiAgICBhc3luYyBjbG9zZUVuZHBvaW50KGVuZHBvaW50SWQpIHtcbiAgICAgICAgY29uc3QgaWQgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuZGVsZXRlKGVuZHBvaW50SWQpO1xuICAgICAgICBjb25zdCBwZW5kaW5nU2V0ID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkLCBcImZcIikuZ2V0KGVuZHBvaW50SWQpO1xuICAgICAgICBwZW5kaW5nU2V0Py5mb3JFYWNoKChwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IGBDaGFubmVsIGNvbm5lY3Rpb24gd2l0aCBpZGVudGl0eSB1dWlkOiAke2lkPy51dWlkfSAvIG5hbWU6ICR7aWQ/Lm5hbWV9IC8gZW5kcG9pbnRJZDogJHtlbmRwb2ludElkfSBubyBsb25nZXIgY29ubmVjdGVkLmA7XG4gICAgICAgICAgICBwLmNhbmNlbChuZXcgRXJyb3IoZXJyb3JNc2cpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkge1xuICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCRiKHRoaXMsIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCwgXCJmXCIpLmhhcyhlbmRwb2ludElkKTtcbiAgICB9XG4gICAgYWRkRW5kcG9pbnQoZW5kcG9pbnRJZCwgcGF5bG9hZCkge1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGIodGhpcywgX0NsYXNzaWNTdHJhdGVneV9lbmRwb2ludElkZW50aXR5TWFwLCBcImZcIikuc2V0KGVuZHBvaW50SWQsIHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eSk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYih0aGlzLCBfQ2xhc3NpY1N0cmF0ZWd5X3BlbmRpbmdNZXNzYWdlc0J5RW5kcG9pbnRJZCwgXCJmXCIpLnNldChlbmRwb2ludElkLCBuZXcgU2V0KCkpO1xuICAgIH1cbiAgICBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuICh0eXBlb2YgcGF5bG9hZD8uZW5kcG9pbnRJZGVudGl0eT8uZW5kcG9pbnRJZCA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgICAgIHR5cGVvZiBwYXlsb2FkPy5lbmRwb2ludElkZW50aXR5Py5jaGFubmVsSWQgPT09ICdzdHJpbmcnKTtcbiAgICB9XG59XG5zdHJhdGVneSQzLkNsYXNzaWNTdHJhdGVneSA9IENsYXNzaWNTdHJhdGVneTtcbl9DbGFzc2ljU3RyYXRlZ3lfd2lyZSA9IG5ldyBXZWFrTWFwKCksIF9DbGFzc2ljU3RyYXRlZ3lfZW5kcG9pbnRJZGVudGl0eU1hcCA9IG5ldyBXZWFrTWFwKCksIF9DbGFzc2ljU3RyYXRlZ3lfcGVuZGluZ01lc3NhZ2VzQnlFbmRwb2ludElkID0gbmV3IFdlYWtNYXAoKTtcbi8vIEFyYml0cmFyaWx5IHN0YXJ0aW5nIGF0IDUgdG8gbGVhdmUgdGhlIGRvb3Igb3BlbiB0byBiYWNrZmlsbGluZyBwcmUgZW5kcG9pbnRJZCBldGMuXG5zdHJhdGVneSQzLkNsYXNzaWNJbmZvID0geyB2ZXJzaW9uOiA1LCBtaW5pbXVtVmVyc2lvbjogMCwgdHlwZTogJ2NsYXNzaWMnIH07XG5cbnZhciBzdHJhdGVneSQyID0ge307XG5cbnZhciBlbmRwb2ludCA9IHt9O1xuXG52YXIgZXJyb3JzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlcnJvcnMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXJyb3JzLmVycm9yVG9QT0pPID0gdm9pZCAwO1xuZnVuY3Rpb24gZXJyb3JUb1BPSk8oZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFjazogZXJyb3Iuc3RhY2ssXG4gICAgICAgIG5hbWU6IGVycm9yLm5hbWUsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgIC8vIHN1cHBvcnQgdGhlIGNhc2Ugd2hlcmUgc3RhY2sgaXMgZW1wdHkgb3IgbWlzc2luZ1xuICAgICAgICB0b1N0cmluZzogKCkgPT4gZXJyb3Iuc3RhY2sgfHwgZXJyb3IudG9TdHJpbmcoKVxuICAgIH07XG59XG5lcnJvcnMuZXJyb3JUb1BPSk8gPSBlcnJvclRvUE9KTztcblxudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkOCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcbn07XG52YXIgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24sIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXI7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZW5kcG9pbnQsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZW5kcG9pbnQuUlRDRW5kcG9pbnQgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IGVycm9yc18xJDEgPSBlcnJvcnM7XG4vKlxuVGhpcyBoYW5kbGVzIHNlbmRpbmcgUlRDIG1lc3NhZ2VzIGJldHdlZW4gUlRDIGNvbm5lY3Rpb25zIG92ZXIgdGhlIHJlcXVlc3QgYW5kIHJlc3BvbnNlIGRhdGEgY2hhbm5lbHMuXG4qL1xuY2xhc3MgUlRDRW5kcG9pbnQge1xuICAgIHN0YXRpYyBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgaXNPYmplY3QgPSAoeCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB4ID09PSAnb2JqZWN0JyAmJiB4ICE9PSBudWxsO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAvLyBUT0RPIGluIGZhY3RvcnkgUFI6XG4gICAgICAgIC8vIHBheWxvYWQudHlwZSA9PT0gJ3J0YycgJiZcbiAgICAgICAgaXNPYmplY3QocGF5bG9hZCkgJiZcbiAgICAgICAgICAgIGlzT2JqZWN0KHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eSkgJiZcbiAgICAgICAgICAgIGlzT2JqZWN0KHBheWxvYWQucnRjKSAmJlxuICAgICAgICAgICAgdHlwZW9mIHBheWxvYWQuZW5kcG9pbnRJZGVudGl0eS5lbmRwb2ludElkID09PSAnc3RyaW5nJyk7XG4gICAgfVxuICAgIGNvbnN0cnVjdG9yKHsgcnRjLCBlbmRwb2ludElkZW50aXR5IH0pIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZU1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24uc2V0KHRoaXMsIG51bGwpO1xuICAgICAgICBfUlRDRW5kcG9pbnRfZGlzY29ubmVjdExpc3RlbmVyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnJ0Yy5ydGNDbGllbnQuY29ubmVjdGlvblN0YXRlICE9PSAnY29ubmVjdGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCRhKHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIFwiZlwiKSkge1xuICAgICAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X2Rpc2Nvbm5lY3RMaXN0ZW5lciwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNlbmQgPSBhc3luYyAoYWN0aW9uLCBwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlSWQgPSBgbWVzc2FnZS0ke01hdGgucmFuZG9tKCl9YDtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNwb25zZU1hcC5zZXQobWVzc2FnZUlkLCB7IHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVxdWVzdC5zZW5kKEpTT04uc3RyaW5naWZ5KHsgYWN0aW9uLCBwYXlsb2FkLCBtZXNzYWdlSWQgfSkpO1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2xvc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwLmZvckVhY2goKHJlc3BvbnNlKSA9PiByZXNwb25zZS5yZWplY3QoJ0Nvbm5lY3Rpb24gaGFzIGNsb3NlZC4nKSk7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVxdWVzdC5jbG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5jbG9zZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJ0YyA9IHJ0YztcbiAgICAgICAgdGhpcy5lbmRwb2ludElkZW50aXR5ID0gZW5kcG9pbnRJZGVudGl0eTtcbiAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIChlKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkYXRhIH0gPSBlO1xuICAgICAgICAgICAgaWYgKGUuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShlLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBtZXNzYWdlSWQsIHBheWxvYWQsIHN1Y2Nlc3MsIGVycm9yIH0gPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgICAgY29uc3QgeyByZXNvbHZlLCByZWplY3QgfSA9IHRoaXMucmVzcG9uc2VNYXAuZ2V0KG1lc3NhZ2VJZCkgPz8ge307XG4gICAgICAgICAgICBpZiAocmVzb2x2ZSAmJiByZWplY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc3BvbnNlTWFwLmRlbGV0ZShtZXNzYWdlSWQpO1xuICAgICAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocGF5bG9hZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDb3VsZCBub3QgZmluZCBpZCBpbiByZXNwb25zZU1hcC4nKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucnRjLmNoYW5uZWxzLnJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkYXRhIH0gPSBlO1xuICAgICAgICAgICAgaWYgKGUuZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShlLmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBtZXNzYWdlSWQsIGFjdGlvbiwgcGF5bG9hZCB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpLmNhbGwodGhpcywgYWN0aW9uLCBwYXlsb2FkLCBlbmRwb2ludElkZW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2Uuc2VuZChKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiByZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFJUQ0RhdGFDaGFubmVsIGlzIG9wZW4gYmVmb3JlIHNlbmRpbmcsIGVycm9yIGdldHMgc3dhbGxvd2VkIGhlcmUgaW4gdGhlIGNhc2Ugd2hlcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xpZW50IGRpc3BhdGNoZWQgdGhlbiBjbG9zZWQgb3IgZGlzY29ubmVjdGVkIGJlZm9yZSB0aGUgZGlzcGF0Y2ggcmVzb2x2ZXMuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJ0Yy5jaGFubmVscy5yZXNwb25zZS5yZWFkeVN0YXRlID09PSAnb3BlbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucnRjLmNoYW5uZWxzLnJlc3BvbnNlLnNlbmQoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogKDAsIGVycm9yc18xJDEuZXJyb3JUb1BPSk8pKGVycm9yKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFJUQ0RhdGFDaGFubmVsIGlzIG9wZW4gZm9yIHNhbWUgcmVhc29uIGFzIGNhdGNoIGJsb2NrIGFib3ZlLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2UucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydGMuY2hhbm5lbHMucmVzcG9uc2Uuc2VuZChKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiAnQ29ubmVjdGlvbiBub3QgcmVhZHkuJ1xuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucnRjLnJ0Y0NsaWVudC5hZGRFdmVudExpc3RlbmVyKCdjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCB0aGlzLmNvbm5lY3Rpb25TdGF0ZUNoYW5nZUhhbmRsZXIpO1xuICAgICAgICAvLyBEaXNjb25uZWN0IGlmIGRhdGEgY2hhbm5lbHMgY2xvc2UgdW5leHBlY3RlZGx5LCBlLmcuIGNhbiBoYXBwZW4gZHVlIHRvIG1lc3NhZ2Ugc2l6ZSA+IH4yNTVrQiAoUlRDUGVlckNvbm5lY3Rpb24uc2N0cC5tYXhNZXNzYWdlU2l6ZUxpbWl0OiAyNjIxNDQpXG4gICAgICAgIE9iamVjdC52YWx1ZXModGhpcy5ydGMuY2hhbm5lbHMpLmZvckVhY2goKGRhdGFjaGFubmVsKSA9PiB7XG4gICAgICAgICAgICBkYXRhY2hhbm5lbC5vbmNsb3NlID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICBbLi4udGhpcy5yZXNwb25zZU1hcC52YWx1ZXMoKV0uZm9yRWFjaCgocHJvbWlzZSkgPT4gcHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdSVENEYXRhQ2hhbm5lbCBjbG9zZWQgdW5leHBlY3RlZGx5LCB0aGlzIGlzIG1vc3QgY29tbW9ubHkgY2F1c2VkIGJ5IG1lc3NhZ2Ugc2l6ZS4gTm90ZTogUlRDIENoYW5uZWxzIGhhdmUgYSBtZXNzYWdlIHNpemUgbGltaXQgb2YgfjI1NWtCLicpKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JGEodGhpcywgX1JUQ0VuZHBvaW50X2Rpc2Nvbm5lY3RMaXN0ZW5lciwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfZGlzY29ubmVjdExpc3RlbmVyLCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgb25EaXNjb25uZWN0KGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCRhKHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIFwiZlwiKSkge1xuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ4KHRoaXMsIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIsIGxpc3RlbmVyLCBcImZcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JUQ0VuZHBvaW50IGRpc2Nvbm5lY3RMaXN0ZW5lciBjYW5ub3QgYmUgc2V0IHR3aWNlLicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlY2VpdmUobGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkYSh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBoYXZlIGFscmVhZHkgc2V0IGEgbGlzdGVuZXIgZm9yIHRoaXMgUlRDIEVuZHBvaW50LicpO1xuICAgICAgICB9XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkOCh0aGlzLCBfUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiwgbGlzdGVuZXIsIFwiZlwiKTtcbiAgICB9XG4gICAgZ2V0IGNvbm5lY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucnRjLnJ0Y0NsaWVudC5jb25uZWN0aW9uU3RhdGUgPT09ICdjb25uZWN0ZWQnO1xuICAgIH1cbn1cbmVuZHBvaW50LlJUQ0VuZHBvaW50ID0gUlRDRW5kcG9pbnQ7XG5fUlRDRW5kcG9pbnRfcHJvY2Vzc0FjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9SVENFbmRwb2ludF9kaXNjb25uZWN0TGlzdGVuZXIgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgc3RyYXRlZ3kkMSA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ3ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0cmF0ZWd5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3RyYXRlZ3kkMS5FbmRwb2ludFN0cmF0ZWd5ID0gdm9pZCAwO1xuY2xhc3MgRW5kcG9pbnRTdHJhdGVneSB7XG4gICAgLy8gTmVlZCB0byBwYXNzIGluIHZhbGlkYXRlIGVuZHBvaW50IHNlcGFyYXRlbHkgZnJvbSBjb25zdHJ1Y3RvciBiZWNhdXNlIHRzIGludGVyZmFjZXMgZG9uJ3QgZG8gd2VsbCB3aXRoIHN0YXRpYyBtZXRob2RzXG4gICAgY29uc3RydWN0b3IoRW5kcG9pbnRUeXBlLCB2YWxpZGF0ZUVuZHBvaW50LCBTdHJhdGVneU5hbWUpIHtcbiAgICAgICAgdGhpcy5FbmRwb2ludFR5cGUgPSBFbmRwb2ludFR5cGU7XG4gICAgICAgIHRoaXMuU3RyYXRlZ3lOYW1lID0gU3RyYXRlZ3lOYW1lO1xuICAgICAgICBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLnNldCh0aGlzLCBudWxsKTtcbiAgICAgICAgX0VuZHBvaW50U3RyYXRlZ3lfZW5kcG9pbnRNYXAuc2V0KHRoaXMsIG5ldyBNYXAoKSk7XG4gICAgICAgIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZC5zZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgIHRoaXMuc2VuZCA9IGFzeW5jIChlbmRwb2ludElkLCBhY3Rpb24sIHBheWxvYWQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEVuZHBvaW50QnlJZChlbmRwb2ludElkKS5zZW5kKGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY2xvc2UgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuZm9yRWFjaCgoZW5kcG9pbnQpID0+IGVuZHBvaW50LmNsb3NlKCkpO1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNyh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgbmV3IE1hcCgpLCBcImZcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDcodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkLCBmYWxzZSwgXCJmXCIpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmlzVmFsaWRFbmRwb2ludFBheWxvYWQgPSB2YWxpZGF0ZUVuZHBvaW50O1xuICAgIH1cbiAgICBvbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmdldEVuZHBvaW50QnlJZChlbmRwb2ludElkKS5vbkRpc2Nvbm5lY3QobGlzdGVuZXIpO1xuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDkodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdSBoYXZlIGFscmVhZHkgc2V0IGEgbGlzdGVuZXIgZm9yIHRoaXMgJHt0aGlzLlN0cmF0ZWd5TmFtZX0gU3RyYXRlZ3lgKTtcbiAgICAgICAgfVxuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDcodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiwgbGlzdGVuZXIsIFwiZlwiKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuZm9yRWFjaCgoZW5kcG9pbnQpID0+IGVuZHBvaW50LnJlY2VpdmUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSkpO1xuICAgIH1cbiAgICBnZXRFbmRwb2ludEJ5SWQoZW5kcG9pbnRJZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgXCJmXCIpLmdldChlbmRwb2ludElkKTtcbiAgICAgICAgaWYgKCFlbmRwb2ludCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBlbmRwb2ludCBpZCAke2VuZHBvaW50SWR9IGlzIG5vdCBjb25uZWN0ZWRgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZW5kcG9pbnQ7XG4gICAgfVxuICAgIGdldCBjb25uZWN0ZWQoKSB7XG4gICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDkodGhpcywgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkLCBcImZcIik7XG4gICAgfVxuICAgIGlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkge1xuICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuaGFzKGVuZHBvaW50SWQpO1xuICAgIH1cbiAgICBhZGRFbmRwb2ludChlbmRwb2ludElkLCBwYXlsb2FkKSB7XG4gICAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2Nvbm5lY3RlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYEFkZGluZyBlbmRwb2ludCB0byBkaXNjb25uZWN0ZWQgJHt0aGlzLlN0cmF0ZWd5TmFtZX0gU3RyYXRlZ3lgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjbGllbnRTdHJhdCA9IG5ldyB0aGlzLkVuZHBvaW50VHlwZShwYXlsb2FkKTtcbiAgICAgICAgaWYgKF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9wcm9jZXNzQWN0aW9uLCBcImZcIikpIHtcbiAgICAgICAgICAgIGNsaWVudFN0cmF0LnJlY2VpdmUoX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X3Byb2Nlc3NBY3Rpb24sIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ5KHRoaXMsIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwLCBcImZcIikuc2V0KGVuZHBvaW50SWQsIGNsaWVudFN0cmF0KTtcbiAgICB9XG4gICAgYXN5bmMgY2xvc2VFbmRwb2ludChlbmRwb2ludElkKSB7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOSh0aGlzLCBfRW5kcG9pbnRTdHJhdGVneV9lbmRwb2ludE1hcCwgXCJmXCIpLmRlbGV0ZShlbmRwb2ludElkKTtcbiAgICB9XG59XG5zdHJhdGVneSQxLkVuZHBvaW50U3RyYXRlZ3kgPSBFbmRwb2ludFN0cmF0ZWd5O1xuX0VuZHBvaW50U3RyYXRlZ3lfcHJvY2Vzc0FjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9FbmRwb2ludFN0cmF0ZWd5X2VuZHBvaW50TWFwID0gbmV3IFdlYWtNYXAoKSwgX0VuZHBvaW50U3RyYXRlZ3lfY29ubmVjdGVkID0gbmV3IFdlYWtNYXAoKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0cmF0ZWd5JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuc3RyYXRlZ3kkMi5SVENJbmZvID0gc3RyYXRlZ3kkMi5SVENTdHJhdGVneSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFycyAqL1xuLyogZXNsaW50LWRpc2FibGUgY2xhc3MtbWV0aG9kcy11c2UtdGhpcyAqL1xuY29uc3QgZW5kcG9pbnRfMSA9IGVuZHBvaW50O1xuY29uc3Qgc3RyYXRlZ3lfMSQxID0gc3RyYXRlZ3kkMTtcbi8qXG5UaGlzIGlzIHVzZWQgdG8gYWJzdHJhY3Qgb3V0IHJ0YyBtZXNzYWdpbmcgZnJvbSB0aGUgY2hhbm5lbHMgaW1wbGVtZW50YXRpb24gdXNpbmcgUlRDRW5kcG9pbnRzLlxuKi9cbmNsYXNzIFJUQ1N0cmF0ZWd5IGV4dGVuZHMgc3RyYXRlZ3lfMSQxLkVuZHBvaW50U3RyYXRlZ3kge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihlbmRwb2ludF8xLlJUQ0VuZHBvaW50LCBlbmRwb2ludF8xLlJUQ0VuZHBvaW50LmlzVmFsaWRFbmRwb2ludFBheWxvYWQsICdSVEMnKTtcbiAgICB9XG59XG5zdHJhdGVneSQyLlJUQ1N0cmF0ZWd5ID0gUlRDU3RyYXRlZ3k7XG5zdHJhdGVneSQyLlJUQ0luZm8gPSB7IHZlcnNpb246IDIsIG1pbmltdW1WZXJzaW9uOiAwLCB0eXBlOiAncnRjJyB9O1xuXG52YXIgaWNlTWFuYWdlciA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoaWNlTWFuYWdlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5pY2VNYW5hZ2VyLlJUQ0lDRU1hbmFnZXIgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEkaCA9IGJhc2U7XG4vKlxuU2luZ2xldG9uIHRoYXQgZmFjaWxpdGF0ZXMgT2ZmZXIgYW5kIEFuc3dlciBleGNoYW5nZSByZXF1aXJlZCBmb3IgZXN0YWJsaXNoaW5nIFJUQyBjb25uZWN0aW9ucy5cbiovXG5jbGFzcyBSVENJQ0VNYW5hZ2VyIGV4dGVuZHMgYmFzZV8xJGguRW1pdHRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKHdpcmUpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgJ2NoYW5uZWwnKTtcbiAgICAgICAgdGhpcy5lbnN1cmVDaGFubmVsT3BlbmVkID0gKGNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNoYW5uZWwucmVhZHlTdGF0ZSA9PT0gJ29wZW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2hhbm5lbC5yZWFkeVN0YXRlID09PSAnY29ubmVjdGluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29wZW4nLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWwuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1RoaXMgQ2hhbm5lbCBoYXMgYWxyZWFkeSBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UobGFiZWwsIHJ0Y0NsaWVudCkge1xuICAgICAgICBsZXQgcmVzb2x2ZXI7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgcmVzb2x2ZXIgPSByZXNvbHZlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3Blbkxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGUuY2hhbm5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdvcGVuJywgb3Blbkxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlcihlLmNoYW5uZWwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChlLmNoYW5uZWwubGFiZWwgPT09IGxhYmVsKSB7XG4gICAgICAgICAgICAgICAgZS5jaGFubmVsLmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBvcGVuTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHJ0Y0NsaWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdkYXRhY2hhbm5lbCcsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcnRjQ2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RhdGFjaGFubmVsJywgbGlzdGVuZXIpO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9XG4gICAgYXN5bmMgbGlzdGVuRm9yUHJvdmlkZXJJY2UocnRjQ29ubmVjdGlvbklkLCBsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKHRoaXMuY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSwgbGlzdGVuZXIsIHsgdGltZXN0YW1wOiBEYXRlLm5vdygpIH0pO1xuICAgIH1cbiAgICBhc3luYyByYWlzZVByb3ZpZGVySWNlKHJ0Y0Nvbm5lY3Rpb25JZCwgcGF5bG9hZCkge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuZW52aXJvbm1lbnQucmFpc2VFdmVudCh0aGlzLmNyZWF0ZVJvdXRlU3RyaW5nKHRoaXMuY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSksIHBheWxvYWQpO1xuICAgIH1cbiAgICBhc3luYyBsaXN0ZW5Gb3JDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKHRoaXMuY3JlYXRlQ2xpZW50RXZlbnROYW1lKHJ0Y0Nvbm5lY3Rpb25JZCksIGxpc3RlbmVyLCB7IHRpbWVzdGFtcDogRGF0ZS5ub3coKSB9KTtcbiAgICB9XG4gICAgYXN5bmMgcmFpc2VDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBwYXlsb2FkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5yYWlzZUV2ZW50KHRoaXMuY3JlYXRlUm91dGVTdHJpbmcodGhpcy5jcmVhdGVDbGllbnRFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSksIHBheWxvYWQpO1xuICAgIH1cbiAgICBjbGVhbnVwSWNlTGlzdGVuZXJzKHJ0Y0Nvbm5lY3Rpb25JZCkge1xuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyh0aGlzLmNyZWF0ZUNsaWVudEV2ZW50TmFtZShydGNDb25uZWN0aW9uSWQpKTtcbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnModGhpcy5jcmVhdGVQcm92aWRlckV2ZW50TmFtZShydGNDb25uZWN0aW9uSWQpKTtcbiAgICB9XG4gICAgY3JlYXRlQ2xpZW50RXZlbnROYW1lKHJ0Y0Nvbm5lY3Rpb25JZCkge1xuICAgICAgICByZXR1cm4gYGljZS1jbGllbnQtJHtydGNDb25uZWN0aW9uSWR9YDtcbiAgICB9XG4gICAgY3JlYXRlUHJvdmlkZXJFdmVudE5hbWUocnRjQ29ubmVjdGlvbklkKSB7XG4gICAgICAgIHJldHVybiBgaWNlLXByb3ZpZGVyLSR7cnRjQ29ubmVjdGlvbklkfWA7XG4gICAgfVxuICAgIGNyZWF0ZVJvdXRlU3RyaW5nKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGBjaGFubmVsLyR7bmFtZX1gO1xuICAgIH1cbiAgICBjcmVhdGVSdGNQZWVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LmdldFJ0Y1BlZXIoKTtcbiAgICB9XG4gICAgYXN5bmMgc3RhcnRDbGllbnRPZmZlcigpIHtcbiAgICAgICAgLy8gVE9ETyByZXBsYWNlIHdpdGggcmVhbCBndWlkLlxuICAgICAgICBjb25zdCBydGNDb25uZWN0aW9uSWQgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IHJ0Y0NsaWVudCA9IHRoaXMuY3JlYXRlUnRjUGVlcigpO1xuICAgICAgICBydGNDbGllbnQuYWRkRXZlbnRMaXN0ZW5lcignaWNlY2FuZGlkYXRlJywgYXN5bmMgKGUpID0+IHtcbiAgICAgICAgICAgIGlmIChlLmNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmFpc2VDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCB7IGNhbmRpZGF0ZTogZS5jYW5kaWRhdGU/LnRvSlNPTigpIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5saXN0ZW5Gb3JQcm92aWRlckljZShydGNDb25uZWN0aW9uSWQsIGFzeW5jIChwYXlsb2FkKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBydGNDbGllbnQuYWRkSWNlQ2FuZGlkYXRlKHBheWxvYWQuY2FuZGlkYXRlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0ge1xuICAgICAgICAgICAgcmVxdWVzdDogcnRjQ2xpZW50LmNyZWF0ZURhdGFDaGFubmVsKCdyZXF1ZXN0JyksXG4gICAgICAgICAgICByZXNwb25zZTogcnRjQ2xpZW50LmNyZWF0ZURhdGFDaGFubmVsKCdyZXNwb25zZScpXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG9mZmVyID0gYXdhaXQgcnRjQ2xpZW50LmNyZWF0ZU9mZmVyKCk7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKTtcbiAgICAgICAgY29uc3QgY2hhbm5lbHNPcGVuZWQgPSBQcm9taXNlLmFsbChbY2hhbm5lbHMucmVxdWVzdCwgY2hhbm5lbHMucmVzcG9uc2VdLm1hcCh0aGlzLmVuc3VyZUNoYW5uZWxPcGVuZWQpKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiB7IHJ0Y0NsaWVudCwgY2hhbm5lbHMsIG9mZmVyLCBydGNDb25uZWN0aW9uSWQsIGNoYW5uZWxzT3BlbmVkIH07XG4gICAgfVxuICAgIGFzeW5jIGZpbmlzaENsaWVudE9mZmVyKHJ0Y0NsaWVudCwgYW5zd2VyLCBwcm92aWRlclJlYWR5KSB7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRSZW1vdGVEZXNjcmlwdGlvbihhbnN3ZXIpO1xuICAgICAgICBhd2FpdCBwcm92aWRlclJlYWR5O1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlUHJvdmlkZXJBbnN3ZXIocnRjQ29ubmVjdGlvbklkLCBvZmZlcikge1xuICAgICAgICBjb25zdCBydGNDbGllbnQgPSB0aGlzLmNyZWF0ZVJ0Y1BlZXIoKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdENoYW5uZWxQcm9taXNlID0gUlRDSUNFTWFuYWdlci5jcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UoJ3JlcXVlc3QnLCBydGNDbGllbnQpO1xuICAgICAgICBjb25zdCByZXNwb25zZUNoYW5uZWxQcm9taXNlID0gUlRDSUNFTWFuYWdlci5jcmVhdGVEYXRhQ2hhbm5lbFByb21pc2UoJ3Jlc3BvbnNlJywgcnRjQ2xpZW50KTtcbiAgICAgICAgcnRjQ2xpZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2ljZWNhbmRpZGF0ZScsIGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICBpZiAoZS5jYW5kaWRhdGUpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJhaXNlUHJvdmlkZXJJY2UocnRjQ29ubmVjdGlvbklkLCB7IGNhbmRpZGF0ZTogZS5jYW5kaWRhdGU/LnRvSlNPTigpIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5saXN0ZW5Gb3JDbGllbnRJY2UocnRjQ29ubmVjdGlvbklkLCBhc3luYyAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgcnRjQ2xpZW50LmFkZEljZUNhbmRpZGF0ZShwYXlsb2FkLmNhbmRpZGF0ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBydGNDbGllbnQuc2V0UmVtb3RlRGVzY3JpcHRpb24ob2ZmZXIpO1xuICAgICAgICBjb25zdCBhbnN3ZXIgPSBhd2FpdCBydGNDbGllbnQuY3JlYXRlQW5zd2VyKCk7XG4gICAgICAgIGF3YWl0IHJ0Y0NsaWVudC5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcik7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gUHJvbWlzZS5hbGwoW3JlcXVlc3RDaGFubmVsUHJvbWlzZSwgcmVzcG9uc2VDaGFubmVsUHJvbWlzZV0pLnRoZW4oKFtyZXF1ZXN0LCByZXNwb25zZV0pID0+IHtcbiAgICAgICAgICAgIC8vIENsZWFuIHVwIGljZSBldmVudHMuXG4gICAgICAgICAgICB0aGlzLmNsZWFudXBJY2VMaXN0ZW5lcnMocnRjQ29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHJldHVybiB7IHJlcXVlc3QsIHJlc3BvbnNlIH07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcnRjQ2xpZW50LFxuICAgICAgICAgICAgYW5zd2VyLFxuICAgICAgICAgICAgY2hhbm5lbHNcbiAgICAgICAgfTtcbiAgICB9XG59XG5pY2VNYW5hZ2VyLlJUQ0lDRU1hbmFnZXIgPSBSVENJQ0VNYW5hZ2VyO1xuXG52YXIgcHJvdmlkZXIgPSB7fTtcblxudmFyIHJ1bnRpbWVWZXJzaW9uaW5nID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShydW50aW1lVmVyc2lvbmluZywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5ydW50aW1lVmVyc2lvbmluZy5ydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uID0gcnVudGltZVZlcnNpb25pbmcucGFyc2VSdW50aW1lVXVpZCA9IHJ1bnRpbWVWZXJzaW9uaW5nLm1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uID0gdm9pZCAwO1xuZnVuY3Rpb24gdk51bSh4KSB7XG4gICAgcmV0dXJuIFsuLi54LnNwbGl0KCcuJykucmV2ZXJzZSgpLmVudHJpZXMoKV0ucmVkdWNlKChwLCBbaSwgdl0pID0+IHAgKyArdiAqIDEwMDAwICoqIGksIDApO1xufVxuLypcbiAgQ29tcGFyZXMgcnVudGltZSB2ZXJzaW9ucyB0byBzZWUgaWYgdGhlIGN1cnJlbnQgcnVudGltZSBtZWV0cyB5b3VyIGRlc2lyZWQgbWluaW11bS5cbiovXG5mdW5jdGlvbiBtZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbihjdXJyZW50VmVyc2lvbiwgbWluVmVyc2lvbikge1xuICAgIGNvbnN0IGN1cnJlbnRWZXJzaW9uUGFyc2VkID0gdk51bShjdXJyZW50VmVyc2lvbik7XG4gICAgY29uc3QgbWluVmVyc2lvblBhcnNlZCA9IHZOdW0obWluVmVyc2lvbik7XG4gICAgcmV0dXJuIGN1cnJlbnRWZXJzaW9uUGFyc2VkID49IG1pblZlcnNpb25QYXJzZWQ7XG59XG5ydW50aW1lVmVyc2lvbmluZy5tZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbiA9IG1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uO1xuLy8gU3RyaXBzIHRoZSBwb3J0IGluZm8gZnJvbSB0aGUgcnVudGltZVV1aWQsIGxlYXZpbmcganVzdCB0aGUgcnVudGltZSB2ZXJzaW9uLlxuZnVuY3Rpb24gcGFyc2VSdW50aW1lVXVpZChydW50aW1lVXVpZCkge1xuICAgIHJldHVybiBydW50aW1lVXVpZC5zcGxpdCgnLycpWzBdO1xufVxucnVudGltZVZlcnNpb25pbmcucGFyc2VSdW50aW1lVXVpZCA9IHBhcnNlUnVudGltZVV1aWQ7XG5mdW5jdGlvbiBydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uKHJ1bnRpbWVVdWlkLCBtaW5WZXJzaW9uKSB7XG4gICAgY29uc3QgcnVudGltZVZlcnNpb24gPSBwYXJzZVJ1bnRpbWVVdWlkKHJ1bnRpbWVVdWlkKTtcbiAgICByZXR1cm4gbWVldHNNaW5pbXVtUnVudGltZVZlcnNpb24ocnVudGltZVZlcnNpb24sIG1pblZlcnNpb24pO1xufVxucnVudGltZVZlcnNpb25pbmcucnVudGltZVV1aWRNZWV0c01pbmltdW1SdW50aW1lVmVyc2lvbiA9IHJ1bnRpbWVVdWlkTWVldHNNaW5pbXVtUnVudGltZVZlcnNpb247XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDggPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIF9DaGFubmVsUHJvdmlkZXJfcHJvdGVjdGVkT2JqLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBfQ2hhbm5lbFByb3ZpZGVyX3JlbW92ZUVuZHBvaW50LCBfQ2hhbm5lbFByb3ZpZGVyX2Nsb3NlO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3ZpZGVyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnByb3ZpZGVyLkNoYW5uZWxQcm92aWRlciA9IHZvaWQgMDtcbmNvbnN0IGNoYW5uZWxfMSA9IGNoYW5uZWw7XG5jb25zdCBydW50aW1lVmVyc2lvbmluZ18xID0gcnVudGltZVZlcnNpb25pbmc7XG4vKipcbiAqIEluc3RhbmNlIGNyZWF0ZWQgdG8gZW5hYmxlIHVzZSBvZiBhIGNoYW5uZWwgYXMgYSBwcm92aWRlci4gQWxsb3dzIGZvciBjb21tdW5pY2F0aW9uIHdpdGggdGhlIHtAbGluayBDaGFubmVsQ2xpZW50IENoYW5uZWxDbGllbnRzfSBieSBpbnZva2luZyBhbiBhY3Rpb24gb25cbiAqIGEgc2luZ2xlIGNsaWVudCB2aWEge0BsaW5rIENoYW5uZWxQcm92aWRlciNkaXNwYXRjaCBkaXNwYXRjaH0gb3IgYWxsIGNsaWVudHMgdmlhIHtAbGluayBDaGFubmVsUHJvdmlkZXIjcHVibGlzaCBwdWJsaXNofVxuICogYW5kIHRvIGxpc3RlbiBmb3IgY29tbXVuaWNhdGlvbiBmcm9tIGNsaWVudHMgYnkgcmVnaXN0ZXJpbmcgYW4gYWN0aW9uIHZpYSB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI3JlZ2lzdGVyIHJlZ2lzdGVyfS5cbiAqXG4gKiAjIyMgU3luY2hyb25vdXMgTWV0aG9kczpcbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjb25Db25uZWN0aW9uIG9uQ29ubmVjdGlvbihsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI29uRGlzY29ubmVjdGlvbiBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNwdWJsaXNoIHB1Ymxpc2goYWN0aW9uLCBwYXlsb2FkKX1cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjcmVnaXN0ZXIgcmVnaXN0ZXIoYWN0aW9uLCBsaXN0ZW5lcil9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI3JlbW92ZSByZW1vdmUoYWN0aW9uKX1cbiAqXG4gKiAjIyMgQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2Rlc3Ryb3kgZGVzdHJveSgpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNkaXNwYXRjaCBkaXNwYXRjaCh0bywgYWN0aW9uLCBwYXlsb2FkKX1cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjZ2V0QWxsQ2xpZW50SW5mbyBnZXRBbGxDbGllbnRJbmZvKCl9XG4gKlxuICogIyMjIE1pZGRsZXdhcmU6XG4gKiBNaWRkbGV3YXJlIGZ1bmN0aW9ucyByZWNlaXZlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOiAoYWN0aW9uLCBwYXlsb2FkLCBzZW5kZXJJZCkuXG4gKiBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBtaWRkbGV3YXJlIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIG9uIGFzIHRoZSBwYXlsb2FkIGZyb20gYmVmb3JlQWN0aW9uLCB0byB0aGUgYWN0aW9uIGxpc3RlbmVyLCB0byBhZnRlckFjdGlvblxuICogdW5sZXNzIGl0IGlzIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB0aGUgbW9zdCByZWNlbnRseSBkZWZpbmVkIHBheWxvYWQgaXMgdXNlZC4gIE1pZGRsZXdhcmUgY2FuIGJlIHVzZWQgZm9yIHNpZGUgZWZmZWN0cy5cbiAqICAqIHtAbGluayBDaGFubmVsUHJvdmlkZXIjc2V0RGVmYXVsdEFjdGlvbiBzZXREZWZhdWx0QWN0aW9uKG1pZGRsZXdhcmUpfVxuICogICoge0BsaW5rIENoYW5uZWxQcm92aWRlciNvbkVycm9yIG9uRXJyb3IobWlkZGxld2FyZSl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2JlZm9yZUFjdGlvbiBiZWZvcmVBY3Rpb24obWlkZGxld2FyZSl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbFByb3ZpZGVyI2FmdGVyQWN0aW9uIGFmdGVyQWN0aW9uKG1pZGRsZXdhcmUpfVxuICovXG5jbGFzcyBDaGFubmVsUHJvdmlkZXIgZXh0ZW5kcyBjaGFubmVsXzEuQ2hhbm5lbEJhc2Uge1xuICAgIC8qKlxuICAgICAqIGEgcmVhZC1vbmx5IGFycmF5IGNvbnRhaW5pbmcgYWxsIHRoZSBpZGVudGl0aWVzIG9mIGNvbm5lY3RpbmcgY2xpZW50cy5cbiAgICAgKi9cbiAgICBnZXQgY29ubmVjdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiBbLi4uX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIFwiZlwiKV07XG4gICAgfVxuICAgIHN0YXRpYyBoYW5kbGVDbGllbnREaXNjb25uZWN0aW9uKGNoYW5uZWwsIHBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgcmVtb3ZlQnlJZCA9IGNoYW5uZWwuY29ubmVjdGlvbnMuZmluZCgoaWRlbnRpdHkpID0+IGlkZW50aXR5LmVuZHBvaW50SWQgPT09IHBheWxvYWQuZW5kcG9pbnRJZCk7XG4gICAgICAgIGlmIChyZW1vdmVCeUlkKSB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgoY2hhbm5lbCwgX0NoYW5uZWxQcm92aWRlcl9yZW1vdmVFbmRwb2ludCwgXCJmXCIpLmNhbGwoY2hhbm5lbCwgcmVtb3ZlQnlJZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtdWx0aXBsZVJlbW92ZXMgPSBjaGFubmVsLmNvbm5lY3Rpb25zLmZpbHRlcigoaWRlbnRpdHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaWRlbnRpdHkudXVpZCA9PT0gcGF5bG9hZC51dWlkICYmIGlkZW50aXR5Lm5hbWUgPT09IHBheWxvYWQubmFtZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbXVsdGlwbGVSZW1vdmVzLmZvckVhY2goX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KGNoYW5uZWwsIF9DaGFubmVsUHJvdmlkZXJfcmVtb3ZlRW5kcG9pbnQsIFwiZlwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2hhbm5lbC5kaXNjb25uZWN0TGlzdGVuZXIocGF5bG9hZCk7XG4gICAgfVxuICAgIHN0YXRpYyBzZXRQcm92aWRlclJlbW92YWwocHJvdmlkZXIsIHJlbW92ZSkge1xuICAgICAgICBDaGFubmVsUHJvdmlkZXIucmVtb3ZhbE1hcC5zZXQocHJvdmlkZXIsIHJlbW92ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHByb3ZpZGVySWRlbnRpdHksIGNsb3NlLCBzdHJhdGVneSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX2Nvbm5lY3Rpb25zLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iai5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneS5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0NoYW5uZWxQcm92aWRlcl9yZW1vdmVFbmRwb2ludC5zZXQodGhpcywgKGlkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdDb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjbGllbnRJZGVudGl0eSkgPT4gY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAhPT0gaWRlbnRpdHkuZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneSwgXCJmXCIpLmNsb3NlRW5kcG9pbnQoaWRlbnRpdHkuZW5kcG9pbnRJZCk7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYodGhpcywgX0NoYW5uZWxQcm92aWRlcl9jb25uZWN0aW9ucywgcmVtYWluaW5nQ29ubmVjdGlvbnMsIFwiZlwiKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIE11c3QgYmUgYm91bmQuXG4gICAgICAgIHRoaXMucHJvY2Vzc0FjdGlvbiA9IGFzeW5jIChhY3Rpb24sIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBpZiAoQ2hhbm5lbFByb3ZpZGVyLmNsaWVudElzTXVsdGlSdW50aW1lKHNlbmRlcklkZW50aXR5KSAmJlxuICAgICAgICAgICAgICAgICEoMCwgcnVudGltZVZlcnNpb25pbmdfMS5ydW50aW1lVXVpZE1lZXRzTWluaW11bVJ1bnRpbWVWZXJzaW9uKShzZW5kZXJJZGVudGl0eS5ydW50aW1lVXVpZCwgJzE4Ljg3LjU2LjAnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlTXVsdGlSdW50aW1lTGVnYWN5Q2xpZW50KHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tGb3JDbGllbnRDb25uZWN0aW9uKHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBlci5wcm9jZXNzQWN0aW9uKGFjdGlvbiwgcGF5bG9hZCwgc2VuZGVySWRlbnRpdHkpO1xuICAgICAgICB9O1xuICAgICAgICBfQ2hhbm5lbFByb3ZpZGVyX2Nsb3NlLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9zdHJhdGVneSwgXCJmXCIpLmNsb3NlKCk7XG4gICAgICAgICAgICBjb25zdCByZW1vdmUgPSBDaGFubmVsUHJvdmlkZXIucmVtb3ZhbE1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDYodGhpcywgX0NoYW5uZWxQcm92aWRlcl9wcm90ZWN0ZWRPYmosIG5ldyBjaGFubmVsXzEuUHJvdGVjdGVkSXRlbXMocHJvdmlkZXJJZGVudGl0eSwgY2xvc2UpLCBcImZcIik7XG4gICAgICAgIHRoaXMuY29ubmVjdExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RMaXN0ZW5lciA9ICgpID0+IHVuZGVmaW5lZDtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ2KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMsIFtdLCBcImZcIik7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNih0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBzdHJhdGVneSwgXCJmXCIpO1xuICAgICAgICBzdHJhdGVneS5yZWNlaXZlKHRoaXMucHJvY2Vzc0FjdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc3BhdGNoIGFuIGFjdGlvbiB0byBhIHNwZWNpZmllZCBjbGllbnQuIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIGV4ZWN1dGluZyB0aGF0IGFjdGlvbiBvbiB0aGUgY2xpZW50IHNpZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdG8gLSBJZGVudGl0eSBvZiB0aGUgdGFyZ2V0IGNsaWVudC5cbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gTmFtZSBvZiB0aGUgYWN0aW9uIHRvIGJlIGludm9rZWQgYnkgdGhlIGNsaWVudC5cbiAgICAgKiBAcGFyYW0gcGF5bG9hZCAtIFBheWxvYWQgdG8gYmUgc2VudCBhbG9uZyB3aXRoIHRoZSBhY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrc1xuICAgICAqXG4gICAgICogQmVjYXVzZSBtdWx0aXBsZSBjbGllbnRzIGNhbiBzaGFyZSB0aGUgc2FtZSBgbmFtZWAgYW5kIGB1dWlkYCwgd2hlbiBkaXNwYXRjaGluZyBmcm9tIGEgcHJvdmlkZXIgdG8gYSBjbGllbnQsXG4gICAgICogdGhlIGBpZGVudGl0eWAgeW91IHByb3ZpZGUgbXVzdCBpbmNsdWRlIHRoZSBjbGllbnQncyB1bmlxdWUgYGVuZHBvaW50SWRgIHByb3BlcnR5LiBUaGlzIGBlbmRwb2ludElkYCBpc1xuICAgICAqIHBhc3NlZCB0byB0aGUgcHJvdmlkZXIgaW4gYm90aCB0aGUgYFByb3ZpZGVyLm9uQ29ubmVjdGlvbmAgY2FsbGJhY2sgYW5kIGluIGFueSByZWdpc3RlcmVkIGFjdGlvbiBjYWxsYmFja3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIGFzeW5jIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIGF3YWl0IHByb3ZpZGVyLmRpc3BhdGNoKGlkZW50aXR5LCAnY2xpZW50LWFjdGlvbicsICdIZWxsbywgV29ybGQhJyk7XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGlzcGF0Y2godG8sIGFjdGlvbiwgcGF5bG9hZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludElkID0gdG8uZW5kcG9pbnRJZCA/PyB0aGlzLmdldEVuZHBvaW50SWRGb3JPcGVuRmluSWQodG8sIGFjdGlvbik7XG4gICAgICAgIGlmIChlbmRwb2ludElkICYmIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBcImZcIikuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3N0cmF0ZWd5LCBcImZcIikuc2VuZChlbmRwb2ludElkLCBhY3Rpb24sIHBheWxvYWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoYENsaWVudCBjb25uZWN0aW9uIHdpdGggaWRlbnRpdHkgdXVpZDogJHt0by51dWlkfSAvIG5hbWU6ICR7dG8ubmFtZX0gLyBlbmRwb2ludElkOiAke2VuZHBvaW50SWR9IG5vIGxvbmdlciBjb25uZWN0ZWQuYCkpO1xuICAgIH1cbiAgICBhc3luYyBwcm9jZXNzQ29ubmVjdGlvbihzZW5kZXJJZCwgcGF5bG9hZCkge1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9jb25uZWN0aW9ucywgXCJmXCIpLnB1c2goc2VuZGVySWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0TGlzdGVuZXIoc2VuZGVySWQsIHBheWxvYWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoIGFuIGFjdGlvbiBhbmQgcGF5bG9hZCB0byBldmVyeSBjb25uZWN0ZWQgY2xpZW50LlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBmb3IgZWFjaCBhY3Rpb24gKHNlZSBkaXNwYXRjaCkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uXG4gICAgICogQHBhcmFtIHBheWxvYWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIucmVnaXN0ZXIoJ3Byb3ZpZGVyLWFjdGlvbicsIGFzeW5jIChwYXlsb2FkLCBpZGVudGl0eSkgPT4ge1xuICAgICAqICAgICAgICAgY29uc29sZS5sb2cocGF5bG9hZCwgaWRlbnRpdHkpO1xuICAgICAqICAgICAgICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKHByb3ZpZGVyLnB1Ymxpc2goJ2NsaWVudC1hY3Rpb24nLCB7IG1lc3NhZ2U6ICdCcm9hZGNhc3QgZnJvbSBwcm92aWRlcid9KSk7XG4gICAgICogICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGlzaChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMubWFwKCh0bykgPT4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfc3RyYXRlZ3ksIFwiZlwiKS5zZW5kKHRvLmVuZHBvaW50SWQsIGFjdGlvbiwgcGF5bG9hZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhIGxpc3RlbmVyIHRoYXQgaXMgY2FsbGVkIG9uIGV2ZXJ5IG5ldyBjbGllbnQgY29ubmVjdGlvbi5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIEl0IGlzIHBhc3NlZCB0aGUgaWRlbnRpdHkgb2YgdGhlIGNvbm5lY3RpbmcgY2xpZW50IGFuZCBhIHBheWxvYWQgaWYgaXQgd2FzIHByb3ZpZGVkIHRvIENoYW5uZWwuY29ubmVjdC5cbiAgICAgKiBJZiB5b3Ugd2lzaCB0byByZWplY3QgdGhlIGNvbm5lY3Rpb24sIHRocm93IGFuIGVycm9yLiBCZSBzdXJlIHRvIHN5bmNocm9ub3VzbHkgcHJvdmlkZSBhbiBvbkNvbm5lY3Rpb24gdXBvbiByZWNlaXB0IG9mXG4gICAgICogdGhlIGNoYW5uZWxQcm92aWRlciB0byBlbnN1cmUgYWxsIHBvdGVudGlhbCBjbGllbnQgY29ubmVjdGlvbnMgYXJlIGNhdWdodCBieSB0aGUgbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBCZWNhdXNlIG11bHRpcGxlIGNsaWVudHMgY2FuIGV4aXN0IGF0IHRoZSBzYW1lIGBuYW1lYCBhbmQgYHV1aWRgLCBpbiBvcmRlciB0byBkaXN0aW5ndWlzaCBiZXR3ZWVuIGluZGl2aWR1YWwgY2xpZW50cyxcbiAgICAgKiB0aGUgYGlkZW50aXR5YCBhcmd1bWVudCBpbiBhIHByb3ZpZGVyJ3MgYG9uQ29ubmVjdGlvbmAgY2FsbGJhY2sgY29udGFpbnMgYW4gYGVuZHBvaW50SWRgIHByb3BlcnR5LiBXaGVuIGRpc3BhdGNoaW5nIGZyb20gYVxuICAgICAqIHByb3ZpZGVyIHRvIGEgY2xpZW50LCB0aGUgYGVuZHBvaW50SWRgIHByb3BlcnR5IG11c3QgYmUgcHJvdmlkZWQgaW4gb3JkZXIgdG8gc2VuZCBhbiBhY3Rpb24gdG8gYSBzcGVjaWZpYyBjbGllbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uQ29ubmVjdGlvbihpZGVudGl0eSA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGNvbm5lY3RlZCcsIGlkZW50aXR5KTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFJlamVjdCBjb25uZWN0aW9uOlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCdjaGFubmVsTmFtZScpO1xuICAgICAqXG4gICAgICogICAgIHByb3ZpZGVyLm9uQ29ubmVjdGlvbihpZGVudGl0eSA9PiB7XG4gICAgICogICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gUmVqZWN0ZWQnKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBvbkNvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0TGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCBvbiBjbGllbnQgZGlzY29ubmVjdGlvbi4gSXQgaXMgcGFzc2VkIHRoZSBkaXNjb25uZWN0aW9uIGV2ZW50IG9mIHRoZSBkaXNjb25uZWN0aW5nXG4gICAgICogY2xpZW50LlxuICAgICAqXG4gICAgICogQHBhcmFtIGxpc3RlbmVyXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAoYXN5bmMgKCk9PiB7XG4gICAgICogICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jcmVhdGUoJ2NoYW5uZWxOYW1lJyk7XG4gICAgICpcbiAgICAgKiAgICAgYXdhaXQgcHJvdmlkZXIub25EaXNjb25uZWN0aW9uKGV2dCA9PiB7XG4gICAgICogICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGRpc2Nvbm5lY3RlZCcsIGB1dWlkOiAke2V2dC51dWlkfSwgbmFtZTogJHtldnQubmFtZX1gKTtcbiAgICAgKiAgICAgfSk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBvbkRpc2Nvbm5lY3Rpb24obGlzdGVuZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0TGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzdHJveSB0aGUgY2hhbm5lbCwgcmFpc2VzIGBkaXNjb25uZWN0ZWRgIGV2ZW50cyBvbiBhbGwgY29ubmVjdGVkIGNoYW5uZWwgY2xpZW50cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIChhc3luYyAoKT0+IHtcbiAgICAgKiAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgICBhd2FpdCBwcm92aWRlci5kZXN0cm95KCk7XG4gICAgICogfSkoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBkZXN0cm95KCkge1xuICAgICAgICBjb25zdCBwcm90ZWN0ZWRPYmogPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDgodGhpcywgX0NoYW5uZWxQcm92aWRlcl9wcm90ZWN0ZWRPYmosIFwiZlwiKTtcbiAgICAgICAgcHJvdGVjdGVkT2JqLnByb3ZpZGVySWRlbnRpdHk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkNih0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX2Nvbm5lY3Rpb25zLCBbXSwgXCJmXCIpO1xuICAgICAgICBhd2FpdCBwcm90ZWN0ZWRPYmouY2xvc2UoKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ4KHRoaXMsIF9DaGFubmVsUHJvdmlkZXJfY2xvc2UsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IHdpdGggaW5mbyBvbiBldmVyeSBDbGllbnQgY29ubmVjdGVkIHRvIHRoZSBQcm92aWRlclxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnb3BlbmZpbicpO1xuICAgICAqIGNvbnN0IGNsaWVudCA9IGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdCgnb3BlbmZpbicpO1xuICAgICAqIGNvbnN0IGNsaWVudEluZm8gPSBhd2FpdCBwcm92aWRlci5nZXRBbGxDbGllbnRJbmZvKCk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhjbGllbnRJbmZvKTtcbiAgICAgKlxuICAgICAqIC8vIFtcbiAgICAgKiAvLyAgICB7XG4gICAgICogLy8gICAgICAgIFwidXVpZFwiOiBcIm9wZW5maW5cIixcbiAgICAgKiAvLyAgICAgICAgXCJuYW1lXCI6IFwib3BlbmZpbi12aWV3XCIsXG4gICAgICogLy8gICAgICAgIFwiZW5kcG9pbnRJZFwiOiBcIjZkNGM3Y2E4LTRhNzQtNDYzNC04N2Y4LTc2MDU1ODIyOTYxM1wiLFxuICAgICAqIC8vICAgICAgICBcImVudGl0eVR5cGVcIjogXCJ2aWV3XCIsXG4gICAgICogLy8gICAgICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9vcGVuZmluLmNvXCJcbiAgICAgKiAvLyAgICB9LFxuICAgICAqIC8vICAgIHtcbiAgICAgKiAvLyAgICAgICAgXCJ1dWlkXCI6IFwib3BlbmZpbjJcIixcbiAgICAgKiAvLyAgICAgICAgXCJuYW1lXCI6IFwib3BlbmZpbi12aWV3MlwiLFxuICAgICAqIC8vICAgICAgICBcImVuZHBvaW50SWRcIjogXCI0ejVkOGFiOS0yYjgxLTM2OTEtOTFleC0xNDIxNzkzODI1MTFcIixcbiAgICAgKiAvLyAgICAgICAgXCJlbnRpdHlUeXBlXCI6IFwidmlld1wiLFxuICAgICAqIC8vICAgICAgICBcInVybFwiOiBcImh0dHBzOi8vZXhhbXBsZS5jb21cIlxuICAgICAqIC8vICAgIH1cbiAgICAgKiAvL11cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGxDbGllbnRJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5tYXAoKGNsaWVudEluZm8pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSwgZW5kcG9pbnRJZCwgZW50aXR5VHlwZSwgY29ubmVjdGlvblVybCB9ID0gY2xpZW50SW5mbztcbiAgICAgICAgICAgIHJldHVybiB7IHV1aWQsIG5hbWUsIGVuZHBvaW50SWQsIGVudGl0eVR5cGUsIGNvbm5lY3Rpb25VcmwgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNoZWNrRm9yQ2xpZW50Q29ubmVjdGlvbihjbGllbnRJZGVudGl0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNDbGllbnRDb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoaXMgYWN0aW9uIHdhcyBzZW50IGZyb20gYSBjbGllbnQgdGhhdCBpcyBub3QgY29ubmVjdGVkIHRvIHRoZSBwcm92aWRlci5cbiAgICAgICAgICAgICAgICAgICAgQ2xpZW50IElkZW50aXR5OiB7dXVpZDogJHtjbGllbnRJZGVudGl0eS51dWlkfSwgbmFtZTogJHtjbGllbnRJZGVudGl0eS5uYW1lfSwgZW5kcG9pbnRJZDogJHtjbGllbnRJZGVudGl0eS5lbmRwb2ludElkfX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc0NsaWVudENvbm5lY3RlZChjbGllbnRJZGVudGl0eSkge1xuICAgICAgICBpZiAoQ2hhbm5lbFByb3ZpZGVyLmNsaWVudElkZW50aXR5SW5jbHVkZXNFbmRwb2ludElkKGNsaWVudElkZW50aXR5KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMuc29tZSgoaWRlbnRpdHkpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIC8vIE1pZ2h0IGJlIHJlZHVuZGFudCB0byBjaGVjayBmb3IgdXVpZCBhbmQgbmFtZSBoZXJlIGFmdGVyIHdlIGdldCBhbiBlbmRwb2ludElkIG1hdGNoLCBidXQganVzdCBpbiBjYXNlXG4gICAgICAgICAgICAgICAgaWRlbnRpdHkuZW5kcG9pbnRJZCA9PT0gY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAmJlxuICAgICAgICAgICAgICAgICAgICBpZGVudGl0eS51dWlkID09PSBjbGllbnRJZGVudGl0eS51dWlkICYmXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5Lm5hbWUgPT09IGNsaWVudElkZW50aXR5Lm5hbWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaXNMZWdhY3lDbGllbnRDb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpO1xuICAgIH1cbiAgICBpc0xlZ2FjeUNsaWVudENvbm5lY3RlZChjbGllbnRJZGVudGl0eSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9ucy5zb21lKChpZGVudGl0eSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGlkZW50aXR5LnV1aWQgPT09IGNsaWVudElkZW50aXR5LnV1aWQgJiYgaWRlbnRpdHkubmFtZSA9PT0gY2xpZW50SWRlbnRpdHkubmFtZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGhhbmRsZU11bHRpUnVudGltZUxlZ2FjeUNsaWVudChzZW5kZXJJZGVudGl0eSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNMZWdhY3lDbGllbnRDb25uZWN0ZWQoc2VuZGVySWRlbnRpdHkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoaXMgYWN0aW9uIHdhcyBzZW50IGZyb20gYSBjbGllbnQgdGhhdCBpcyBub3QgY29ubmVjdGVkIHRvIHRoZSBwcm92aWRlci4gQ2xpZW50IElkZW50aXR5OlxuICAgICAgICAgICAgICAgICAgICB7dXVpZDogJHtzZW5kZXJJZGVudGl0eS51dWlkfSwgbmFtZTogJHtzZW5kZXJJZGVudGl0eS5uYW1lfSwgZW5kcG9pbnRJZDogJHtzZW5kZXJJZGVudGl0eS5lbmRwb2ludElkfX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRFbmRwb2ludElkRm9yT3BlbkZpbklkKGNsaWVudElkZW50aXR5LCBhY3Rpb24pIHtcbiAgICAgICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjKSA9PiBjLm5hbWUgPT09IGNsaWVudElkZW50aXR5Lm5hbWUgJiYgYy51dWlkID09PSBjbGllbnRJZGVudGl0eS51dWlkKTtcbiAgICAgICAgaWYgKG1hdGNoaW5nQ29ubmVjdGlvbnMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb3RlY3RlZE9iaiA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkOCh0aGlzLCBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iaiwgXCJmXCIpO1xuICAgICAgICAgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSBjbGllbnRJZGVudGl0eTtcbiAgICAgICAgICAgIGNvbnN0IHByb3ZpZGVyVXVpZCA9IHByb3RlY3RlZE9iaj8ucHJvdmlkZXJJZGVudGl0eS51dWlkO1xuICAgICAgICAgICAgY29uc3QgcHJvdmlkZXJOYW1lID0gcHJvdGVjdGVkT2JqPy5wcm92aWRlcklkZW50aXR5Lm5hbWU7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKGBXQVJOSU5HOiBEaXNwYXRjaCBjYWxsIG1heSBoYXZlIHVuaW50ZW5kZWQgcmVzdWx0cy4gVGhlIFwidG9cIiBhcmd1bWVudCBvZiB5b3VyIGRpc3BhdGNoIGNhbGwgaXMgbWlzc2luZyB0aGVcbiAgICAgICAgICAgICAgICBcImVuZHBvaW50SWRcIiBwYXJhbWV0ZXIuIFRoZSBpZGVudGl0eSB5b3UgYXJlIGRpc3BhdGNoaW5nIHRvICh7dXVpZDogJHt1dWlkfSwgbmFtZTogJHtuYW1lfX0pXG4gICAgICAgICAgICAgICAgaGFzIG11bHRpcGxlIGNoYW5uZWxDbGllbnRzIGZvciB0aGlzIGNoYW5uZWwuIFlvdXIgZGlzcGF0Y2hlZCBhY3Rpb246ICgke2FjdGlvbn0pIGZyb20gdGhlIHByb3ZpZGVyOlxuICAgICAgICAgICAgICAgICh7dXVpZDogJHtwcm92aWRlclV1aWR9LCBuYW1lOiAke3Byb3ZpZGVyTmFtZX19KSB3aWxsIG9ubHkgYmUgcHJvY2Vzc2VkIGJ5IHRoZSBtb3N0IHJlY2VudGx5LWNyZWF0ZWQgY2xpZW50LmApO1xuICAgICAgICB9XG4gICAgICAgIC8vIFBvcCB0byByZXR1cm4gdGhlIG1vc3QgcmVjZW50bHkgY3JlYXRlZCBlbmRwb2ludElkLlxuICAgICAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9ucy5wb3AoKT8uZW5kcG9pbnRJZDtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBzdGF0aWMgY2xpZW50SWRlbnRpdHlJbmNsdWRlc0VuZHBvaW50SWQoc3Vic2NyaXB0aW9uSWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbklkZW50aXR5LmVuZHBvaW50SWQgIT09IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgICBzdGF0aWMgY2xpZW50SXNNdWx0aVJ1bnRpbWUoc3Vic2NyaXB0aW9uSWRlbnRpdHkpIHtcbiAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbklkZW50aXR5LnJ1bnRpbWVVdWlkICE9PSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHN0YXRpYyBhc3luYyB3aXJlQ2xvc2Uod2lyZSwgY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgYXdhaXQgd2lyZS5zZW5kQWN0aW9uKCdkZXN0cm95LWNoYW5uZWwnLCB7IGNoYW5uZWxOYW1lIH0pO1xuICAgIH1cbn1cbnByb3ZpZGVyLkNoYW5uZWxQcm92aWRlciA9IENoYW5uZWxQcm92aWRlcjtcbl9DaGFubmVsUHJvdmlkZXJfY29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbFByb3ZpZGVyX3Byb3RlY3RlZE9iaiA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsUHJvdmlkZXJfc3RyYXRlZ3kgPSBuZXcgV2Vha01hcCgpLCBfQ2hhbm5lbFByb3ZpZGVyX3JlbW92ZUVuZHBvaW50ID0gbmV3IFdlYWtNYXAoKSwgX0NoYW5uZWxQcm92aWRlcl9jbG9zZSA9IG5ldyBXZWFrTWFwKCk7XG4vLyBUaGUgZm9sbG93aW5nIGxpbmUgc2hvdWxkIGJlIGNoYW5nZWQgZm9sbG93aW5nIGEgdHlwZXNjcmlwdCB1cGRhdGUuXG4vLyBzdGF0aWMgI3JlbW92YWxNYXAgPSBuZXcgV2Vha01hcDxDaGFubmVsUHJvdmlkZXIsIEZ1bmN0aW9uPigpO1xuQ2hhbm5lbFByb3ZpZGVyLnJlbW92YWxNYXAgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgbWVzc2FnZVJlY2VpdmVyID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXNzYWdlUmVjZWl2ZXIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xubWVzc2FnZVJlY2VpdmVyLk1lc3NhZ2VSZWNlaXZlciA9IHZvaWQgMDtcbmNvbnN0IGNsaWVudF8xJDEgPSBjbGllbnQ7XG5jb25zdCBiYXNlXzEkZyA9IGJhc2U7XG4vKlxuVGhpcyBpcyBhIHNpbmdsZXRvbiAocGVyIGZpbiBvYmplY3QpIHRhc2tlZCB3aXRoIHJvdXRpbmcgbWVzc2FnZXMgY29taW5nIG9mZiB0aGUgaXBjIHRvIHRoZSBjb3JyZWN0IGVuZHBvaW50LlxuSXQgbmVlZHMgdG8gYmUgYSBzaW5nbGV0b24gYmVjYXVzZSB0aGVyZSBjYW4gb25seSBiZSBvbmUgcGVyIHdpcmUuIEl0IHRyYWNrcyBib3RoIGNsaWVudHMgYW5kIHByb3ZpZGVycycgcHJvY2Vzc0FjdGlvbiBwYXNzZWQgaW4gdmlhIHRoZSBzdHJhdGVneS5cbklmIGZ1bmN0aW9uYWxpdHkgaXMgbm90IGFib3V0IHJlY2VpdmluZyBtZXNzYWdlcywgaXQgZG9lcyBub3QgYmVsb25nIGhlcmUuXG4qL1xuY2xhc3MgTWVzc2FnZVJlY2VpdmVyIGV4dGVuZHMgYmFzZV8xJGcuQmFzZSB7XG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgdGhpcy5vbm1lc3NhZ2UgPSAobXNnKSA9PiB7XG4gICAgICAgICAgICBpZiAobXNnLmFjdGlvbiA9PT0gJ3Byb2Nlc3MtY2hhbm5lbC1tZXNzYWdlJykge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0NoYW5uZWxNZXNzYWdlKG1zZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW5kcG9pbnRNYXAgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkID0gbmV3IE1hcCgpO1xuICAgICAgICB3aXJlLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5vbm1lc3NhZ2UuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIGFzeW5jIHByb2Nlc3NDaGFubmVsTWVzc2FnZShtc2cpIHtcbiAgICAgICAgY29uc3QgeyBzZW5kZXJJZGVudGl0eSwgcHJvdmlkZXJJZGVudGl0eSwgYWN0aW9uLCBhY2tUb1NlbmRlciwgcGF5bG9hZCwgaW50ZW5kZWRUYXJnZXRJZGVudGl0eSB9ID0gbXNnLnBheWxvYWQ7XG4gICAgICAgIGNvbnN0IGtleSA9IGludGVuZGVkVGFyZ2V0SWRlbnRpdHkuY2hhbm5lbElkID8/IC8vIFRoZSByZWNpcGllbnQgaXMgYSBwcm92aWRlclxuICAgICAgICAgICAgaW50ZW5kZWRUYXJnZXRJZGVudGl0eS5lbmRwb2ludElkID8/IC8vIFRoZSByZWNpcGllbnQgaXMgYSBjbGllbnRcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmdldChwcm92aWRlcklkZW50aXR5LmNoYW5uZWxJZCk7IC8vIE5vIGVuZHBvaW50SWQgd2FzIHBhc3NlZCwgbWFrZSBiZXN0IGF0dGVtcHRcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuZW5kcG9pbnRNYXAuZ2V0KGtleSk7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5zdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnJlYXNvbiA9IGBDbGllbnQgY29ubmVjdGlvbiB3aXRoIGlkZW50aXR5IHV1aWQ6ICR7dGhpcy53aXJlLm1lLnV1aWR9IC8gbmFtZTogJHt0aGlzLndpcmUubWUubmFtZX0gLyBlbmRwb2ludElkOiAke2tleX0gbm8gbG9uZ2VyIGNvbm5lY3RlZC5gO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgaGFuZGxlcihhY3Rpb24sIHBheWxvYWQsIHNlbmRlcklkZW50aXR5KTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCA9IGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCB8fCB7fTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZC5yZXN1bHQgPSByZXM7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRSYXcoYWNrVG9TZW5kZXIpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnN1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucmVhc29uID0gZS5tZXNzYWdlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGRFbmRwb2ludChoYW5kbGVyLCBjaGFubmVsSWQsIGVuZHBvaW50SWQpIHtcbiAgICAgICAgdGhpcy5lbmRwb2ludE1hcC5zZXQoZW5kcG9pbnRJZCwgaGFuZGxlcik7XG4gICAgICAgIC8vIFByb3ZpZGVycyBoYXZlIHRoZSBzYW1lIGVuZHBvaW50SWQgYW5kIGNoYW5uZWxJZC5cbiAgICAgICAgLy8gVGhpcyBpcyBvbmx5IHVzZWQgd2hlbiBjbGllbnRzIGFyZSByZWNlaXZpbmcgbWVzc2FnZXMgZnJvbSBwcm92aWRlcnMsIHNvIHdlIHNob3VsZG4ndCBzYXZlIHByb3ZpZGVyIGVuZHBvaW50SWQgaGVyZS5cbiAgICAgICAgaWYgKGNoYW5uZWxJZCAhPT0gZW5kcG9pbnRJZCkge1xuICAgICAgICAgICAgdGhpcy5sYXRlc3RFbmRwb2ludElkQnlDaGFubmVsSWQuc2V0KGNoYW5uZWxJZCwgZW5kcG9pbnRJZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlRW5kcG9pbnQoY2hhbm5lbElkLCBlbmRwb2ludElkKSB7XG4gICAgICAgIHRoaXMuZW5kcG9pbnRNYXAuZGVsZXRlKGVuZHBvaW50SWQpO1xuICAgICAgICBpZiAodGhpcy5sYXRlc3RFbmRwb2ludElkQnlDaGFubmVsSWQuZ2V0KGNoYW5uZWxJZCkgPT09IGVuZHBvaW50SWQpIHtcbiAgICAgICAgICAgIHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmRlbGV0ZShjaGFubmVsSWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNoZWNrRm9yUHJldmlvdXNDbGllbnRDb25uZWN0aW9uKGNoYW5uZWxJZCkge1xuICAgICAgICBjb25zdCBlbmRwb2ludElkRnJvbVByZXZpb3VzQ29ubmVjdGlvbiA9IHRoaXMubGF0ZXN0RW5kcG9pbnRJZEJ5Q2hhbm5lbElkLmdldChjaGFubmVsSWQpO1xuICAgICAgICBpZiAoZW5kcG9pbnRJZEZyb21QcmV2aW91c0Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIC8vIE5vdCBjb252aW5jZWQgYnkgdGhpcyB3YXkgb2YgZG9pbmcgdGhpbmdzLCBidXQgcHVzaGluZyB1cCBmb3Igbm93LlxuICAgICAgICAgICAgY2xpZW50XzEkMS5DaGFubmVsQ2xpZW50LmNsb3NlQ2hhbm5lbEJ5RW5kcG9pbnRJZChlbmRwb2ludElkRnJvbVByZXZpb3VzQ29ubmVjdGlvbik7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdZb3UgaGF2ZSBjcmVhdGVkIGEgc2Vjb25kIGNvbm5lY3Rpb24gdG8gYW4gb2xkZXIgcHJvdmlkZXIuIEZpcnN0IGNvbm5lY3Rpb24gaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBjbGllbnRNYXAnKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0lmIHRoZSBwcm92aWRlciBjYWxscyBwdWJsaXNoKCksIHlvdSBtYXkgcmVjZWl2ZSBtdWx0aXBsZSBtZXNzYWdlcy4nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbm1lc3NhZ2VSZWNlaXZlci5NZXNzYWdlUmVjZWl2ZXIgPSBNZXNzYWdlUmVjZWl2ZXI7XG5cbnZhciBwcm90b2NvbE1hbmFnZXIgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvY29sTWFuYWdlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5wcm90b2NvbE1hbmFnZXIuUHJvdG9jb2xNYW5hZ2VyID0gdm9pZCAwO1xuLypcblRoaXMgc2hvdWxkIGJlIGFnbm9zdGljIG9mIGFueSBhY3R1YWwgb3BlbmZpbiBjb2RlIHRvIGJlIHVuaXQgdGVzdGFibGUuXG5EZXBlbmRlbmNpZXMgb24gdGhlIGFjdHVhbCBzcmF0ZWdpZXMgc2hvdWxkIGJlIGhhbmRsZWQgaW4gQ29ubmVjdGlvbk1hbmFnZXJcbiovXG5jbGFzcyBQcm90b2NvbE1hbmFnZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNvbnN0cnVjdG9yXG4gICAgY29uc3RydWN0b3IoUHJvdG9jb2xzSW5QcmVmZXJlbmNlT3JkZXIpIHtcbiAgICAgICAgdGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlciA9IFByb3RvY29sc0luUHJlZmVyZW5jZU9yZGVyO1xuICAgICAgICB0aGlzLkRlZmF1bHRDbGllbnRQcm90b2NvbHMgPSBbJ2NsYXNzaWMnXTtcbiAgICAgICAgdGhpcy5EZWZhdWx0UHJvdmlkZXJQcm90b2NvbHMgPSBbJ2NsYXNzaWMnXTtcbiAgICAgICAgdGhpcy5nZXRDbGllbnRQcm90b2NvbHMgPSAocHJvdG9jb2xzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdXBwb3J0ZWQgPSBwcm90b2NvbHNcbiAgICAgICAgICAgICAgICA/IHRoaXMuUHJvdG9jb2xzSW5QcmVmZXJlbmNlT3JkZXIuZmlsdGVyKCh4KSA9PiBwcm90b2NvbHMuaW5jbHVkZXMoeCkpXG4gICAgICAgICAgICAgICAgOiB0aGlzLkRlZmF1bHRDbGllbnRQcm90b2NvbHM7XG4gICAgICAgICAgICBpZiAoIXN1cHBvcnRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHZhbGlkIHByb3RvY29scyB3ZXJlIHBhc3NlZCBpbi4gQWNjZXB0ZWQgdmFsdWVzIGFyZTogJHt0aGlzLlByb3RvY29sc0luUHJlZmVyZW5jZU9yZGVyLmpvaW4oJywgJyl9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN1cHBvcnRlZDtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5nZXRQcm92aWRlclByb3RvY29scyA9IChwcm90b2NvbHMpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1cHBvcnRlZCA9IHByb3RvY29sc1xuICAgICAgICAgICAgICAgID8gdGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlci5maWx0ZXIoKHgpID0+IHByb3RvY29scy5pbmNsdWRlcyh4KSlcbiAgICAgICAgICAgICAgICA6IHRoaXMuRGVmYXVsdFByb3ZpZGVyUHJvdG9jb2xzO1xuICAgICAgICAgICAgaWYgKCFzdXBwb3J0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB2YWxpZCBwcm90b2NvbHMgd2VyZSBwYXNzZWQgaW4uIEFjY2VwdGVkIHZhbHVlcyBhcmU6ICR7dGhpcy5Qcm90b2NvbHNJblByZWZlcmVuY2VPcmRlci5qb2luKCcsICcpfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdXBwb3J0ZWQ7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZ2V0Q29tcGF0aWJsZVByb3RvY29scyA9IChwcm92aWRlclByb3RvY29scywgY2xpZW50T2ZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN1cHBvcnRlZCA9IGNsaWVudE9mZmVyLnN1cHBvcnRlZFByb3RvY29scy5maWx0ZXIoKGNsaWVudFByb3RvY29sKSA9PiBwcm92aWRlclByb3RvY29scy5zb21lKChwcm92aWRlclByb3RvY29sKSA9PiBwcm92aWRlclByb3RvY29sLnR5cGUgPT09IGNsaWVudFByb3RvY29sLnR5cGUgJiZcbiAgICAgICAgICAgICAgICBjbGllbnRQcm90b2NvbC52ZXJzaW9uID49IHByb3ZpZGVyUHJvdG9jb2wubWluaW11bVZlcnNpb24gJiZcbiAgICAgICAgICAgICAgICBwcm92aWRlclByb3RvY29sLnZlcnNpb24gPj0gKGNsaWVudFByb3RvY29sLm1pbmltdW1WZXJzaW9uID8/IDApKSk7XG4gICAgICAgICAgICByZXR1cm4gc3VwcG9ydGVkLnNsaWNlKDAsIGNsaWVudE9mZmVyLm1heFByb3RvY29scyk7XG4gICAgICAgIH07XG4gICAgfVxufVxucHJvdG9jb2xNYW5hZ2VyLlByb3RvY29sTWFuYWdlciA9IFByb3RvY29sTWFuYWdlcjtcblxudmFyIHN0cmF0ZWd5ID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdHJhdGVneSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jbGFzcyBDb21iaW5lZFN0cmF0ZWd5IHtcbiAgICAvLyBNYWtpbmcgdGhpcyBhIHN0YXRpYyBtZXRob2QgYmVjYXVzZSB0aGUgY29uc3RydWN0b3IgY2FuJ3QgYmUgdHlwZWQuXG4gICAgLy8gT3RoZXJ3aXNlIGl0IHdpbGwgZXJyb3Igd2hlbiBjYWxsaW5nIGFkZEVuZHBvaW50IGJ1dCBJJ2QgcmF0aGVyIHRoZSB3aG9sZSBpbnN0YW5jZSBiZSB0eXBlZCBhcyBuZXZlci5cbiAgICBzdGF0aWMgY29tYmluZShhLCBiKSB7XG4gICAgICAgIHJldHVybiBuZXcgQ29tYmluZWRTdHJhdGVneShhLCBiKTtcbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY29uc3RydWN0b3JcbiAgICBjb25zdHJ1Y3RvcihwcmltYXJ5LCBzZWNvbmRhcnkpIHtcbiAgICAgICAgdGhpcy5wcmltYXJ5ID0gcHJpbWFyeTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkgPSBzZWNvbmRhcnk7XG4gICAgfVxuICAgIG9uRW5kcG9pbnREaXNjb25uZWN0KGVuZHBvaW50SWQsIGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucHJpbWFyeS5vbkVuZHBvaW50RGlzY29ubmVjdChlbmRwb2ludElkLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vjb25kYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnRJZCkpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkub25FbmRwb2ludERpc2Nvbm5lY3QoZW5kcG9pbnRJZCwgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnByaW1hcnkuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJpbWFyeS5pc1ZhbGlkRW5kcG9pbnRQYXlsb2FkKHBheWxvYWQpIHx8IHRoaXMuc2Vjb25kYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCk7XG4gICAgfVxuICAgIGFzeW5jIGNsb3NlRW5kcG9pbnQoZW5kcG9pbnRJZCkge1xuICAgICAgICBhd2FpdCB0aGlzLnByaW1hcnkuY2xvc2VFbmRwb2ludChlbmRwb2ludElkKTtcbiAgICAgICAgYXdhaXQgdGhpcy5zZWNvbmRhcnkuY2xvc2VFbmRwb2ludChlbmRwb2ludElkKTtcbiAgICB9XG4gICAgaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcmltYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnQpIHx8IHRoaXMuc2Vjb25kYXJ5LmlzRW5kcG9pbnRDb25uZWN0ZWQoZW5kcG9pbnQpO1xuICAgIH1cbiAgICBhc3luYyBhZGRFbmRwb2ludChlbmRwb2ludCwgcGF5bG9hZCkge1xuICAgICAgICBpZiAodGhpcy5wcmltYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucHJpbWFyeS5hZGRFbmRwb2ludChlbmRwb2ludCwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2Vjb25kYXJ5LmlzVmFsaWRFbmRwb2ludFBheWxvYWQocGF5bG9hZCkpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2Vjb25kYXJ5LmFkZEVuZHBvaW50KGVuZHBvaW50LCBwYXlsb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZWNlaXZlKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMucHJpbWFyeS5yZWNlaXZlKGxpc3RlbmVyKTtcbiAgICAgICAgdGhpcy5zZWNvbmRhcnkucmVjZWl2ZShsaXN0ZW5lcik7XG4gICAgfVxuICAgIHNlbmQoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKSB7XG4gICAgICAgIGlmICh0aGlzLnByaW1hcnkuaXNFbmRwb2ludENvbm5lY3RlZChlbmRwb2ludElkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJpbWFyeS5zZW5kKGVuZHBvaW50SWQsIGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vjb25kYXJ5LnNlbmQoZW5kcG9pbnRJZCwgYWN0aW9uLCBwYXlsb2FkKTtcbiAgICB9XG4gICAgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFt0aGlzLnByaW1hcnkuY2xvc2UoKSwgdGhpcy5zZWNvbmRhcnkuY2xvc2UoKV0pO1xuICAgIH1cbn1cbnN0cmF0ZWd5LmRlZmF1bHQgPSBDb21iaW5lZFN0cmF0ZWd5O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ1ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2ltcG9ydERlZmF1bHQkMSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2ltcG9ydERlZmF1bHQpIHx8IGZ1bmN0aW9uIChtb2QpIHtcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcbn07XG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgX0Nvbm5lY3Rpb25NYW5hZ2VyX3J0Y0Nvbm5lY3Rpb25NYW5hZ2VyO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbm5lY3Rpb25NYW5hZ2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbm5lY3Rpb25NYW5hZ2VyLkNvbm5lY3Rpb25NYW5hZ2VyID0gdm9pZCAwO1xuY29uc3QgZXhoYXVzdGl2ZV8xID0gZXhoYXVzdGl2ZTtcbmNvbnN0IGJhc2VfMSRmID0gYmFzZTtcbmNvbnN0IHN0cmF0ZWd5XzEgPSBzdHJhdGVneSQzO1xuY29uc3Qgc3RyYXRlZ3lfMiA9IHN0cmF0ZWd5JDI7XG5jb25zdCBpY2VfbWFuYWdlcl8xID0gaWNlTWFuYWdlcjtcbmNvbnN0IHByb3ZpZGVyXzEkMSA9IHByb3ZpZGVyO1xuY29uc3QgbWVzc2FnZV9yZWNlaXZlcl8xID0gbWVzc2FnZVJlY2VpdmVyO1xuY29uc3QgcHJvdG9jb2xfbWFuYWdlcl8xID0gcHJvdG9jb2xNYW5hZ2VyO1xuY29uc3Qgc3RyYXRlZ3lfMyA9IF9faW1wb3J0RGVmYXVsdCQxKHN0cmF0ZWd5KTtcbmNsYXNzIENvbm5lY3Rpb25NYW5hZ2VyIGV4dGVuZHMgYmFzZV8xJGYuQmFzZSB7XG4gICAgc3RhdGljIGdldFByb3RvY29sT3B0aW9uc0Zyb21TdHJpbmdzKHByb3RvY29scykge1xuICAgICAgICByZXR1cm4gcHJvdG9jb2xzLm1hcCgocHJvdG9jb2wpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAocHJvdG9jb2wpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdydGMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyYXRlZ3lfMi5SVENJbmZvO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NsYXNzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyYXRlZ3lfMS5DbGFzc2ljSW5mbztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKDAsIGV4aGF1c3RpdmVfMS5leGhhdXN0aXZlQ2hlY2spKHByb3RvY29sLCBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlci5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgX0Nvbm5lY3Rpb25NYW5hZ2VyX3J0Y0Nvbm5lY3Rpb25NYW5hZ2VyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICB0aGlzLnJlbW92ZUNoYW5uZWxGcm9tUHJvdmlkZXJNYXAgPSAoY2hhbm5lbElkKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb3ZpZGVyTWFwLmRlbGV0ZShjaGFubmVsSWQpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9ubWVzc2FnZSA9IChtc2cpID0+IHtcbiAgICAgICAgICAgIGlmIChtc2cuYWN0aW9uID09PSAncHJvY2Vzcy1jaGFubmVsLWNvbm5lY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ2hhbm5lbENvbm5lY3Rpb24obXNnKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcm92aWRlck1hcCA9IG5ldyBNYXAoKTtcbiAgICAgICAgdGhpcy5wcm90b2NvbE1hbmFnZXIgPSBuZXcgcHJvdG9jb2xfbWFuYWdlcl8xLlByb3RvY29sTWFuYWdlcih0aGlzLndpcmUuZW52aXJvbm1lbnQudHlwZSA9PT0gJ25vZGUnID8gWydjbGFzc2ljJ10gOiBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDUodGhpcywgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgbmV3IG1lc3NhZ2VfcmVjZWl2ZXJfMS5NZXNzYWdlUmVjZWl2ZXIod2lyZSksIFwiZlwiKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ1KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9ydGNDb25uZWN0aW9uTWFuYWdlciwgbmV3IGljZV9tYW5hZ2VyXzEuUlRDSUNFTWFuYWdlcih3aXJlKSwgXCJmXCIpO1xuICAgICAgICB3aXJlLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5vbm1lc3NhZ2UuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIGNyZWF0ZVByb3ZpZGVyKG9wdGlvbnMsIHByb3ZpZGVySWRlbnRpdHkpIHtcbiAgICAgICAgY29uc3Qgb3B0cyA9IE9iamVjdC5hc3NpZ24odGhpcy53aXJlLmVudmlyb25tZW50LmdldERlZmF1bHRDaGFubmVsT3B0aW9ucygpLmNyZWF0ZSwgb3B0aW9ucyB8fCB7fSk7XG4gICAgICAgIGNvbnN0IHByb3RvY29scyA9IHRoaXMucHJvdG9jb2xNYW5hZ2VyLmdldFByb3ZpZGVyUHJvdG9jb2xzKG9wdHM/LnByb3RvY29scyk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVNpbmdsZVN0cmF0ZWd5ID0gKHN0cmF0VHlwZSkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChzdHJhdFR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdydGMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3koKTtcbiAgICAgICAgICAgICAgICBjYXNlICdjbGFzc2ljJzpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBzdHJhdGVneV8xLkNsYXNzaWNTdHJhdGVneSh0aGlzLndpcmUsIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfbWVzc2FnZVJlY2VpdmVyLCBcImZcIiksIFxuICAgICAgICAgICAgICAgICAgICAvLyBQcm92aWRlcnMgZG8gbm90IGhhdmUgYW4gZW5kcG9pbnRJZCwgdXNlIGNoYW5uZWxJZCBhcyBlbmRwb2ludElkIGluIHRoZSBzdHJhdGVneS5cbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXJJZGVudGl0eS5jaGFubmVsSWQsIHByb3ZpZGVySWRlbnRpdHkpO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoMCwgZXhoYXVzdGl2ZV8xLmV4aGF1c3RpdmVDaGVjaykoc3RyYXRUeXBlLCBbJ3J0YycsICdjbGFzc2ljJ10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzdHJhdGVnaWVzID0gcHJvdG9jb2xzLm1hcChjcmVhdGVTaW5nbGVTdHJhdGVneSk7XG4gICAgICAgIGxldCBzdHJhdGVneTtcbiAgICAgICAgaWYgKHN0cmF0ZWdpZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICBjb25zdCBbYSwgYl0gPSBzdHJhdGVnaWVzO1xuICAgICAgICAgICAgc3RyYXRlZ3kgPSBzdHJhdGVneV8zLmRlZmF1bHQuY29tYmluZShhLCBiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdHJhdGVnaWVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgW3N0cmF0ZWd5XSA9IHN0cmF0ZWdpZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBTaG91bGQgYmUgaW1wb3NzaWJsZS5cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIGNvbWJpbmUgc3RyYXRlZ2llcycpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgcHJvdmlkZXJfMSQxLkNoYW5uZWxQcm92aWRlcihwcm92aWRlcklkZW50aXR5LCAoKSA9PiBwcm92aWRlcl8xJDEuQ2hhbm5lbFByb3ZpZGVyLndpcmVDbG9zZSh0aGlzLndpcmUsIHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbE5hbWUpLCBzdHJhdGVneSk7XG4gICAgICAgIGNvbnN0IGtleSA9IHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkO1xuICAgICAgICB0aGlzLnByb3ZpZGVyTWFwLnNldChrZXksIHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBjaGFubmVsLFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHM6IENvbm5lY3Rpb25NYW5hZ2VyLmdldFByb3RvY29sT3B0aW9uc0Zyb21TdHJpbmdzKHByb3RvY29scylcbiAgICAgICAgfSk7XG4gICAgICAgIHByb3ZpZGVyXzEkMS5DaGFubmVsUHJvdmlkZXIuc2V0UHJvdmlkZXJSZW1vdmFsKGNoYW5uZWwsIHRoaXMucmVtb3ZlQ2hhbm5lbEZyb21Qcm92aWRlck1hcC5iaW5kKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIGNoYW5uZWw7XG4gICAgfVxuICAgIGFzeW5jIGNyZWF0ZUNsaWVudE9mZmVyKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgcHJvdG9jb2xzID0gdGhpcy5wcm90b2NvbE1hbmFnZXIuZ2V0Q2xpZW50UHJvdG9jb2xzKG9wdGlvbnM/LnByb3RvY29scyk7XG4gICAgICAgIGxldCBydGNQYWNrZXQ7XG4gICAgICAgIGNvbnN0IHN1cHBvcnRlZFByb3RvY29scyA9IGF3YWl0IFByb21pc2UuYWxsKHByb3RvY29scy5tYXAoYXN5bmMgKHR5cGUpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ3J0Yyc6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBydGNDbGllbnQsIGNoYW5uZWxzLCBvZmZlciwgcnRjQ29ubmVjdGlvbklkLCBjaGFubmVsc09wZW5lZCB9ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ3KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9ydGNDb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLnN0YXJ0Q2xpZW50T2ZmZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgcnRjUGFja2V0ID0geyBydGNDbGllbnQsIGNoYW5uZWxzLCBjaGFubmVsc09wZW5lZCB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3J0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzdHJhdGVneV8yLlJUQ0luZm8udmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgb2ZmZXIsIHJ0Y0Nvbm5lY3Rpb25JZCB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgJ2NsYXNzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnY2xhc3NpYycsIHZlcnNpb246IHN0cmF0ZWd5XzEuQ2xhc3NpY0luZm8udmVyc2lvbiB9O1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoMCwgZXhoYXVzdGl2ZV8xLmV4aGF1c3RpdmVDaGVjaykodHlwZSwgWydydGMnLCAnY2xhc3NpYyddKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb2ZmZXI6IHtcbiAgICAgICAgICAgICAgICBzdXBwb3J0ZWRQcm90b2NvbHMsXG4gICAgICAgICAgICAgICAgbWF4UHJvdG9jb2xzOiAyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnRjOiBydGNQYWNrZXRcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlQ2xpZW50U3RyYXRlZ3kocnRjUGFja2V0LCByb3V0aW5nSW5mbykge1xuICAgICAgICBpZiAoIXJvdXRpbmdJbmZvLmVuZHBvaW50SWQpIHtcbiAgICAgICAgICAgIHJvdXRpbmdJbmZvLmVuZHBvaW50SWQgPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpO1xuICAgICAgICAgICAgLy8gRm9yIE5ldyBDbGllbnRzIGNvbm5lY3RpbmcgdG8gT2xkIFByb3ZpZGVycy4gVG8gcHJldmVudCBtdWx0aS1kaXNwYXRjaGluZyBhbmQgcHVibGlzaGluZywgd2UgZGVsZXRlIHByZXZpb3VzbHktY29ubmVjdGVkXG4gICAgICAgICAgICAvLyBjbGllbnRzIHRoYXQgYXJlIGluIHRoZSBzYW1lIGNvbnRleHQgYXMgdGhlIG5ld2x5LWNvbm5lY3RlZCBjbGllbnQuXG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDcodGhpcywgX0Nvbm5lY3Rpb25NYW5hZ2VyX21lc3NhZ2VSZWNlaXZlciwgXCJmXCIpLmNoZWNrRm9yUHJldmlvdXNDbGllbnRDb25uZWN0aW9uKHJvdXRpbmdJbmZvLmNoYW5uZWxJZCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYW5zd2VyID0gcm91dGluZ0luZm8uYW5zd2VyID8/IHtcbiAgICAgICAgICAgIHN1cHBvcnRlZFByb3RvY29sczogW3sgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiAxIH1dXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNyZWF0ZVN0cmF0ZWd5RnJvbUFuc3dlciA9IGFzeW5jIChwcm90b2NvbCkgPT4ge1xuICAgICAgICAgICAgaWYgKHByb3RvY29sLnR5cGUgPT09ICdydGMnICYmIHJ0Y1BhY2tldCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5maW5pc2hDbGllbnRPZmZlcihydGNQYWNrZXQucnRjQ2xpZW50LCBwcm90b2NvbC5wYXlsb2FkLmFuc3dlciwgcnRjUGFja2V0LmNoYW5uZWxzT3BlbmVkKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3koKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcm90b2NvbC50eXBlID09PSAnY2xhc3NpYycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IHN0cmF0ZWd5XzEuQ2xhc3NpY1N0cmF0ZWd5KHRoaXMud2lyZSwgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ3KHRoaXMsIF9Db25uZWN0aW9uTWFuYWdlcl9tZXNzYWdlUmVjZWl2ZXIsIFwiZlwiKSwgcm91dGluZ0luZm8uZW5kcG9pbnRJZCwgcm91dGluZ0luZm8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFsbFByb3RvY29scyA9IChhd2FpdCBQcm9taXNlLmFsbChhbnN3ZXIuc3VwcG9ydGVkUHJvdG9jb2xzLm1hcChjcmVhdGVTdHJhdGVneUZyb21BbnN3ZXIpKSkuZmlsdGVyKCh4KSA9PiB4ICE9PSBudWxsKTtcbiAgICAgICAgLy8gQ2xlYW4gdXAgbG9naWMgaWYgcHJvdmlkZXIgZGlkbid0IHN1cHBvcnQgcnRjLlxuICAgICAgICBpZiAocnRjUGFja2V0ICYmICFhbGxQcm90b2NvbHMuc29tZSgoeCkgPT4geCBpbnN0YW5jZW9mIHN0cmF0ZWd5XzIuUlRDU3RyYXRlZ3kpKSB7XG4gICAgICAgICAgICBpZiAocnRjUGFja2V0KSB7XG4gICAgICAgICAgICAgICAgcnRjUGFja2V0LnJ0Y0NsaWVudC5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBzdHJhdGVneTtcbiAgICAgICAgaWYgKGFsbFByb3RvY29scy5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgc3RyYXRlZ3kgPSBzdHJhdGVneV8zLmRlZmF1bHQuY29tYmluZShhbGxQcm90b2NvbHNbMF0sIGFsbFByb3RvY29sc1sxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWxsUHJvdG9jb2xzLmxlbmd0aCkge1xuICAgICAgICAgICAgW3N0cmF0ZWd5XSA9IGFsbFByb3RvY29scztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNob3VsZCBiZSBpbXBvc3NpYmxlLlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb21wYXRpYmxlIHByb3RvY29scycpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFzIGNhc3RpbmcgcnRjUGFja2V0IGJlY2F1c2Ugd2Ugd29uJ3QgaGF2ZSBhbiBydGNTdHJhdGVneSBpZiBydGNQYWNrZXQgaXMgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBlbmRwb2ludFBheWxvYWQgPSB7IGVuZHBvaW50SWRlbnRpdHk6IHJvdXRpbmdJbmZvLCBydGM6IHJ0Y1BhY2tldCB9O1xuICAgICAgICBzdHJhdGVneS5hZGRFbmRwb2ludChyb3V0aW5nSW5mby5jaGFubmVsSWQsIGVuZHBvaW50UGF5bG9hZCk7XG4gICAgICAgIHJldHVybiBzdHJhdGVneTtcbiAgICB9XG4gICAgYXN5bmMgcHJvY2Vzc0NoYW5uZWxDb25uZWN0aW9uKG1zZykge1xuICAgICAgICBjb25zdCB7IGNsaWVudElkZW50aXR5LCBwcm92aWRlcklkZW50aXR5LCBhY2tUb1NlbmRlciwgcGF5bG9hZCwgb2ZmZXI6IGNsaWVudE9mZmVyIH0gPSBtc2cucGF5bG9hZDtcbiAgICAgICAgaWYgKCFjbGllbnRJZGVudGl0eS5lbmRwb2ludElkKSB7XG4gICAgICAgICAgICAvLyBTaG91bGQgYmUgcG9seWZpbGxlZCBieSBjb3JlIGJ1dCBub3QgaW4gY2FzZXMgb2Ygbm9kZSBjb25uZWN0aW5nIHRvIGFuIG9sZCBydW50aW1lLlxuICAgICAgICAgICAgY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCA9IHRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCk7XG4gICAgICAgICAgICBjbGllbnRJZGVudGl0eS5pc0xvY2FsRW5kcG9pbnRJZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjbGllbnRJZGVudGl0eS5pc0xvY2FsRW5kcG9pbnRJZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGtleSA9IHByb3ZpZGVySWRlbnRpdHkuY2hhbm5lbElkO1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLnByb3ZpZGVyTWFwLmdldChrZXkpO1xuICAgICAgICBpZiAoIWJ1cykge1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5zdWNjZXNzID0gZmFsc2U7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnJlYXNvbiA9IGBDaGFubmVsIFwiJHtwcm92aWRlcklkZW50aXR5LmNoYW5uZWxOYW1lfVwiIGhhcyBiZWVuIGRlc3Ryb3llZC5gO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kUmF3KGFja1RvU2VuZGVyKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHByb3ZpZGVyLCBzdHJhdGVneSwgc3VwcG9ydGVkUHJvdG9jb2xzIH0gPSBidXM7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIShwcm92aWRlciBpbnN0YW5jZW9mIHByb3ZpZGVyXzEkMS5DaGFubmVsUHJvdmlkZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0Nhbm5vdCBjb25uZWN0IHRvIGEgY2hhbm5lbCBjbGllbnQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG9mZmVyID0gY2xpZW50T2ZmZXIgPz8ge1xuICAgICAgICAgICAgICAgIHN1cHBvcnRlZFByb3RvY29sczogW3sgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiAxIH1dLFxuICAgICAgICAgICAgICAgIG1heFByb3RvY29sczogMVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IG92ZXJsYXBwaW5nUHJvdG9jb2xzID0gdGhpcy5wcm90b2NvbE1hbmFnZXIuZ2V0Q29tcGF0aWJsZVByb3RvY29scyhzdXBwb3J0ZWRQcm90b2NvbHMsIG9mZmVyKTtcbiAgICAgICAgICAgIGlmICghb3ZlcmxhcHBpbmdQcm90b2NvbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHByb3ZpZGVyIGRvZXMgbm90IHN1cHBvcnQgYW55IG9mIHRoZSBvZmZlcmVkIHByb3RvY29scy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHByb3ZpZGVyLnByb2Nlc3NDb25uZWN0aW9uKGNsaWVudElkZW50aXR5LCBwYXlsb2FkKTtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCA9IGFja1RvU2VuZGVyLnBheWxvYWQucGF5bG9hZCB8fCB7fTtcbiAgICAgICAgICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgc3VwcG9ydGVkIHByb3RvY29scyBhbmQgYWNjdW11bGF0ZSB0aGVtIGludG8gdGhlIGFuc3dlclxuICAgICAgICAgICAgLy8gYWRkRW5kcG9pbnQgaXMgdHJpY2t5IGJ1dCB3ZSBuZWVkIHRvIHdhaXQgZm9yIGNoYW5uZWwgcmVzb2x1dGlvbiBiZWZvcmUgYWRkaW5nIHRoZSBlbmRwb2ludC5cbiAgICAgICAgICAgIGxldCBjbGllbnRBbnN3ZXIgPSB7XG4gICAgICAgICAgICAgICAgc3VwcG9ydGVkUHJvdG9jb2xzOiBbXSxcbiAgICAgICAgICAgICAgICBlbmRwb2ludFBheWxvYWRQcm9taXNlOiBQcm9taXNlLnJlc29sdmUoeyBlbmRwb2ludElkZW50aXR5OiBjbGllbnRJZGVudGl0eSB9KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNsaWVudEFuc3dlciA9IGF3YWl0IG92ZXJsYXBwaW5nUHJvdG9jb2xzLnJlZHVjZShhc3luYyAoYWNjdW1QLCBwcm90b2NvbFRvVXNlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYW5zd2VyID0gYXdhaXQgYWNjdW1QO1xuICAgICAgICAgICAgICAgIGlmIChwcm90b2NvbFRvVXNlLnR5cGUgPT09ICdydGMnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgYW5zd2VyOiBydGNBbnN3ZXIsIHJ0Y0NsaWVudCwgY2hhbm5lbHMgfSA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNyh0aGlzLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5jcmVhdGVQcm92aWRlckFuc3dlcihwcm90b2NvbFRvVXNlLnBheWxvYWQucnRjQ29ubmVjdGlvbklkLCBwcm90b2NvbFRvVXNlLnBheWxvYWQub2ZmZXIpO1xuICAgICAgICAgICAgICAgICAgICBhbnN3ZXIuc3VwcG9ydGVkUHJvdG9jb2xzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3J0YycsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uOiBzdHJhdGVneV8yLlJUQ0luZm8udmVyc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbnN3ZXI6IHJ0Y0Fuc3dlclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgYW5zd2VyLmVuZHBvaW50UGF5bG9hZFByb21pc2UgPSBhbnN3ZXIuZW5kcG9pbnRQYXlsb2FkUHJvbWlzZS50aGVuKChlbmRwb2ludFBheWxvYWQpID0+IGNoYW5uZWxzLnRoZW4oKHJlc29sdmVkQ2hhbm5lbHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZW5kcG9pbnRQYXlsb2FkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ0Yzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGNDbGllbnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzOiByZXNvbHZlZENoYW5uZWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYW5zd2VyLnN1cHBvcnRlZFByb3RvY29scy5wdXNoKHsgdHlwZTogJ2NsYXNzaWMnLCB2ZXJzaW9uOiBzdHJhdGVneV8xLkNsYXNzaWNJbmZvLnZlcnNpb24gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICAgICAgICB9LCBQcm9taXNlLnJlc29sdmUoY2xpZW50QW5zd2VyKSk7XG4gICAgICAgICAgICAvLyBOZWVkIHRvIGFzIGNhc3QgaGVyZS5cbiAgICAgICAgICAgIGNsaWVudEFuc3dlci5lbmRwb2ludFBheWxvYWRQcm9taXNlLnRoZW4oKGVuZHBvaW50UGF5bG9hZCkgPT4gc3RyYXRlZ3kuYWRkRW5kcG9pbnQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCwgZW5kcG9pbnRQYXlsb2FkKSk7XG4gICAgICAgICAgICBhY2tUb1NlbmRlci5wYXlsb2FkLnBheWxvYWQucmVzdWx0ID0gcmVzO1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5wYXlsb2FkLmFuc3dlciA9IGNsaWVudEFuc3dlcjtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZFJhdyhhY2tUb1NlbmRlcik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGFja1RvU2VuZGVyLnBheWxvYWQuc3VjY2VzcyA9IGZhbHNlO1xuICAgICAgICAgICAgYWNrVG9TZW5kZXIucGF5bG9hZC5yZWFzb24gPSBlLm1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRSYXcoYWNrVG9TZW5kZXIpO1xuICAgICAgICB9XG4gICAgfVxufVxuY29ubmVjdGlvbk1hbmFnZXIuQ29ubmVjdGlvbk1hbmFnZXIgPSBDb25uZWN0aW9uTWFuYWdlcjtcbl9Db25uZWN0aW9uTWFuYWdlcl9tZXNzYWdlUmVjZWl2ZXIgPSBuZXcgV2Vha01hcCgpLCBfQ29ubmVjdGlvbk1hbmFnZXJfcnRjQ29ubmVjdGlvbk1hbmFnZXIgPSBuZXcgV2Vha01hcCgpO1xuXG4vKipcbiAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIGBDaGFubmVsYCBzdWJzZXQgb2YgdGhlIGBJbnRlckFwcGxpY2F0aW9uQnVzYCBBUEkgKGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsYCkuXG4gKlxuICogKiB7QGxpbmsgQ2hhbm5lbH0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBDaGFubmVsYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbGAuXG4gKiAqIHtAbGluayBPcGVuRmluLkNoYW5uZWxDbGllbnR9IGRlc2NyaWJlcyBhIGNsaWVudCBvZiBhIGNoYW5uZWwsIGUuZy4gYXMgcmV0dXJuZWQgYnkgYGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY29ubmVjdGAuXG4gKiAqIHtAbGluayBPcGVuRmluLkNoYW5uZWxQcm92aWRlcn0gZGVzY3JpYmVzIGEgcHJvdmlkZXIgb2YgYSBjaGFubmVsLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZWAuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNiA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWwkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jaGFubmVsJDEuQ2hhbm5lbCA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmNvbnN0IGV2ZW50c18xJDUgPSByZXF1aXJlJCQwO1xuY29uc3QgbGF6eV8xJDEgPSBsYXp5O1xuY29uc3QgYmFzZV8xJGUgPSBiYXNlO1xuY29uc3QgY2xpZW50XzEgPSBjbGllbnQ7XG5jb25zdCBjb25uZWN0aW9uX21hbmFnZXJfMSA9IGNvbm5lY3Rpb25NYW5hZ2VyO1xuY29uc3QgcHJvdmlkZXJfMSA9IHByb3ZpZGVyO1xuZnVuY3Rpb24gcmV0cnlEZWxheShjb3VudCkge1xuICAgIGNvbnN0IGludGVydmFsID0gNTAwOyAvLyBiYXNlIGRlbGF5XG4gICAgY29uc3Qgc3RlcHMgPSAxMDsgLy8gSG93IG1hbnkgcmV0cmllcyB0byBkbyBiZWZvcmUgaW5jcmVtZW50aW5nIHRoZSBkZWxheVxuICAgIGNvbnN0IGJhc2UgPSAyOyAvLyBIb3cgbXVjaCB0byBtdWx0aXBseSB0aGUgcHJldmlvdXMgZGVsYXkgYnlcbiAgICBjb25zdCBtYXggPSAzMDAwMDsgLy8gbWF4IGRlbGF5XG4gICAgY29uc3Qgc3RlcCA9IE1hdGguZmxvb3IoY291bnQgLyBzdGVwcyk7XG4gICAgY29uc3QgZGVsYXkgPSBNYXRoLm1pbihtYXgsIGludGVydmFsICogYmFzZSAqKiBzdGVwKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfSwgZGVsYXkpO1xuICAgIH0pO1xufVxuLyoqXG4gKiBUaGUgQ2hhbm5lbCBBUEkgYWxsb3dzIGFuIE9wZW5GaW4gYXBwbGljYXRpb24gdG8gY3JlYXRlIGEgY2hhbm5lbCBhcyBhIHtAbGluayBDaGFubmVsUHJvdmlkZXIgQ2hhbm5lbFByb3ZpZGVyfSxcbiAqIG9yIGNvbm5lY3QgdG8gYSBjaGFubmVsIGFzIGEge0BsaW5rIENoYW5uZWxDbGllbnQgQ2hhbm5lbENsaWVudH0uXG4gKiBAcmVtYXJrcyBUaGUgXCJoYW5kc2hha2VcIiBiZXR3ZWVuIHRoZSBjb21tdW5pY2F0aW9uIHBhcnRuZXJzIGlzXG4gKiBzaW1wbGlmaWVkIHdoZW4gdXNpbmcgYSBjaGFubmVsLiAgQSByZXF1ZXN0IHRvIGNvbm5lY3QgdG8gYSBjaGFubmVsIGFzIGEgY2xpZW50IHdpbGwgcmV0dXJuIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIGlmL3doZW4gdGhlIGNoYW5uZWwgaGFzIGJlZW4gY3JlYXRlZC4gQm90aCB0aGVcbiAqIHByb3ZpZGVyIGFuZCBjbGllbnQgY2FuIGRpc3BhdGNoIGFjdGlvbnMgdGhhdCBoYXZlIGJlZW4gcmVnaXN0ZXJlZCBvbiB0aGVpciBvcHBvc2l0ZXMsIGFuZCBkaXNwYXRjaCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYSBwYXlsb2FkIGZyb20gdGhlIG90aGVyXG4gKiBjb21tdW5pY2F0aW9uIHBhcnRpY2lwYW50LiBUaGVyZSBjYW4gYmUgb25seSBvbmUgcHJvdmlkZXIgcGVyIGNoYW5uZWwsIGJ1dCBtYW55IGNsaWVudHMuICBWZXJzaW9uIGA5LjYxLjM1LipgIG9yIGxhdGVyIGlzIHJlcXVpcmVkIGZvciBib3RoIGNvbW11bmljYXRpb24gcGFydG5lcnMuXG4gKlxuICogQXN5bmNocm9ub3VzIE1ldGhvZHM6XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbC5jcmVhdGUgY3JlYXRlKGNoYW5uZWxOYW1lLCBvcHRpb25zKX1cbiAqICAqIHtAbGluayBDaGFubmVsLmNvbm5lY3QgY29ubmVjdChjaGFubmVsTmFtZSwgb3B0aW9ucyl9XG4gKiAgKiB7QGxpbmsgQ2hhbm5lbC5vbkNoYW5uZWxDb25uZWN0IG9uQ2hhbm5lbENvbm5lY3QobGlzdGVuZXIpfVxuICogICoge0BsaW5rIENoYW5uZWwub25DaGFubmVsRGlzY29ubmVjdCBvbkNoYW5uZWxEaXNjb25uZWN0KGxpc3RlbmVyKX1cbiAqL1xuY2xhc3MgQ2hhbm5lbCBleHRlbmRzIGJhc2VfMSRlLkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlKSB7XG4gICAgICAgIHN1cGVyKHdpcmUsICdjaGFubmVsJyk7XG4gICAgICAgIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLnNldCh0aGlzLCB2b2lkIDApO1xuICAgICAgICBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIuc2V0KHRoaXMsIG5ldyBldmVudHNfMSQ1LkV2ZW50RW1pdHRlcigpKTtcbiAgICAgICAgLy8gT3BlbkZpbiBBUEkgaGFzIG5vdCBiZWVuIGluamVjdGVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lLCAqbXVzdCogd2FpdCBmb3IgQVBJIHRvIGJlIHJlYWR5LlxuICAgICAgICBfQ2hhbm5lbF9yZWFkeVRvQ29ubmVjdC5zZXQodGhpcywgbmV3IGxhenlfMSQxLkFzeW5jUmV0cnlhYmxlTGF6eShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgdGhpcy5vbignZGlzY29ubmVjdGVkJywgKGV2ZW50UGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjbGllbnRfMS5DaGFubmVsQ2xpZW50LmhhbmRsZVByb3ZpZGVyRGlzY29ubmVjdChldmVudFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMub24oJ2Nvbm5lY3RlZCcsICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5lbWl0KCdjb25uZWN0ZWQnLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXSkuY2F0Y2goKCkgPT4gbmV3IEVycm9yKCdlcnJvciBzZXR0aW5nIHVwIGNoYW5uZWwgY29ubmVjdGlvbiBsaXN0ZW5lcnMnKSk7XG4gICAgICAgIH0pKTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQ0KHRoaXMsIF9DaGFubmVsX2Nvbm5lY3Rpb25NYW5hZ2VyLCBuZXcgY29ubmVjdGlvbl9tYW5hZ2VyXzEuQ29ubmVjdGlvbk1hbmFnZXIod2lyZSksIFwiZlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICpcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBhc3luYyBnZXRBbGxDaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdnZXQtYWxsLWNoYW5uZWxzJykudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3RlbnMgZm9yIGNoYW5uZWwgY29ubmVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXIgLSBjYWxsYmFjayB0byBleGVjdXRlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbGlzdGVuZXIgPSAoY2hhbm5lbFBheWxvYWQpID0+IGNvbnNvbGUubG9nKGNoYW5uZWxQYXlsb2FkKTsgLy8gc2VlIHJldHVybiB2YWx1ZSBiZWxvd1xuICAgICAqXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5vbkNoYW5uZWxDb25uZWN0KGxpc3RlbmVyKTtcbiAgICAgKlxuICAgICAqIC8vIGV4YW1wbGUgc2hhcGVcbiAgICAgKiB7XG4gICAgICogICAgIFwidG9waWNcIjogXCJjaGFubmVsXCIsXG4gICAgICogICAgIFwidHlwZVwiOiBcImNvbm5lY3RlZFwiLFxuICAgICAqICAgICBcInV1aWRcIjogXCJPcGVuZmluUE9DXCIsXG4gICAgICogICAgIFwibmFtZVwiOiBcIk9wZW5maW5QT0NcIixcbiAgICAgKiAgICAgXCJjaGFubmVsTmFtZVwiOiBcImNvdW50ZXJcIixcbiAgICAgKiAgICAgXCJjaGFubmVsSWRcIjogXCJPcGVuZmluUE9DL09wZW5maW5QT0MvY291bnRlclwiXG4gICAgICogfVxuICAgICAqXG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgb25DaGFubmVsQ29ubmVjdChsaXN0ZW5lcikge1xuICAgICAgICBhd2FpdCB0aGlzLm9uKCdjb25uZWN0ZWQnLCBsaXN0ZW5lcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3RlbiBmb3IgY2hhbm5lbCBkaXNjb25uZWN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBsaXN0ZW5lciAtIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsaXN0ZW5lciA9IChjaGFubmVsUGF5bG9hZCkgPT4gY29uc29sZS5sb2coY2hhbm5lbFBheWxvYWQpOyAvLyBzZWUgcmV0dXJuIHZhbHVlIGJlbG93XG4gICAgICpcbiAgICAgKiBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLm9uQ2hhbm5lbERpc2Nvbm5lY3QobGlzdGVuZXIpO1xuICAgICAqXG4gICAgICogLy8gZXhhbXBsZSBzaGFwZVxuICAgICAqIHtcbiAgICAgKiAgICAgXCJ0b3BpY1wiOiBcImNoYW5uZWxcIixcbiAgICAgKiAgICAgXCJ0eXBlXCI6IFwiZGlzY29ubmVjdGVkXCIsXG4gICAgICogICAgIFwidXVpZFwiOiBcIk9wZW5maW5QT0NcIixcbiAgICAgKiAgICAgXCJuYW1lXCI6IFwiT3BlbmZpblBPQ1wiLFxuICAgICAqICAgICBcImNoYW5uZWxOYW1lXCI6IFwiY291bnRlclwiLFxuICAgICAqICAgICBcImNoYW5uZWxJZFwiOiBcIk9wZW5maW5QT0MvT3BlbmZpblBPQy9jb3VudGVyXCJcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBvbkNoYW5uZWxEaXNjb25uZWN0KGxpc3RlbmVyKSB7XG4gICAgICAgIGF3YWl0IHRoaXMub24oJ2Rpc2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICB9XG4gICAgYXN5bmMgc2FmZUNvbm5lY3QoY2hhbm5lbE5hbWUsIHNob3VsZFdhaXQsIGNvbm5lY3RQYXlsb2FkKSB7XG4gICAgICAgIGNvbnN0IHJldHJ5SW5mbyA9IHsgY291bnQ6IDAgfTtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCwgbm8tY29uc3RhbnQtY29uZGl0aW9uICovXG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIC8vIHNldHVwIGEgbGlzdGVuZXIgYW5kIGEgY29ubmVjdGVkIHByb21pc2UgdG8gYXdhaXQgaW4gY2FzZSB3ZSBjb25uZWN0IGJlZm9yZSB0aGUgY2hhbm5lbCBpcyByZWFkeVxuICAgICAgICAgICAgbGV0IGNvbm5lY3RlZExpc3RlbmVyID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGVkTGlzdGVuZXIgPSAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbE5hbWUgPT09IHBheWxvYWQuY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5vbignY29ubmVjdGVkJywgY29ubmVjdGVkTGlzdGVuZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChyZXRyeUluZm8uY291bnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdhaXQgYmVmb3JlIHJldHJ5aW5nXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGF5IHJldHVybnMgZmFsc2UgY29ubmVjdGVkUHJvbWlzZSByZXR1cm5zIHRydWUgc28gd2UgY2FuIGtub3cgaWYgYSByZXRyeSBpcyBkdWUgdG8gY29ubmVjdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHJldHJ5SW5mby5nb3RDb25uZWN0ZWRFdmVudCA9IGF3YWl0IFByb21pc2UucmFjZShbcmV0cnlEZWxheShyZXRyeUluZm8uY291bnQpLCBjb25uZWN0ZWRQcm9taXNlXSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjb25uZWN0LXRvLWNoYW5uZWwnLCB7IC4uLmNvbm5lY3RQYXlsb2FkLCByZXRyeUluZm8gfSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvZyBvbmx5IGlmIHRoZXJlIHdhcyBhIHJldHJ5XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzZnVsbHkgY29ubmVjdGVkIHRvIGNoYW5uZWxOYW1lOiAke2NoYW5uZWxOYW1lfWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnBheWxvYWQuZGF0YTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gU2VuZCByZXRyeUluZm8gdG8gdGhlIGNvcmUgZm9yIGRlYnVnIGxvZyBpbmNsdXNpb25cbiAgICAgICAgICAgICAgICBjb25zdCBzZW50TWVzc2FnZVByb21pc2UgPSB0aGlzLndpcmUuc2VuZEFjdGlvbignY29ubmVjdC10by1jaGFubmVsJywgY29ubmVjdFBheWxvYWQpO1xuICAgICAgICAgICAgICAgIC8vIFNhdmUgbWVzc2FnZUlkIGZyb20gdGhlIGZpcnN0IGNvbm5lY3Rpb24gYXR0ZW1wdFxuICAgICAgICAgICAgICAgIHJldHJ5SW5mby5vcmlnaW5hbE1lc3NhZ2VJZCA9IHNlbnRNZXNzYWdlUHJvbWlzZS5tZXNzYWdlSWQ7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VudE1lc3NhZ2VQcm9taXNlO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucGF5bG9hZC5kYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnJvci5tZXNzYWdlLmluY2x1ZGVzKCdpbnRlcm5hbC1uYWNrJykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90IGFuIGludGVybmFsIG5hY2ssIGJyZWFrIHRoZSBsb29wXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkV2FpdCAmJiByZXRyeUluZm8uY291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgd2FpdGluZyBvbiB0aGUgbmV4dCBpdGVyYXRpb24sIHdhcm4gdGhlIHVzZXJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBObyBjaGFubmVsIGZvdW5kIGZvciBjaGFubmVsTmFtZTogJHtjaGFubmVsTmFtZX0uIFdhaXRpbmcgZm9yIGNvbm5lY3Rpb24uLi5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICByZXRyeUluZm8uY291bnQgKz0gMTtcbiAgICAgICAgICAgICAgICAvLyBpbiBjYXNlIG9mIG90aGVyIGVycm9ycywgcmVtb3ZlIG91ciBsaXN0ZW5lclxuICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9pbnRlcm5hbEVtaXR0ZXIsIFwiZlwiKS5yZW1vdmVMaXN0ZW5lcignY29ubmVjdGVkJywgY29ubmVjdGVkTGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IHdoaWxlIChzaG91bGRXYWl0KTsgLy8gSWYgd2UncmUgd2FpdGluZyB3ZSByZXRyeSB0aGUgYWJvdmUgbG9vcFxuICAgICAgICAvLyBTaG91bGQgd2FpdCB3YXMgZmFsc2UsIG5vIGNoYW5uZWwgd2FzIGZvdW5kLlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGNoYW5uZWwgZm91bmQgZm9yIGNoYW5uZWxOYW1lOiAke2NoYW5uZWxOYW1lfS5gKTtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1hd2FpdC1pbi1sb29wLCBuby1jb25zdGFudC1jb25kaXRpb24gKi9cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0byBhIGNoYW5uZWwuIElmIHlvdSB3aXNoIHRvIHNlbmQgYSBwYXlsb2FkIHRvIHRoZSBwcm92aWRlciwgYWRkIGEgcGF5bG9hZCBwcm9wZXJ0eSB0byB0aGUgb3B0aW9ucyBhcmd1bWVudC5cbiAgICAgKiBFWFBFUklNRU5UQUw6IHBhc3MgeyBwcm90b2NvbHM6IFsncnRjJ10gfSBhcyBvcHRpb25zIHRvIG9wdC1pbiB0byBIaWdoIFRocm91Z2hwdXQgQ2hhbm5lbHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hhbm5lbE5hbWUgLSBOYW1lIG9mIHRoZSB0YXJnZXQgY2hhbm5lbC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIENvbm5lY3Rpb24gb3B0aW9ucy5cbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENoYW5uZWxDbGllbnQgQ2hhbm5lbENsaWVudH0uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgY29ubmVjdGlvbiByZXF1ZXN0IHdpbGwgYmUgcm91dGVkIHRvIHRoZSBjaGFubmVsUHJvdmlkZXIgaWYvd2hlbiB0aGUgY2hhbm5lbCBpcyBjcmVhdGVkLiAgSWYgdGhlIGNvbm5lY3RcbiAgICAgKiByZXF1ZXN0IGlzIHNlbnQgcHJpb3IgdG8gY3JlYXRpb24sIHRoZSBwcm9taXNlIHdpbGwgbm90IHJlc29sdmUgb3IgcmVqZWN0IHVudGlsIHRoZSBjaGFubmVsIGlzIGNyZWF0ZWQgYnkgYSBjaGFubmVsUHJvdmlkZXJcbiAgICAgKiAod2hldGhlciBvciBub3QgdG8gd2FpdCBmb3IgY3JlYXRpb24gaXMgY29uZmlndXJhYmxlIGluIHRoZSBjb25uZWN0T3B0aW9ucykuXG4gICAgICpcbiAgICAgKiBUaGUgY29ubmVjdCBjYWxsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdpdGggYSBjaGFubmVsQ2xpZW50IGJ1cyBpZiBhY2NlcHRlZCBieSB0aGUgY2hhbm5lbFByb3ZpZGVyLCBvciByZWplY3QgaWZcbiAgICAgKiB0aGUgY2hhbm5lbFByb3ZpZGVyIHRocm93cyBhbiBlcnJvciB0byByZWplY3QgdGhlIGNvbm5lY3Rpb24uIFRoaXMgYnVzIGNhbiBjb21tdW5pY2F0ZSB3aXRoIHRoZSBQcm92aWRlciwgYnV0IG5vdCB0byBvdGhlclxuICAgICAqIGNsaWVudHMgb24gdGhlIGNoYW5uZWwuIFVzaW5nIHRoZSBidXMsIHRoZSBjaGFubmVsQ2xpZW50IGNhbiByZWdpc3RlciBhY3Rpb25zIGFuZCBtaWRkbGV3YXJlLiBDaGFubmVsIGxpZmVjeWNsZSBjYW4gYWxzbyBiZVxuICAgICAqIGhhbmRsZWQgd2l0aCBhbiBvbkRpc2Nvbm5lY3Rpb24gbGlzdGVuZXIuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBtYWtlQ2xpZW50KGNoYW5uZWxOYW1lKSB7XG4gICAgICogICAgLy8gQSBwYXlsb2FkIGNhbiBiZSBzZW50IGFsb25nIHdpdGggY2hhbm5lbCBjb25uZWN0aW9uIHJlcXVlc3RzIHRvIGhlbHAgd2l0aCBhdXRoZW50aWNhdGlvblxuICAgICAqICAgIGNvbnN0IGNvbm5lY3RQYXlsb2FkID0geyBwYXlsb2FkOiAndG9rZW4nIH07XG4gICAgICpcbiAgICAgKiAgICAvLyBJZiB0aGUgY2hhbm5lbCBoYXMgYmVlbiBjcmVhdGVkIHRoaXMgcmVxdWVzdCB3aWxsIGJlIHNlbnQgdG8gdGhlIHByb3ZpZGVyLiAgSWYgbm90LCB0aGVcbiAgICAgKiAgICAvLyBwcm9taXNlIHdpbGwgbm90IGJlIHJlc29sdmVkIG9yIHJlamVjdGVkIHVudGlsIHRoZSBjaGFubmVsIGhhcyBiZWVuIGNyZWF0ZWQuXG4gICAgICogICAgY29uc3QgY2xpZW50QnVzID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxOYW1lLCBjb25uZWN0UGF5bG9hZCk7XG4gICAgICpcbiAgICAgKiAgICBjbGllbnRCdXMub25EaXNjb25uZWN0aW9uKGNoYW5uZWxJbmZvID0+IHtcbiAgICAgKiAgICAgICAgLy8gaGFuZGxlIHRoZSBjaGFubmVsIGxpZmVjeWNsZSBoZXJlIC0gd2UgY2FuIGNvbm5lY3QgYWdhaW4gd2hpY2ggd2lsbCByZXR1cm4gYSBwcm9taXNlXG4gICAgICogICAgICAgIC8vIHRoYXQgd2lsbCByZXNvbHZlIGlmL3doZW4gdGhlIGNoYW5uZWwgaXMgcmUtY3JlYXRlZC5cbiAgICAgKiAgICAgICAgbWFrZUNsaWVudChjaGFubmVsSW5mby5jaGFubmVsTmFtZSk7XG4gICAgICogICAgfSlcbiAgICAgKlxuICAgICAqICAgIGNsaWVudEJ1cy5yZWdpc3RlcigndG9waWMnLCAocGF5bG9hZCwgaWRlbnRpdHkpID0+IHtcbiAgICAgKiAgICAgICAgLy8gcmVnaXN0ZXIgYSBjYWxsYmFjayBmb3IgYSB0b3BpYyB0byB3aGljaCB0aGUgY2hhbm5lbCBwcm92aWRlciBjYW4gZGlzcGF0Y2ggYW4gYWN0aW9uXG4gICAgICogICAgICAgIGNvbnNvbGUubG9nKCdBY3Rpb24gZGlzcGF0Y2hlZCBieSBwcm92aWRlcjogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgZWNobzogcGF5bG9hZFxuICAgICAqICAgICAgICB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIG1ha2VDbGllbnQoJ2NoYW5uZWxOYW1lJylcbiAgICAgKiAudGhlbigoKSA9PiBjb25zb2xlLmxvZygnQ29ubmVjdGVkJykpXG4gICAgICogLmNhdGNoKGNvbnNvbGUuZXJyb3IpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGNvbm5lY3QoY2hhbm5lbE5hbWUsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAvLyBNYWtlIHN1cmUgd2UgZG9uJ3QgY29ubmVjdCBiZWZvcmUgbGlzdGVuZXJzIGFyZSBzZXQgdXBcbiAgICAgICAgLy8gVGhpcyBhbHNvIGVycm9ycyBpZiB3ZSdyZSBub3QgaW4gT3BlbkZpbiwgZW5zdXJpbmcgd2UgZG9uJ3QgcnVuIHVubmVjZXNzYXJ5IGNvZGVcbiAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ2KHRoaXMsIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0LCBcImZcIikuZ2V0VmFsdWUoKTtcbiAgICAgICAgaWYgKCFjaGFubmVsTmFtZSB8fCB0eXBlb2YgY2hhbm5lbE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgY2hhbm5lbE5hbWUgc3RyaW5nIHRvIGNvbm5lY3QgdG8gYSBjaGFubmVsLicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdHMgPSB7IHdhaXQ6IHRydWUsIC4uLnRoaXMud2lyZS5lbnZpcm9ubWVudC5nZXREZWZhdWx0Q2hhbm5lbE9wdGlvbnMoKS5jb25uZWN0LCAuLi5vcHRpb25zIH07XG4gICAgICAgIGNvbnN0IHsgb2ZmZXIsIHJ0YzogcnRjUGFja2V0IH0gPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDYodGhpcywgX0NoYW5uZWxfY29ubmVjdGlvbk1hbmFnZXIsIFwiZlwiKS5jcmVhdGVDbGllbnRPZmZlcihvcHRzKTtcbiAgICAgICAgbGV0IGNvbm5lY3Rpb25Vcmw7XG4gICAgICAgIGlmICh0aGlzLmZpbi5tZS5pc0ZyYW1lIHx8IHRoaXMuZmluLm1lLmlzVmlldyB8fCB0aGlzLmZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgICAgY29ubmVjdGlvblVybCA9IChhd2FpdCB0aGlzLmZpbi5tZS5nZXRJbmZvKCkpLnVybDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb25uZWN0UGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgICAgLi4ub3B0cyxcbiAgICAgICAgICAgIG9mZmVyLFxuICAgICAgICAgICAgY29ubmVjdGlvblVybFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCByb3V0aW5nSW5mbyA9IGF3YWl0IHRoaXMuc2FmZUNvbm5lY3QoY2hhbm5lbE5hbWUsIG9wdHMud2FpdCwgY29ubmVjdFBheWxvYWQpO1xuICAgICAgICBjb25zdCBzdHJhdGVneSA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLmNyZWF0ZUNsaWVudFN0cmF0ZWd5KHJ0Y1BhY2tldCwgcm91dGluZ0luZm8pO1xuICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IGNsaWVudF8xLkNoYW5uZWxDbGllbnQocm91dGluZ0luZm8sICgpID0+IGNsaWVudF8xLkNoYW5uZWxDbGllbnQud2lyZUNsb3NlKHRoaXMud2lyZSwgcm91dGluZ0luZm8sIHJvdXRpbmdJbmZvLmVuZHBvaW50SWQpLCBzdHJhdGVneSk7XG4gICAgICAgIC8vIEl0IGlzIHRoZSBjbGllbnQncyByZXNwb25zaWJpbGl0eSB0byBoYW5kbGUgZW5kcG9pbnQgZGlzY29ubmVjdGlvbiB0byB0aGUgcHJvdmlkZXIuXG4gICAgICAgIC8vIElmIHRoZSBlbmRwb2ludCBkaWVzLCB0aGUgY2xpZW50IHdpbGwgZm9yY2UgYSBkaXNjb25uZWN0aW9uIHRocm91Z2ggdGhlIGNvcmUuXG4gICAgICAgIC8vIFRoZSBwcm92aWRlciBkb2VzIG5vdCBjYXJlIGFib3V0IGVuZHBvaW50IGRpc2Nvbm5lY3Rpb24uXG4gICAgICAgIHN0cmF0ZWd5Lm9uRW5kcG9pbnREaXNjb25uZWN0KHJvdXRpbmdJbmZvLmNoYW5uZWxJZCwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjaGFubmVsLnNlbmREaXNjb25uZWN0QWN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFNvbWV0aGluZyB3ZW50IHdyb25nIGR1cmluZyBkaXNjb25uZWN0IGZvciBjbGllbnQgd2l0aCB1dWlkOiAke3JvdXRpbmdJbmZvLnV1aWR9IC8gbmFtZTogJHtyb3V0aW5nSW5mby5uYW1lfSAvIGVuZHBvaW50SWQ6ICR7cm91dGluZ0luZm8uZW5kcG9pbnRJZH0uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBjbGllbnRfMS5DaGFubmVsQ2xpZW50LmhhbmRsZVByb3ZpZGVyRGlzY29ubmVjdChyb3V0aW5nSW5mbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hhbm5lbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGNoYW5uZWwuXG4gICAgICogWW91IG11c3QgcHJvdmlkZSBhIHVuaXF1ZSBjaGFubmVsTmFtZS4gSWYgYSBjaGFubmVsTmFtZSBpcyBub3QgcHJvdmlkZWQsIG9yIGl0IGlzIG5vdCB1bmlxdWUsIHRoZSBjcmVhdGlvbiB3aWxsIGZhaWwuXG4gICAgICogRVhQRVJJTUVOVEFMOiBwYXNzIHsgcHJvdG9jb2xzOiBbJ3J0YyddIH0gYXMgb3B0aW9ucyB0byBvcHQtaW4gdG8gSGlnaCBUaHJvdWdocHV0IENoYW5uZWxzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoYW5uZWxOYW1lIC0gTmFtZSBvZiB0aGUgY2hhbm5lbCB0byBiZSBjcmVhdGVkLlxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gQ3JlYXRpb24gb3B0aW9ucy5cbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gaW5zdGFuY2Ugb2Yge0BsaW5rIENoYW5uZWxQcm92aWRlciBDaGFubmVsUHJvdmlkZXJ9LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgc3VjY2Vzc2Z1bCwgdGhlIGNyZWF0ZSBtZXRob2QgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBpbnN0YW5jZSBvZiB0aGUgY2hhbm5lbFByb3ZpZGVyIGJ1cy4gVGhlIGNhbGxlclxuICAgICAqIHRoZW4gYmVjb21lcyB0aGUg4oCcY2hhbm5lbCBwcm92aWRlcuKAnSBhbmQgY2FuIHVzZSB0aGUgY2hhbm5lbFByb3ZpZGVyIGJ1cyB0byByZWdpc3RlciBhY3Rpb25zIGFuZCBtaWRkbGV3YXJlLlxuICAgICAqXG4gICAgICogVGhlIGNhbGxlciBjYW4gYWxzbyBzZXQgYW4gb25Db25uZWN0aW9uIGFuZC9vciBvbkRpc2Nvbm5lY3Rpb24gbGlzdGVuZXIgdGhhdCB3aWxsIGV4ZWN1dGUgb24gYW55IG5ldyBjaGFubmVsXG4gICAgICogY29ubmVjdGlvbi9kaXNjb25uZWN0aW9uIGF0dGVtcHQgZnJvbSBhIGNoYW5uZWwgY2xpZW50LiBUbyByZWplY3QgYSBjb25uZWN0aW9uLCBzaW1wbHkgdGhyb3cgYW4gZXJyb3IgaW4gdGhlXG4gICAgICogb25Db25uZWN0aW9uIGxpc3RlbmVyLiAgVGhlIGRlZmF1bHQgYmVoYXZpb3IgaXMgdG8gYWNjZXB0IGFsbCBuZXcgY29ubmVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBBIG1hcCBvZiBjbGllbnQgY29ubmVjdGlvbnMgaXMgdXBkYXRlZCBhdXRvbWF0aWNhbGx5IG9uIGNsaWVudCBjb25uZWN0aW9uIGFuZCBkaXNjb25uZWN0aW9uIGFuZCBzYXZlZCBpbiB0aGVcbiAgICAgKiBbcmVhZC1vbmx5XSBgY29ubmVjdGlvbnNgIHByb3BlcnR5IG9uIHRoZSBjaGFubmVsUHJvdmlkZXIgYnVzLiAgVGhlIGNoYW5uZWwgd2lsbCBleGlzdCB1bnRpbCB0aGUgcHJvdmlkZXJcbiAgICAgKiBkZXN0cm95cyBpdCBvciBkaXNjb25uZWN0cyBieSBjbG9zaW5nIG9yIGRlc3Ryb3lpbmcgdGhlIGNvbnRleHQgKG5hdmlnYXRpbmcgb3IgcmVsb2FkaW5nKS4gVG8gc2V0dXAgYSBjaGFubmVsXG4gICAgICogYXMgYSBjaGFubmVsUHJvdmlkZXIsIGNhbGwgYENoYW5uZWwuY3JlYXRlYCB3aXRoIGEgdW5pcXVlIGNoYW5uZWwgbmFtZS4gQSBtYXAgb2YgY2xpZW50IGNvbm5lY3Rpb25zIGlzIHVwZGF0ZWRcbiAgICAgKiBhdXRvbWF0aWNhbGx5IG9uIGNsaWVudCBjb25uZWN0aW9uIGFuZCBkaXNjb25uZWN0aW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogKGFzeW5jICgpPT4ge1xuICAgICAqICAgIC8vIGVudGl0eSBjcmVhdGVzIGEgY2hhbm5lbCBhbmQgYmVjb21lcyB0aGUgY2hhbm5lbFByb3ZpZGVyXG4gICAgICogICAgY29uc3QgcHJvdmlkZXJCdXMgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZSgnY2hhbm5lbE5hbWUnKTtcbiAgICAgKlxuICAgICAqICAgIHByb3ZpZGVyQnVzLm9uQ29ubmVjdGlvbigoaWRlbnRpdHksIHBheWxvYWQpID0+IHtcbiAgICAgKiAgICAgICAgLy8gY2FuIHJlamVjdCBhIGNvbm5lY3Rpb24gaGVyZSBieSB0aHJvd2luZyBhbiBlcnJvclxuICAgICAqICAgICAgICBjb25zb2xlLmxvZygnQ2xpZW50IGNvbm5lY3Rpb24gcmVxdWVzdCBpZGVudGl0eTogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ0NsaWVudCBjb25uZWN0aW9uIHJlcXVlc3QgcGF5bG9hZDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgIH0pO1xuICAgICAqXG4gICAgICogICAgcHJvdmlkZXJCdXMucmVnaXN0ZXIoJ3RvcGljJywgKHBheWxvYWQsIGlkZW50aXR5KSA9PiB7XG4gICAgICogICAgICAgIC8vIHJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIGEgJ3RvcGljJyB0byB3aGljaCBjbGllbnRzIGNhbiBkaXNwYXRjaCBhbiBhY3Rpb25cbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ0FjdGlvbiBkaXNwYXRjaGVkIGJ5IGNsaWVudDogJywgSlNPTi5zdHJpbmdpZnkoaWRlbnRpdHkpKTtcbiAgICAgKiAgICAgICAgY29uc29sZS5sb2coJ1BheWxvYWQgc2VudCBpbiBkaXNwYXRjaDogJywgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAqICAgICAgICByZXR1cm4ge1xuICAgICAqICAgICAgICAgICAgZWNobzogcGF5bG9hZFxuICAgICAqICAgICAgICB9O1xuICAgICAqICAgIH0pO1xuICAgICAqIH0pKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlKGNoYW5uZWxOYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICghY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHByb3ZpZGUgYSBjaGFubmVsTmFtZSB0byBjcmVhdGUgYSBjaGFubmVsJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGE6IHByb3ZpZGVySWRlbnRpdHkgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NyZWF0ZS1jaGFubmVsJywgeyBjaGFubmVsTmFtZSB9KTtcbiAgICAgICAgY29uc3QgY2hhbm5lbCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkNih0aGlzLCBfQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciwgXCJmXCIpLmNyZWF0ZVByb3ZpZGVyKG9wdGlvbnMsIHByb3ZpZGVySWRlbnRpdHkpO1xuICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICB0aGlzLm9uKCdjbGllbnQtZGlzY29ubmVjdGVkJywgKGV2ZW50UGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50UGF5bG9hZC5jaGFubmVsTmFtZSA9PT0gY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICBwcm92aWRlcl8xLkNoYW5uZWxQcm92aWRlci5oYW5kbGVDbGllbnREaXNjb25uZWN0aW9uKGNoYW5uZWwsIGV2ZW50UGF5bG9hZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hhbm5lbDtcbiAgICB9XG59XG5jaGFubmVsJDEuQ2hhbm5lbCA9IENoYW5uZWw7XG5fQ2hhbm5lbF9jb25uZWN0aW9uTWFuYWdlciA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsX2ludGVybmFsRW1pdHRlciA9IG5ldyBXZWFrTWFwKCksIF9DaGFubmVsX3JlYWR5VG9Db25uZWN0ID0gbmV3IFdlYWtNYXAoKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGludGVyYXBwYnVzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmludGVyYXBwYnVzLkludGVyQXBwUGF5bG9hZCA9IGludGVyYXBwYnVzLkludGVyQXBwbGljYXRpb25CdXMgPSB2b2lkIDA7XG4vKipcbiAqIEVudHJ5IHBvaW50IGZvciB0aGUgT3BlbkZpbiBgSW50ZXJBcHBsaWNhdGlvbkJ1c2AgQVBJIChgZmluLkludGVyQXBwbGljYXRpb25CdXNgKS5cbiAqXG4gKiAqIHtAbGluayBJbnRlckFwcGxpY2F0aW9uQnVzfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEludGVyQXBwbGljYXRpb25CdXNgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1c2AuXG4gKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKi9cbmNvbnN0IGV2ZW50c18xJDQgPSByZXF1aXJlJCQwO1xuY29uc3QgYmFzZV8xJGQgPSBiYXNlO1xuY29uc3QgcmVmX2NvdW50ZXJfMSA9IHJlZkNvdW50ZXI7XG5jb25zdCBpbmRleF8xJDIgPSBjaGFubmVsJDE7XG5jb25zdCB2YWxpZGF0ZV8xJDMgPSB2YWxpZGF0ZTtcbi8qKlxuICogQSBtZXNzYWdpbmcgYnVzIHRoYXQgYWxsb3dzIGZvciBwdWIvc3ViIG1lc3NhZ2luZyBiZXR3ZWVuIGRpZmZlcmVudCBhcHBsaWNhdGlvbnMuXG4gKlxuICovXG5jbGFzcyBJbnRlckFwcGxpY2F0aW9uQnVzIGV4dGVuZHMgYmFzZV8xJGQuQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgdGhpcy5ldmVudHMgPSB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyQWRkZWQ6ICdzdWJzY3JpYmVyLWFkZGVkJyxcbiAgICAgICAgICAgIHN1YnNjcmliZXJSZW1vdmVkOiAnc3Vic2NyaWJlci1yZW1vdmVkJ1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnJlZkNvdW50ZXIgPSBuZXcgcmVmX2NvdW50ZXJfMS5SZWZDb3VudGVyKCk7XG4gICAgICAgIHRoaXMuQ2hhbm5lbCA9IG5ldyBpbmRleF8xJDIuQ2hhbm5lbCh3aXJlKTtcbiAgICAgICAgdGhpcy5lbWl0dGVyID0gbmV3IGV2ZW50c18xJDQuRXZlbnRFbWl0dGVyKCk7XG4gICAgICAgIHdpcmUucmVnaXN0ZXJNZXNzYWdlSGFuZGxlcih0aGlzLm9ubWVzc2FnZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5vbiA9IHRoaXMuZW1pdHRlci5vbi5iaW5kKHRoaXMuZW1pdHRlcik7XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzID0gdGhpcy5lbWl0dGVyLnJlbW92ZUFsbExpc3RlbmVycy5iaW5kKHRoaXMuZW1pdHRlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2hlcyBhIG1lc3NhZ2UgdG8gYWxsIGFwcGxpY2F0aW9ucyBydW5uaW5nIG9uIE9wZW5GaW4gUnVudGltZSB0aGF0XG4gICAgICogYXJlIHN1YnNjcmliZWQgdG8gdGhlIHNwZWNpZmllZCB0b3BpYy5cbiAgICAgKiBAcGFyYW0gdG9waWMgVGhlIHRvcGljIG9uIHdoaWNoIHRoZSBtZXNzYWdlIGlzIHNlbnRcbiAgICAgKiBAcGFyYW0gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBiZSBwdWJsaXNoZWQuIENhbiBiZSBlaXRoZXIgYSBwcmltaXRpdmVcbiAgICAgKiBkYXRhIHR5cGUgKHN0cmluZywgbnVtYmVyLCBvciBib29sZWFuKSBvciBjb21wb3NpdGUgZGF0YSB0eXBlIChvYmplY3QsIGFycmF5KVxuICAgICAqIHRoYXQgaXMgY29tcG9zZWQgb2Ygb3RoZXIgcHJpbWl0aXZlIG9yIGNvbXBvc2l0ZSBkYXRhIHR5cGVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMucHVibGlzaCgndG9waWMnLCAnaGVsbG8nKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdQdWJsaXNoZWQnKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHB1Ymxpc2godG9waWMsIG1lc3NhZ2UpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3B1Ymxpc2gtbWVzc2FnZScsIHtcbiAgICAgICAgICAgIHRvcGljLFxuICAgICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWU6IHRoaXMubWUubmFtZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZHMgYSBtZXNzYWdlIHRvIGEgc3BlY2lmaWMgYXBwbGljYXRpb24gb24gYSBzcGVjaWZpYyB0b3BpYy5cbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGlkZW50aXR5IG9mIHRoZSBhcHBsaWNhdGlvbiB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIHRvcGljIFRoZSB0b3BpYyBvbiB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gYmUgc2VudC4gQ2FuIGJlIGVpdGhlciBhIHByaW1pdGl2ZSBkYXRhXG4gICAgICogdHlwZSAoc3RyaW5nLCBudW1iZXIsIG9yIGJvb2xlYW4pIG9yIGNvbXBvc2l0ZSBkYXRhIHR5cGUgKG9iamVjdCwgYXJyYXkpIHRoYXRcbiAgICAgKiBpcyBjb21wb3NlZCBvZiBvdGhlciBwcmltaXRpdmUgb3IgY29tcG9zaXRlIGRhdGEgdHlwZXNcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5zZW5kKGZpbi5tZSwgJ3RvcGljJywgJ0hlbGxvIHRoZXJlIScpLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ01lc3NhZ2Ugc2VudCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgc2VuZChkZXN0aW5hdGlvbiwgdG9waWMsIG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMSQzLnZhbGlkYXRlSWRlbnRpdHkpKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzZW5kLW1lc3NhZ2UnLCB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvblV1aWQ6IGRlc3RpbmF0aW9uLnV1aWQsXG4gICAgICAgICAgICBkZXN0aW5hdGlvbldpbmRvd05hbWU6IGRlc3RpbmF0aW9uLm5hbWUsXG4gICAgICAgICAgICB0b3BpYyxcbiAgICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICBzb3VyY2VXaW5kb3dOYW1lOiB0aGlzLm1lLm5hbWVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gbWVzc2FnZXMgZnJvbSB0aGUgc3BlY2lmaWVkIGFwcGxpY2F0aW9uIG9uIHRoZSBzcGVjaWZpZWQgdG9waWMuXG4gICAgICogQHBhcmFtIHNvdXJjZSBUaGlzIG9iamVjdCBpcyBkZXNjcmliZWQgaW4gdGhlIElkZW50aXR5IGluIHRoZSB0eXBlZGVmXG4gICAgICogQHBhcmFtIHRvcGljIFRoZSB0b3BpYyBvbiB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50XG4gICAgICogQHBhcmFtIGxpc3RlbmVyIEEgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiBhIG1lc3NhZ2UgaGFzXG4gICAgICogYmVlbiByZWNlaXZlZC4gSXQgaXMgcGFzc2VkIHRoZSBtZXNzYWdlLCB1dWlkIGFuZCBuYW1lIG9mIHRoZSBzZW5kaW5nIGFwcGxpY2F0aW9uLlxuICAgICAqIFRoZSBtZXNzYWdlIGNhbiBiZSBlaXRoZXIgYSBwcmltaXRpdmUgZGF0YSB0eXBlIChzdHJpbmcsIG51bWJlciwgb3IgYm9vbGVhbikgb3JcbiAgICAgKiBjb21wb3NpdGUgZGF0YSB0eXBlIChvYmplY3QsIGFycmF5KSB0aGF0IGlzIGNvbXBvc2VkIG9mIG90aGVyIHByaW1pdGl2ZSBvciBjb21wb3NpdGVcbiAgICAgKiBkYXRhIHR5cGVzXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogLy8gc3Vic2NyaWJlIHRvIGEgc3BlY2lmaWVkIGFwcGxpY2F0aW9uXG4gICAgICogZmluLkludGVyQXBwbGljYXRpb25CdXMuc3Vic2NyaWJlKGZpbi5tZSwgJ3RvcGljJywgc3ViX21zZyA9PiBjb25zb2xlLmxvZyhzdWJfbXNnKSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnU3Vic2NyaWJlZCB0byB0aGUgc3BlY2lmaWVkIGFwcGxpY2F0aW9uJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIC8vIHN1YnNjcmliZSB0byB3aWxkY2FyZFxuICAgICAqIGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLnN1YnNjcmliZSh7IHV1aWQ6ICcqJyB9LCAndG9waWMnLCBzdWJfbXNnID0+IGNvbnNvbGUubG9nKHN1Yl9tc2cpKS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdTdWJzY3JpYmVkIHRvIConKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHN1YnNjcmliZShzb3VyY2UsIHRvcGljLCBsaXN0ZW5lcikge1xuICAgICAgICBjb25zdCBzdWJLZXkgPSB0aGlzLmNyZWF0ZVN1YnNjcmlwdGlvbktleShzb3VyY2UudXVpZCwgc291cmNlLm5hbWUgfHwgJyonLCB0b3BpYyk7XG4gICAgICAgIGNvbnN0IHNlbmRTdWJzY3JpcHRpb24gPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignc3Vic2NyaWJlJywge1xuICAgICAgICAgICAgICAgIHNvdXJjZVV1aWQ6IHNvdXJjZS51dWlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWU6IHNvdXJjZS5uYW1lIHx8ICcqJyxcbiAgICAgICAgICAgICAgICB0b3BpYyxcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbldpbmRvd05hbWU6IHRoaXMubWUubmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFscmVhZHlTdWJzY3JpYmVkID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmVtaXR0ZXIub24oc3ViS2V5LCBsaXN0ZW5lcik7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZkNvdW50ZXIuYWN0T25GaXJzdChzdWJLZXksIHNlbmRTdWJzY3JpcHRpb24sIGFscmVhZHlTdWJzY3JpYmVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIHRvIG1lc3NhZ2VzIGZyb20gdGhlIHNwZWNpZmllZCBhcHBsaWNhdGlvbiBvbiB0aGUgc3BlY2lmaWVkIHRvcGljLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgeW91IGFyZSBsaXN0ZW5pbmcgdG8gYWxsIGFwcHMgb24gYSB0b3BpYywgKGkuZSB5b3UgcGFzc2VkIGB7IHV1aWQ6JyonIH1gIHRvIHRoZSBzdWJzY3JpYmUgZnVuY3Rpb24pXG4gICAgICogdGhlbiB5b3UgbmVlZCB0byBwYXNzIGB7IHV1aWQ6JyonIH1gIHRvIHVuc3Vic2NyaWJlIGFzIHdlbGwuIElmIHlvdSBhcmUgbGlzdGVuaW5nIHRvIGEgc3BlY2lmaWMgYXBwbGljYXRpb24sXG4gICAgICogKGkuZSB5b3UgcGFzc2VkIGB7IHV1aWQ6J3NvbWVfYXBwJyB9YCB0byB0aGUgc3Vic2NyaWJlIGZ1bmN0aW9uKSB0aGVuIHlvdSBuZWVkIHRvIHByb3ZpZGUgdGhlIHNhbWUgaWRlbnRpZmllciB0b1xuICAgICAqIHVuc3Vic2NyaWJlLCB1bnN1YnNjcmliaW5nIHRvIGAqYCBvbiB0aGF0IHNhbWUgdG9waWMgd2lsbCBub3QgdW5ob29rIHlvdXIgaW5pdGlhbCBsaXN0ZW5lciBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc291cmNlIFRoaXMgb2JqZWN0IGlzIGRlc2NyaWJlZCBpbiB0aGUgSWRlbnRpdHkgaW4gdGhlIHR5cGVkZWZcbiAgICAgKiBAcGFyYW0gdG9waWMgVGhlIHRvcGljIG9uIHdoaWNoIHRoZSBtZXNzYWdlIGlzIHNlbnRcbiAgICAgKiBAcGFyYW0gbGlzdGVuZXIgQSBjYWxsYmFjayBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBzdWJzY3JpYmUoKVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGxpc3RlbmVyID0gY29uc29sZS5sb2c7XG4gICAgICpcbiAgICAgKiAvLyBJZiBhbnkgYXBwbGljYXRpb24gcHVibGlzaGVzIGEgbWVzc2FnZSBvbiB0b3BpYyBgZm9vYCwgb3VyIGxpc3RlbmVyIHdpbGwgYmUgY2FsbGVkLlxuICAgICAqIGF3YWl0IGZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLnN1YnNjcmliZSh7IHV1aWQ6JyonIH0sICdmb28nLCBsaXN0ZW5lcilcbiAgICAgKlxuICAgICAqIC8vIFdoZW4geW91IHdhbnQgdG8gdW5zdWJzY3JpYmUsIHlvdSBuZWVkIHRvIHNwZWNpZnkgdGhlIHV1aWQgb2YgdGhlIGFwcCB5b3UnZCBsaWtlIHRvXG4gICAgICogLy8gdW5zdWJzY3JpYmUgZnJvbSAob3IgYCpgKSBhbmQgcHJvdmlkZSB0aGUgc2FtZSBmdW5jdGlvbiB5b3UgZ2F2ZSB0aGUgc3Vic2NyaWJlIGZ1bmN0aW9uXG4gICAgICogYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMudW5zdWJzY3JpYmUoeyB1dWlkOicqJyB9LCAnZm9vJywgbGlzdGVuZXIpXG4gICAgICogYGBgXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmUoc291cmNlLCB0b3BpYywgbGlzdGVuZXIpIHtcbiAgICAgICAgY29uc3Qgc291cmNlV2luZG93TmFtZSA9IHNvdXJjZS5uYW1lIHx8ICcqJztcbiAgICAgICAgY29uc3Qgc3ViS2V5ID0gdGhpcy5jcmVhdGVTdWJzY3JpcHRpb25LZXkoc291cmNlLnV1aWQsIHNvdXJjZVdpbmRvd05hbWUsIHRvcGljKTtcbiAgICAgICAgY29uc3Qgc2VuZFVuc3Vic2NyaXB0aW9uID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3Vuc3Vic2NyaWJlJywge1xuICAgICAgICAgICAgICAgIHNvdXJjZVV1aWQ6IHNvdXJjZS51dWlkLFxuICAgICAgICAgICAgICAgIHNvdXJjZVdpbmRvd05hbWUsXG4gICAgICAgICAgICAgICAgdG9waWMsXG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25XaW5kb3dOYW1lOiB0aGlzLm1lLm5hbWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBkb250U2VuZFVuc3Vic2NyaXB0aW9uID0gKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyKSA9PiByKS50aGVuKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihzdWJLZXksIGxpc3RlbmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVmQ291bnRlci5hY3RPbkxhc3Qoc3ViS2V5LCBzZW5kVW5zdWJzY3JpcHRpb24sIGRvbnRTZW5kVW5zdWJzY3JpcHRpb24pO1xuICAgIH1cbiAgICBwcm9jZXNzTWVzc2FnZShtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZDogeyBtZXNzYWdlOiBwYXlsb2FkTWVzc2FnZSwgc291cmNlV2luZG93TmFtZSwgc291cmNlVXVpZCwgdG9waWMgfSB9ID0gbWVzc2FnZTtcbiAgICAgICAgY29uc3Qga2V5cyA9IFtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHNvdXJjZVV1aWQsIHNvdXJjZVdpbmRvd05hbWUsIHRvcGljKSxcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHNvdXJjZVV1aWQsICcqJywgdG9waWMpLFxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdWJzY3JpcHRpb25LZXkoJyonLCAnKicsIHRvcGljKVxuICAgICAgICBdO1xuICAgICAgICBjb25zdCBpZE9mU2VuZGVyID0geyB1dWlkOiBzb3VyY2VVdWlkLCBuYW1lOiBzb3VyY2VXaW5kb3dOYW1lIH07XG4gICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIuZW1pdChrZXksIHBheWxvYWRNZXNzYWdlLCBpZE9mU2VuZGVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVtaXRTdWJzY3JpdmVyRXZlbnQodHlwZSwgbWVzc2FnZSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQ6IHsgdGFyZ2V0TmFtZTogbmFtZSwgdXVpZCwgdG9waWMgfSB9ID0gbWVzc2FnZTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHsgbmFtZSwgdXVpZCwgdG9waWMgfTtcbiAgICAgICAgdGhpcy5lbWl0dGVyLmVtaXQodHlwZSwgcGF5bG9hZCk7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG4gICAgY3JlYXRlU3Vic2NyaXB0aW9uS2V5KHV1aWQsIG5hbWUsIHRvcGljKSB7XG4gICAgICAgIGNvbnN0IG4gPSBuYW1lIHx8ICcqJztcbiAgICAgICAgaWYgKCEodXVpZCAmJiBuICYmIHRvcGljKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHV1aWQsIG5hbWUsIG9yIHRvcGljIHN0cmluZycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjcmVhdGVLZXkodXVpZCwgbiwgdG9waWMpO1xuICAgIH1cbiAgICBvbm1lc3NhZ2UobWVzc2FnZSkge1xuICAgICAgICBjb25zdCB7IGFjdGlvbiB9ID0gbWVzc2FnZTtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24pIHtcbiAgICAgICAgICAgIGNhc2UgJ3Byb2Nlc3MtbWVzc2FnZSc6XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzTWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgdGhpcy5ldmVudHMuc3Vic2NyaWJlckFkZGVkOlxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdFN1YnNjcml2ZXJFdmVudCh0aGlzLmV2ZW50cy5zdWJzY3JpYmVyQWRkZWQsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0aGlzLmV2ZW50cy5zdWJzY3JpYmVyUmVtb3ZlZDpcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRTdWJzY3JpdmVyRXZlbnQodGhpcy5ldmVudHMuc3Vic2NyaWJlclJlbW92ZWQsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbmludGVyYXBwYnVzLkludGVyQXBwbGljYXRpb25CdXMgPSBJbnRlckFwcGxpY2F0aW9uQnVzO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgSW50ZXJBcHBQYXlsb2FkIHtcbn1cbmludGVyYXBwYnVzLkludGVyQXBwUGF5bG9hZCA9IEludGVyQXBwUGF5bG9hZDtcbmZ1bmN0aW9uIGNyZWF0ZUtleSguLi50b0hhc2gpIHtcbiAgICByZXR1cm4gdG9IYXNoXG4gICAgICAgIC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGAke2l0ZW19YCkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIH0pXG4gICAgICAgIC5qb2luKCcvJyk7XG59XG5cbnZhciBjbGlwYm9hcmQgPSB7fTtcblxuLyoqXG4gKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYENsaXBib2FyZGAgQVBJIChgZmluLkNsaXBib2FyZGApLlxuICpcbiAqICoge0BsaW5rIENsaXBib2FyZH0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBDbGlwYm9hcmRgIEFQSSwgYWNjZXNzaWJsZSB0aHJvdWdoIGBmaW4uQ2xpcGJvYXJkYC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGNsaXBib2FyZCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jbGlwYm9hcmQuQ2xpcGJvYXJkID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJGMgPSBiYXNlO1xuLyoqXG4gKiBUaGUgQ2xpcGJvYXJkIEFQSSBhbGxvd3MgcmVhZGluZyBhbmQgd3JpdGluZyB0byB0aGUgY2xpcGJvYXJkIGluIG11bHRpcGxlIGZvcm1hdHMuXG4gKlxuICovXG5jbGFzcyBDbGlwYm9hcmQgZXh0ZW5kcyBiYXNlXzEkYy5CYXNlIHtcbiAgICAvKipcbiAgICAgKiBXcml0ZXMgZGF0YSBpbnRvIHRoZSBjbGlwYm9hcmQgYXMgcGxhaW4gdGV4dFxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZVRleHQoe1xuICAgICAqICAgICBkYXRhOiAnaGVsbG8sIHdvcmxkJ1xuICAgICAqIH0pLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ1RleHQgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVRleHQod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS10ZXh0Jywgd3JpdGVPYmopO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjb250ZW50IG9mIHRoZSBjbGlwYm9hcmQgYXMgcGxhaW4gdGV4dFxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkVGV4dCgpLnRoZW4odGV4dCA9PiBjb25zb2xlLmxvZyh0ZXh0KSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRUZXh0KHR5cGUpIHtcbiAgICAgICAgLy8gTk9URTogV2hlbiB3ZSBzdGFydCBzdXBwb3J0aW5nIGxpbnV4LCB3ZSBjb3VsZCBkZXRlY3QgdGhlIE9TIGFuZCBjaG9vc2UgJ3NlbGVjdGlvbicgYXV0b21hdGljYWxseSBmb3IgdGhlIHVzZXJcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXJlYWQtdGV4dCcsIHsgdHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIGFuIEltYWdlXG4gICAgICogQHBhcmFtIHdyaXRlUmVxdWVzdCBUaGUgb2JqZWN0IHRvIHdyaXRlIGFuIGltYWdlIHRvIHRoZSBjbGlwYm9hcmRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBmaW4uQ2xpcGJvYXJkLndyaXRlSW1hZ2Uoe1xuICAgICAqICAgLy8gcmF3IGJhc2U2NCBzdHJpbmcsIG9yIGRhdGFVUkwgb2YgZWl0aGVyIGRhdGE6aW1hZ2UvcG5nIG9yIGRhdGE6aW1hZ2UvanBlZyB0eXBlXG4gICAgICogICBpbWFnZTogJy4uLidcbiAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdJbWFnZSB3cml0dGVuIHRvIGNsaXBib2FyZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JpdGVJbWFnZSh3cml0ZVJlcXVlc3QpIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS1pbWFnZScsIHdyaXRlUmVxdWVzdCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZCBhcyBhIGJhc2U2NCBzdHJpbmcgb3IgYSBkYXRhVVJMIGJhc2VkIG9uIHRoZSBpbnB1dCBwYXJhbWV0ZXIgJ2Zvcm1hdCcsIGRlZmF1bHRzIHRvICdkYXRhVVJMJ1xuICAgICAqIEBwYXJhbSByZWFkUmVxdWVzdCBDbGlwYm9hcmQgUmVhZCBJbWFnZSByZXF1ZXN0IHdpdGggZm9ybWF0dGluZyBvcHRpb25zXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogLy8gc2VlIFRTIHR5cGU6IE9wZW5GaW4uSW1hZ2VGb3JtYXRPcHRpb25zXG4gICAgICpcbiAgICAgKiBjb25zdCBwbmdPckRhdGFVUkxPckJtcE9wdGlvbnMgPSB7XG4gICAgICogICAgIGZvcm1hdDogJ3BuZycsIC8vIGNhbiBiZTogJ3BuZycgfCAnZGF0YVVSTCcgfCAnYm1wJ1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBjb25zdCBqcGdPcHRpb25zID0ge1xuICAgICAqICAgICBmb3JtYXQ6ICdqcGcnLFxuICAgICAqICAgICBxdWFsaXR5OiA4MCAvLyBvcHRpb25hbCwgaWYgb21pdHRlZCBkZWZhdWx0cyB0byAxMDBcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSW1hZ2UocG5nT3JEYXRhVVJMT3JCbXBPcHRpb25zKVxuICAgICAqICAgICAudGhlbihpbWFnZSA9PiBjb25zb2xlLmxvZygnSW1hZ2UgcmVhZCBmcm9tIGNsaXBib2FyZCBhcyBQTkcsIERhdGFVUkwgb3IgQk1QJywgaW1hZ2UpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSW1hZ2UoanBnT3B0aW9ucylcbiAgICAgKiAgICAgLnRoZW4oaW1hZ2UgPT4gY29uc29sZS5sb2coJ0ltYWdlIHJlYWQgZnJvbSBjbGlwYm9hcmQgYXMgSlBHJywgaW1hZ2UpKVxuICAgICAqICAgICAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqXG4gICAgICogLy8gZGVmYXVsdHMgdG8ge2Zvcm1hdDogJ2RhdGFVUkwnfVxuICAgICAqIGZpbi5DbGlwYm9hcmQucmVhZEltYWdlKClcbiAgICAgKiAgICAgLnRoZW4oaW1hZ2UgPT4gY29uc29sZS5sb2coJ0ltYWdlIHJlYWQgZnJvbSBjbGlwYm9hcmQgYXMgRGF0YVVSTCcsIGltYWdlKSlcbiAgICAgKiAgICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRJbWFnZShyZWFkUmVxdWVzdCA9IHsgZm9ybWF0OiAnZGF0YVVSTCcgfSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGlwYm9hcmQtcmVhZC1pbWFnZScsIHJlYWRSZXF1ZXN0KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIEh0bWxcbiAgICAgKiBAcGFyYW0gd3JpdGVPYmogVGhlIG9iamVjdCBmb3Igd3JpdGluZyBkYXRhIGludG8gdGhlIGNsaXBib2FyZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5DbGlwYm9hcmQud3JpdGVIdG1sKHtcbiAgICAgKiAgICAgICAgIGRhdGE6ICc8aDE+SGVsbG8sIFdvcmxkITwvaDE+J1xuICAgICAqIH0pLnRoZW4oKCkgPT4gY29uc29sZS5sb2coJ0hUTUwgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZUh0bWwod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZS1odG1sJywgd3JpdGVPYmopO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjb250ZW50IG9mIHRoZSBjbGlwYm9hcmQgYXMgSHRtbFxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5yZWFkSHRtbCgpLnRoZW4oaHRtbCA9PiBjb25zb2xlLmxvZyhodG1sKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRIdG1sKHR5cGUpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXJlYWQtaHRtbCcsIHsgdHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIHBheWxvYWQuZGF0YTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JpdGVzIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkIGFzIFJ0ZlxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZVJ0Zih7XG4gICAgICogICAgICAgICBkYXRhOiAnc29tZSB0ZXh0IGdvZXMgaGVyZSdcbiAgICAgKiB9KS50aGVuKCgpID0+IGNvbnNvbGUubG9nKCdSVEYgT24gY2xpcGJvYXJkJykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cml0ZVJ0Zih3cml0ZU9iaikge1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignY2xpcGJvYXJkLXdyaXRlLXJ0ZicsIHdyaXRlT2JqKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY29udGVudCBvZiB0aGUgY2xpcGJvYXJkIGFzIFJ0ZlxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB3cml0ZU9iaiA9IHtcbiAgICAgKiAgICAgZGF0YTogJ3NvbWUgdGV4dCBnb2VzIGhlcmUnXG4gICAgICogfTtcbiAgICAgKiBhc3luYyBmdW5jdGlvbiByZWFkUnRmKCkge1xuICAgICAqICAgICBhd2FpdCBmaW4uQ2xpcGJvYXJkLndyaXRlUnRmKHdyaXRlT2JqKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGZpbi5DbGlwYm9hcmQucmVhZFJ0ZigpO1xuICAgICAqIH1cbiAgICAgKiByZWFkUnRmKCkudGhlbihydGYgPT4gY29uc29sZS5sb2cocnRmKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHJlYWRSdGYodHlwZSkge1xuICAgICAgICBjb25zdCB7IHBheWxvYWQgfSA9IGF3YWl0IHRoaXMud2lyZS5zZW5kQWN0aW9uKCdjbGlwYm9hcmQtcmVhZC1ydGYnLCB7IHR5cGUgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyaXRlcyBkYXRhIGludG8gdGhlIGNsaXBib2FyZFxuICAgICAqIEBwYXJhbSB3cml0ZU9iaiBUaGUgb2JqZWN0IGZvciB3cml0aW5nIGRhdGEgaW50byB0aGUgY2xpcGJvYXJkXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC53cml0ZSh7XG4gICAgICogICBkYXRhOiB7XG4gICAgICogICAgIHRleHQ6ICdhJyxcbiAgICAgKiAgICAgaHRtbDogJ2InLFxuICAgICAqICAgICBydGY6ICdjJyxcbiAgICAgKiAgICAgLy8gQ2FuIGJlIGVpdGhlciBhIGJhc2U2NCBzdHJpbmcsIG9yIGEgRGF0YVVSTCBzdHJpbmcuIElmIHVzaW5nIERhdGFVUkwsIHRoZVxuICAgICAqICAgICAvLyBzdXBwb3J0ZWQgZm9ybWF0cyBhcmUgYGRhdGE6aW1hZ2UvcG5nWztiYXNlNjRdLGAgYW5kIGBkYXRhOmltYWdlL2pwZWdbO2Jhc2U2NF0sYC5cbiAgICAgKiAgICAgLy8gVXNpbmcgb3RoZXIgaW1hZ2UvPGZvcm1hdD4gRGF0YVVSTHMgd2lsbCB0aHJvdyBhbiBFcnJvci5cbiAgICAgKiAgICAgaW1hZ2U6ICcuLi4nXG4gICAgICogICB9XG4gICAgICogfSkudGhlbigoKSA9PiBjb25zb2xlLmxvZygnd3JpdGUgZGF0YSBpbnRvIGNsaXBib2FyZCcpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JpdGUod3JpdGVPYmopIHtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC13cml0ZScsIHdyaXRlT2JqKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZHMgYXZhaWxhYmxlIGZvcm1hdHMgZm9yIHRoZSBjbGlwYm9hcmQgdHlwZVxuICAgICAqIEBwYXJhbSB0eXBlIENsaXBib2FyZCBUeXBlIGRlZmF1bHRzIHRvICdjbGlwYm9hcmQnLCB1c2UgJ3NlbGVjdGlvbicgZm9yIGxpbnV4XG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkNsaXBib2FyZC5nZXRBdmFpbGFibGVGb3JtYXRzKCkudGhlbihmb3JtYXRzID0+IGNvbnNvbGUubG9nKGZvcm1hdHMpKS5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0QXZhaWxhYmxlRm9ybWF0cyh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHsgcGF5bG9hZCB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2NsaXBib2FyZC1yZWFkLWZvcm1hdHMnLCB7IHR5cGUgfSk7XG4gICAgICAgIHJldHVybiBwYXlsb2FkLmRhdGE7XG4gICAgfVxufVxuY2xpcGJvYXJkLkNsaXBib2FyZCA9IENsaXBib2FyZDtcblxudmFyIGV4dGVybmFsQXBwbGljYXRpb24gPSB7fTtcblxudmFyIEZhY3RvcnkkNSA9IHt9O1xuXG52YXIgSW5zdGFuY2UkNCA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW5zdGFuY2UkNCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZSQ0LkV4dGVybmFsQXBwbGljYXRpb24gPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5jb25zdCBiYXNlXzEkYiA9IGJhc2U7XG4vKipcbiAqIEFuIEV4dGVybmFsQXBwbGljYXRpb24gb2JqZWN0IHJlcHJlc2VudGluZyBuYXRpdmUgbGFuZ3VhZ2UgYWRhcHRlciBjb25uZWN0aW9ucyB0byB0aGUgcnVudGltZS4gQWxsb3dzXG4gKiB0aGUgZGV2ZWxvcGVyIHRvIGxpc3RlbiB0byB7QGxpbmsgT3BlbkZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uRXZlbnRzIGV4dGVybmFsIGFwcGxpY2F0aW9uIGV2ZW50c30uXG4gKiBEaXNjb3Zlcnkgb2YgY29ubmVjdGlvbnMgaXMgcHJvdmlkZWQgYnkge0BsaW5rIFN5c3RlbS5TeXN0ZW0uZ2V0QWxsRXh0ZXJuYWxBcHBsaWNhdGlvbnMgZ2V0QWxsRXh0ZXJuYWxBcHBsaWNhdGlvbnN9LjwvYT5cbiAqXG4gKiBQcm9jZXNzZXMgdGhhdCBjYW4gYmUgd3JhcHBlZCBhcyBgRXh0ZXJuYWxBcHBsaWNhdGlvbmBzIGluY2x1ZGUgdGhlIGZvbGxvd2luZzpcbiAqIC0gUHJvY2Vzc2VzIHdoaWNoIGhhdmUgY29ubmVjdGVkIHRvIGFuIE9wZW5GaW4gcnVudGltZSB2aWEgYW4gYWRhcHRlclxuICogLSBQcm9jZXNzZXMgc3RhcnRlZCB2aWEgYFN5c3RlbS5sYXVuY2hFeHRlcm5hbEFwcGxpY2F0aW9uYFxuICogLSBQcm9jZXNzZXMgbW9uaXRvcmVkIHZpYSBgU3lzdGVtLm1vbml0b3JFeHRlcm5hbFByb2Nlc3NgXG4gKi9cbmNsYXNzIEV4dGVybmFsQXBwbGljYXRpb24gZXh0ZW5kcyBiYXNlXzEkYi5FbWl0dGVyQmFzZSB7XG4gICAgLyoqXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iod2lyZSwgaWRlbnRpdHkpIHtcbiAgICAgICAgc3VwZXIod2lyZSwgJ2V4dGVybmFsLWFwcGxpY2F0aW9uJywgaWRlbnRpdHkudXVpZCk7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBleHRlcm5hbCBhcHBsaWNhdGlvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRJbmZvKCkge1xuICAgICAqICAgICBjb25zdCBleHRBcHAgPSBhd2FpdCBmaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbi53cmFwKCdqYXZhQXBwLXV1aWQnKTtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IGV4dEFwcC5nZXRJbmZvKCk7XG4gICAgICogfVxuICAgICAqIGdldEluZm8oKS50aGVuKGluZm8gPT4gY29uc29sZS5sb2coaW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRJbmZvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dldC1leHRlcm5hbC1hcHBsaWNhdGlvbi1pbmZvJywgdGhpcy5pZGVudGl0eSkudGhlbigoeyBwYXlsb2FkIH0pID0+IHBheWxvYWQuZGF0YSk7XG4gICAgfVxufVxuSW5zdGFuY2UkNC5FeHRlcm5hbEFwcGxpY2F0aW9uID0gRXh0ZXJuYWxBcHBsaWNhdGlvbjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkNSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDUuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSRhID0gYmFzZTtcbmNvbnN0IEluc3RhbmNlXzEkNCA9IEluc3RhbmNlJDQ7XG4vKipcbiAqIFN0YXRpYyBuYW1lc3BhY2UgZm9yIE9wZW5GaW4gQVBJIG1ldGhvZHMgdGhhdCBpbnRlcmFjdCB3aXRoIHRoZSB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbn0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkV4dGVybmFsQXBwbGljYXRpb25gLlxuICovXG5jbGFzcyBFeHRlcm5hbEFwcGxpY2F0aW9uTW9kdWxlIGV4dGVuZHMgYmFzZV8xJGEuQmFzZSB7XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBFeHRlcm5hbCBBcHBsaWNhdGlvbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGFuIGV4dGVybmFsIGFwcGxpY2F0aW9uLlxuICAgICAqIDxicj5JdCBpcyBwb3NzaWJsZSB0byB3cmFwIGEgcHJvY2VzcyB0aGF0IGRvZXMgbm90IHlldCBleGlzdCwgKGZvciBleGFtcGxlLCB0byBsaXN0ZW4gZm9yIHN0YXJ0dXAtcmVsYXRlZCBldmVudHMpXG4gICAgICogcHJvdmlkZWQgaXRzIHV1aWQgaXMgYWxyZWFkeSBrbm93bi5cbiAgICAgKiBAcGFyYW0gdXVpZCBUaGUgVVVJRCBvZiB0aGUgZXh0ZXJuYWwgYXBwbGljYXRpb24gdG8gYmUgd3JhcHBlZFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uLndyYXAoJ2phdmFBcHAtdXVpZCcpO1xuICAgICAqIC50aGVuKGV4dEFwcCA9PiBjb25zb2xlLmxvZygnd3JhcHBlZCBleHRlcm5hbCBhcHBsaWNhdGlvbicpKVxuICAgICAqIC5jYXRjaChlcnIgPT4gY29uc29sZS5sb2coZXJyKSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgd3JhcCh1dWlkKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdleHRlcm5hbC1hcHBsaWNhdGlvbi13cmFwJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgSW5zdGFuY2VfMSQ0LkV4dGVybmFsQXBwbGljYXRpb24odGhpcy53aXJlLCB7IHV1aWQgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gRXh0ZXJuYWwgQXBwbGljYXRpb24gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleHRlcm5hbCBhcHBsaWNhdGlvbi5cbiAgICAgKiA8YnI+SXQgaXMgcG9zc2libGUgdG8gd3JhcCBhIHByb2Nlc3MgdGhhdCBkb2VzIG5vdCB5ZXQgZXhpc3QsIChmb3IgZXhhbXBsZSwgdG8gbGlzdGVuIGZvciBzdGFydHVwLXJlbGF0ZWQgZXZlbnRzKVxuICAgICAqIHByb3ZpZGVkIGl0cyB1dWlkIGlzIGFscmVhZHkga25vd24uXG4gICAgICogQHBhcmFtIHV1aWQgVGhlIFVVSUQgb2YgdGhlIGV4dGVybmFsIGFwcGxpY2F0aW9uIHRvIGJlIHdyYXBwZWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBleHRBcHAgPSBmaW4uRXh0ZXJuYWxBcHBsaWNhdGlvbi53cmFwU3luYygnamF2YUFwcC11dWlkJyk7XG4gICAgICogY29uc3QgaW5mbyA9IGF3YWl0IGV4dEFwcC5nZXRJbmZvKCk7XG4gICAgICogY29uc29sZS5sb2coaW5mbyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgd3JhcFN5bmModXVpZCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZXh0ZXJuYWwtYXBwbGljYXRpb24td3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDQuRXh0ZXJuYWxBcHBsaWNhdGlvbih0aGlzLndpcmUsIHsgdXVpZCB9KTtcbiAgICB9XG59XG5GYWN0b3J5JDUuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSA9IEV4dGVybmFsQXBwbGljYXRpb25Nb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgRXh0ZXJuYWxBcHBsaWNhdGlvbmAgQVBJIChgZmluLkV4dGVybmFsQXBwbGljYXRpb25gKS5cblx0ICpcblx0ICogKiB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBFeHRlcm5hbEFwcGxpY2F0aW9uYCB0eXBlLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5FeHRlcm5hbEFwcGxpY2F0aW9uYC5cblx0ICogKiB7QGxpbmsgRXh0ZXJuYWxBcHBsaWNhdGlvbn0gZGVzY3JpYmVzIGFuIGluc3RhbmNlIG9mIGFuIE9wZW5GaW4gRXh0ZXJuYWxBcHBsaWNhdGlvbiwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLkV4dGVybmFsQXBwbGljYXRpb24uZ2V0Q3VycmVudGAuXG5cdCAqXG5cdCAqIFRoZXNlIGFyZSBzZXBhcmF0ZSBjb2RlIGVudGl0aWVzLCBhbmQgYXJlIGRvY3VtZW50ZWQgc2VwYXJhdGVseS4gIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdCAqL1xuXHRfX2V4cG9ydFN0YXIoRmFjdG9yeSQ1LCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKEluc3RhbmNlJDQsIGV4cG9ydHMpOyBcbn0gKGV4dGVybmFsQXBwbGljYXRpb24pKTtcblxudmFyIGZyYW1lID0ge307XG5cbnZhciBGYWN0b3J5JDQgPSB7fTtcblxudmFyIEluc3RhbmNlJDMgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuSW5zdGFuY2UkMy5fRnJhbWUgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvcHJlZmVyLWRlZmF1bHQtZXhwb3J0ICovXG5jb25zdCBiYXNlXzEkOSA9IGJhc2U7XG4vKipcbiAqIEFuIGlmcmFtZSByZXByZXNlbnRzIGFuIGVtYmVkZGVkIEhUTUwgcGFnZSB3aXRoaW4gYSBwYXJlbnQgSFRNTCBwYWdlLiBCZWNhdXNlIHRoaXMgZW1iZWRkZWQgcGFnZVxuICogaGFzIGl0cyBvd24gRE9NIGFuZCBnbG9iYWwgSlMgY29udGV4dCAod2hpY2ggbWF5IG9yIG1heSBub3QgYmUgbGlua2VkIHRvIHRoYXQgb2YgdGhlIHBhcmVudCBkZXBlbmRpbmdcbiAqIG9uIGlmIGl0IGlzIGNvbnNpZGVyZWQgb3V0IG9mIHRoZSByb290IGRvbWFpbiBvciBub3QpLCBpdCByZXByZXNlbnRzIGEgdW5pcXVlIGVuZHBvaW50IGFzIGFuIE9wZW5GaW5cbiAqIGNvbm5lY3Rpb24uIElmcmFtZXMgbWF5IGJlIGdlbmVyYXRlZCBkeW5hbWljYWxseSwgb3IgYmUgcHJlc2VudCBvbiBpbml0aWFsIHBhZ2UgbG9hZCBhbmQgZWFjaCBub24tQ09SU1xuICogaWZyYW1lIGhhcyB0aGUgT3BlbkZpbiBBUEkgaW5qZWN0ZWQgYnkgZGVmYXVsdC4gSXQgaXMgcG9zc2libGUgdG8gb3B0IGludG8gY3Jvc3Mtb3JpZ2luIGlmcmFtZXMgaGF2aW5nXG4gKiB0aGUgQVBJIGJ5IHNldHRpbmcgYXBpLmlmcmFtZS5jcm9zc09yaWdpbkluamVjdGlvbiB0byB0cnVlIGluIGEgd2luZG93J3Mgb3B0aW9ucy4gVG8gYmxvY2sgYWxsIGlmcmFtZXNcbiAqIGZyb20gZ2V0dGluZyB0aGUgQVBJIGluamVjdGVkIHlvdSBjYW4gc2V0IGFwaS5mcmFtZS5zYW1lT3JpZ2luSW5qZWN0aW9uXG4gKiB0byBmYWxzZSA8YSBocmVmPVwiV2luZG93Lmh0bWwjfm9wdGlvbnNcIiB0YXJnZXQ9XCJfYmxhbmtcIj4oe0BsaW5rIE9wZW5GaW4uV2luZG93Q3JlYXRpb25PcHRpb25zIHNlZSBXaW5kb3cgT3B0aW9uc30pPC9hPi5cbiAqXG4gKiBUbyBiZSBhYmxlIHRvIGRpcmVjdGx5IGFkZHJlc3MgdGhpcyBjb250ZXh0IGZvciBldmVudGluZyBhbmQgbWVzc2FnaW5nIHB1cnBvc2VzLCBpdCBuZWVkcyBhXG4gKiB1bmlxdWUgdXVpZCBuYW1lIHBhaXJpbmcuIEZvciBPcGVuRmluIGFwcGxpY2F0aW9ucyBhbmQgd2luZG93cyB0aGlzIGlzIHByb3ZpZGVkIHZpYSBhIGNvbmZpZ3VyYXRpb25cbiAqIG9iamVjdCBpbiB0aGUgZm9ybSBvZiBhIG1hbmlmZXN0IFVSTCBvciBvcHRpb25zIG9iamVjdCwgYnV0IHRoZXJlIGlzIG5vIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciBpZnJhbWVzLlxuICogSnVzdCBhcyBhIGNhbGwgdG8gd2luZG93Lm9wZW4gb3V0c2lkZSBvZiBvdXIgV2luZG93IEFQSSByZXR1cm5zIGEgbmV3IHdpbmRvdyB3aXRoIGEgcmFuZG9tIEdVSUQgYXNzaWduZWRcbiAqIGZvciB0aGUgbmFtZSwgZWFjaCBpZnJhbWUgdGhhdCBoYXMgdGhlIEFQSSBpbmplY3RlZCB3aWxsIGJlIGFzc2lnbmVkIGEgR1VJRCBhcyBpdHMgbmFtZSwgdGhlIFVVSUQgd2lsbCBiZVxuICogdGhlIHNhbWUgYXMgdGhlIHBhcmVudCB3aW5kb3cncy5cbiAqXG4gKiBUaGUgZmluLkZyYW1lIG5hbWVzcGFjZSByZXByZXNlbnRzIGEgd2F5IHRvIGludGVyYWN0IHdpdGggYGlmcmFtZXNgIGFuZCBmYWNpbGl0YXRlcyB0aGUgZGlzY292ZXJ5IG9mIGN1cnJlbnQgY29udGV4dFxuICogKGlmcmFtZSBvciBtYWluIHdpbmRvdykgYXMgd2VsbCBhcyB0aGUgYWJpbGl0eSB0byBsaXN0ZW4gZm9yIHtAbGluayBPcGVuRmluLkZyYW1lRXZlbnRzIGZyYW1lLXNwZWNpZmljIGV2ZW50c30uXG4gKi9cbmNsYXNzIF9GcmFtZSBleHRlbmRzIGJhc2VfMSQ5LkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlLCBpZGVudGl0eSkge1xuICAgICAgICBzdXBlcih3aXJlLCAnZnJhbWUnLCBpZGVudGl0eS51dWlkLCBpZGVudGl0eS5uYW1lKTtcbiAgICAgICAgdGhpcy5pZGVudGl0eSA9IGlkZW50aXR5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgZnJhbWUgaW5mbyBvYmplY3QgZm9yIHRoZSByZXByZXNlbnRlZCBmcmFtZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBnZXRJbmZvKCkge1xuICAgICAqICAgICBjb25zdCBmcm0gPSBhd2FpdCBmaW4uRnJhbWUuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZnJtLmdldEluZm8oKTtcbiAgICAgKiB9XG4gICAgICogZ2V0SW5mbygpLnRoZW4oaW5mbyA9PiBjb25zb2xlLmxvZyhpbmZvKSkuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEluZm8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LWZyYW1lLWluZm8nLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGZyYW1lIGluZm8gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgd2luZG93IHRoYXQgdGhlIHJlZmVyZW5jZWQgaWZyYW1lIGlzXG4gICAgICogY3VycmVudGx5IGVtYmVkZGVkIGluLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgdGhlIGZyYW1lIGlzIGVtYmVkZGVkIGluIGEgdmlldywgdGhpcyB3aWxsIHJldHVybiBhbiBpbnZhbGlkIHN0dWIgd2l0aCBlbXB0eSBmaWVsZHMuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogYXN5bmMgZnVuY3Rpb24gZ2V0UGFyZW50V2luZG93KCkge1xuICAgICAqICAgICBjb25zdCBmcm0gPSBhd2FpdCBmaW4uRnJhbWUuZ2V0Q3VycmVudCgpO1xuICAgICAqICAgICByZXR1cm4gYXdhaXQgZnJtLmdldFBhcmVudFdpbmRvdygpO1xuICAgICAqIH1cbiAgICAgKiBnZXRQYXJlbnRXaW5kb3coKS50aGVuKHdpbkluZm8gPT4gY29uc29sZS5sb2cod2luSW5mbykpLmNhdGNoKGVyciA9PiBjb25zb2xlLmxvZyhlcnIpKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRQYXJlbnRXaW5kb3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2V0LXBhcmVudC13aW5kb3cnLCB0aGlzLmlkZW50aXR5KS50aGVuKCh7IHBheWxvYWQgfSkgPT4gcGF5bG9hZC5kYXRhKTtcbiAgICB9XG59XG5JbnN0YW5jZSQzLl9GcmFtZSA9IF9GcmFtZTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkNCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDQuX0ZyYW1lTW9kdWxlID0gdm9pZCAwO1xuY29uc3QgYmFzZV8xJDggPSBiYXNlO1xuY29uc3QgdmFsaWRhdGVfMSQyID0gdmFsaWRhdGU7XG5jb25zdCBJbnN0YW5jZV8xJDMgPSBJbnN0YW5jZSQzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIF9GcmFtZX0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLkZyYW1lYC5cbiAqL1xuY2xhc3MgX0ZyYW1lTW9kdWxlIGV4dGVuZHMgYmFzZV8xJDguQmFzZSB7XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhbiBBUEkgaGFuZGxlIGZvciB0aGUgZ2l2ZW4gRnJhbWUgaWRlbnRpdHkuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXcmFwcGluZyBhIEZyYW1lIGlkZW50aXR5IHRoYXQgZG9lcyBub3QgeWV0IGV4aXN0IHdpbGwgKm5vdCogdGhyb3cgYW4gZXJyb3IsIGFuZCBpbnN0ZWFkXG4gICAgICogcmV0dXJucyBhIHN0dWIgb2JqZWN0IHRoYXQgY2Fubm90IHlldCBwZXJmb3JtIHJlbmRlcmluZyB0YXNrcy4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBwbHVtYmluZyBldmVudGluZ1xuICAgICAqIGZvciBhIEZyYW1lIHRocm91Z2hvdXQgaXRzIGVudGlyZSBsaWZlY3ljbGUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkZyYW1lLndyYXAoeyB1dWlkOiAndGVzdEZyYW1lJywgbmFtZTogJ3Rlc3RGcmFtZScgfSlcbiAgICAgKiAudGhlbihmcm0gPT4gY29uc29sZS5sb2coJ3dyYXBwZWQgZnJhbWUnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHdyYXAoaWRlbnRpdHkpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZyYW1lLXdyYXAnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xJDIudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuICAgICAgICBpZiAoZXJyb3JNc2cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDMuX0ZyYW1lKHRoaXMud2lyZSwgaWRlbnRpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jaHJvbm91c2x5IHJldHVybnMgYW4gQVBJIGhhbmRsZSBmb3IgdGhlIGdpdmVuIEZyYW1lIGlkZW50aXR5LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgV3JhcHBpbmcgYSBGcmFtZSBpZGVudGl0eSB0aGF0IGRvZXMgbm90IHlldCBleGlzdCB3aWxsICpub3QqIHRocm93IGFuIGVycm9yLCBhbmQgaW5zdGVhZFxuICAgICAqIHJldHVybnMgYSBzdHViIG9iamVjdCB0aGF0IGNhbm5vdCB5ZXQgcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgcGx1bWJpbmcgZXZlbnRpbmdcbiAgICAgKiBmb3IgYSBGcmFtZSB0aHJvdWdob3V0IGl0cyBlbnRpcmUgbGlmZWN5Y2xlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGZybSA9IGZpbi5GcmFtZS53cmFwU3luYyh7IHV1aWQ6ICd0ZXN0RnJhbWUnLCBuYW1lOiAndGVzdEZyYW1lJyB9KTtcbiAgICAgKiBjb25zdCBpbmZvID0gYXdhaXQgZnJtLmdldEluZm8oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhpbmZvKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZnJhbWUtd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSAoMCwgdmFsaWRhdGVfMSQyLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMSQzLl9GcmFtZSh0aGlzLndpcmUsIGlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBmcmFtZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGZpbi5GcmFtZS5nZXRDdXJyZW50KClcbiAgICAgKiAudGhlbihmcm0gPT4gY29uc29sZS5sb2coJ2N1cnJlbnQgZnJhbWUnKSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IGNvbnNvbGUubG9nKGVycikpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmcmFtZS1nZXQtY3VycmVudCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEluc3RhbmNlXzEkMy5fRnJhbWUodGhpcy53aXJlLCB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0Q3VycmVudEVudGl0eUlkZW50aXR5KCkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IGZyYW1lXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgZnJtID0gZmluLkZyYW1lLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgaW5mbyA9IGF3YWl0IGZybS5nZXRJbmZvKCk7XG4gICAgICogY29uc29sZS5sb2coaW5mbyk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q3VycmVudFN5bmMoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmcmFtZS1nZXQtY3VycmVudC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDMuX0ZyYW1lKHRoaXMud2lyZSwgdGhpcy53aXJlLmVudmlyb25tZW50LmdldEN1cnJlbnRFbnRpdHlJZGVudGl0eSgpKTtcbiAgICB9XG59XG5GYWN0b3J5JDQuX0ZyYW1lTW9kdWxlID0gX0ZyYW1lTW9kdWxlO1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0LyoqXG5cdCAqIEVudHJ5IHBvaW50cyBmb3IgdGhlIE9wZW5GaW4gYEZyYW1lYCBBUEkgKGBmaW4uRnJhbWVgKS5cblx0ICpcblx0ICogKiB7QGxpbmsgX0ZyYW1lTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEZyYW1lYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLkZyYW1lYC5cblx0ICogKiB7QGxpbmsgX0ZyYW1lfSBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gT3BlbkZpbiBGcmFtZSwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLkZyYW1lLmdldEN1cnJlbnRgLlxuXHQgKlxuXHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogVW5kZXJzY29yZSBwcmVmaXhpbmcgb2YgT3BlbkZpbiB0eXBlcyB0aGF0IGFsaWFzIERPTSBlbnRpdGllcyB3aWxsIGJlIGZpeGVkIGluIGEgZnV0dXJlIHZlcnNpb24uXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnkkNCwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihJbnN0YW5jZSQzLCBleHBvcnRzKTsgXG59IChmcmFtZSkpO1xuXG52YXIgZ2xvYmFsSG90a2V5ID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxIb3RrZXksIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZ2xvYmFsSG90a2V5Lkdsb2JhbEhvdGtleSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSQ3ID0gYmFzZTtcbi8qKlxuICogVGhlIEdsb2JhbEhvdGtleSBtb2R1bGUgY2FuIHJlZ2lzdGVyL3VucmVnaXN0ZXIgYSBnbG9iYWwgaG90a2V5cy5cbiAqXG4gKi9cbmNsYXNzIEdsb2JhbEhvdGtleSBleHRlbmRzIGJhc2VfMSQ3LkVtaXR0ZXJCYXNlIHtcbiAgICAvKipcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih3aXJlKSB7XG4gICAgICAgIHN1cGVyKHdpcmUsICdnbG9iYWwtaG90a2V5Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlZ2lzdGVycyBhIGdsb2JhbCBob3RrZXkgd2l0aCB0aGUgb3BlcmF0aW5nIHN5c3RlbS5cbiAgICAgKiBAcGFyYW0gaG90a2V5IGEgaG90a2V5IHN0cmluZ1xuICAgICAqIEBwYXJhbSBsaXN0ZW5lciBjYWxsZWQgd2hlbiB0aGUgcmVnaXN0ZXJlZCBob3RrZXkgaXMgcHJlc3NlZCBieSB0aGUgdXNlci5cbiAgICAgKiBAdGhyb3dzIElmIHRoZSBgaG90a2V5YCBpcyByZXNlcnZlZCwgc2VlIGxpc3QgYmVsb3cuXG4gICAgICogQHRocm93cyBpZiB0aGUgYGhvdGtleWAgaXMgYWxyZWFkeSByZWdpc3RlcmVkIGJ5IGFub3RoZXIgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgYGhvdGtleWAgcGFyYW1ldGVyIGV4cGVjdHMgYW4gZWxlY3Ryb24gY29tcGF0aWJsZSBbYWNjZWxlcmF0b3JdKGh0dHBzOi8vZ2l0aHViLmNvbS9lbGVjdHJvbi9lbGVjdHJvbi9ibG9iL21hc3Rlci9kb2NzL2FwaS9hY2NlbGVyYXRvci5tZCkgYW5kIHRoZSBgbGlzdGVuZXJgIHdpbGwgYmUgY2FsbGVkIGlmIHRoZSBgaG90a2V5YCBpcyBwcmVzc2VkIGJ5IHRoZSB1c2VyLlxuICAgICAqIElmIHN1Y2Nlc3NmdWxsLCB0aGUgaG90a2V5IHdpbGwgYmUgJ2NsYWltZWQnIGJ5IHRoZSBhcHBsaWNhdGlvbiwgbWVhbmluZyB0aGF0IHRoaXMgcmVnaXN0ZXIgY2FsbCBjYW4gYmUgY2FsbGVkIG11bHRpcGxlIHRpbWVzIGZyb20gd2l0aGluIHRoZSBzYW1lIGFwcGxpY2F0aW9uIGJ1dCB3aWxsIGZhaWwgaWYgYW5vdGhlciBhcHBsaWNhdGlvbiBoYXMgcmVnaXN0ZXJlZCB0aGUgaG90a2V5LlxuICAgICAqIDxicj5UaGUgcmVnaXN0ZXIgY2FsbCB3aWxsIGZhaWwgaWYgZ2l2ZW4gYW55IG9mIHRoZXNlIHJlc2VydmVkIEhvdGtleXM6XG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCswYFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrPWBcbiAgICAgKiAqIGBDb21tYW5kT3JDb250cm9sK1BsdXNgXG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCstYFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrX2BcbiAgICAgKiAqIGBDb21tYW5kT3JDb250cm9sK1NoaWZ0K0lgXG4gICAgICogKiBgRjVgXG4gICAgICogKiBgQ29tbWFuZE9yQ29udHJvbCtSYFxuICAgICAqICogYFNoaWZ0K0Y1YFxuICAgICAqICogYENvbW1hbmRPckNvbnRyb2wrU2hpZnQrUmBcbiAgICAgKlxuICAgICAqIFJhaXNlcyB0aGUgYHJlZ2lzdGVyZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGhvdGtleSA9ICdDb21tYW5kT3JDb250cm9sK1gnO1xuICAgICAqXG4gICAgICogZmluLkdsb2JhbEhvdGtleS5yZWdpc3Rlcihob3RrZXksICgpID0+IHtcbiAgICAgKiBjb25zb2xlLmxvZyhgJHtob3RrZXl9IHByZXNzZWRgKTtcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKCgpID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ1N1Y2Nlc3MnKTtcbiAgICAgKiB9KVxuICAgICAqIC5jYXRjaChlcnIgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnRXJyb3IgcmVnaXN0ZXJpbmcgdGhlIGhvdGtleScsIGVycik7XG4gICAgICogfSk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcmVnaXN0ZXIoaG90a2V5LCBsaXN0ZW5lcikge1xuICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChob3RrZXkgZXZlbnRzIGFyZSBub3QgdHlwZWQpXG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgICAgYXdhaXQgdGhpcy5vbihob3RrZXksIGxpc3RlbmVyKTtcbiAgICAgICAgYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dsb2JhbC1ob3RrZXktcmVnaXN0ZXInLCB7IGhvdGtleSB9KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5yZWdpc3RlcnMgYSBnbG9iYWwgaG90a2V5IHdpdGggdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICogQHBhcmFtIGhvdGtleSBhIGhvdGtleSBzdHJpbmdcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIHdpbGwgdW5yZWdpc3RlciBhbGwgZXhpc3RpbmcgcmVnaXN0cmF0aW9ucyBvZiB0aGUgaG90a2V5IHdpdGhpbiB0aGUgYXBwbGljYXRpb24uXG4gICAgICogUmFpc2VzIHRoZSBgdW5yZWdpc3RlcmVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBob3RrZXkgPSAnQ29tbWFuZE9yQ29udHJvbCtYJztcbiAgICAgKlxuICAgICAqIGZpbi5HbG9iYWxIb3RrZXkudW5yZWdpc3Rlcihob3RrZXkpXG4gICAgICogLnRoZW4oKCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnU3VjY2VzcycpO1xuICAgICAqIH0pXG4gICAgICogLmNhdGNoKGVyciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnJlZ2lzdGVyaW5nIHRoZSBob3RrZXknLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXIoaG90a2V5KSB7XG4gICAgICAgIC8vIFRPRE86IGZpeCB0eXBpbmcgKGhvdGtleSBldmVudHMgYXJlIG5vdCB0eXBlZClcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhob3RrZXkpO1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2xvYmFsLWhvdGtleS11bnJlZ2lzdGVyJywgeyBob3RrZXkgfSk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVucmVnaXN0ZXJzIGFsbCBnbG9iYWwgaG90a2V5cyBmb3IgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24uXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBSYWlzZXMgdGhlIGB1bnJlZ2lzdGVyZWRgIGV2ZW50IGZvciBlYWNoIGhvdGtleSB1bnJlZ2lzdGVyZWQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogZmluLkdsb2JhbEhvdGtleS51bnJlZ2lzdGVyQWxsKClcbiAgICAgKiAudGhlbigoKSA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdTdWNjZXNzJyk7XG4gICAgICogfSlcbiAgICAgKiAuY2F0Y2goZXJyID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0Vycm9yIHVucmVnaXN0ZXJpbmcgYWxsIGhvdGtleXMgZm9yIHRoaXMgYXBwbGljYXRpb24nLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIHVucmVnaXN0ZXJBbGwoKSB7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMuZXZlbnROYW1lcygpXG4gICAgICAgICAgICAuZmlsdGVyKChuYW1lKSA9PiAhKG5hbWUgPT09ICdyZWdpc3RlcmVkJyB8fCBuYW1lID09PSAndW5yZWdpc3RlcmVkJykpXG4gICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChob3RrZXkgZXZlbnRzIGFyZSBub3QgdHlwZWQpXG4gICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAubWFwKChuYW1lKSA9PiB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhuYW1lKSkpO1xuICAgICAgICBhd2FpdCB0aGlzLndpcmUuc2VuZEFjdGlvbignZ2xvYmFsLWhvdGtleS11bnJlZ2lzdGVyLWFsbCcsIHt9KTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgZ2l2ZW4gaG90a2V5IGhhcyBiZWVuIHJlZ2lzdGVyZWQgYnkgYW4gYXBwbGljYXRpb24gd2l0aGluIHRoZSBjdXJyZW50IHJ1bnRpbWUuXG4gICAgICogQHBhcmFtIGhvdGtleSBhIGhvdGtleSBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBob3RrZXkgPSAnQ29tbWFuZE9yQ29udHJvbCtYJztcbiAgICAgKlxuICAgICAqIGZpbi5HbG9iYWxIb3RrZXkuaXNSZWdpc3RlcmVkKGhvdGtleSlcbiAgICAgKiAudGhlbigocmVnaXN0ZXJlZCkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgaG90a2V5ICR7aG90a2V5fSBpcyByZWdpc3RlcmVkID8gJHtyZWdpc3RlcmVkfWApO1xuICAgICAqIH0pXG4gICAgICogLmNhdGNoKGVyciA9PiB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdFcnJvciB1bnJlZ2lzdGVyaW5nIHRoZSBob3RrZXknLCBlcnIpO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGlzUmVnaXN0ZXJlZChob3RrZXkpIHtcbiAgICAgICAgY29uc3QgeyBwYXlsb2FkOiB7IGRhdGEgfSB9ID0gYXdhaXQgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2dsb2JhbC1ob3RrZXktaXMtcmVnaXN0ZXJlZCcsIHsgaG90a2V5IH0pO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG59XG5nbG9iYWxIb3RrZXkuR2xvYmFsSG90a2V5ID0gR2xvYmFsSG90a2V5O1xuXG52YXIgcGxhdGZvcm0gPSB7fTtcblxudmFyIEZhY3RvcnkkMyA9IHt9O1xuXG52YXIgSW5zdGFuY2UkMiA9IHt9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ1ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX1BsYXRmb3JtX2Nvbm5lY3RUb1Byb3ZpZGVyO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluc3RhbmNlJDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuSW5zdGFuY2UkMi5QbGF0Zm9ybSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9wcmVmZXItZGVmYXVsdC1leHBvcnQsIG5vLXVuZGVmICovXG5jb25zdCBiYXNlXzEkNiA9IGJhc2U7XG5jb25zdCB2YWxpZGF0ZV8xJDEgPSB2YWxpZGF0ZTtcbi8vIFJldXNlIGNsaWVudHMgdG8gYXZvaWQgb3ZlcndyaXRpbmcgYWxyZWFkeS1yZWdpc3RlcmVkIGNsaWVudCBpbiBwcm92aWRlclxuY29uc3QgY2xpZW50TWFwID0gbmV3IE1hcCgpO1xuLyoqIE1hbmFnZXMgdGhlIGxpZmUgY3ljbGUgb2Ygd2luZG93cyBhbmQgdmlld3MgaW4gdGhlIGFwcGxpY2F0aW9uLlxuICpcbiAqIEVuYWJsZXMgdGFraW5nIHNuYXBzaG90cyBvZiBpdHNlbGYgYW5kIGFwcGx5aW5nIHRoZW0gdG8gcmVzdG9yZSBhIHByZXZpb3VzIGNvbmZpZ3VyYXRpb25cbiAqIGFzIHdlbGwgYXMgbGlzdGVuIHRvIHtAbGluayBPcGVuRmluLlBsYXRmb3JtRXZlbnRzIHBsYXRmb3JtIGV2ZW50c30uXG4gKi9cbmNsYXNzIFBsYXRmb3JtIGV4dGVuZHMgYmFzZV8xJDYuRW1pdHRlckJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdHJ1Y3RvcihpZGVudGl0eSwgY2hhbm5lbCkge1xuICAgICAgICAvLyB3ZSBwaWdneWJhY2sgb2ZmIG9mIGFwcGxpY2F0aW9uIGV2ZW50IGVtaXR0ZXIgYmVjYXVzZSBmcm9tIHRoZSBjb3JlJ3MgcGVyc3BlY3RpdmUgcGxhdGZvcm0gaXMganVzdCBhbiBhcHAuXG4gICAgICAgIHN1cGVyKGNoYW5uZWwud2lyZSwgJ2FwcGxpY2F0aW9uJywgaWRlbnRpdHkudXVpZCk7XG4gICAgICAgIHRoaXMuZ2V0Q2xpZW50ID0gKGlkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tZ2V0LWNsaWVudCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGlkZW50aXR5IHx8IHRoaXMuaWRlbnRpdHk7XG4gICAgICAgICAgICBjb25zdCB7IHV1aWQgfSA9IHRhcmdldDtcbiAgICAgICAgICAgIGlmICghY2xpZW50TWFwLmhhcyh1dWlkKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudFByb21pc2UgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDUodGhpcywgX1BsYXRmb3JtX2Nvbm5lY3RUb1Byb3ZpZGVyLCBcImZcIikuY2FsbCh0aGlzLCB1dWlkKTtcbiAgICAgICAgICAgICAgICBjbGllbnRNYXAuc2V0KHV1aWQsIGNsaWVudFByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gd2Ugc2V0IGl0IGFib3ZlXG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgcmV0dXJuIGNsaWVudE1hcC5nZXQodXVpZCk7XG4gICAgICAgIH07XG4gICAgICAgIF9QbGF0Zm9ybV9jb25uZWN0VG9Qcm92aWRlci5zZXQodGhpcywgYXN5bmMgKHV1aWQpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSBgY3VzdG9tLWZyYW1lLSR7dXVpZH1gO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuX2NoYW5uZWwuY29ubmVjdChjaGFubmVsTmFtZSwgeyB3YWl0OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICBjbGllbnQub25EaXNjb25uZWN0aW9uKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50TWFwLmRlbGV0ZSh1dWlkKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2xpZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjbGllbnRNYXAuZGVsZXRlKHV1aWQpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIHRhcmdldGVkIFBsYXRmb3JtIGlzIG5vdCBjdXJyZW50bHkgcnVubmluZy4gTGlzdGVuIGZvciBhcHBsaWNhdGlvbi1zdGFydGVkIGV2ZW50IGZvciB0aGUgZ2l2ZW4gVXVpZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAZGVwcmVjYXRlZCAocmVuYW1lZClcbiAgICAgICAgICogQGlnbm9yZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYXVuY2hMZWdhY3lNYW5pZmVzdCA9IHRoaXMubGF1bmNoQ29udGVudE1hbmlmZXN0O1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xJDEudmFsaWRhdGVJZGVudGl0eSkoaWRlbnRpdHkpO1xuICAgICAgICBpZiAoZXJyb3JNc2cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2hhbm5lbCA9IGNoYW5uZWw7XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSB7IHV1aWQ6IGlkZW50aXR5LnV1aWQgfTtcbiAgICAgICAgdGhpcy5MYXlvdXQgPSB0aGlzLmZpbi5QbGF0Zm9ybS5MYXlvdXQ7XG4gICAgICAgIHRoaXMuQXBwbGljYXRpb24gPSB0aGlzLmZpbi5BcHBsaWNhdGlvbi53cmFwU3luYyh0aGlzLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyB2aWV3IGFuZCBhdHRhY2hlcyBpdCB0byBhIHNwZWNpZmllZCB0YXJnZXQgd2luZG93LlxuICAgICAqIEBwYXJhbSB2aWV3T3B0aW9ucyBWaWV3IGNyZWF0aW9uIG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gdGFyZ2V0IFRoZSB3aW5kb3cgdG8gd2hpY2ggdGhlIG5ldyB2aWV3IGlzIHRvIGJlIGF0dGFjaGVkLiBJZiBubyB0YXJnZXQsIGNyZWF0ZSBhIHZpZXcgaW4gYSBuZXcgd2luZG93LlxuICAgICAqIEBwYXJhbSB0YXJnZXRWaWV3IElmIHByb3ZpZGVkLCB0aGUgbmV3IHZpZXcgd2lsbCBiZSBhZGRlZCB0byB0aGUgc2FtZSB0YWJzdHJpcCBhcyB0YXJnZXRWaWV3LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgSWYgdGhlIHZpZXcgYWxyZWFkeSBleGlzdHMsIHdpbGwgcmVwYXJlbnQgdGhlIHZpZXcgdG8gdGhlIG5ldyB0YXJnZXQuIFlvdSBkbyBub3QgbmVlZCB0byBzZXQgYSBuYW1lIGZvciBhIFZpZXcuXG4gICAgICogVmlld3MgdGhhdCBhcmUgbm90IHBhc3NlZCBhIG5hbWUgZ2V0IGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG9uZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBsZXQgd2luZG93SWRlbnRpdHk7XG4gICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKlxuICAgICAqIHBsYXRmb3JtLmNyZWF0ZVZpZXcoe1xuICAgICAqICAgICBuYW1lOiAndGVzdF92aWV3JyxcbiAgICAgKiAgICAgdXJsOiAnaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vZG9jcy9wbGF0Zm9ybS1hcGknXG4gICAgICogfSwgd2luZG93SWRlbnRpdHkpLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogUmVwYXJlbnRpbmcgYSB2aWV3OlxuICAgICAqIGBgYGpzXG4gICAgICogbGV0IHdpbmRvd0lkZW50aXR5O1xuICAgICAqIGlmIChmaW4ubWUuaXNXaW5kb3cpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSBmaW4ubWUuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICogICAgIHdpbmRvd0lkZW50aXR5ID0gKGF3YWl0IGZpbi5tZS5nZXRDdXJyZW50V2luZG93KCkpLmlkZW50aXR5O1xuICAgICAqIH0gZWxzZSB7XG4gICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGxldCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGxldCB2aWV3T3B0aW9ucyA9IHtcbiAgICAgKiAgICAgbmFtZTogJ2V4YW1wbGVfdmlldycsXG4gICAgICogICAgIHVybDogJ2h0dHBzOi8vZXhhbXBsZS5jb20nXG4gICAgICogfTtcbiAgICAgKiAvLyBhIG5ldyB2aWV3IHdpbGwgbm93IHNob3cgaW4gdGhlIGN1cnJlbnQgd2luZG93XG4gICAgICogYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgd2luZG93SWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogY29uc3QgdmlldyA9IGZpbi5WaWV3LndyYXBTeW5jKHsgdXVpZDogd2luZG93SWRlbnRpdHkudXVpZCwgbmFtZTogJ3lhaG9vX3ZpZXcnIH0pO1xuICAgICAqIC8vIHJlcGFyZW50IGBleGFtcGxlX3ZpZXdgIHdoZW4gYSB2aWV3IGluIHRoZSBuZXcgd2luZG93IGlzIHNob3duXG4gICAgICogdmlldy5vbignc2hvd24nLCBhc3luYyAoKSA9PiB7XG4gICAgICogICAgIGxldCB2aWV3SWRlbnRpdHkgPSB7IHV1aWQ6IHdpbmRvd0lkZW50aXR5LnV1aWQsIG5hbWU6ICdleGFtcGxlX3ZpZXcnfTtcbiAgICAgKiAgICAgbGV0IHRhcmdldCA9IHt1dWlkOiB3aW5kb3dJZGVudGl0eS51dWlkLCBuYW1lOiAndGVzdF93aW4nfTtcbiAgICAgKiAgICAgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgdGFyZ2V0KTtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIC8vIGNyZWF0ZSBhIG5ldyB3aW5kb3dcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5jcmVhdGVXaW5kb3coe1xuICAgICAqICAgICBuYW1lOiBcInRlc3Rfd2luXCIsXG4gICAgICogICAgIGxheW91dDoge1xuICAgICAqICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgKiAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAneWFob29fdmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8veWFob28uY29tJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIF1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVZpZXcodmlld09wdGlvbnMsIHRhcmdldCwgdGFyZ2V0Vmlldykge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tY3JlYXRlLXZpZXcnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnY3JlYXRlLXZpZXcnLCB7XG4gICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICBvcHRzOiB2aWV3T3B0aW9ucyxcbiAgICAgICAgICAgIHRhcmdldFZpZXdcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghcmVzcG9uc2UgfHwgKDAsIHZhbGlkYXRlXzEkMS52YWxpZGF0ZUlkZW50aXR5KShyZXNwb25zZS5pZGVudGl0eSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgV2hlbiBvdmVyd3JpdGluZyB0aGUgY3JlYXRlVmlldyBjYWxsLCBwbGVhc2UgcmV0dXJuIGFuIG9iamVjdCB0aGF0IGhhcyBhIHZhbGlkICdpZGVudGl0eScgcHJvcGVydHk6ICR7SlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmZpbi5WaWV3LndyYXBTeW5jKHJlc3BvbnNlLmlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBXaW5kb3cuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgV2luZG93IGNyZWF0aW9uIG9wdGlvbnNcbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoZXJlIGFyZSB0d28gV2luZG93IHR5cGVzIGF0IHlvdXIgZGlzcG9zYWwgd2hpbGUgdXNpbmcgT3BlbkZpbiBQbGF0Zm9ybXMgLSBEZWZhdWx0IFdpbmRvdyBhbmQgQ3VzdG9tIFdpbmRvdy5cbiAgICAgKlxuICAgICAqIFRoZSBEZWZhdWx0IFdpbmRvdyB1c2VzIHRoZSBzdGFuZGFyZCBPcGVuRmluIFdpbmRvdyBVSS4gSXQgY29udGFpbnMgdGhlIHN0YW5kYXJkIGNsb3NlLCBtYXhpbWl6ZSBhbmQgbWluaW1pemUgYnV0dG9ucyxcbiAgICAgKiBhbmQgd2lsbCBhdXRvbWF0aWNhbGx5IHJlbmRlciB0aGUgV2luZG93J3MgbGF5b3V0IGlmIG9uZSBpcyBzcGVjaWZpZWQuXG4gICAgICpcbiAgICAgKiBGb3IgZGVlcGVyIGN1c3RvbWl6YXRpb24sIHlvdSBjYW4gYnJpbmcgeW91ciBvd24gV2luZG93IGNvZGUgaW50byBhIFBsYXRmb3JtLiBUaGlzIGlzIGNhbGxlZCBhIEN1c3RvbSBXaW5kb3cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICpcbiAgICAgKiBUaGUgZXhhbXBsZSBiZWxvdyB3aWxsIGNyZWF0ZSBhIERlZmF1bHQgV2luZG93IHdoaWNoIHVzZXMgT3BlbkZpbiBkZWZhdWx0IFdpbmRvdyBVSS48YnI+XG4gICAgICogVGhlIFdpbmRvdyBjb250YWlucyB0d28gVmlld3MgaW4gYSBzdGFjayBMYXlvdXQ6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogcGxhdGZvcm0uY3JlYXRlV2luZG93KHtcbiAgICAgKiAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICBjb250ZW50OiBbXG4gICAgICogICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICogICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ3ZpZXcnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICogICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ3ZpZXcnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMicsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIF1cbiAgICAgKiAgICAgfVxuICAgICAqIH0pLnRoZW4oY29uc29sZS5sb2cpO1xuICAgICAqIGBgYFxuICAgICAqIFRoZSBEZWZhdWx0IFdpbmRvdydzIGRlc2lnbiBjYW4gYmUgY3VzdG9taXplZCBieSBzcGVjaWZ5aW5nIHRoZSBgc3R5bGVzaGVldFVybGAgcHJvcGVydHkgaW4gdGhlIG1hbmlmZXN0OlxuICAgICAqXG4gICAgICogYGBganNvblxuICAgICAqIHtcbiAgICAgKiAgICAgcGxhdGZvcm06IHtcbiAgICAgKiAgICAgICAgIGRlZmF1bHRXaW5kb3dPcHRpb25zOiB7XG4gICAgICogICAgICAgICAgICAgc3R5bGVzaGVldFVybDogJ3NvbWUtdXJsLmNzcycsXG4gICAgICogICAgICAgICAgICAgLi4uXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogRm9yIGEgbGlzdCBvZiBjb21tb24gTGF5b3V0IENTUyBjbGFzc2VzIHlvdSBjYW4gb3ZlcnJpZGUgaW4geW91ciBjdXN0b20gc3R5bGVzaGVldCwgc2VlIDxhIGhyZWY9XCJ0dXRvcmlhbC1sYXlvdXRTdHlsZXMuaHRtbFwiPlVzZWZ1bCBMYXlvdXQgQ1NTIENsYXNzZXM8L2E+XG4gICAgICoqXG4gICAgICogVG8gc3BlY2lmeSBhIFBsYXRmb3JtIEN1c3RvbSBXaW5kb3csIHByb3ZpZGUgYSBgdXJsYCBwcm9wZXJ0eSB3aGVuIGNyZWF0aW5nIGEgV2luZG93LlxuICAgICAqIElmIHlvdSBpbnRlbmQgdG8gcmVuZGVyIGEgTGF5b3V0IGluIHlvdXIgQ3VzdG9tIFdpbmRvdywgeW91IG11c3QgYWxzbyBzcGVjaWZ5IGFuIGBIVE1MRWxlbWVudGAgdGhhdCB0aGUgTGF5b3V0IHdpbGwgaW5qZWN0IGludG8gYW5kIHNldCBpdHMgYGlkYCBwcm9wZXJ0eSB0byBgXCJsYXlvdXQtY29udGFpbmVyXCJgLlxuICAgICAqXG4gICAgICogVGhlIGV4YW1wbGUgYmVsb3cgd2lsbCBjcmVhdGUgYSBQbGF0Zm9ybSBDdXN0b20gV2luZG93OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiAgICAgLy8gaW4gYW4gT3BlbkZpbiBhcHA6XG4gICAgICogICAgIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogICAgIGNvbnN0IHdpbmRvd0NvbmZpZyA9XG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vd3d3Lm15LWRvbWFpbi5jb20vbXktY3VzdG9tLXdpbmRvdy5odG1sXCIsIC8vIGhlcmUgd2UgcG9pbnQgdG8gd2hlcmUgdGhlIEN1c3RvbSBGcmFtZSBpcyBob3N0ZWQuXG4gICAgICogICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0YWNrXCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImNvbXBvbmVudFwiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogXCJ2aWV3XCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiYXBwICMxXCIsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBcImh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0L2NhbmFyeS9QbGF0Zm9ybS5odG1sXCJcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJjb21wb25lbnRcIixcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6IFwidmlld1wiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U3RhdGU6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImFwcCAjMlwiLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogXCJodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC9jYW5hcnkvUGxhdGZvcm0uaHRtbFwiXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9O1xuICAgICAqICAgICBwbGF0Zm9ybS5jcmVhdGVXaW5kb3cod2luZG93Q29uZmlnKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEhlcmUncyBhbiBleGFtcGxlIG9mIGEgbWluaW1hbGlzdCBDdXN0b20gUGxhdGZvcm0gV2luZG93IGltcGxlbWVudGF0aW9uOlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aHRtbD5cbiAgICAgKiAgICAgPGhlYWQ+XG4gICAgICogICAgICAgICA8bWV0YSBjaGFyc2V0PVwidXRmLThcIj5cbiAgICAgKiAgICAgICAgIDxtZXRhIG5hbWU9XCJ2aWV3cG9ydFwiIGNvbnRlbnQ9XCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MVwiPlxuICAgICAqICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIHR5cGU9XCJ0ZXh0L2Nzc1wiIGhyZWY9XCIuL3N0eWxlcy5jc3NcIj5cbiAgICAgKiAgICAgPC9oZWFkPlxuICAgICAqICAgICA8Ym9keT5cbiAgICAgKiAgICAgICAgIDxkaXYgaWQ9XCJvZi1mcmFtZS1tYWluXCI+XG4gICAgICogICAgICAgICAgICAgPGRpdiBpZD1cInRpdGxlLWJhclwiPlxuICAgICAqICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGUtYmFyLWRyYWdnYWJsZVwiPlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD1cInRpdGxlXCI+IFRoaXMgaXMgYSBjdXN0b20gZnJhbWUhIDwvZGl2PlxuICAgICAqICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgKiAgICAgICAgICAgICAgICAgPGRpdiBpZD1cImJ1dHRvbnMtd3JhcHBlclwiPlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvblwiIGlkPVwibWluaW1pemUtYnV0dG9uXCI+PC9kaXY+XG4gICAgICogICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uXCIgaWQ9XCJleHBhbmQtYnV0dG9uXCI+PC9kaXY+XG4gICAgICogICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uXCIgaWQ9XCJjbG9zZS1idXR0b25cIj48L2Rpdj5cbiAgICAgKiAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICAgICAgICAgPC9kaXY+XG4gICAgICogICAgICAgICAgICAgPGRpdiBpZD1cImxheW91dC1jb250YWluZXJcIj48L2Rpdj4gPCEtLSBPcGVuRmluIGxheW91dCB3b3VsZCBiZSBpbmplY3RlZCBoZXJlIC0tPlxuICAgICAqICAgICAgICAgICAgIDxzY3JpcHQgc3JjPVwiLi9jdXN0b20tZnJhbWUuanNcIj48L3NjcmlwdD5cbiAgICAgKiAgICAgICAgIDwvZGl2PlxuICAgICAqICAgICA8L2JvZHk+XG4gICAgICogPC9odG1sPlxuICAgICAqIGBgYFxuICAgICAqIFlvdXIgQ3VzdG9tIFdpbmRvdyBjYW4gdXNlIGluLWRvbWFpbiByZXNvdXJjZXMgZm9yIGZ1cnRoZXIgY3VzdG9taXphdGlvbiAoc3VjaCBhcyBDU1MsIHNjcmlwdHMsIGV0Yy4pLjxicj5cbiAgICAgKiBGb3IgYSBsaXN0IG9mIGNvbW1vbiBMYXlvdXQgQ1NTIGNsYXNzZXMgeW91IGNhbiBvdmVycmlkZSBpbiB5b3VyIHN0eWxlc2hlZXQsIHNlZSA8YSBocmVmPVwidHV0b3JpYWwtbGF5b3V0U3R5bGVzLmh0bWxcIj5Vc2VmdWwgTGF5b3V0IENTUyBDbGFzc2VzPC9hPlxuICAgICAqXG4gICAgICogVGhlIGV4YW1wbGUgYWJvdmUgd2lsbCByZXF1aXJlIHRoZSBgYm9keWAgZWxlbWVudCB0byBoYXZlIGBoZWlnaHQ6IDEwMCU7YCBzZXQgaW4gb3JkZXIgdG8gcmVuZGVyIHRoZSBsYXlvdXQgY29ycmVjdGx5LlxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVdpbmRvdyhvcHRpb25zKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1jcmVhdGUtd2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgaWYgKCFvcHRpb25zLnJlYXNvbikge1xuICAgICAgICAgICAgb3B0aW9ucy5yZWFzb24gPSAnYXBpLWNhbGwnO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdjcmVhdGUtdmlldy1jb250YWluZXInLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSB8fCAoMCwgdmFsaWRhdGVfMSQxLnZhbGlkYXRlSWRlbnRpdHkpKHJlc3BvbnNlLmlkZW50aXR5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXaGVuIG92ZXJ3cml0aW5nIHRoZSBjcmVhdGVXaW5kb3cgY2FsbCwgcGxlYXNlIHJldHVybiBhbiBvYmplY3QgdGhhdCBoYXMgYSB2YWxpZCAnaWRlbnRpdHknIHByb3BlcnR5OiAke0pTT04uc3RyaW5naWZ5KHJlc3BvbnNlKX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGlkZW50aXR5IH0gPSByZXNwb25zZTtcbiAgICAgICAgY29uc3QgcmVzID0gdGhpcy5maW4uV2luZG93LndyYXBTeW5jKGlkZW50aXR5KTtcbiAgICAgICAgLy8gd2UgYWRkIHRoZSBpZGVudGl0eSBhdCB0aGUgdG9wIGxldmVsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cbiAgICAgICAgcmVzLm5hbWUgPSBpZGVudGl0eS5uYW1lO1xuICAgICAgICByZXMudXVpZCA9IGlkZW50aXR5LnV1aWQ7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBjdXJyZW50IHBsYXRmb3JtLCBhbGwgaXRzIHdpbmRvd3MsIGFuZCB0aGVpciB2aWV3cy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogcGxhdGZvcm0ucXVpdCgpO1xuICAgICAqIC8vIEFsbCB3aW5kb3dzL3ZpZXdzIGluIGN1cnJlbnQgbGF5b3V0IHBsYXRmb3JtIHdpbGwgY2xvc2UgYW5kIHBsYXRmb3JtIHdpbGwgc2h1dCBkb3duXG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgcXVpdCgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLXF1aXQnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdxdWl0Jyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBhIHNwZWNpZmllZCB2aWV3IGluIGEgdGFyZ2V0IHdpbmRvdy5cbiAgICAgKiBAcGFyYW0gdmlld0lkZW50aXR5IFZpZXcgaWRlbnRpdHlcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBsZXQgd2luZG93SWRlbnRpdHk7XG4gICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3Qgdmlld09wdGlvbnMgPSB7XG4gICAgICogICAgIG5hbWU6ICd0ZXN0X3ZpZXcnLFxuICAgICAqICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tJ1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBzbGVlcChtcykge1xuICAgICAqICAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgd2luZG93SWRlbnRpdHkpO1xuICAgICAqIC8vIGEgbmV3IHZpZXcgd2lsbCBub3cgc2hvdyBpbiB0aGUgY3VycmVudCB3aW5kb3dcbiAgICAgKlxuICAgICAqIGF3YWl0IHNsZWVwKDUwMDApO1xuICAgICAqXG4gICAgICogY29uc3Qgdmlld0lkZW50aXR5ID0geyB1dWlkOiB3aW5kb3dJZGVudGl0eS51dWlkLCBuYW1lOiAndGVzdF92aWV3J307XG4gICAgICogcGxhdGZvcm0uY2xvc2VWaWV3KHZpZXdJZGVudGl0eSk7XG4gICAgICogLy8gdGhlIHZpZXcgd2lsbCBub3cgY2xvc2VcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZVZpZXcodmlld0lkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1jbG9zZS12aWV3JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdjbG9zZS12aWV3Jywge1xuICAgICAgICAgICAgdmlldzogdmlld0lkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqKipERVBSRUNBVEVEIC0gcGxlYXNlIHVzZSB7QGxpbmsgUGxhdGZvcm0uY3JlYXRlVmlldyBQbGF0Zm9ybS5jcmVhdGVWaWV3fS4qKipcbiAgICAgKiBSZXBhcmVudHMgYSBzcGVjaWZpZWQgdmlldyBpbiBhIG5ldyB0YXJnZXQgd2luZG93LlxuICAgICAqIEBwYXJhbSB2aWV3SWRlbnRpdHkgVmlldyBpZGVudGl0eVxuICAgICAqIEBwYXJhbSB0YXJnZXQgbmV3IG93bmVyIHdpbmRvdyBpZGVudGl0eVxuICAgICAqXG4gICAgICovXG4gICAgYXN5bmMgcmVwYXJlbnRWaWV3KHZpZXdJZGVudGl0eSwgdGFyZ2V0KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUud2FybignUGxhdGZvcm0ucmVwYXJlbnRWaWV3IGhhcyBiZWVuIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgUGxhdGZvcm0uY3JlYXRlVmlldycpO1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tcmVwYXJlbnQtdmlldycsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWaWV3SWRlbnRpdHkgPSB7XG4gICAgICAgICAgICAuLi52aWV3SWRlbnRpdHksXG4gICAgICAgICAgICB1dWlkOiB2aWV3SWRlbnRpdHkudXVpZCA/PyB0aGlzLmlkZW50aXR5LnV1aWRcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdmlldyA9IGF3YWl0IHRoaXMuZmluLlZpZXcud3JhcChub3JtYWxpemVkVmlld0lkZW50aXR5KTtcbiAgICAgICAgY29uc3Qgdmlld09wdGlvbnMgPSBhd2FpdCB2aWV3LmdldE9wdGlvbnMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlVmlldyh2aWV3T3B0aW9ucywgdGFyZ2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIHRoZSBwbGF0Zm9ybSBpbiBpdHMgY3VycmVudCBzdGF0ZS4gWW91IGNhbiBwYXNzIHRoZSByZXR1cm5pbmcgb2JqZWN0IHRvXG4gICAgICogW1BsYXRmb3JtLmFwcGx5U25hcHNob3Rde0BsaW5rIFBsYXRmb3JtI2FwcGx5U25hcHNob3R9IHRvIGxhdW5jaCBpdC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoZSBzbmFwc2hvdCB3aWxsIGluY2x1ZGUgZGV0YWlscyBzdWNoIGFzIGFuIFtJU08gZm9ybWF0XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fODYwMSlcbiAgICAgKiB0aW1lc3RhbXAgb2Ygd2hlbiB0aGUgc25hcHNob3Qgd2FzIHRha2VuLCBPcGVuRmluIHJ1bnRpbWUgdmVyc2lvbiB0aGUgcGxhdGZvcm0gaXMgcnVubmluZyBvbiwgbW9uaXRvciBpbmZvcm1hdGlvblxuICAgICAqIGFuZCB0aGUgbGlzdCBvZiBjdXJyZW50bHkgcnVubmluZyB3aW5kb3dzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHBsYXRmb3JtLmdldFNuYXBzaG90KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1nZXQtc25hcHNob3QnLCB0aGlzLmlkZW50aXR5KS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXQtc25hcHNob3QnKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKipOT1RFKio6IEludGVybmFsIHVzZSBvbmx5LiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdG8gbWFuYWdlIHRoZSBzdGF0ZSBvZiBpbmRpdmlkdWFsIHZpZXdzLlxuICAgICAqXG4gICAgICogUmV0dXJucyBhIHNuYXBzaG90IG9mIGEgc2luZ2xlIHZpZXcncyBvcHRpb25zIGluIGl0cyBjdXJyZW50IHN0YXRlLlxuICAgICAqXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gcmVzdG9yZSBhIHZpZXcgdG8gYSBwcmV2aW91cyBzdGF0ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2aWV3SWRlbnRpdHkgVmlldyBpZGVudGl0eVxuICAgICAqXG4gICAgICogQGludGVybmFsXG4gICAgICogQGV4cGVyaW1lbnRhbFxuICAgICAqIEByZW1hcmtzIFRoaXMgc2xpY2Ugb2Ygc25hcHNob3Qgc3RhdGUgaXMgZXF1aXZhbGVudCB0byB3aGF0IGlzIHN0b3JlZCBhcyBgY29tcG9uZW50U3RhdGVgIGZvciB2aWV3c1xuICAgICAqIHdoZW4gY2FwdHVyaW5nIHBsYXRmb3JtIHN0YXRlIHVzaW5nIFtQbGF0Zm9ybS5nZXRTbmFwc2hvdF17QGxpbmsgUGxhdGZvcm0jZ2V0U25hcHNob3R9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCB1cmwgPSAnaHR0cHM6Ly9nb29nbGUuY29tJztcbiAgICAgKiBjb25zdCB2aWV3ID0gYXdhaXQgZmluLlZpZXcuY3JlYXRlKHsgbmFtZTogJ215LXZpZXcnLCB0YXJnZXQ6IGZpbi5tZS5pZGVudGl0eSwgdXJsIH0pO1xuICAgICAqXG4gICAgICogYXdhaXQgdmlldy5uYXZpZ2F0ZSh1cmwpO1xuICAgICAqXG4gICAgICogY29uc3Qgdmlld1N0YXRlID0gYXdhaXQgcGxhdGZvcm0uZ2V0Vmlld1NuYXBzaG90KHZpZXcuaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2codmlld1N0YXRlKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRWaWV3U25hcHNob3Qodmlld0lkZW50aXR5KSB7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2dldC12aWV3LXNuYXBzaG90JywgeyB2aWV3SWRlbnRpdHkgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBzbmFwc2hvdCB0byBhIHJ1bm5pbmcgUGxhdGZvcm0uXG4gICAgICogUmVxdWVzdGVkIHNuYXBzaG90IG11c3QgYmUgYSB2YWxpZCBTbmFwc2hvdCBvYmplY3QsIG9yIGEgdXJsIG9yIGZpbGVwYXRoIHRvIHN1Y2ggYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQ2FuIG9wdGlvbmFsbHkgY2xvc2UgZXhpc3Rpbmcgd2luZG93cyBhbmQgb3ZlcndyaXRlIGN1cnJlbnQgcGxhdGZvcm0gc3RhdGUgd2l0aCB0aGF0IG9mIGEgc25hcHNob3QuXG4gICAgICpcbiAgICAgKiBUaGUgZnVuY3Rpb24gYWNjZXB0cyBlaXRoZXIgYSBzbmFwc2hvdCB0YWtlbiB1c2luZyB7QGxpbmsgUGxhdGZvcm0jZ2V0U25hcHNob3QgZ2V0U25hcHNob3R9LFxuICAgICAqIG9yIGEgdXJsIG9yIGZpbGVwYXRoIHRvIGEgc25hcHNob3QgSlNPTiBvYmplY3QuXG4gICAgICogQHBhcmFtIHJlcXVlc3RlZFNuYXBzaG90IFNuYXBzaG90IHRvIGFwcGx5LCBvciBhIHVybCBvciBmaWxlcGF0aC5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25hbCBwYXJhbWV0ZXJzIHRvIHNwZWNpZnkgd2hldGhlciBleGlzdGluZyB3aW5kb3dzIHNob3VsZCBiZSBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBXaWxsIGNyZWF0ZSBhbnkgd2luZG93cyBhbmQgdmlld3MgdGhhdCBhcmUgbm90IHJ1bm5pbmcgYnV0IGFyZSBwYXNzZWQgaW4gdGhlIHNuYXBzaG90IG9iamVjdC4gQW55IFZpZXdcbiAgICAgKiBzcGVjaWZpZWQgaW4gdGhlIHNuYXBzaG90IGlzIGFzc2lnbmVkIGEgcmFuZG9tbHkgZ2VuZXJhdGVkIG5hbWUgdG8gYXZvaWQgY29sbGlzaW9ucy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiAvLyBHZXQgYSB3cmFwcGVkIGxheW91dCBwbGF0Zm9ybSBpbnN0YW5jZVxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0ge1xuICAgICAqICAgICB3aW5kb3dzOiBbXG4gICAgICogICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IFtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb21wb25lbnRfWCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly93d3cub3BlbmZpbi5jbydcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb21wb25lbnRfWScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly9jZG4ub3BlbmZpbi5jby9lbWJlZC13ZWIvY2hhcnQuaHRtbCdcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgXVxuICAgICAqICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgIH1cbiAgICAgKiAgICAgXVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHBsYXRmb3JtLmFwcGx5U25hcHNob3Qoc25hcHNob3QpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogSW4gcGxhY2Ugb2YgYSBzbmFwc2hvdCBvYmplY3QsIGBhcHBseVNuYXBzaG90YCBjYW4gdGFrZSBhIHVybCBvciBmaWxlcGF0aCBhbmQgdG8gcmV0cmlldmUgYSBKU09OIHNuYXBzaG90LlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogcGxhdGZvcm0uYXBwbHlTbmFwc2hvdCgnaHR0cHM6Ly9hcGkuanNvbmJpbi5pby9iLzVlNmY5MDNlZjQzMzFlNjgxZmMxMjMxZC8xJyk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBPcHRpb25hbGx5LCBgYXBwbHlTbmFwc2hvdGAgY2FuIGNsb3NlIGV4aXN0aW5nIHdpbmRvd3MgYW5kIHJlc3RvcmUgYSBQbGF0Zm9ybSB0byBhIHByZXZpb3VzbHkgc2F2ZWQgc3RhdGUuXG4gICAgICogVGhpcyBpcyBhY2NvbXBsaXNoZWQgYnkgcHJvdmlkaW5nIGB7IGNsb3NlRXhpc3RpbmdXaW5kb3dzOiB0cnVlIH1gIGFzIGFuIG9wdGlvbi5cbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogLy8gR2V0IGEgd3JhcHBlZCBsYXlvdXQgcGxhdGZvcm0gaW5zdGFuY2VcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICpcbiAgICAgKiBhc3luYyBmdW5jdGlvbiBhZGRWaWV3VG9XaW5kb3cod2luSWQpIHtcbiAgICAgKiAgICAgcmV0dXJuIGF3YWl0IHBsYXRmb3JtLmNyZWF0ZVZpZXcoe1xuICAgICAqICAgICAgICAgbmFtZTogJ3Rlc3Rfdmlld18zJyxcbiAgICAgKiAgICAgICAgIHVybDogJ2h0dHBzOi8vb3BlbmZpbi5jbydcbiAgICAgKiAgICAgfSwgd2luSWQpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVdpbmRvd1dpdGhUd29WaWV3cygpIHtcbiAgICAgKiAgICAgY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqXG4gICAgICogICAgIHJldHVybiBwbGF0Zm9ybS5jcmVhdGVXaW5kb3coe1xuICAgICAqICAgICAgICAgbGF5b3V0OiB7XG4gICAgICogICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RhY2snLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2NvbXBvbmVudCcsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50U3RhdGU6IHtcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZpZXdfMScsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tJ1xuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAndmlldycsXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudFN0YXRlOiB7XG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndGVzdF92aWV3XzInLFxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiAnaHR0cHM6Ly95YWhvby5jb20nXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICAgICAgICAgIH1cbiAgICAgKiAgICAgICAgICAgICBdXG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGNvbnN0IHdpbiA9IGF3YWl0IGNyZWF0ZVdpbmRvd1dpdGhUd29WaWV3cygpO1xuICAgICAqIC8vIC4uLiB5b3Ugd2lsbCBub3cgc2VlIGEgbmV3IHdpbmRvdyB3aXRoIHR3byB2aWV3cyBpbiBpdFxuICAgICAqXG4gICAgICogLy8gd2UgdGFrZSBhIHNuYXBzaG90IG9mIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBhcHAsIGJlZm9yZSBjaGFuZ2luZyBpdFxuICAgICAqIGNvbnN0IHNuYXBzaG90T2ZJbml0aWFsQXBwU3RhdGUgPSBhd2FpdCBwbGF0Zm9ybS5nZXRTbmFwc2hvdCgpO1xuICAgICAqXG4gICAgICogLy8gbm93IGxldCdzIGNoYW5nZSB0aGUgc3RhdGUgb2YgdGhlIGFwcDpcbiAgICAgKiBhd2FpdCBhZGRWaWV3VG9XaW5kb3cod2luLmlkZW50aXR5KTtcbiAgICAgKiAvLyAuLi4gdGhlIHdpbmRvdyBub3cgaGFzIHRocmVlIHZpZXdzIGluIGl0XG4gICAgICpcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5hcHBseVNuYXBzaG90KHNuYXBzaG90T2ZJbml0aWFsQXBwU3RhdGUsIHsgY2xvc2VFeGlzdGluZ1dpbmRvd3M6IHRydWUgfSk7XG4gICAgICogLy8gLi4uIHRoZSB3aW5kb3cgd2lsbCByZXZlcnQgdG8gcHJldmlvdXMgc3RhdGUsIHdpdGgganVzdCB0d28gdmlld3NcbiAgICAgKlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGFwcGx5U25hcHNob3QocmVxdWVzdGVkU25hcHNob3QsIG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWFwcGx5LXNuYXBzaG90JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZXJyTXNnID0gJ1JlcXVlc3RlZCBzbmFwc2hvdCBtdXN0IGJlIGEgdmFsaWQgU25hcHNob3Qgb2JqZWN0LCBvciBhIHVybCBvciBmaWxlcGF0aCB0byBzdWNoIGFuIG9iamVjdC4nO1xuICAgICAgICBsZXQgc25hcHNob3Q7XG4gICAgICAgIGlmICh0eXBlb2YgcmVxdWVzdGVkU25hcHNob3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBGZXRjaCBhbmQgcGFyc2Ugc25hcHNob3RcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9jaGFubmVsLndpcmUuc2VuZEFjdGlvbignZ2V0LWFwcGxpY2F0aW9uLW1hbmlmZXN0Jywge1xuICAgICAgICAgICAgICAgICAgICBtYW5pZmVzdFVybDogcmVxdWVzdGVkU25hcHNob3RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBzbmFwc2hvdCA9IHJlc3BvbnNlLnBheWxvYWQuZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyTXNnfTogJHtlcnJ9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzbmFwc2hvdCA9IHJlcXVlc3RlZFNuYXBzaG90O1xuICAgICAgICB9XG4gICAgICAgIGlmICghc25hcHNob3Qud2luZG93cykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVyck1zZyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdhcHBseS1zbmFwc2hvdCcsIHtcbiAgICAgICAgICAgIHNuYXBzaG90LFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgYSBKU09OIG1hbmlmZXN0IHVzaW5nIHRoZSBicm93c2VyIHByb2Nlc3MgYW5kIHJldHVybnMgYSBKYXZhc2NyaXB0IG9iamVjdC5cbiAgICAgKiBDYW4gYmUgb3ZlcndyaXR0ZW4gdXNpbmcge0BsaW5rIFBsYXRmb3JtLlBsYXRmb3JtTW9kdWxlLmluaXQgUGxhdGZvcm0uaW5pdH0uXG4gICAgICogQHBhcmFtIG1hbmlmZXN0VXJsIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRvIGZldGNoLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2FuIGJlIG92ZXJ3cml0dGVuIHVzaW5nIHtAbGluayBQbGF0Zm9ybSNpbml0IFBsYXRmb3JtLmluaXR9LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKiBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHBsYXRmb3JtLmZldGNoTWFuaWZlc3QoJ2h0dHBzOi8vd3d3LnBhdGgtdG8tbWFuaWZlc3QuY29tL2FwcC5qc29uJyk7XG4gICAgICogY29uc29sZS5sb2cobWFuaWZlc3QpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGZldGNoTWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgncGxhdGZvcm0tZmV0Y2gtbWFuaWZlc3QnLCB7IG1hbmlmZXN0VXJsIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYSBtYW5pZmVzdCBieSB1cmwgYW5kIGxhdW5jaGVzIGEgbGVnYWN5IGFwcGxpY2F0aW9uIG1hbmlmZXN0IG9yIHNuYXBzaG90IGludG8gdGhlIHBsYXRmb3JtLiAgUmV0dXJucyBhIHByb21pc2UgdGhhdFxuICAgICAqIHJlc29sdmVzIHRvIHRoZSB3cmFwcGVkIFBsYXRmb3JtLlxuICAgICAqIEBwYXJhbSBtYW5pZmVzdFVybCAtIFRoZSBVUkwgb2YgdGhlIG1hbmlmZXN0IHRoYXQgd2lsbCBiZSBsYXVuY2hlZCBpbnRvIHRoZSBwbGF0Zm9ybS4gIElmIHRoaXMgYXBwIG1hbmlmZXN0XG4gICAgICogY29udGFpbnMgYSBzbmFwc2hvdCwgdGhhdCB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiAgSWYgbm90LCB0aGUgYXBwbGljYXRpb24gZGVzY3JpYmVkIGluIHN0YXJ0dXBfYXBwIG9wdGlvbnNcbiAgICAgKiB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiBUaGUgYXBwbGljYWJsZSBzdGFydHVwX2FwcCBvcHRpb25zIHdpbGwgYmVjb21lIHtAbGluayBPcGVuRmluLlZpZXdDcmVhdGlvbk9wdGlvbnMgVmlldyBPcHRpb25zfS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIElmIHRoZSBhcHAgbWFuaWZlc3QgY29udGFpbnMgYSBzbmFwc2hvdCwgdGhhdCB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtLiAgSWYgbm90LCB0aGVcbiAgICAgKiBhcHBsaWNhdGlvbiBkZXNjcmliZWQgaW4gc3RhcnR1cF9hcHAgb3B0aW9ucyB3aWxsIGJlIGxhdW5jaGVkIGludG8gdGhlIHBsYXRmb3JtIGFzIGEgd2luZG93IHdpdGggYSBzaW5nbGUgdmlldy5cbiAgICAgKiBUaGUgYXBwbGljYWJsZSBzdGFydHVwX2FwcCBvcHRpb25zIHdpbGwgYmVjb21lIFZpZXcgT3B0aW9ucy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqICAgICBhd2FpdCBwbGF0Zm9ybS5sYXVuY2hDb250ZW50TWFuaWZlc3QoJ2h0dHA6Ly9sb2NhbGhvc3Q6NTU1NS9hcHAuanNvbicpO1xuICAgICAqICAgICBjb25zb2xlLmxvZyhgY29udGVudCBsYXVuY2hlZCBzdWNjZXNzZnVsbHkgaW50byBwbGF0Zm9ybWApO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAqIH1cbiAgICAgKiAvLyBGb3IgYSBsb2NhbCBtYW5pZmVzdCBmaWxlOlxuICAgICAqIHRyeSB7XG4gICAgICogICAgIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogICAgIHBsYXRmb3JtLmxhdW5jaENvbnRlbnRNYW5pZmVzdCgnZmlsZTovLy9DOi9zb21lZm9sZGVyL2FwcC5qc29uJyk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKGBjb250ZW50IGxhdW5jaGVkIHN1Y2Nlc3NmdWxseSBpbnRvIHBsYXRmb3JtYCk7XG4gICAgICogfSBjYXRjaChlKSB7XG4gICAgICogICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgKi9cbiAgICBhc3luYyBsYXVuY2hDb250ZW50TWFuaWZlc3QobWFuaWZlc3RVcmwpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWxhdW5jaC1jb250ZW50LW1hbmlmZXN0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCB0aGlzLmdldENsaWVudCgpO1xuICAgICAgICBjb25zdCBtYW5pZmVzdCA9IGF3YWl0IHRoaXMuZmV0Y2hNYW5pZmVzdChtYW5pZmVzdFVybCk7XG4gICAgICAgIGNsaWVudC5kaXNwYXRjaCgnbGF1bmNoLWludG8tcGxhdGZvcm0nLCB7IG1hbmlmZXN0LCBtYW5pZmVzdFVybCB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY29udGV4dCBvZiBhIGhvc3Qgd2luZG93LiBUaGUgY29udGV4dCB3aWxsIGJlIGF2YWlsYWJsZSB0byB0aGUgd2luZG93IGl0c2VsZiwgYW5kIHRvIGl0cyBjaGlsZCBWaWV3cy4gSXQgd2lsbCBiZSBzYXZlZCBpbiBhbnkgcGxhdGZvcm0gc25hcHNob3RzLlxuICAgICAqIEl0IGNhbiBiZSByZXRyaWV2ZWQgdXNpbmcge0BsaW5rIFBsYXRmb3JtI2dldFdpbmRvd0NvbnRleHQgZ2V0V2luZG93Q29udGV4dH0uXG4gICAgICogQHBhcmFtIGNvbnRleHQgLSBBIGZpZWxkIHdoZXJlIHNlcmlhbGl6YWJsZSBjb250ZXh0IGRhdGEgY2FuIGJlIHN0b3JlZCB0byBiZSBzYXZlZCBpbiBwbGF0Zm9ybSBzbmFwc2hvdHMuXG4gICAgICogQHBhcmFtIHRhcmdldCAtIEEgdGFyZ2V0IHdpbmRvdyBvciB2aWV3IG1heSBvcHRpb25hbGx5IGJlIHByb3ZpZGVkLiBJZiBubyB0YXJnZXQgaXMgcHJvdmlkZWQsIHRoZSB1cGRhdGUgd2lsbCBiZSBhcHBsaWVkXG4gICAgICogdG8gdGhlIGN1cnJlbnQgd2luZG93IChpZiBjYWxsZWQgZnJvbSBhIFdpbmRvdykgb3IgdGhlIGN1cnJlbnQgaG9zdCB3aW5kb3cgKGlmIGNhbGxlZCBmcm9tIGEgVmlldykuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBUaGUgY29udGV4dCBkYXRhIG11c3QgYmUgc2VyaWFsaXphYmxlLiAgVGhpcyBjYW4gb25seSBiZSBjYWxsZWQgZnJvbSBhIHdpbmRvdyBvciB2aWV3IHRoYXQgaGFzIGJlZW4gbGF1bmNoZWQgaW50byBhXG4gICAgICogcGxhdGZvcm0uXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBmcm9tIHRoZSB3aW5kb3cgaXRzZWxmLCBvciBmcm9tIGFueSBjaGlsZCB2aWV3LiBDb250ZXh0IGRhdGEgaXMgc2hhcmVkIGJ5IGFsbFxuICAgICAqIGVudGl0aWVzIHdpdGhpbiBhIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogU2V0dGluZyBvd24gY29udGV4dDpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGF3YWl0IHBsYXRmb3JtLnNldFdpbmRvd0NvbnRleHQoY29udGV4dERhdGEpO1xuICAgICAqIC8vIENvbnRleHQgb2YgY3VycmVudCB3aW5kb3cgaXMgbm93IHNldCB0byBgY29udGV4dERhdGFgXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBTZXR0aW5nIHRoZSBjb250ZXh0IG9mIGFub3RoZXIgd2luZG93IG9yIHZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGNvbnN0IGNvbnRleHREYXRhID0ge1xuICAgICAqICAgICBzZWN1cml0eTogJ1NUT0NLJyxcbiAgICAgKiAgICAgY3VycmVudFZpZXc6ICdkZXRhaWxlZCdcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBjb25zdCB3aW5kb3dPclZpZXdJZGVudGl0eSA9IHsgdXVpZDogZmluLm1lLnV1aWQsIG5hbWU6ICduYW1lT2ZXaW5kb3dPclZpZXcnIH07XG4gICAgICogYXdhaXQgcGxhdGZvcm0uc2V0V2luZG93Q29udGV4dChjb250ZXh0RGF0YSwgd2luZG93T3JWaWV3SWRlbnRpdHkpO1xuICAgICAqIC8vIENvbnRleHQgb2YgdGhlIHRhcmdldCB3aW5kb3cgb3IgdmlldyBpcyBub3cgc2V0IHRvIGBjb250ZXh0RGF0YWBcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEEgdmlldyBjYW4gbGlzdGVuIHRvIGNoYW5nZXMgdG8gaXRzIGhvc3Qgd2luZG93J3MgY29udGV4dCBieSBsaXN0ZW5pbmcgdG8gdGhlIGBob3N0LWNvbnRleHQtY2hhbmdlZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGZpcmUgd2hlbiBhIGhvc3Qgd2luZG93J3MgY29udGV4dCBpcyB1cGRhdGVkIG9yIHdoZW4gdGhlIHZpZXcgaXMgcmVwYXJlbnRlZCB0byBhIG5ldyB3aW5kb3c6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gYSB2aWV3XG4gICAgICogY29uc3QgY29udGV4dENoYW5nZUhhbmRsZXIgPSAoeyBjb250ZXh0IH0pID0+IHtcbiAgICAgKiAgICAgY29uc29sZS5sb2coJ0hvc3Qgd2luZG93XFwncyBjb250ZXh0IGhhcyBjaGFuZ2VkLiBOZXcgY29udGV4dCBkYXRhOicsIGNvbnRleHQpO1xuICAgICAqICAgICAvLyByZWFjdCB0byBuZXcgY29udGV4dCBkYXRhIGhlcmVcbiAgICAgKiB9XG4gICAgICogYXdhaXQgZmluLm1lLm9uKCdob3N0LWNvbnRleHQtY2hhbmdlZCcsIGNvbnRleHRDaGFuZ2VIYW5kbGVyKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKiBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGNvbnRleHREYXRhKSAvLyBjb250ZXh0Q2hhbmdlSGFuZGxlciB3aWxsIGxvZyB0aGUgbmV3IGNvbnRleHRcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRvIGxpc3RlbiB0byBhIHdpbmRvdydzIGNvbnRleHQgdXBkYXRlcywgdXNlIHRoZSBgY29udGV4dC1jaGFuZ2VkYCBldmVudDpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gYSB3aW5kb3dcbiAgICAgKiBjb25zdCBjb250ZXh0Q2hhbmdlSGFuZGxlciA9ICh7IGNvbnRleHQgfSkgPT4ge1xuICAgICAqICAgICBjb25zb2xlLmxvZygnVGhpcyB3aW5kb3dcXCdzIGNvbnRleHQgaGFzIGNoYW5nZWQuIE5ldyBjb250ZXh0IGRhdGE6JywgY29udGV4dCk7XG4gICAgICogICAgIC8vIHJlYWN0IHRvIG5ldyBjb250ZXh0IGRhdGEgaGVyZVxuICAgICAqIH1cbiAgICAgKiBhd2FpdCBmaW4ubWUub24oJ2NvbnRleHQtY2hhbmdlZCcsIGNvbnRleHRDaGFuZ2VIYW5kbGVyKTtcbiAgICAgKlxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3QgY29udGV4dERhdGEgPSB7XG4gICAgICogICAgIHNlY3VyaXR5OiAnU1RPQ0snLFxuICAgICAqICAgICBjdXJyZW50VmlldzogJ2RldGFpbGVkJ1xuICAgICAqIH1cbiAgICAgKiBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGNvbnRleHREYXRhKSAvLyBjb250ZXh0Q2hhbmdlSGFuZGxlciB3aWxsIGxvZyB0aGUgbmV3IGNvbnRleHRcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgc2V0V2luZG93Q29udGV4dChjb250ZXh0ID0ge30sIHRhcmdldCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tc2V0LXdpbmRvdy1jb250ZXh0JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgc2VyaWFsaXphYmxlIG9iamVjdCBvciBzdHJpbmcgdG8gc2V0IHRoZSBjb250ZXh0LicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5VHlwZSB9ID0gdGFyZ2V0ID8gYXdhaXQgdGhpcy5maW4uU3lzdGVtLmdldEVudGl0eUluZm8odGFyZ2V0LnV1aWQsIHRhcmdldC5uYW1lKSA6IHRoaXMuZmluLm1lO1xuICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3NldC13aW5kb3ctY29udGV4dCcsIHtcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBlbnRpdHlUeXBlLFxuICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQgfHwgeyB1dWlkOiB0aGlzLmZpbi5tZS51dWlkLCBuYW1lOiB0aGlzLmZpbi5tZS5uYW1lIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY29udGV4dCBjb250ZXh0IG9mIGEgaG9zdCB3aW5kb3cgdGhhdCB3YXMgcHJldmlvdXNseSBzZXQgdXNpbmcge0BsaW5rIFBsYXRmb3JtI3NldFdpbmRvd0NvbnRleHQgc2V0V2luZG93Q29udGV4dH0uXG4gICAgICogVGhlIGNvbnRleHQgd2lsbCBiZSBzYXZlZCBpbiBhbnkgcGxhdGZvcm0gc25hcHNob3RzLiAgUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gQSB0YXJnZXQgd2luZG93IG9yIHZpZXcgbWF5IG9wdGlvbmFsbHkgYmUgcHJvdmlkZWQuIElmIG5vIHRhcmdldCBpcyBwcm92aWRlZCwgdGFyZ2V0IHdpbGwgYmVcbiAgICAgKiB0aGUgY3VycmVudCB3aW5kb3cgKGlmIGNhbGxlZCBmcm9tIGEgV2luZG93KSBvciB0aGUgY3VycmVudCBob3N0IHdpbmRvdyAoaWYgY2FsbGVkIGZyb20gYSBWaWV3KS5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIFRoaXMgbWV0aG9kIGNhbiBiZSBjYWxsZWQgZnJvbSB0aGUgd2luZG93IGl0c2VsZiwgb3IgZnJvbSBhbnkgY2hpbGQgdmlldy4gQ29udGV4dCBkYXRhIGlzIHNoYXJlZFxuICAgICAqIGJ5IGFsbCBlbnRpdGllcyB3aXRoaW4gYSB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogUmV0cmlldmluZyBjb250ZXh0IGZyb20gY3VycmVudCB3aW5kb3c6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIGNvbnN0IGN1c3RvbUNvbnRleHQgPSB7IGFuc3dlcjogNDIgfTtcbiAgICAgKiBhd2FpdCBwbGF0Zm9ybS5zZXRXaW5kb3dDb250ZXh0KGN1c3RvbUNvbnRleHQpO1xuICAgICAqXG4gICAgICogY29uc3QgbXlDb250ZXh0ID0gYXdhaXQgcGxhdGZvcm0uZ2V0V2luZG93Q29udGV4dCgpO1xuICAgICAqIGNvbnNvbGUubG9nKG15Q29udGV4dCk7IC8vIHsgYW5zd2VyOiA0MiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBSZXRyaWV2aW5nIHRoZSBjb250ZXh0IG9mIGFub3RoZXIgd2luZG93IG9yIHZpZXc6XG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqXG4gICAgICogY29uc3Qgd2luZG93T3JWaWV3SWRlbnRpdHkgPSB7IHV1aWQ6IGZpbi5tZS51dWlkLCBuYW1lOiAnbmFtZU9mV2luZG93T3JWaWV3JyB9O1xuICAgICAqXG4gICAgICogY29uc3QgdGFyZ2V0V2luZG93Q29udGV4dCA9IGF3YWl0IHBsYXRmb3JtLmdldFdpbmRvd0NvbnRleHQod2luZG93T3JWaWV3SWRlbnRpdHkpO1xuICAgICAqIGNvbnNvbGUubG9nKHRhcmdldFdpbmRvd0NvbnRleHQpOyAvLyBjb250ZXh0IG9mIHRhcmdldCB3aW5kb3dcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgZ2V0V2luZG93Q29udGV4dCh0YXJnZXQpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWdldC13aW5kb3ctY29udGV4dCcsIHRoaXMuaWRlbnRpdHkpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5VHlwZSB9ID0gdGFyZ2V0ID8gYXdhaXQgdGhpcy5maW4uU3lzdGVtLmdldEVudGl0eUluZm8odGFyZ2V0LnV1aWQsIHRhcmdldC5uYW1lKSA6IHRoaXMuZmluLm1lO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXQtd2luZG93LWNvbnRleHQnLCB7XG4gICAgICAgICAgICB0YXJnZXQ6IHRhcmdldCB8fCB7IHV1aWQ6IHRoaXMuZmluLm1lLnV1aWQsIG5hbWU6IHRoaXMuZmluLm1lLm5hbWUgfSxcbiAgICAgICAgICAgIGVudGl0eVR5cGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlcyBhIHdpbmRvdy4gSWYgZW5hYmxlQmVmb3JlVW5sb2FkIGlzIGVuYWJsZWQgaW4gdGhlIFBsYXRmb3JtIG9wdGlvbnMsIGFueSBiZWZvcmV1bmxvYWQgaGFuZGxlciBzZXQgb24gVmlld3Mgd2lsbCBmaXJlXG4gICAgICogVGhpcyBiZWhhdmlvciBjYW4gYmUgZGlzYWJsZWQgYnkgc2V0dGluZyBza2lwQmVmb3JlVW5sb2FkIHRvIGZhbHNlIGluIHRoZSBvcHRpb25zIHBhcmFtZXRlci5cbiAgICAgKiBAcGFyYW0gd2luSWRcbiAgICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgICAqXG4gICAgICogQHJlbWFya3MgVGhpcyBtZXRob2Qgd29ya3MgYnkgc2V0dGluZyBhIGBjbG9zZS1yZXF1ZXN0ZWRgIGhhbmRsZXIgb24gdGhlIFBsYXRmb3JtIFdpbmRvdy4gSWYgeW91IGhhdmUgeW91ciBvd24gYGNsb3NlLXJlcXVlc3RlZGAgaGFuZGxlciBzZXQgb24gdGhlIFBsYXRmb3JtIFdpbmRvdyBhcyB3ZWxsLFxuICAgICAqIGl0IGlzIHJlY29tbWVuZGVkIHRvIG1vdmUgdGhhdCBsb2dpYyBvdmVyIHRvIHRoZSBbUGxhdGZvcm1Qcm92aWRlci5jbG9zZVdpbmRvd117QGxpbmsgUGxhdGZvcm1Qcm92aWRlciNjbG9zZVdpbmRvd30gb3ZlcnJpZGUgdG8gZW5zdXJlIGl0IHJ1bnMgd2hlbiB0aGUgV2luZG93IGNsb3Nlcy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIENsb3NlIHRoZSBjdXJyZW50IFdpbmRvdyBpbnNpZGUgYSBXaW5kb3cgY29udGV4dFxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBwbGF0Zm9ybS5jbG9zZVdpbmRvdyhmaW4ubWUuaWRlbnRpdHkpO1xuICAgICAqXG4gICAgICogLy8gQ2xvc2UgdGhlIFdpbmRvdyBmcm9tIGluc2lkZSBhIFZpZXcgY29udGV4dFxuICAgICAqIGNvbnN0IHBsYXRmb3JtID0gYXdhaXQgZmluLlBsYXRmb3JtLmdldEN1cnJlbnQoKTtcbiAgICAgKiBjb25zdCBwYXJlbnRXaW5kb3cgPSBhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFdpbmRvdygpO1xuICAgICAqIHBsYXRmb3JtLmNsb3NlV2luZG93KHBhcmVudFdpbmRvdy5pZGVudGl0eSk7XG4gICAgICpcbiAgICAgKiAvLyBDbG9zZSB0aGUgV2luZG93IGFuZCBkbyBub3QgZmlyZSB0aGUgYmVmb3JlIHVubG9hZCBoYW5kbGVyIG9uIFZpZXdzXG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudCgpO1xuICAgICAqIHBsYXRmb3JtLmNsb3NlV2luZG93KGZpbi5tZS5pZGVudGl0eSwgeyBza2lwQmVmb3JlVW5sb2FkOiB0cnVlIH0pO1xuICAgICAqIGBgYFxuICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZVdpbmRvdyh3aW5kb3dJZCwgb3B0aW9ucyA9IHsgc2tpcEJlZm9yZVVubG9hZDogZmFsc2UgfSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tY2xvc2Utd2luZG93JywgdGhpcy5pZGVudGl0eSkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnY2xvc2Utd2luZG93JywgeyB3aW5kb3dJZCwgb3B0aW9ucyB9KTtcbiAgICB9XG59XG5JbnN0YW5jZSQyLlBsYXRmb3JtID0gUGxhdGZvcm07XG5fUGxhdGZvcm1fY29ubmVjdFRvUHJvdmlkZXIgPSBuZXcgV2Vha01hcCgpO1xuXG52YXIgbGF5b3V0ID0ge307XG5cbnZhciBGYWN0b3J5JDIgPSB7fTtcblxudmFyIEluc3RhbmNlJDEgPSB7fTtcblxudmFyIGNvbW1vblV0aWxzID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb21tb25VdGlscywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5jb21tb25VdGlscy5vdmVycmlkZUZyb21Db21wb3NhYmxlcyA9IGNvbW1vblV0aWxzLmlzVmFsaWRQcmVzZXRUeXBlID0gdm9pZCAwO1xuZnVuY3Rpb24gaXNWYWxpZFByZXNldFR5cGUodHlwZSkge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlICdjb2x1bW5zJzpcbiAgICAgICAgY2FzZSAnZ3JpZCc6XG4gICAgICAgIGNhc2UgJ3Jvd3MnOlxuICAgICAgICBjYXNlICd0YWJzJzpcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmNvbW1vblV0aWxzLmlzVmFsaWRQcmVzZXRUeXBlID0gaXNWYWxpZFByZXNldFR5cGU7XG5mdW5jdGlvbiBvdmVycmlkZUZyb21Db21wb3NhYmxlcyguLi5vdmVycmlkZXMpIHtcbiAgICByZXR1cm4gKGJhc2UpID0+IG92ZXJyaWRlcy5yZWR1Y2VSaWdodCgocCwgYykgPT4gKGIpID0+IGMocChiKSksICh4KSA9PiB4KShiYXNlKTtcbn1cbmNvbW1vblV0aWxzLm92ZXJyaWRlRnJvbUNvbXBvc2FibGVzID0gb3ZlcnJpZGVGcm9tQ29tcG9zYWJsZXM7XG5jb21tb25VdGlscy5kZWZhdWx0ID0geyBpc1ZhbGlkUHJlc2V0VHlwZSB9O1xuXG52YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQ0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX0xheW91dF9sYXlvdXRDbGllbnQ7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoSW5zdGFuY2UkMSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZSQxLkxheW91dCA9IHZvaWQgMDtcbmNvbnN0IGxhenlfMSA9IGxhenk7XG5jb25zdCB2YWxpZGF0ZV8xID0gdmFsaWRhdGU7XG5jb25zdCBiYXNlXzEkNSA9IGJhc2U7XG5jb25zdCBjb21tb25fdXRpbHNfMSA9IGNvbW1vblV0aWxzO1xuY29uc3QgbGF5b3V0X2VudGl0aWVzXzEgPSBsYXlvdXRFbnRpdGllcztcbmNvbnN0IGxheW91dF9jb25zdGFudHNfMSQxID0gbGF5b3V0X2NvbnN0YW50cztcbi8qKlxuICpcbiAqIExheW91dHMgZ2l2ZSBhcHAgcHJvdmlkZXJzIHRoZSBhYmlsaXR5IHRvIGVtYmVkIG11bHRpcGxlIHZpZXdzIGluIGEgc2luZ2xlIHdpbmRvdy4gVGhlIExheW91dCBuYW1lc3BhY2VcbiAqIGVuYWJsZXMgdGhlIGluaXRpYWxpemF0aW9uIGFuZCBtYW5pcHVsYXRpb24gb2YgYSB3aW5kb3cncyBMYXlvdXQuIEEgTGF5b3V0IHdpbGxcbiAqIGVtaXQgZXZlbnRzIGxvY2FsbHkgb24gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgbGF5b3V0LWNvbnRhaW5lci5cbiAqXG4gKlxuICogIyMjIExheW91dC5ET01FdmVudHNcbiAqXG4gKiBXaGVuIGEgTGF5b3V0IGlzIGNyZWF0ZWQsIGl0IGVtaXRzIGV2ZW50cyBvbnRvIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRpbmcgdGhlIExheW91dCBjb250YWluZXIuXG4gKiBUaGlzIExheW91dCBjb250YWluZXIgaXMgdGhlIERPTSBlbGVtZW50IHJlZmVyZW5jZWQgYnkgY29udGFpbmVySWQgaW4ge0BsaW5rIExheW91dC5MYXlvdXRNb2R1bGUjaW5pdCBMYXlvdXQuaW5pdH0uXG4gKiBZb3UgY2FuIHVzZSB0aGUgYnVpbHQtaW4gZXZlbnQgZW1pdHRlciB0byBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIHVzaW5nIFthZGRFdmVudExpc3RlbmVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lcikuXG4gKiBUaGUgZXZlbnRzIGFyZSBlbWl0dGVkIHN5bmNocm9ub3VzbHkgYW5kIG9ubHkgaW4gdGhlIHByb2Nlc3Mgd2hlcmUgdGhlIExheW91dCBleGlzdHMuXG4gKiBBbnkgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBjYWxsZWQgbGlzdGVuZXJzIGFyZSBpZ25vcmVkIGFuZCB3aWxsIGJlIGRpc2NhcmRlZC5cbiAqIElmIHRoZSB0YXJnZXQgRE9NIGVsZW1lbnQgaXMgZGVzdHJveWVkLCBhbnkgZXZlbnRzIHRoYXQgaGF2ZSBiZWVuIHNldCB1cCBvbiB0aGF0IGVsZW1lbnQgd2lsbCBiZSBkZXN0cm95ZWQuXG4gKlxuICogQHJlbWFya3MgVGhlIGJ1aWx0LWluIGV2ZW50IGVtaXR0ZXIgaXMgbm90IGFuIE9wZW5GaW4gZXZlbnQgZW1pdHRlciBzbyBpdCBkb2Vzbid0IHNoYXJlIHByb3BhZ2F0aW9uIHNlbWFudGljcy5cbiAqXG4gKiAjIyMjIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyIFssIG9wdGlvbnNdKTt9XG4gKiBBZGRzIGEgbGlzdGVuZXIgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdGVuZXJzIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBjb25zdCBteUxheW91dENvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsYXlvdXQtY29udGFpbmVyJyk7XG4gKlxuICogbXlMYXlvdXRDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcigndGFiLWNyZWF0ZWQnLCBmdW5jdGlvbihldmVudCkge1xuICogICAgICBjb25zdCB7IHRhYlNlbGVjdG9yIH0gPSBldmVudC5kZXRhaWw7XG4gKiAgICAgIGNvbnN0IHRhYkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJTZWxlY3Rvcik7XG4gKiAgICAgIGNvbnN0IGV4aXN0aW5nQ29sb3IgPSB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvcjtcbiAqICAgICAgdGFiRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcInJlZFwiO1xuICogICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAqICAgICAgICAgIHRhYkVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gZXhpc3RpbmdDb2xvcjtcbiAqICAgICAgfSwgMjAwMCk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqICMjIyMge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9yZW1vdmVFdmVudExpc3RlbmVyIHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIgWywgb3B0aW9uc10pO31cbiAqIEFkZHMgYSBsaXN0ZW5lciB0byB0aGUgZW5kIG9mIHRoZSBsaXN0ZW5lcnMgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBganNcbiAqIGNvbnN0IG15TGF5b3V0Q29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2xheW91dC1jb250YWluZXInKTtcbiAqXG4gKiBjb25zdCBsaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coZXZlbnQuZGV0YWlsKTtcbiAqICAgICBjb25zb2xlLmxvZygnY29udGFpbmVyLWNyZWF0ZWQgZXZlbnQgZmlyZWQgb25jZSwgcmVtb3ZpbmcgbGlzdGVuZXInKTtcbiAqICAgICBteUxheW91dENvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdjb250YWluZXItY3JlYXRlZCcsIGxpc3RlbmVyKTtcbiAqIH07XG4gKlxuICogbXlMYXlvdXRDb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY29udGFpbmVyLWNyZWF0ZWQnLCBsaXN0ZW5lcik7XG4gKiBgYGBcbiAqXG4gKiAjIyMgU3VwcG9ydGVkIGV2ZW50IHR5cGVzIGFyZTpcbiAqXG4gKiAqIHRhYi1jcmVhdGVkXG4gKiAqIGNvbnRhaW5lci1jcmVhdGVkXG4gKiAqIGxheW91dC1zdGF0ZS1jaGFuZ2VkXG4gKiAqIHRhYi1jbG9zZWRcbiAqICogdGFiLWRyb3BwZWRcbiAqXG4gKiAjIyMgTGF5b3V0IERPTSBOb2RlIEV2ZW50c1xuICpcbiAqICMjIyMgdGFiLWNyZWF0ZWRcbiAqIEdlbmVyYXRlZCB3aGVuIGEgdGFiIGlzIGNyZWF0ZWQuICBBcyBhIHVzZXIgZHJhZ3MgYW5kIGRyb3BzIHRhYnMgd2l0aGluIHdpbmRvdywgbmV3IHRhYnMgYXJlIGNyZWF0ZWQuICBBIHNpbmdsZSB2aWV3IG1heSBoYXZlIG11bHRpcGxlIHRhYnMgY3JlYXRlZCBhbmQgZGVzdHJveWVkIGR1cmluZyBpdHMgbGlmZXRpbWUgYXR0YWNoZWQgdG8gYSBzaW5nbGUgd2luZG93LlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWw6XG4gKiB7XG4gKiAgICAgY29udGFpbmVyU2VsZWN0b3I6IFwiY29udGFpbmVyLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgbmFtZTogXCJjb21wb25lbnRfQVwiLFxuICogICAgIHRhYlNlbGVjdG9yOiBcInRhYi1jb21wb25lbnRfQVwiLFxuICogICAgIHRvcGljOiBcIm9wZW5maW4tRE9NLWV2ZW50XCIsXG4gKiAgICAgdHlwZTogXCJ0YWItY3JlYXRlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIyBjb250YWluZXItY3JlYXRlZFxuICogR2VuZXJhdGVkIHdoZW4gYSBjb250YWluZXIgaXMgY3JlYXRlZC4gIEEgc2luZ2xlIHZpZXcgd2lsbCBoYXZlIG9ubHkgb25lIGNvbnRhaW5lciBkdXJpbmcgaXRzIGxpZmV0aW1lIGF0dGFjaGVkIHRvIGEgc2luZ2xlIHdpbmRvdyBhbmQgdGhlIGNvbnRhaW5lcidzIGxpZmVjeWNsZSBpcyB0aWVkIHRvIHRoZSB2aWV3LiAgVG8gZGlzY292ZXIgd2hlbiB0aGUgY29udGFpbmVyIGlzIGRlc3Ryb3llZCwgcGxlYXNlIGxpc3RlbiB0byB2aWV3LWRldGFjaGVkIGV2ZW50LlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWw6XG4gKiB7XG4gKiAgICAgY29udGFpbmVyU2VsZWN0b3I6IFwiY29udGFpbmVyLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgbmFtZTogXCJjb21wb25lbnRfQVwiLFxuICogICAgIHRhYlNlbGVjdG9yOiBcInRhYi1jb21wb25lbnRfQVwiLFxuICogICAgIHRvcGljOiBcIm9wZW5maW4tRE9NLWV2ZW50XCIsXG4gKiAgICAgdHlwZTogXCJjb250YWluZXItY3JlYXRlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIGxheW91dC1zdGF0ZS1jaGFuZ2VkXG4gKiBHZW5lcmF0ZWQgd2hlbiB0aGUgc3RhdGUgb2YgdGhlIGxheW91dCBjaGFuZ2VzIGluIGFueSB3YXksIHN1Y2ggYXMgYSB2aWV3IGFkZGVkL3JlbW92ZWQvcmVwbGFjZWQuIE5vdGUgdGhhdCB0aGlzIGV2ZW50IGNhbiBmaXJlIGZyZXF1ZW50bHkgYXMgdGhlIHVuZGVybHlpbmcgbGF5b3V0IGNhbiBjaGFuZ2UgbXVsdGlwbGUgY29tcG9uZW50cyBmcm9tIGFsbCBraW5kcyBvZiBjaGFuZ2VzIChyZXNpemluZyBmb3IgZXhhbXBsZSkuIEdpdmVuIHRoaXMsIGl0IGlzIHJlY29tbWVuZGVkIHRvIGRlYm91bmNlIHRoaXMgZXZlbnQgYW5kIHRoZW4geW91IGNhbiB1c2UgdGhlIHtAbGluayBMYXlvdXQjZ2V0Q29uZmlnIExheW91dC5nZXRDb25maWd9IEFQSSB0byByZXRyaWV2ZSB0aGUgbW9zdCB1cC10by1kYXRlIHN0YXRlLlxuICogYGBganNcbiAqIC8vIFRoZSByZXNwb25zZSBoYXMgdGhlIGZvbGxvd2luZyBzaGFwZSBpbiBldmVudC5kZXRhaWxcbiAqIHtcbiAqICAgICBjb250YWluZXJTZWxlY3RvcjogXCJjb250YWluZXItY29tcG9uZW50X0FcIixcbiAqICAgICBuYW1lOiBcImNvbXBvbmVudF9BXCIsXG4gKiAgICAgdGFiU2VsZWN0b3I6IFwidGFiLWNvbXBvbmVudF9BXCIsXG4gKiAgICAgdG9waWM6IFwib3BlbmZpbi1ET00tZXZlbnRcIixcbiAqICAgICB0eXBlOiBcImxheW91dC1zdGF0ZS1jaGFuZ2VkXCIsXG4gKiAgICAgdXVpZDogXCJPcGVuRmluIFBPQ1wiXG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMjIHRhYi1jbG9zZWRcbiAqIEdlbmVyYXRlZCB3aGVuIGEgdGFiIGlzIGNsb3NlZC5cbiAqIGBgYGpzXG4gKiAvLyBUaGUgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGUgaW4gZXZlbnQuZGV0YWlsOlxuICoge1xuICogICAgIGNvbnRhaW5lclNlbGVjdG9yOiBcImNvbnRhaW5lci1jb21wb25lbnRfQVwiLFxuICogICAgIG5hbWU6IFwiY29tcG9uZW50X0FcIixcbiAqICAgICB0YWJTZWxlY3RvcjogXCJ0YWItY29tcG9uZW50X0FcIixcbiAqICAgICB0b3BpYzogXCJvcGVuZmluLURPTS1ldmVudFwiLFxuICogICAgIHR5cGU6IFwidGFiLWNsb3NlZFwiLFxuICogICAgIHV1aWQ6IFwiT3BlbkZpbiBQT0NcIixcbiAqICAgICB1cmw6IFwiaHR0cDovL29wZW5maW4uY29cIiAgIC8vIFRoZSB1cmwgb2YgdGhlIHZpZXcgdGhhdCB3YXMgY2xvc2VkLlxuICogfVxuICogYGBgXG4gKlxuICogIyMjIyB0YWItZHJvcHBlZFxuICogR2VuZXJhdGVkIHdoZW4gYSB0YWIgaXMgZHJvcHBlZC5cbiAqIGBgYGpzXG4gKiAvLyBUaGUgcmVzcG9uc2UgaGFzIHRoZSBmb2xsb3dpbmcgc2hhcGUgaW4gZXZlbnQuZGV0YWlsOlxuICoge1xuICogICAgIGNvbnRhaW5lclNlbGVjdG9yOiBcImNvbnRhaW5lci1jb21wb25lbnRfQVwiLFxuICogICAgIG5hbWU6IFwiY29tcG9uZW50X0FcIixcbiAqICAgICB0YWJTZWxlY3RvcjogXCJ0YWItY29tcG9uZW50X0FcIixcbiAqICAgICB0b3BpYzogXCJvcGVuZmluLURPTS1ldmVudFwiLFxuICogICAgIHR5cGU6IFwidGFiLWRyb3BwZWRcIixcbiAqICAgICB1dWlkOiBcIk9wZW5GaW4gUE9DXCIsXG4gKiAgICAgdXJsOiBcImh0dHA6Ly9vcGVuZmluLmNvXCIgICAgLy8gVGhlIHVybCBvZiB0aGUgdmlldyBsaW5rZWQgdG8gdGhlIGRyb3BwZWQgdGFiLlxuICogfVxuICogYGBgXG4gKi9cbmNsYXNzIExheW91dCBleHRlbmRzIGJhc2VfMSQ1LkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zaGFkb3dcbiAgICBjb25zdHJ1Y3RvcihpZGVudGl0eSwgd2lyZSkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBpbnRlcm5hbFxuICAgICAgICAgKiBMYXppbHkgY29uc3RydWN0ZWQge0BsaW5rIExheW91dEVudGl0aWVzQ2xpZW50fSBib3VuZCB0byB0aGlzIHBsYXRmb3JtJ3MgY2xpZW50IGFuZCBpZGVudGl0eVxuICAgICAgICAgKiBUaGUgY2xpZW50IGlzIGZvciB7QGxpbmsgTGF5b3V0RW50aXRpZXNDb250cm9sbGVyfVxuICAgICAgICAgKi9cbiAgICAgICAgX0xheW91dF9sYXlvdXRDbGllbnQuc2V0KHRoaXMsIG5ldyBsYXp5XzEuTGF6eShhc3luYyAoKSA9PiBsYXlvdXRfZW50aXRpZXNfMS5MYXlvdXROb2RlLm5ld0xheW91dEVudGl0aWVzQ2xpZW50KGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCksIGxheW91dF9jb25zdGFudHNfMSQxLkxBWU9VVF9DT05UUk9MTEVSX0lELCB0aGlzLmlkZW50aXR5KSkpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwbGFjZXMgYSBQbGF0Zm9ybSB3aW5kb3cncyBsYXlvdXQgd2l0aCBhIG5ldyBsYXlvdXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZW1hcmtzIEFueSB2aWV3cyB0aGF0IHdlcmUgaW4gdGhlIG9sZCBsYXlvdXQgYnV0IG5vdCB0aGUgbmV3IGxheW91dCB3aWxsIGJlIGRlc3Ryb3llZC4gVmlld3Mgd2lsbCBiZSBhc3NpZ25lZCBhIHJhbmRvbWx5IGdlbmVyYXRlZCBuYW1lIHRvIGF2b2lkIGNvbGxpc2lvbnMuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGBgYGpzXG4gICAgICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSBmaW4ubWUuaWRlbnRpdHk7XG4gICAgICAgICAqIH0gZWxzZSBpZiAoZmluLm1lLmlzVmlldykge1xuICAgICAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICAgICAqIH0gZWxzZSB7XG4gICAgICAgICAqICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluIGEgcGxhdGZvcm0gVmlldyBvciBXaW5kb3cnKTtcbiAgICAgICAgICogfVxuICAgICAgICAgKlxuICAgICAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LndyYXBTeW5jKHdpbmRvd0lkZW50aXR5KTtcbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3QgbmV3TGF5b3V0ID0ge1xuICAgICAgICAgKiAgICAgY29udGVudDogW1xuICAgICAgICAgKiAgICAgICAgIHtcbiAgICAgICAgICogICAgICAgICAgICAgdHlwZTogJ3N0YWNrJyxcbiAgICAgICAgICogICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmV3X2NvbXBvbmVudF9BMScsXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NBZmZpbml0eTogJ3BzXzEnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6ICdodHRwczovL3d3dy5leGFtcGxlLmNvbSdcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAqICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICd2aWV3JyxcbiAgICAgICAgICogICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRTdGF0ZToge1xuICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmV3X2NvbXBvbmVudF9BMicsXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogJ2h0dHBzOi8vY2RuLm9wZW5maW4uY28vZW1iZWQtd2ViL2NoYXJ0Lmh0bWwnXG4gICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgKiAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgKiAgICAgICAgICAgICBdXG4gICAgICAgICAqICAgICAgICAgfVxuICAgICAgICAgKiAgICAgXVxuICAgICAgICAgKiB9O1xuICAgICAgICAgKlxuICAgICAgICAgKiBsYXlvdXQucmVwbGFjZShuZXdMYXlvdXQpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVwbGFjZSA9IGFzeW5jIChsYXlvdXQpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtcmVwbGFjZScpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlcGxhY2UtbGF5b3V0Jywge1xuICAgICAgICAgICAgICAgIHRhcmdldDogdGhpcy5pZGVudGl0eSxcbiAgICAgICAgICAgICAgICBvcHRzOiB7IGxheW91dCB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGxhY2VzIHRoZSBzcGVjaWZpZWQgdmlldyB3aXRoIGEgdmlldyB3aXRoIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmVtYXJrcyBUaGUgb2xkIHZpZXcgaXMgc3RyaXBwZWQgb2YgaXRzIGxpc3RlbmVycyBhbmQgZWl0aGVyIGNsb3NlZCBvciBhdHRhY2hlZCB0byB0aGUgcHJvdmlkZXIgd2luZG93XG4gICAgICAgICAqIGRlcGVuZGluZyBvbiBgZGV0YWNoT25DbG9zZWAgdmlldyBvcHRpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB2aWV3VG9SZXBsYWNlIElkZW50aXR5IG9mIHRoZSB2aWV3IHRvIGJlIHJlcGxhY2VkXG4gICAgICAgICAqIEBwYXJhbSBuZXdWaWV3IENyZWF0aW9uIG9wdGlvbnMgb2YgdGhlIG5ldyB2aWV3LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBsZXQgY3VycmVudFdpbmRvdztcbiAgICAgICAgICogaWYgKGZpbi5tZS5pc1dpbmRvdykge1xuICAgICAgICAgKiAgICAgY3VycmVudFdpbmRvdyA9IGZpbi5tZTtcbiAgICAgICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICBjdXJyZW50V2luZG93ID0gYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKTtcbiAgICAgICAgICogfSBlbHNlIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcFN5bmMoY3VycmVudFdpbmRvdy5pZGVudGl0eSk7XG4gICAgICAgICAqIGNvbnN0IHZpZXdUb1JlcGxhY2UgPSAoYXdhaXQgY3VycmVudFdpbmRvdy5nZXRDdXJyZW50Vmlld3MoKSlbMF07XG4gICAgICAgICAqIGNvbnN0IG5ld1ZpZXdDb25maWcgPSB7dXJsOiAnaHR0cHM6Ly9leGFtcGxlLmNvbSd9O1xuICAgICAgICAgKiBhd2FpdCBsYXlvdXQucmVwbGFjZVZpZXcodmlld1RvUmVwbGFjZS5pZGVudGl0eSwgbmV3Vmlld0NvbmZpZyk7XG4gICAgICAgICAqIGBgYFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZXBsYWNlVmlldyA9IGFzeW5jICh2aWV3VG9SZXBsYWNlLCBuZXdWaWV3KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LXJlcGxhY2UtdmlldycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlcGxhY2UtdmlldycsIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3B0czogeyB2aWV3VG9SZXBsYWNlLCBuZXdWaWV3IH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwbGFjZXMgYSBQbGF0Zm9ybSB3aW5kb3cncyBsYXlvdXQgd2l0aCBhIHByZXNldCBsYXlvdXQgYXJyYW5nZW1lbnQgdXNpbmcgdGhlIGV4aXN0aW5nIFZpZXdzIGF0dGFjaGVkIHRvIHRoZSB3aW5kb3cuXG4gICAgICAgICAqIFRoZSBwcmVzZXQgb3B0aW9ucyBhcmUgYGNvbHVtbnNgLCBgZ3JpZGAsIGByb3dzYCwgYW5kIGB0YWJzYC5cbiAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgTWFuZGF0b3J5IG9iamVjdCB3aXRoIGBwcmVzZXRUeXBlYCBwcm9wZXJ0eSB0aGF0IHNldHMgd2hpY2ggcHJlc2V0IGxheW91dCBhcnJhbmdlbWVudCB0byB1c2UuXG4gICAgICAgICAqIFRoZSBwcmVzZXQgb3B0aW9ucyBhcmUgYGNvbHVtbnNgLCBgZ3JpZGAsIGByb3dzYCwgYW5kIGB0YWJzYC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogbGV0IHdpbmRvd0lkZW50aXR5O1xuICAgICAgICAgKiBpZiAoZmluLm1lLmlzV2luZG93KSB7XG4gICAgICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgICAgICogfSBlbHNlIGlmIChmaW4ubWUuaXNWaWV3KSB7XG4gICAgICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IChhd2FpdCBmaW4ubWUuZ2V0Q3VycmVudFdpbmRvdygpKS5pZGVudGl0eTtcbiAgICAgICAgICogfSBlbHNlIHtcbiAgICAgICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3IG9yIFdpbmRvdycpO1xuICAgICAgICAgKiB9XG4gICAgICAgICAqXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQud3JhcFN5bmMod2luZG93SWRlbnRpdHkpO1xuICAgICAgICAgKiBhd2FpdCBsYXlvdXQuYXBwbHlQcmVzZXQoeyBwcmVzZXRUeXBlOiAnZ3JpZCcgfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIHdhaXQgNSBzZWNvbmRzIHVudGlsIHlvdSBjaGFuZ2UgdGhlIGxheW91dCBmcm9tIGdyaWQgdG8gdGFic1xuICAgICAgICAgKiBhd2FpdCBuZXcgUHJvbWlzZSAocmVzID0+IHNldFRpbWVvdXQocmVzLCA1MDAwKSk7XG4gICAgICAgICAqIGF3YWl0IGxheW91dC5hcHBseVByZXNldCh7IHByZXNldFR5cGU6ICd0YWJzJyB9KTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFwcGx5UHJlc2V0ID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtYXBwbHktcHJlc2V0JykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5wbGF0Zm9ybS5nZXRDbGllbnQoKTtcbiAgICAgICAgICAgIGNvbnN0IHsgcHJlc2V0VHlwZSB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGlmICghcHJlc2V0VHlwZSB8fCAhKDAsIGNvbW1vbl91dGlsc18xLmlzVmFsaWRQcmVzZXRUeXBlKShwcmVzZXRUeXBlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGFwcGx5IHByZXNldCBsYXlvdXQsIHBsZWFzZSBpbmNsdWRlIGFuIGFwcGxpY2FibGUgcHJlc2V0VHlwZSBwcm9wZXJ0eSBpbiB0aGUgUHJlc2V0TGF5b3V0T3B0aW9ucy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnYXBwbHktcHJlc2V0LWxheW91dCcsIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgb3B0czogeyBwcmVzZXRUeXBlIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBlcnJvck1zZyA9ICgwLCB2YWxpZGF0ZV8xLnZhbGlkYXRlSWRlbnRpdHkpKGlkZW50aXR5KTtcbiAgICAgICAgaWYgKGVycm9yTXNnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgICAgICAgdGhpcy5wbGF0Zm9ybSA9IHRoaXMuZmluLlBsYXRmb3JtLndyYXBTeW5jKHsgdXVpZDogaWRlbnRpdHkudXVpZCB9KTtcbiAgICAgICAgaWYgKGlkZW50aXR5LnV1aWQgPT09IHRoaXMuZmluLm1lLnV1aWQgJiYgaWRlbnRpdHkubmFtZSA9PT0gdGhpcy5maW4ubWUubmFtZSkge1xuICAgICAgICAgICAgdGhpcy5pbml0ID0gdGhpcy5maW4uUGxhdGZvcm0uTGF5b3V0LmluaXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgd2luZG93J3MgbGF5b3V0LiAgUmV0dXJucyB0aGUgc2FtZSBpbmZvcm1hdGlvbiB0aGF0IGlzIHJldHVybmVkIGZvciBhbGwgd2luZG93cyBpbiBnZXRTbmFwc2hvdC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIENhbm5vdCBiZSBjYWxsZWQgZnJvbSBhIFZpZXcuXG4gICAgICpcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gZ2V0IHRoZSBsYXlvdXQgY29uZmlndXJhdGlvbiBvZiB0aGUgY3VycmVudCB3aW5kb3cncyBMYXlvdXQ6XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldENvbmZpZygpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2xheW91dC1nZXQtY29uZmlnJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5wbGF0Zm9ybS5nZXRDbGllbnQoKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0LWZyYW1lLXNuYXBzaG90Jywge1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGF0dGFjaGVkIHZpZXdzIGluIGN1cnJlbnQgd2luZG93IGxheW91dC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogY29uc3Qgdmlld3MgPSBhd2FpdCBsYXlvdXQuZ2V0Q3VycmVudFZpZXdzKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgZ2V0Q3VycmVudFZpZXdzKCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LWdldC12aWV3cycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IHRoaXMucGxhdGZvcm0uZ2V0Q2xpZW50KCk7XG4gICAgICAgIGNvbnN0IHZpZXdJZGVudGl0aWVzID0gYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdnZXQtbGF5b3V0LXZpZXdzJywge1xuICAgICAgICAgICAgdGFyZ2V0OiB0aGlzLmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdmlld0lkZW50aXRpZXMubWFwKChpZGVudGl0eSkgPT4gdGhpcy5maW4uVmlldy53cmFwU3luYyhpZGVudGl0eSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIHRvcCBsZXZlbCBjb250ZW50IGl0ZW0gb2YgdGhlIGxheW91dC5cbiAgICAgKlxuICAgICAqIEByZW1hcmtzIENhbm5vdCBiZSBjYWxsZWQgZnJvbSBhIHZpZXcuXG4gICAgICpcbiAgICAgKlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGlmICghZmluLm1lLmlzV2luZG93KSB7XG4gICAgICogICAgIHRocm93IG5ldyBFcnJvcignTm90IHJ1bm5pbmcgaW4gYSBwbGF0Zm9ybSBWaWV3LicpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIC8vIEZyb20gdGhlIGxheW91dCB3aW5kb3dcbiAgICAgKiBjb25zdCBsYXlvdXQgPSBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRTeW5jKCk7XG4gICAgICogLy8gUmV0cmlldmVzIHRoZSBDb2x1bW5PclJvdyBpbnN0YW5jZVxuICAgICAqIGNvbnN0IHJvb3RJdGVtID0gYXdhaXQgbGF5b3V0LmdldFJvb3RJdGVtKCk7XG4gICAgICogY29uc3QgY29udGVudCA9IGF3YWl0IHJvb3RJdGVtLmdldENvbnRlbnQoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhgVGhlIHJvb3QgQ29sdW1uT3JSb3cgaW5zdGFuY2UgaGFzICR7Y29udGVudC5sZW5ndGh9IGl0ZW0ocylgKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyBnZXRSb290SXRlbSgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2xheW91dC1nZXQtcm9vdC1pdGVtJykuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDQodGhpcywgX0xheW91dF9sYXlvdXRDbGllbnQsIFwiZlwiKS5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCByb290ID0gYXdhaXQgY2xpZW50LmdldFJvb3QoJ2xheW91dE5hbWUnIGluIHRoaXMuaWRlbnRpdHkgPyB0aGlzLmlkZW50aXR5IDogdW5kZWZpbmVkKTtcbiAgICAgICAgcmV0dXJuIGxheW91dF9lbnRpdGllc18xLkxheW91dE5vZGUuZ2V0RW50aXR5KHJvb3QsIGNsaWVudCk7XG4gICAgfVxufVxuSW5zdGFuY2UkMS5MYXlvdXQgPSBMYXlvdXQ7XG5fTGF5b3V0X2xheW91dENsaWVudCA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDMgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDMgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9MYXlvdXRNb2R1bGVfaW5zdGFuY2VzLCBfTGF5b3V0TW9kdWxlX2xheW91dEluaXRpYWxpemF0aW9uQXR0ZW1wdGVkLCBfTGF5b3V0TW9kdWxlX2xheW91dE1hbmFnZXIsIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweSwgX0xheW91dE1vZHVsZV9nZXRTYWZlTGF5b3V0TWFuYWdlcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDIsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuRmFjdG9yeSQyLkxheW91dE1vZHVsZSA9IHZvaWQgMDtcbmNvbnN0IGJhc2VfMSQ0ID0gYmFzZTtcbmNvbnN0IEluc3RhbmNlXzEkMiA9IEluc3RhbmNlJDE7XG5jb25zdCBsYXlvdXRfY29uc3RhbnRzXzEgPSBsYXlvdXRfY29uc3RhbnRzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIExheW91dH0gY2xhc3MsIGF2YWlsYWJsZSB1bmRlciBgZmluLlBsYXRmb3JtLkxheW91dGAuXG4gKi9cbmNsYXNzIExheW91dE1vZHVsZSBleHRlbmRzIGJhc2VfMSQ0LkJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcy5hZGQodGhpcyk7XG4gICAgICAgIF9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQuc2V0KHRoaXMsIGZhbHNlKTtcbiAgICAgICAgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLnNldCh0aGlzLCBudWxsKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXRpYWxpemUgdGhlIHdpbmRvdydzIExheW91dC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJlbWFya3MgTXVzdCBiZSBjYWxsZWQgZnJvbSBhIGN1c3RvbSB3aW5kb3cgdGhhdCBoYXMgYSAnbGF5b3V0JyBvcHRpb24gc2V0IHVwb24gY3JlYXRpb24gb2YgdGhhdCB3aW5kb3cuXG4gICAgICAgICAqIElmIGEgY29udGFpbmVySWQgaXMgbm90IHByb3ZpZGVkLCB0aGlzIG1ldGhvZCBhdHRlbXB0cyB0byBmaW5kIGFuIGVsZW1lbnQgd2l0aCB0aGUgaWQgYGxheW91dC1jb250YWluZXJgLlxuICAgICAgICAgKiBBIExheW91dCB3aWxsIGVtaXQgZXZlbnRzIGxvY2FsbHkgb24gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGluZyB0aGUgbGF5b3V0LWNvbnRhaW5lci5cbiAgICAgICAgICogSW4gb3JkZXIgdG8gY2FwdHVyZSB0aGUgcmVsZXZhbnQgZXZlbnRzIGR1cmluZyBMYXlvdXQgaW5pdGlhdGlvbiwgc2V0IHVwIHRoZSBsaXN0ZW5lcnMgb24gdGhlIERPTSBlbGVtZW50IHByaW9yIHRvIGNhbGxpbmcgYGluaXRgLlxuICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIExheW91dCBpbml0IG9wdGlvbnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBleHBlcmltZW50YWxcbiAgICAgICAgICpcbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogYGBganNcbiAgICAgICAgICogLy8gSWYgbm8gb3B0aW9ucyBhcmUgaW5jbHVkZWQsIHRoZSBsYXlvdXQgaW4gdGhlIHdpbmRvdyBvcHRpb25zIGlzIGluaXRpYWxpemVkIGluIGFuIGVsZW1lbnQgd2l0aCB0aGUgaWQgYGxheW91dC1jb250YWluZXJgXG4gICAgICAgICAqIGNvbnN0IGxheW91dCA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5MYXlvdXQuaW5pdCgpO1xuICAgICAgICAgKiBgYGBcbiAgICAgICAgICogPGJyPlxuICAgICAgICAgKlxuICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgKiBjb25zdCBjb250YWluZXJJZCA9ICdteS1jdXN0b20tY29udGFpbmVyLWlkJztcbiAgICAgICAgICpcbiAgICAgICAgICogY29uc3QgbXlMYXlvdXRDb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChjb250YWluZXJJZCk7XG4gICAgICAgICAqXG4gICAgICAgICAqIG15TGF5b3V0Q29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RhYi1jcmVhdGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICogICAgIGNvbnN0IHsgdGFiU2VsZWN0b3IgfSA9IGV2ZW50LmRldGFpbDtcbiAgICAgICAgICogICAgIGNvbnN0IHRhYkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YWJTZWxlY3Rvcik7XG4gICAgICAgICAqICAgICBjb25zdCBleGlzdGluZ0NvbG9yID0gdGFiRWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgICAqICAgICB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgICAgICAqICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICogICAgICAgICB0YWJFbGVtZW50LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGV4aXN0aW5nQ29sb3I7XG4gICAgICAgICAqICAgICB9LCAyMDAwKTtcbiAgICAgICAgICogfSk7XG4gICAgICAgICAqXG4gICAgICAgICAqIC8vIGluaXRpYWxpemUgdGhlIGxheW91dCBpbnRvIGFuIGV4aXN0aW5nIEhUTUwgZWxlbWVudCB3aXRoIHRoZSBkaXYgYG15LWN1c3RvbS1jb250YWluZXItaWRgXG4gICAgICAgICAqIC8vIHRoZSB3aW5kb3cgbXVzdCBoYXZlIGJlZW4gY3JlYXRlZCB3aXRoIGEgbGF5b3V0IGluIGl0cyB3aW5kb3cgb3B0aW9uc1xuICAgICAgICAgKiBjb25zdCBsYXlvdXQgPSBhd2FpdCBmaW4uUGxhdGZvcm0uTGF5b3V0LmluaXQoeyBjb250YWluZXJJZCB9KTtcbiAgICAgICAgICogYGBgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmluaXQgPSBhc3luYyAob3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LWluaXQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMud2lyZS5lbnZpcm9ubWVudC5sYXlvdXRBbGxvd2VkSW5Db250ZXh0KHRoaXMuZmluKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTGF5b3V0LmluaXQgY2FuIG9ubHkgYmUgY2FsbGVkIGZyb20gYSBXaW5kb3cgY29udGV4dC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRJbml0aWFsaXphdGlvbkF0dGVtcHRlZCwgXCJmXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMYXlvdXQuaW5pdCB3YXMgYWxyZWFkeSBjYWxsZWQsIHBsZWFzZSB1c2UgTGF5b3V0LmNyZWF0ZSB0byBhZGQgYWRkaXRpb25hbCBsYXlvdXRzLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMud2lyZS5lbnZpcm9ubWVudC50eXBlID09PSAnb3BlbmZpbicpIHtcbiAgICAgICAgICAgICAgICAvLyBwcmVsb2FkIHRoZSBjbGllbnRcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpLmdldENsaWVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQsIHRydWUsIFwiZlwiKTtcbiAgICAgICAgICAgIC8vIFRPRE86IHJlbmFtZSB0byBjcmVhdGVMYXlvdXRNYW5hZ2VyXG4gICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLCBhd2FpdCB0aGlzLndpcmUuZW52aXJvbm1lbnQuaW5pdExheW91dE1hbmFnZXIodGhpcy5maW4sIHRoaXMud2lyZSwgb3B0aW9ucyksIFwiZlwiKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMud2lyZS5lbnZpcm9ubWVudC5hcHBseUxheW91dFNuYXBzaG90KHRoaXMuZmluLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9sYXlvdXRNYW5hZ2VyLCBcImZcIiksIG9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgbWVJZGVudGl0eSA9IHsgbmFtZTogdGhpcy5maW4ubWUubmFtZSwgdXVpZDogdGhpcy5maW4ubWUudXVpZCB9O1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zLmxheW91dE1hbmFnZXJPdmVycmlkZSkge1xuICAgICAgICAgICAgICAgIC8vIENPUkUtMTA4MSB0byBiZSByZW1vdmVkIHdoZW4gd2UgYWN0dWFsbHkgZGVsZXRlIHRoZSBgbGF5b3V0TWFuYWdlcmAgcHJvcFxuICAgICAgICAgICAgICAgIC8vIGluIHNpbmdsZS1sYXlvdXQgY2FzZSwgd2UgcmV0dXJuIHRoZSB1bmRvY3VtZW50ZWQgbGF5b3V0TWFuYWdlciB0eXBlXG4gICAgICAgICAgICAgICAgY29uc3QgbGF5b3V0SWRlbnRpdHkgPSB7IGxheW91dE5hbWU6IGxheW91dF9jb25zdGFudHNfMS5ERUZBVUxUX0xBWU9VVF9LRVksIC4uLm1lSWRlbnRpdHkgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweSwgXCJmXCIpLmNhbGwodGhpcywgbGF5b3V0SWRlbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcFN5bmMobWVJZGVudGl0eSk7XG4gICAgICAgIH07XG4gICAgICAgIF9MYXlvdXRNb2R1bGVfZ2V0TGF5b3V0TWFuYWdlclNweS5zZXQodGhpcywgKGxheW91dElkZW50aXR5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSAnW0xheW91dF0gWW91IGFyZSB1c2luZyBhIGRlcHJlY2F0ZWQgcHJvcGVydHkgYGxheW91dE1hbmFnZXJgIC0gaXQgd2lsbCB0aHJvdyBpZiB5b3UgYWNjZXNzIGl0IHN0YXJ0aW5nIGluIHYzNy4nO1xuICAgICAgICAgICAgY29uc3QgbWFuYWdlclByb3h5ID0gbmV3IFByb3h5KHt9LCB7XG4gICAgICAgICAgICAgICAgZ2V0KHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgW0xheW91dC1tZ3ItcHJveHldIGFjY2Vzc2luZyAke2tleS50b1N0cmluZygpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGxheW91dCA9IE9iamVjdC5hc3NpZ24odGhpcy53cmFwU3luYyhsYXlvdXRJZGVudGl0eSksIHsgbGF5b3V0TWFuYWdlcjogbWFuYWdlclByb3h5IH0pO1xuICAgICAgICAgICAgY29uc3QgbGF5b3V0UHJveHkgPSBuZXcgUHJveHkobGF5b3V0LCB7XG4gICAgICAgICAgICAgICAgZ2V0KHRhcmdldCwga2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkgPT09ICdsYXlvdXRNYW5hZ2VyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbTGF5b3V0LXByb3h5XSBhY2Nlc3NpbmcgJHtrZXkudG9TdHJpbmcoKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBsYXlvdXRQcm94eTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBsYXlvdXQgbWFuYWdlciBmb3IgdGhlIGN1cnJlbnQgd2luZG93XG4gICAgICAgICAqIEByZXR1cm5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmdldEN1cnJlbnRMYXlvdXRNYW5hZ2VyU3luYyA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDModGhpcywgX0xheW91dE1vZHVsZV9pbnN0YW5jZXMsIFwibVwiLCBfTGF5b3V0TW9kdWxlX2dldFNhZmVMYXlvdXRNYW5hZ2VyKS5jYWxsKHRoaXMsIGBmaW4uUGxhdGZvcm0uTGF5b3V0LmdldEN1cnJlbnRMYXlvdXRNYW5hZ2VyU3luYygpYCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuY3JlYXRlID0gYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndpcmUuZW52aXJvbm1lbnQuY3JlYXRlTGF5b3V0KF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMyh0aGlzLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcywgXCJtXCIsIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIpLmNhbGwodGhpcywgYGZpbi5QbGF0Zm9ybS5MYXlvdXQuY3JlYXRlKClgKSwgb3B0aW9ucyk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZGVzdHJveSA9IGFzeW5jIChsYXlvdXRJZGVudGl0eSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5lbnZpcm9ubWVudC5kZXN0cm95TGF5b3V0KF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMyh0aGlzLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcywgXCJtXCIsIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIpLmNhbGwodGhpcywgYGZpbi5QbGF0Zm9ybS5MYXlvdXQuZGVzdHJveSgpYCksIGxheW91dElkZW50aXR5KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgKiBpZiAoIWZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgbGF5b3V0ID0gYXdhaXQgZmluLlBsYXRmb3JtLkxheW91dC53cmFwKHdpbmRvd0lkZW50aXR5KTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBsYXlvdXRDb25maWcgPSBhd2FpdCBsYXlvdXQuZ2V0Q29uZmlnKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignbGF5b3V0LXdyYXAnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IEluc3RhbmNlXzEkMi5MYXlvdXQoaWRlbnRpdHksIHRoaXMud2lyZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCB3aW5kb3dJZGVudGl0eTtcbiAgICAgKiBpZiAoIWZpbi5tZS5pc1dpbmRvdykge1xuICAgICAqICAgICB3aW5kb3dJZGVudGl0eSA9IGZpbi5tZS5pZGVudGl0eTtcbiAgICAgKiB9IGVsc2UgaWYgKGZpbi5tZS5pc1ZpZXcpIHtcbiAgICAgKiAgICAgd2luZG93SWRlbnRpdHkgPSAoYXdhaXQgZmluLm1lLmdldEN1cnJlbnRXaW5kb3coKSkuaWRlbnRpdHk7XG4gICAgICogfSBlbHNlIHtcbiAgICAgKiAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgcnVubmluZyBpbiBhIHBsYXRmb3JtIFZpZXcgb3IgV2luZG93Jyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogY29uc3QgbGF5b3V0ID0gZmluLlBsYXRmb3JtLkxheW91dC53cmFwU3luYyh3aW5kb3dJZGVudGl0eSk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHdyYXBTeW5jKGlkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtd3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDIuTGF5b3V0KGlkZW50aXR5LCB0aGlzLndpcmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgTGF5b3V0IG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYSBXaW5kb3cncyBsYXlvdXQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgbGF5b3V0ID0gYXdhaXQgZmluLlBsYXRmb3JtLkxheW91dC5nZXRDdXJyZW50KCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3QgbGF5b3V0Q29uZmlnID0gYXdhaXQgbGF5b3V0LmdldENvbmZpZygpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtZ2V0LWN1cnJlbnQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXRoaXMuZmluLm1lLmlzV2luZG93KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IGluIGEgV2luZG93IGNvbnRleHQuICBPbmx5IFdpbmRvd3MgY2FuIGhhdmUgYSBMYXlvdXQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSB0aGlzLmZpbi5tZTtcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcCh7IHV1aWQsIG5hbWUgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmNocm9ub3VzbHkgcmV0dXJucyBhIExheW91dCBvYmplY3QgdGhhdCByZXByZXNlbnRzIGEgV2luZG93J3MgbGF5b3V0LlxuICAgICAqXG4gICAgICogQHJlbWFya3MgQ2Fubm90IGJlIGNhbGxlZCBmcm9tIGEgdmlldy5cbiAgICAgKlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IGxheW91dCA9IGZpbi5QbGF0Zm9ybS5MYXlvdXQuZ2V0Q3VycmVudFN5bmMoKTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBsYXlvdXRDb25maWcgPSBhd2FpdCBsYXlvdXQuZ2V0Q29uZmlnKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0Q3VycmVudFN5bmMoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdsYXlvdXQtZ2V0LWN1cnJlbnQtc3luYycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghdGhpcy5maW4ubWUuaXNXaW5kb3cpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgaW4gYSBXaW5kb3cgY29udGV4dC4gIE9ubHkgV2luZG93cyBjYW4gaGF2ZSBhIExheW91dC4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IHRoaXMuZmluLm1lO1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQsIG5hbWUgfSk7XG4gICAgfVxufVxuRmFjdG9yeSQyLkxheW91dE1vZHVsZSA9IExheW91dE1vZHVsZTtcbl9MYXlvdXRNb2R1bGVfbGF5b3V0SW5pdGlhbGl6YXRpb25BdHRlbXB0ZWQgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2xheW91dE1hbmFnZXIgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2dldExheW91dE1hbmFnZXJTcHkgPSBuZXcgV2Vha01hcCgpLCBfTGF5b3V0TW9kdWxlX2luc3RhbmNlcyA9IG5ldyBXZWFrU2V0KCksIF9MYXlvdXRNb2R1bGVfZ2V0U2FmZUxheW91dE1hbmFnZXIgPSBmdW5jdGlvbiBfTGF5b3V0TW9kdWxlX2dldFNhZmVMYXlvdXRNYW5hZ2VyKG1ldGhvZCkge1xuICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0TWFuYWdlciwgXCJmXCIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgWW91IG11c3QgY2FsbCBpbml0IGJlZm9yZSB1c2luZyB0aGUgQVBJICR7bWV0aG9kfWApO1xuICAgIH1cbiAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQzKHRoaXMsIF9MYXlvdXRNb2R1bGVfbGF5b3V0TWFuYWdlciwgXCJmXCIpO1xufTtcblxuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdC8qKlxuXHQgKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYExheW91dGAgc3Vic2V0IG9mIHRoZSBgUGxhdGZvcm1gIEFQSSAoYGZpbi5QbGF0Zm9ybS5MYXlvdXRgKS5cblx0ICpcblx0ICogKiB7QGxpbmsgTGF5b3V0TW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYExheW91dGAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5QbGF0Zm9ybS5MYXlvdXRgLlxuXHQgKiAqIHtAbGluayBMYXlvdXR9IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIExheW91dCwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlBsYXRmb3JtLkxheW91dC5nZXRDdXJyZW50YC5cblx0ICpcblx0ICogVGhlc2UgYXJlIHNlcGFyYXRlIGNvZGUgZW50aXRpZXMsIGFuZCBhcmUgZG9jdW1lbnRlZCBzZXBhcmF0ZWx5LiBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKlxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnkkMiwgZXhwb3J0cyk7XG5cdF9fZXhwb3J0U3RhcihJbnN0YW5jZSQxLCBleHBvcnRzKTsgXG59IChsYXlvdXQpKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEZhY3RvcnkkMywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5GYWN0b3J5JDMuUGxhdGZvcm1Nb2R1bGUgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEkMyA9IGJhc2U7XG5jb25zdCBJbnN0YW5jZV8xJDEgPSBJbnN0YW5jZSQyO1xuY29uc3QgaW5kZXhfMSQxID0gbGF5b3V0O1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIFBsYXRmb3JtfSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uUGxhdGZvcm1gLlxuICovXG5jbGFzcyBQbGF0Zm9ybU1vZHVsZSBleHRlbmRzIGJhc2VfMSQzLkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIGNoYW5uZWwpIHtcbiAgICAgICAgc3VwZXIod2lyZSk7XG4gICAgICAgIHRoaXMuX2NoYW5uZWwgPSBjaGFubmVsO1xuICAgICAgICAvKipcbiAgICAgICAgICpcbiAgICAgICAgICogQGRlc2MgTGF5b3V0cyBnaXZlIGFwcCBwcm92aWRlcnMgdGhlIGFiaWxpdHkgdG8gZW1iZWQgbXVsdGlwbGUgdmlld3MgaW4gYSBzaW5nbGUgd2luZG93LiAgVGhlIExheW91dCBuYW1lc3BhY2VcbiAgICAgICAgICogZW5hYmxlcyB0aGUgaW5pdGlhbGl6YXRpb24gYW5kIG1hbmlwdWxhdGlvbiBvZiBhIHdpbmRvdydzIExheW91dC4gIEEgTGF5b3V0IHdpbGxcbiAgICAgICAgICogPGEgaHJlZj1cInR1dG9yaWFsLUxheW91dC5ET01FdmVudHMuaHRtbFwiPmVtaXQgZXZlbnRzIGxvY2FsbHk8L2E+IG9uIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRpbmcgdGhlIGxheW91dC1jb250YWluZXIuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLkxheW91dCA9IG5ldyBpbmRleF8xJDEuTGF5b3V0TW9kdWxlKHRoaXMud2lyZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGEgUGxhdGZvcm0uIE11c3QgYmUgY2FsbGVkIGZyb20gdGhlIFByb3ZpZGVyIHdoZW4gdXNpbmcgYSBjdXN0b20gcHJvdmlkZXIuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBwbGF0Zm9ybSBvcHRpb25zIGluY2x1ZGluZyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZXh0ZW5kIG9yIHJlcGxhY2VcbiAgICAgKiBkZWZhdWx0IFByb3ZpZGVyIGJlaGF2aW9yLlxuICAgICAqXG4gICAgICogQHJlbWFya3MgTXVzdCBiZSBjYWxsZWQgZnJvbSB0aGUgUHJvdmlkZXIgd2hlbiB1c2luZyBhIGN1c3RvbSBwcm92aWRlci5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIC8vIEZyb20gUHJvdmlkZXIgY29udGV4dFxuICAgICAqIGF3YWl0IGZpbi5QbGF0Zm9ybS5pbml0KCk7XG4gICAgICogLy8gUGxhdGZvcm0gQVBJIGlzIG5vdyBob29rZWQgdXAgYW5kIHdpbmRvd3MgY29udGFpbmVkIGluIHRoZSBtYW5pZmVzdCBzbmFwc2hvdCBhcmUgb3Blbi5cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIGBQbGF0Zm9ybS5pbml0YCBhY2NlcHRzIGFuIG9wdGlvbnMgb2JqZWN0IHRoYXQgY2FuIGNvbnRhaW4gYSBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCBjYW4gYmUgdXNlZCB0byBleHRlbmQgb3JcbiAgICAgKiByZXBsYWNlIGRlZmF1bHQgUHJvdmlkZXIgYmVoYXZpb3IuIEFzIGFuIGFyZ3VtZW50LCB0aGlzIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0aGUgYFByb3ZpZGVyYCBjbGFzcywgd2hpY2ggaXNcbiAgICAgKiB1c2VkIHRvIGhhbmRsZSBQbGF0Zm9ybSBhY3Rpb25zLiBUaGUgZnVuY3Rpb24gbXVzdCByZXR1cm4gYW4gb2JqZWN0IHdpdGggbWV0aG9kcyB0byBoYW5kbGUgUGxhdGZvcm0gQVBJIGFjdGlvbnMuXG4gICAgICogVGhlIHJlY29tbWVuZGVkIGFwcHJvYWNoIGlzIHRvIGV4dGVuZCB0aGUgYFByb3ZpZGVyYCBjbGFzcywgb3ZlcnJpZGluZyB0aGUgbWV0aG9kcyB5b3Ugd2lzaCB0byBhbHRlciwgYW5kIHJldHVybiBhblxuICAgICAqIGluc3RhbmNlIG9mIHlvdXIgc3ViY2xhc3M6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IG92ZXJyaWRlQ2FsbGJhY2sgPSBhc3luYyAoUGxhdGZvcm1Qcm92aWRlcikgPT4ge1xuICAgICAqICAgICAvLyBBY3Rpb25zIGNhbiBiZSBwZXJmb3JtZWQgYmVmb3JlIGluaXRpYWxpemF0aW9uLlxuICAgICAqICAgICAvLyBlLmcuIHdlIG1pZ2h0IGF1dGhlbnRpY2F0ZSBhIHVzZXIsIHNldCB1cCBhIENoYW5uZWwsIGV0YyBiZWZvcmUgaW5pdGlhbGl6aW5nIHRoZSBQbGF0Zm9ybS5cbiAgICAgKiAgICAgY29uc3QgeyBtYW5pZmVzdFVybCB9ID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCkuZ2V0SW5mbygpO1xuICAgICAqXG4gICAgICogICAgIC8vIEV4dGVuZCBvciByZXBsYWNlIGRlZmF1bHQgUGxhdGZvcm1Qcm92aWRlciBiZWhhdmlvciBieSBleHRlbmRpbmcgdGhlIFBsYXRmb3JtUHJvdmlkZXIgY2xhc3MuXG4gICAgICogICAgIGNsYXNzIE15T3ZlcnJpZGUgZXh0ZW5kcyBQbGF0Zm9ybVByb3ZpZGVyIHtcbiAgICAgKiAgICAgICAgIC8vIERlZmF1bHQgYmVoYXZpb3IgY2FuIGJlIGNoYW5nZWQgYnkgaW1wbGVtZW50aW5nIG1ldGhvZHMgd2l0aCB0aGUgc2FtZSBuYW1lcyBhcyB0aG9zZSB1c2VkIGJ5IHRoZSBkZWZhdWx0IFBsYXRmb3JtUHJvdmlkZXIuXG4gICAgICogICAgICAgICBhc3luYyBnZXRTbmFwc2hvdCgpIHtcbiAgICAgKiAgICAgICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgZXh0ZW5kaW5nIHRoZSBjbGFzcywgd2UgY2FuIGNhbGwgYHN1cGVyYCBtZXRob2RzIHRvIGFjY2VzcyBkZWZhdWx0IGJlaGF2aW9yLlxuICAgICAqICAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc3VwZXIuZ2V0U25hcHNob3QoKTtcbiAgICAgKiAgICAgICAgICAgICAvLyBCdXQgd2UgY2FuIG1vZGlmeSByZXR1cm4gdmFsdWVzLlxuICAgICAqICAgICAgICAgICAgIHJldHVybiB7IC4uLnNuYXBzaG90LCBhbnN3ZXI6IDQyLCBtYW5pZmVzdFVybCB9O1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICAgICAgYXN5bmMgcmVwbGFjZUxheW91dCh7IG9wdHMsIHRhcmdldCB9KSB7XG4gICAgICogICAgICAgICAgICAgLy8gVG8gZGlzYWJsZSBhbiBBUEkgbWV0aG9kLCBvdmVyd3JpdGUgd2l0aCBhIG5vb3AgZnVuY3Rpb24uXG4gICAgICogICAgICAgICAgICAgcmV0dXJuO1xuICAgICAqICAgICAgICAgfVxuICAgICAqICAgICB9XG4gICAgICogICAgIC8vIFJldHVybiBpbnN0YW5jZSB3aXRoIG1ldGhvZHMgdG8gYmUgY29uc3VtZWQgYnkgUGxhdGZvcm0uXG4gICAgICogICAgIC8vIFRoZSByZXR1cm5lZCBvYmplY3QgbXVzdCBpbXBsZW1lbnQgYWxsIG1ldGhvZHMgb2YgdGhlIFBsYXRmb3JtUHJvdmlkZXIgY2xhc3MuXG4gICAgICogICAgIC8vIEJ5IGV4dGVuZGluZyB0aGUgY2xhc3MsIHdlIGNhbiBzaW1wbHkgaW5oZXJpdCBtZXRob2RzIHdlIGRvIG5vdCB3aXNoIHRvIGFsdGVyLlxuICAgICAqICAgICByZXR1cm4gbmV3IE15T3ZlcnJpZGUoKTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogZmluLlBsYXRmb3JtLmluaXQoe292ZXJyaWRlQ2FsbGJhY2t9KTtcbiAgICAgKiBgYGBcbiAgICAgKiBAZXhwZXJpbWVudGFsXG4gICAgICovXG4gICAgYXN5bmMgaW5pdChvcHRpb25zKSB7XG4gICAgICAgIGlmICghZmluLl9faW50ZXJuYWxfLmlzUGxhdGZvcm0gfHwgZmluLm1lLm5hbWUgIT09IGZpbi5tZS51dWlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Zpbi5QbGF0Zm9ybS5pbml0IHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmcm9tIGEgY3VzdG9tIHBsYXRmb3JtIHByb3ZpZGVyIHJ1bm5pbmcgaW4gdGhlIG1haW4gd2luZG93IG9mIHRoZSBhcHBsaWNhdGlvbi4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy53aXJlLmVudmlyb25tZW50LmluaXRQbGF0Zm9ybSh0aGlzLmZpbiwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzeW5jaHJvbm91c2x5IHJldHVybnMgYSBQbGF0Zm9ybSBvYmplY3QgdGhhdCByZXByZXNlbnRzIGFuIGV4aXN0aW5nIHBsYXRmb3JtLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGNvbnN0IHsgaWRlbnRpdHkgfSA9IGZpbi5tZTtcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS53cmFwKGlkZW50aXR5KTtcbiAgICAgKiAvLyBVc2Ugd3JhcHBlZCBpbnN0YW5jZSB0byBjb250cm9sIGxheW91dCwgZS5nLjpcbiAgICAgKiBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHBsYXRmb3JtLmdldFNuYXBzaG90KCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgYXN5bmMgd3JhcChpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0td3JhcCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMSQxLlBsYXRmb3JtKHsgdXVpZDogaWRlbnRpdHkudXVpZCB9LCB0aGlzLl9jaGFubmVsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhbiBleGlzdGluZyBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCB7IGlkZW50aXR5IH0gPSBmaW4ubWU7XG4gICAgICogY29uc3QgcGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0ud3JhcFN5bmMoaWRlbnRpdHkpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlIHRvIGNvbnRyb2wgbGF5b3V0LCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcGxhdGZvcm0uZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0td3JhcC1zeW5jJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnN0YW5jZV8xJDEuUGxhdGZvcm0oeyB1dWlkOiBpZGVudGl0eS51dWlkIH0sIHRoaXMuX2NoYW5uZWwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50KCk7XG4gICAgICogLy8gVXNlIHdyYXBwZWQgaW5zdGFuY2UgdG8gY29udHJvbCBsYXlvdXQsIGUuZy46XG4gICAgICogY29uc3Qgc25hcHNob3QgPSBhd2FpdCBwbGF0Zm9ybS5nZXRTbmFwc2hvdCgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGFzeW5jIGdldEN1cnJlbnQoKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1nZXQtY3VycmVudCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXAoeyB1dWlkOiB0aGlzLndpcmUubWUudXVpZCB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgUGxhdGZvcm0gb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwbGF0Zm9ybS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlIHRvIGNvbnRyb2wgbGF5b3V0LCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcGxhdGZvcm0uZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRDdXJyZW50U3luYygpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3BsYXRmb3JtLWdldC1jdXJyZW50LXN5bmMnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy53cmFwU3luYyh7IHV1aWQ6IHRoaXMud2lyZS5tZS51dWlkIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuZCBzdGFydHMgYSBQbGF0Zm9ybSBhbmQgcmV0dXJucyBhIHdyYXBwZWQgYW5kIHJ1bm5pbmcgUGxhdGZvcm0gaW5zdGFuY2UuIFRoZSB3cmFwcGVkIFBsYXRmb3JtIG1ldGhvZHMgY2FuXG4gICAgICogYmUgdXNlZCB0byBsYXVuY2ggY29udGVudCBpbnRvIHRoZSBwbGF0Zm9ybS4gIFByb21pc2Ugd2lsbCByZWplY3QgaWYgdGhlIHBsYXRmb3JtIGlzIGFscmVhZHkgcnVubmluZy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5zdGFydCh7XG4gICAgICogICAgICAgICB1dWlkOiAncGxhdGZvcm0tMScsXG4gICAgICogICAgICAgICBhdXRvU2hvdzogZmFsc2UsXG4gICAgICogICAgICAgICBkZWZhdWx0V2luZG93T3B0aW9uczoge1xuICAgICAqICAgICAgICAgICAgIHN0eWxlc2hlZXRVcmw6ICdjc3Mtc2hlZXQtdXJsJyxcbiAgICAgKiAgICAgICAgICAgICBjb3JuZXJSb3VuZGluZzoge1xuICAgICAqICAgICAgICAgICAgICAgICBoZWlnaHQ6IDEwLFxuICAgICAqICAgICAgICAgICAgICAgICB3aWR0aDogMTBcbiAgICAgKiAgICAgICAgICAgICB9XG4gICAgICogICAgICAgICB9XG4gICAgICogICAgIH0pO1xuICAgICAqICAgICBjb25zb2xlLmxvZygnUGxhdGZvcm0gaXMgcnVubmluZycsIHBsYXRmb3JtKTtcbiAgICAgKiB9IGNhdGNoKGUpIHtcbiAgICAgKiAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgc3RhcnQocGxhdGZvcm1PcHRpb25zKSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdwbGF0Zm9ybS1zdGFydCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgdXVpZCB9ID0gcGxhdGZvcm1PcHRpb25zO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSB2YXJpYWJsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLmZpbi5BcHBsaWNhdGlvbi5fY3JlYXRlKHsgLi4ucGxhdGZvcm1PcHRpb25zLCBpc1BsYXRmb3JtQ29udHJvbGxlcjogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgYXBwLm9uY2UoJ3BsYXRmb3JtLWFwaS1yZWFkeScsICgpID0+IHJlc29sdmUodGhpcy53cmFwU3luYyh7IHV1aWQgfSkpKTtcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIHVzaW5nIHByaXZhdGUgdmFyaWFibGUuXG4gICAgICAgICAgICAgICAgYXBwLl9ydW4oeyB1dWlkIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgcGxhdGZvcm1zJ3MgbWFuaWZlc3QgYW5kIHJldHVybnMgYSB3cmFwcGVkIGFuZCBydW5uaW5nIFBsYXRmb3JtLiAgSWYgdGhlcmUgaXMgYSBzbmFwc2hvdCBpbiB0aGUgbWFuaWZlc3QsXG4gICAgICogaXQgd2lsbCBiZSBsYXVuY2hlZCBpbnRvIHRoZSBwbGF0Zm9ybS5cbiAgICAgKiBAcGFyYW0gbWFuaWZlc3RVcmwgLSBUaGUgVVJMIG9mIHBsYXRmb3JtJ3MgbWFuaWZlc3QuXG4gICAgICogQHBhcmFtIG9wdHMgLSBQYXJhbWV0ZXJzIHRoYXQgdGhlIFJWTSB3aWxsIHVzZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiB0cnkge1xuICAgICAqICAgICBjb25zdCBwbGF0Zm9ybSA9IGF3YWl0IGZpbi5QbGF0Zm9ybS5zdGFydEZyb21NYW5pZmVzdCgnaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9nb2xkZW4tcHJvdG90eXBlL3B1YmxpYy5qc29uJyk7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdQbGF0Zm9ybSBpcyBydW5uaW5nLCB3cmFwcGVkIHBsYXRmb3JtOiAnLCBwbGF0Zm9ybSk7XG4gICAgICogfSBjYXRjaChlKSB7XG4gICAgICogICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICogfVxuICAgICAqIC8vIEZvciBhIGxvY2FsIG1hbmlmZXN0IGZpbGU6XG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgcGxhdGZvcm0gPSBhd2FpdCBmaW4uUGxhdGZvcm0uc3RhcnRGcm9tTWFuaWZlc3QoJ2ZpbGU6Ly8vQzovc29tZWZvbGRlci9hcHAuanNvbicpO1xuICAgICAqICAgICBjb25zb2xlLmxvZygnUGxhdGZvcm0gaXMgcnVubmluZywgd3JhcHBlZCBwbGF0Zm9ybTogJywgcGxhdGZvcm0pO1xuICAgICAqIH0gY2F0Y2goZSkge1xuICAgICAqICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBzdGFydEZyb21NYW5pZmVzdChtYW5pZmVzdFVybCwgb3B0cykge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbigncGxhdGZvcm0tc3RhcnQtZnJvbS1tYW5pZmVzdCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2VcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdXNpbmcgcHJpdmF0ZSB2YXJpYWJsZS5cbiAgICAgICAgICAgICAgICBjb25zdCBhcHAgPSBhd2FpdCB0aGlzLmZpbi5BcHBsaWNhdGlvbi5fY3JlYXRlRnJvbU1hbmlmZXN0KG1hbmlmZXN0VXJsKTtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBmaXggdHlwaW5nIChpbnRlcm5hbClcbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgYXBwLm9uY2UoJ3BsYXRmb3JtLWFwaS1yZWFkeScsICgpID0+IHJlc29sdmUodGhpcy53cmFwU3luYyh7IHV1aWQ6IGFwcC5pZGVudGl0eS51dWlkIH0pKSk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB1c2luZyBwcml2YXRlIG1ldGhvZCB3aXRob3V0IHdhcm5pbmcuXG4gICAgICAgICAgICAgICAgYXBwLl9ydW4ob3B0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuRmFjdG9yeSQzLlBsYXRmb3JtTW9kdWxlID0gUGxhdGZvcm1Nb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHR2YXIgX19jcmVhdGVCaW5kaW5nID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XG5cdCAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuXHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHQgICAgfVxuXHQgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcblx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdCAgICBvW2syXSA9IG1ba107XG5cdH0pKTtcblx0dmFyIF9fZXhwb3J0U3RhciA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcblx0ICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZXhwb3J0cywgcCkpIF9fY3JlYXRlQmluZGluZyhleHBvcnRzLCBtLCBwKTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgUGxhdGZvcm1gIEFQSSAoYGZpbi5QbGF0Zm9ybWApXG5cdCAqXG5cdCAqICoge0BsaW5rIFBsYXRmb3JtTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYFBsYXRmb3JtYCBBUEksIGFjY2Vzc2libGUgdGhyb3VnaCBgZmluLlBsYXRmb3JtYC5cblx0ICogKiB7QGxpbmsgUGxhdGZvcm19IGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBPcGVuRmluIFBsYXRmb3JtLCBlLmcuIGFzIHJldHVybmVkIGJ5IGBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudGAuXG5cdCAqXG5cdCAqIFRoZXNlIGFyZSBzZXBhcmF0ZSBjb2RlIGVudGl0aWVzLCBhbmQgYXJlIGRvY3VtZW50ZWQgc2VwYXJhdGVseS4gIEluIHRoZSBbcHJldmlvdXMgdmVyc2lvbiBvZiB0aGUgQVBJIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2RuLm9wZW5maW4uY28vZG9jcy9qYXZhc2NyaXB0LzMyLjExNC43Ni4xMC9pbmRleC5odG1sKSxcblx0ICogYm90aCBvZiB0aGVzZSB3ZXJlIGRvY3VtZW50ZWQgb24gdGhlIHNhbWUgcGFnZS5cblx0ICpcblx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdCAqL1xuXHRfX2V4cG9ydFN0YXIoRmFjdG9yeSQzLCBleHBvcnRzKTtcblx0X19leHBvcnRTdGFyKEluc3RhbmNlJDIsIGV4cG9ydHMpOyBcbn0gKHBsYXRmb3JtKSk7XG5cbnZhciBtZSA9IHt9O1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLmdldE1lID0gZXhwb3J0cy5nZXRCYXNlTWUgPSBleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlID0gdm9pZCAwO1xuXHRjb25zdCB2aWV3XzEgPSByZXF1aXJlVmlldygpO1xuXHRjb25zdCBmcmFtZV8xID0gZnJhbWU7XG5cdGNvbnN0IHdpbmRvd18xID0gcmVxdWlyZVdpbmRvdygpO1xuXHRjb25zdCBleHRlcm5hbF9hcHBsaWNhdGlvbl8xID0gZXh0ZXJuYWxBcHBsaWNhdGlvbjtcblx0ZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSA9ICdZb3UgYXJlIG5vdCBydW5uaW5nIGluIE9wZW5GaW4uJztcblx0ZnVuY3Rpb24gZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpIHtcblx0ICAgIGNvbnN0IGVudGl0eVR5cGVIZWxwZXJzID0ge1xuXHQgICAgICAgIGlzVmlldzogZW50aXR5VHlwZSA9PT0gJ3ZpZXcnLFxuXHQgICAgICAgIGlzV2luZG93OiBlbnRpdHlUeXBlID09PSAnd2luZG93Jyxcblx0ICAgICAgICBpc0ZyYW1lOiBlbnRpdHlUeXBlID09PSAnaWZyYW1lJyxcblx0ICAgICAgICBpc0V4dGVybmFsOiBlbnRpdHlUeXBlID09PSAnZXh0ZXJuYWwgY29ubmVjdGlvbidcblx0ICAgIH07XG5cdCAgICByZXR1cm4geyAuLi5lbnRpdHlUeXBlSGVscGVycywgdXVpZCwgbmFtZSwgZW50aXR5VHlwZSB9O1xuXHR9XG5cdGV4cG9ydHMuZ2V0QmFzZU1lID0gZ2V0QmFzZU1lO1xuXHQvLyBXZSBuZWVkIHRvIGRvIGEgbG90IG9mIGNhc3RpbmcgYXMgdW5rbm93biBoZXJlIGJlY2F1c2UgdGhlIGNvbXBpbGVyIGdldCdzIGNvbmZ1c2VkIGFib3V0IG1hdGNoaW5nIHR5cGVzLiBXaGF0IG1hdHRlcnMgaXMgdGhhdCBpdCB3b3JrcyBvbiB0aGUgb3V0c2lkZVxuXHRmdW5jdGlvbiBnZXRNZSh3aXJlKSB7XG5cdCAgICBjb25zdCB7IHV1aWQsIG5hbWUsIGVudGl0eVR5cGUgfSA9IHdpcmUubWU7XG5cdCAgICBjb25zdCB1bnN1cHBvcnRlZEludGVyb3AgPSB7XG5cdCAgICAgICAgc2V0Q29udGV4dCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgYWRkQ29udGV4dEhhbmRsZXIoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldENvbnRleHRHcm91cHMoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGpvaW5Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHJlbW92ZUZyb21Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdCAgICBjb25zdCBmYWxsYmFja0Vycm9yTWVzc2FnZSA9ICdJbnRlcm9wIEFQSSBoYXMgbm90IGJlZW4gaW5zdGFudGlhdGVkLiBFaXRoZXIgY29ubmVjdGlvbiBoYXMgZmFpbGVkIG9yIHlvdSBoYXZlIG5vdCBkZWNsYXJlZCBpbnRlcm9wIGluIHlvdXIgY29uZmlnLic7XG5cdCAgICBjb25zdCBmYWxsYmFja0ludGVyb3AgPSB7XG5cdCAgICAgICAgc2V0Q29udGV4dCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGFkZENvbnRleHRIYW5kbGVyKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0Q29udGV4dEdyb3VwcygpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGpvaW5Db250ZXh0R3JvdXAoKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihmYWxsYmFja0Vycm9yTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICByZW1vdmVGcm9tQ29udGV4dEdyb3VwKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZmFsbGJhY2tFcnJvck1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGZhbGxiYWNrRXJyb3JNZXNzYWdlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgY29uc3QgdW5zdXBwb3J0ZWRFdmVudEJhc2UgPSB7XG5cdCAgICAgICAgZXZlbnROYW1lczogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBlbWl0OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGxpc3RlbmVyczogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwb3J0cy5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBsaXN0ZW5lckNvdW50OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGFkZExpc3RlbmVyOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uY2U6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcHJlcGVuZExpc3RlbmVyOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHByZXBlbmRPbmNlTGlzdGVuZXI6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcmVtb3ZlTGlzdGVuZXI6ICgpID0+IHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cG9ydHMuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgcmVtb3ZlQWxsTGlzdGVuZXJzOiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihleHBvcnRzLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHQgICAgc3dpdGNoIChlbnRpdHlUeXBlKSB7XG5cdCAgICAgICAgY2FzZSAndmlldyc6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB2aWV3XzEuVmlldyh3aXJlLCB7IHV1aWQsIG5hbWUgfSksIGdldEJhc2VNZShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKSwge1xuXHQgICAgICAgICAgICAgICAgaW50ZXJvcDogZmFsbGJhY2tJbnRlcm9wLFxuXHQgICAgICAgICAgICAgICAgaXNPcGVuRmluOiB0cnVlXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIGNhc2UgJ3dpbmRvdyc6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyB3aW5kb3dfMS5fV2luZG93KHdpcmUsIHsgdXVpZCwgbmFtZSB9KSwgZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpLCB7XG5cdCAgICAgICAgICAgICAgICBpbnRlcm9wOiBmYWxsYmFja0ludGVyb3AsXG5cdCAgICAgICAgICAgICAgICBpc09wZW5GaW46IHRydWVcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgY2FzZSAnaWZyYW1lJzpcblx0ICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IGZyYW1lXzEuX0ZyYW1lKHdpcmUsIHsgdXVpZCwgbmFtZSB9KSwgZ2V0QmFzZU1lKGVudGl0eVR5cGUsIHV1aWQsIG5hbWUpLCB7XG5cdCAgICAgICAgICAgICAgICBpbnRlcm9wOiBmYWxsYmFja0ludGVyb3AsXG5cdCAgICAgICAgICAgICAgICBpc09wZW5GaW46IHRydWVcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgY2FzZSAnZXh0ZXJuYWwgY29ubmVjdGlvbic6XG5cdCAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBleHRlcm5hbF9hcHBsaWNhdGlvbl8xLkV4dGVybmFsQXBwbGljYXRpb24od2lyZSwgeyB1dWlkIH0pLCBnZXRCYXNlTWUoZW50aXR5VHlwZSwgdXVpZCwgbmFtZSksIHtcblx0ICAgICAgICAgICAgICAgIGludGVyb3A6IGZhbGxiYWNrSW50ZXJvcCxcblx0ICAgICAgICAgICAgICAgIGlzT3BlbkZpbjogZmFsc2Vcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgZGVmYXVsdDpcblx0ICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgICAgIC4uLmdldEJhc2VNZShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKSxcblx0ICAgICAgICAgICAgICAgIC4uLnVuc3VwcG9ydGVkRXZlbnRCYXNlLFxuXHQgICAgICAgICAgICAgICAgaW50ZXJvcDogdW5zdXBwb3J0ZWRJbnRlcm9wLFxuXHQgICAgICAgICAgICAgICAgaXNPcGVuRmluOiBmYWxzZVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgfVxuXHR9XG5cdGV4cG9ydHMuZ2V0TWUgPSBnZXRNZTsgXG59IChtZSkpO1xuXG52YXIgaW50ZXJvcCA9IHt9O1xuXG52YXIgRmFjdG9yeSQxID0ge307XG5cbnZhciBpbmFjY2Vzc2libGVPYmplY3QgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGluYWNjZXNzaWJsZU9iamVjdCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlV2FybmluZ09iamVjdCA9IGluYWNjZXNzaWJsZU9iamVjdC5jcmVhdGVVbnVzYWJsZU9iamVjdCA9IHZvaWQgMDtcbmZ1bmN0aW9uIGNyZWF0ZVVudXNhYmxlT2JqZWN0KG1lc3NhZ2UpIHtcbiAgICBjb25zdCBoYW5kbGUgPSAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJveHkoe30sIHtcbiAgICAgICAgYXBwbHk6IGhhbmRsZSxcbiAgICAgICAgY29uc3RydWN0OiBoYW5kbGUsXG4gICAgICAgIGRlZmluZVByb3BlcnR5OiBoYW5kbGUsXG4gICAgICAgIGRlbGV0ZVByb3BlcnR5OiBoYW5kbGUsXG4gICAgICAgIGdldDogaGFuZGxlLFxuICAgICAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6IGhhbmRsZSxcbiAgICAgICAgZ2V0UHJvdG90eXBlT2Y6IGhhbmRsZSxcbiAgICAgICAgaGFzOiBoYW5kbGUsXG4gICAgICAgIGlzRXh0ZW5zaWJsZTogaGFuZGxlLFxuICAgICAgICBvd25LZXlzOiBoYW5kbGUsXG4gICAgICAgIHByZXZlbnRFeHRlbnNpb25zOiBoYW5kbGUsXG4gICAgICAgIHNldDogaGFuZGxlLFxuICAgICAgICBzZXRQcm90b3R5cGVPZjogaGFuZGxlXG4gICAgfSk7XG59XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlVW51c2FibGVPYmplY3QgPSBjcmVhdGVVbnVzYWJsZU9iamVjdDtcbmZ1bmN0aW9uIGNyZWF0ZVdhcm5pbmdPYmplY3QobWVzc2FnZSwgb2JqKSB7XG4gICAgcmV0dXJuIG5ldyBQcm94eShvYmosIHtcbiAgICAgICAgZ2V0OiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LnNldCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBSZWZsZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb3duS2V5czogKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgICBjb25zb2xlLndhcm4obWVzc2FnZSk7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5pbmFjY2Vzc2libGVPYmplY3QuY3JlYXRlV2FybmluZ09iamVjdCA9IGNyZWF0ZVdhcm5pbmdPYmplY3Q7XG5cbnZhciBJbnRlcm9wQnJva2VyID0ge307XG5cbnZhciBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyID0ge307XG5cbnZhciBoYXNSZXF1aXJlZFNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXI7XG5cbmZ1bmN0aW9uIHJlcXVpcmVTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcikgcmV0dXJuIFNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXI7XG5cdGhhc1JlcXVpcmVkU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0Y29uc3QgXzEgPSByZXF1aXJlSW50ZXJvcCgpO1xuXHRsZXQgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciQxID0gY2xhc3MgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlciB7XG5cdCAgICBjb25zdHJ1Y3Rvcihwcm92aWRlciwgaWQpIHtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyID0gcHJvdmlkZXI7XG5cdCAgICAgICAgdGhpcy5pZCA9IGlkO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHQgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0R3JvdXBNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5jbGllbnRzID0gbmV3IE1hcCgpO1xuXHQgICAgICAgIHRoaXMucmVnaXN0ZXJMaXN0ZW5lcnMoKTtcblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoYHNlc3Npb25Db250ZXh0R3JvdXA6Z2V0Q29udGV4dC0ke3RoaXMuaWR9YCwgdGhpcy5nZXRDdXJyZW50Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKGBzZXNzaW9uQ29udGV4dEdyb3VwOnNldENvbnRleHQtJHt0aGlzLmlkfWAsIHRoaXMuc2V0Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKGBzZXNzaW9uQ29udGV4dEdyb3VwOmhhbmRsZXJBZGRlZC0ke3RoaXMuaWR9YCwgdGhpcy5oYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcihgc2Vzc2lvbkNvbnRleHRHcm91cDpoYW5kbGVyUmVtb3ZlZC0ke3RoaXMuaWR9YCwgdGhpcy5oYW5kbGVyUmVtb3ZlZC5iaW5kKHRoaXMpKTtcblx0ICAgIH1cblx0ICAgIGdldEN1cnJlbnRDb250ZXh0KHBheWxvYWQpIHtcblx0ICAgICAgICByZXR1cm4gcGF5bG9hZC50eXBlID8gdGhpcy5jb250ZXh0R3JvdXBNYXAuZ2V0KHBheWxvYWQudHlwZSkgOiB0aGlzLmxhc3RDb250ZXh0O1xuXHQgICAgfVxuXHQgICAgc2V0Q29udGV4dChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgY29udGV4dCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQgPSBfMS5JbnRlcm9wQnJva2VyLmNoZWNrQ29udGV4dEludGVncml0eShjb250ZXh0KTtcblx0ICAgICAgICBpZiAoY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0LmlzVmFsaWQgPT09IGZhbHNlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHNldCBDb250ZXh0IC0gYmFkIENvbnRleHQuIFJlYXNvbjogJHtjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQucmVhc29ufS4gQ29udGV4dDogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkbid0IGdldCBoaXQuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0gJHtjbGllbnRJZGVudGl0eS5uYW1lfSBub3QgaW4gU2Vzc2lvbiBDbGllbnQgU3RhdGUgTWFwYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIC8vIHNldCB0aGUgY29udGV4dFxuXHQgICAgICAgIHRoaXMuY29udGV4dEdyb3VwTWFwLnNldChjb250ZXh0LnR5cGUsIGNvbnRleHQpO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHQgPSBjb250ZXh0O1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlcyA9IEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKTtcblx0ICAgICAgICBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZXMuZm9yRWFjaCgoY2xpZW50KSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0ICAgICAgICAgICAgY2xpZW50LmNvbnRleHRIYW5kbGVycy5nZXQoY29udGV4dC50eXBlKT8uZm9yRWFjaCgoaGFuZGxlcklkKSA9PiB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudC5jbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGlmIChjbGllbnQuZ2xvYmFsSGFuZGxlcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnQuY2xpZW50SWRlbnRpdHksIGNsaWVudC5nbG9iYWxIYW5kbGVyLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChpZC5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIGFzeW5jIGhhbmRsZXJBZGRlZChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGlmICghY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBJZGVudGl0eTogJHtjbGllbnRJZGVudGl0eS51dWlkfSAke2NsaWVudElkZW50aXR5Lm5hbWV9IG5vdCBpbiBDbGllbnQgU3RhdGUgTWFwYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50SGFuZGxlckxpc3QgPSBjbGllbnRTdWJzY3JpcHRpb25TdGF0ZS5jb250ZXh0SGFuZGxlcnMuZ2V0KGNvbnRleHRUeXBlKSB8fCBbXTtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEhhbmRsZXJzLnNldChjb250ZXh0VHlwZSwgWy4uLmN1cnJlbnRIYW5kbGVyTGlzdCwgaGFuZGxlcklkXSk7XG5cdCAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gdGhpcy5jb250ZXh0R3JvdXBNYXAuZ2V0KGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250ZXh0KSB7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGN1cnJlbnRDb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuZ2xvYmFsSGFuZGxlciA9IGhhbmRsZXJJZDtcblx0ICAgICAgICAgICAgY29uc3QgZ2xvYmFsRGlzcGF0Y2hQcm9taXNlcyA9IFsuLi50aGlzLmNvbnRleHRHcm91cE1hcC5rZXlzKCldLm1hcChhc3luYyAoY3VycmVudENvbnRleHRUeXBlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dCA9IHRoaXMuY29udGV4dEdyb3VwTWFwLmdldChjdXJyZW50Q29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRDb250ZXh0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjdXJyZW50Q29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChnbG9iYWxEaXNwYXRjaFByb21pc2VzKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBoYW5kbGVyUmVtb3ZlZChwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCk7XG5cdCAgICAgICAgaWYgKGNsaWVudCkge1xuXHQgICAgICAgICAgICBBcnJheS5mcm9tKGNsaWVudC5jb250ZXh0SGFuZGxlcnMpLmZvckVhY2goKFssIGhhbmRsZXJzXSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBoYW5kbGVycy5pbmRleE9mKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICBpZiAoY2xpZW50Lmdsb2JhbEhhbmRsZXIgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50Lmdsb2JhbEhhbmRsZXIgPSB1bmRlZmluZWQ7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybihgVHJ5aW5nIHRvIHJlbW92ZSBhIGhhbmRsZXIgZnJvbSBhIGNsaWVudCB0aGF0IGlzbid0IG1hcHBlZC4gaGFuZGxlcklkOiAke2hhbmRsZXJJZH0uIGNsaWVudElkZW50aXR5OiAke2NsaWVudElkZW50aXR5fWApO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTmV3Q2xpZW50KGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlID0ge1xuXHQgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzOiBuZXcgTWFwKCksXG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eSxcblx0ICAgICAgICAgICAgICAgIGdsb2JhbEhhbmRsZXI6IHVuZGVmaW5lZFxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB0aGlzLmNsaWVudHMuc2V0KGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQsIGNsaWVudFN1YnNjcmlwdGlvblN0YXRlKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBvbkRpc2Nvbm5lY3Rpb24oY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpO1xuXHQgICAgfVxuXHR9O1xuXHRTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyLmRlZmF1bHQgPSBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyJDE7XG5cdHJldHVybiBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyO1xufVxuXG52YXIgdXRpbHMkMyA9IHt9O1xuXG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLndyYXBJbnRlbnRIYW5kbGVyID0gZXhwb3J0cy5CUk9LRVJfRVJST1JTID0gZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZyA9IGV4cG9ydHMuZ2VuZXJhdGVPdmVycmlkZUVycm9yID0gZXhwb3J0cy53cmFwQ29udGV4dEhhbmRsZXIgPSBleHBvcnRzLndyYXBJblRyeUNhdGNoID0gZXhwb3J0cy5nZW5lcmF0ZUlkID0gdm9pZCAwO1xuXHRjb25zdCBnZW5lcmF0ZUlkID0gKCkgPT4gYCR7TWF0aC5yYW5kb20oKX0ke0RhdGUubm93KCl9YDtcblx0ZXhwb3J0cy5nZW5lcmF0ZUlkID0gZ2VuZXJhdGVJZDtcblx0Y29uc3Qgd3JhcEluVHJ5Q2F0Y2ggPSAoZiwgcHJlZml4KSA9PiAoLi4uYXJncykgPT4ge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICByZXR1cm4gZiguLi5hcmdzKTtcblx0ICAgIH1cblx0ICAgIGNhdGNoIChlKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKChwcmVmaXggfHwgJycpICsgZSk7XG5cdCAgICB9XG5cdH07XG5cdGV4cG9ydHMud3JhcEluVHJ5Q2F0Y2ggPSB3cmFwSW5UcnlDYXRjaDtcblx0Y29uc3Qgd3JhcENvbnRleHRIYW5kbGVyID0gKGhhbmRsZXIsIGhhbmRsZXJJZCkgPT4ge1xuXHQgICAgcmV0dXJuIGFzeW5jIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgaGFuZGxlcihjb250ZXh0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHRocm93biBieSBoYW5kbGVyICR7aGFuZGxlcklkfSBmb3IgY29udGV4dCB0eXBlICR7Y29udGV4dC50eXBlfTogJHtlcnJvcn1gKTtcblx0ICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy53cmFwQ29udGV4dEhhbmRsZXIgPSB3cmFwQ29udGV4dEhhbmRsZXI7XG5cdGNvbnN0IGdlbmVyYXRlT3ZlcnJpZGVFcnJvciA9IChjbGllbnRBcGksIGJyb2tlckFwaSkgPT4ge1xuXHQgICAgcmV0dXJuIGBZb3UgaGF2ZSB0cmllZCB0byB0byB1c2UgJHtjbGllbnRBcGl9IGJ1dCAke2Jyb2tlckFwaX0gaGFzIG5vdCBiZWVuIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3AgQnJva2VyLiBQbGVhc2Ugb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbi4gUmVmZXIgdG8gb3VyIGRvY3VtZW50YXRpb24gZm9yIG1vcmUgaW5mby5gO1xuXHR9O1xuXHRleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvciA9IGdlbmVyYXRlT3ZlcnJpZGVFcnJvcjtcblx0Y29uc3QgZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcgPSAoZmRjM0NsaWVudEFwaSwgYnJva2VyQXBpLCBpZGVudGl0eSwgaW50ZXJvcENsaWVudEFwaSkgPT4ge1xuXHQgICAgY29uc3QgeyB1dWlkLCBuYW1lIH0gPSBpZGVudGl0eTtcblx0ICAgIGNvbnN0IG1lc3NhZ2UgPSBpbnRlcm9wQ2xpZW50QXBpXG5cdCAgICAgICAgPyBgRW50aXR5IHdpdGggaWRlbnRpdHk6ICR7dXVpZH0vJHtuYW1lfSBoYXMgY2FsbGVkICR7aW50ZXJvcENsaWVudEFwaX0gb3IgJHtmZGMzQ2xpZW50QXBpfSBidXQgJHticm9rZXJBcGl9IGhhcyBub3QgYmVlbiBvdmVycmlkZGVuLmBcblx0ICAgICAgICA6IGBFbnRpdHkgd2l0aCBpZGVudGl0eTogJHt1dWlkfS8ke25hbWV9IGhhcyBjYWxsZWQgJHtmZGMzQ2xpZW50QXBpfSBidXQgJHticm9rZXJBcGl9IGhhcyBub3QgYmVlbiBvdmVycmlkZGVuLmA7XG5cdCAgICByZXR1cm4gbWVzc2FnZTtcblx0fTtcblx0ZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZyA9IGdlbmVyYXRlT3ZlcnJpZGVXYXJuaW5nO1xuXHRleHBvcnRzLkJST0tFUl9FUlJPUlMgPSB7XG5cdCAgICBmaXJlSW50ZW50OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdmaXJlSW50ZW50JywgJ2hhbmRsZUZpcmVkSW50ZW50JyksXG5cdCAgICBmaXJlSW50ZW50Rm9yQ29udGV4dDogKDAsIGV4cG9ydHMuZ2VuZXJhdGVPdmVycmlkZUVycm9yKSgnZmlyZUludGVudEZvckNvbnRleHQnLCAnaGFuZGxlRmlyZWRJbnRlbnRGb3JDb250ZXh0JyksXG5cdCAgICBnZXRJbmZvRm9ySW50ZW50OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdnZXRJbmZvRm9ySW50ZW50JywgJ2hhbmRsZUluZm9Gb3JJbnRlbnQnKSxcblx0ICAgIGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0OiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdnZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcsICdoYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcpLFxuXHQgICAgam9pblNlc3Npb25Db250ZXh0R3JvdXBXaXRoSm9pbkNvbnRleHRHcm91cDogJ1RoZSBDb250ZXh0IEdyb3VwIHlvdSBoYXZlIHRyaWVkIHRvIGpvaW4gaXMgYSBTZXNzaW9uIENvbnRleHQgR3JvdXAuIEN1c3RvbSBDb250ZXh0IEdyb3VwcyBjYW4gb25seSBiZSBkZWZpbmVkIGJ5IHRoZSBJbnRlcm9wIEJyb2tlciB0aHJvdWdoIGNvZGUgb3IgbWFuaWZlc3QgY29uZmlndXJhdGlvbi4gUGxlYXNlIHVzZSBqb2luU2Vzc2lvbkNvbnRleHRHcm91cC4nLFxuXHQgICAgZmRjM09wZW46ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMub3BlbicsICdmZGMzSGFuZGxlT3BlbicpLFxuXHQgICAgZmRjM0ZpbmRJbnN0YW5jZXM6ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMuZmluZEluc3RhbmNlcycsICdmZGMzSGFuZGxlRmluZEluc3RhbmNlcycpLFxuXHQgICAgZmRjM0dldEFwcE1ldGFkYXRhOiAoMCwgZXhwb3J0cy5nZW5lcmF0ZU92ZXJyaWRlRXJyb3IpKCdmZGMzLmdldEFwcE1ldGFkYXRhJywgJ2ZkYzNIYW5kbGVHZXRBcHBNZXRhZGF0YScpLFxuXHQgICAgZmRjM0dldEluZm86ICgwLCBleHBvcnRzLmdlbmVyYXRlT3ZlcnJpZGVFcnJvcikoJ2ZkYzMuZ2V0SW5mbycsICdmZGMzSGFuZGxlR2V0SW5mbycpXG5cdH07XG5cdGNvbnN0IHdyYXBJbnRlbnRIYW5kbGVyID0gKGhhbmRsZXIsIGhhbmRsZXJJZCkgPT4ge1xuXHQgICAgcmV0dXJuIGFzeW5jIChpbnRlbnQpID0+IHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gaGFuZGxlcihpbnRlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgdGhyb3duIGJ5IGhhbmRsZXIgJHtoYW5kbGVySWR9OiAke2Vycm9yfWApO1xuXHQgICAgICAgICAgICB0aHJvdyBlcnJvcjtcblx0ICAgICAgICB9XG5cdCAgICB9O1xuXHR9O1xuXHRleHBvcnRzLndyYXBJbnRlbnRIYW5kbGVyID0gd3JhcEludGVudEhhbmRsZXI7IFxufSAodXRpbHMkMykpO1xuXG52YXIgUHJpdmF0ZUNoYW5uZWxQcm92aWRlciA9IHt9O1xuXG52YXIgaGFzUmVxdWlyZWRQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xuXG5mdW5jdGlvbiByZXF1aXJlUHJpdmF0ZUNoYW5uZWxQcm92aWRlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFByaXZhdGVDaGFubmVsUHJvdmlkZXIpIHJldHVybiBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xuXHRoYXNSZXF1aXJlZFByaXZhdGVDaGFubmVsUHJvdmlkZXIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoUHJpdmF0ZUNoYW5uZWxQcm92aWRlciwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFByaXZhdGVDaGFubmVsUHJvdmlkZXIuUHJpdmF0ZUNoYW5uZWxQcm92aWRlciA9IHZvaWQgMDtcblx0Y29uc3QgSW50ZXJvcEJyb2tlcl8xID0gcmVxdWlyZUludGVyb3BCcm9rZXIoKTtcblx0bGV0IFByaXZhdGVDaGFubmVsUHJvdmlkZXIkMSA9IGNsYXNzIFByaXZhdGVDaGFubmVsUHJvdmlkZXIge1xuXHQgICAgY29uc3RydWN0b3IocHJvdmlkZXIsIGlkKSB7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyO1xuXHQgICAgICAgIHRoaXMuaWQgPSBpZDtcblx0ICAgICAgICB0aGlzLmNsaWVudHMgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5yZWdpc3Rlckxpc3RlbmVycygpO1xuXHQgICAgICAgIHRoaXMuY29udGV4dEJ5Q29udGV4dFR5cGUgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5sYXN0Q29udGV4dCA9IHVuZGVmaW5lZDtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLm9uQ29ubmVjdGlvbigoY2xpZW50SWRlbnRpdHkpID0+IHRoaXMucmVnaXN0ZXJOZXdDbGllbnQoY2xpZW50SWRlbnRpdHkpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLm9uRGlzY29ubmVjdGlvbihhc3luYyAoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBlbmRwb2ludElkIH0gPSBjbGllbnRJZGVudGl0eTtcblx0ICAgICAgICAgICAgaWYgKHRoaXMuY2xpZW50cy5oYXMoZW5kcG9pbnRJZCkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlQ2xpZW50RGlzY29ubmVjdGluZyhjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKChhd2FpdCB0aGlzLnByb3ZpZGVyLmdldEFsbENsaWVudEluZm8oKSkubGVuZ3RoID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRlc3Ryb3koKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnRzLmdldChpZC5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIHJlZ2lzdGVyTGlzdGVuZXJzKCkge1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2Jyb2FkY2FzdCcsIHRoaXMuYnJvYWRjYXN0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2dldEN1cnJlbnRDb250ZXh0JywgdGhpcy5nZXRDdXJyZW50Q29udGV4dC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKCdjb250ZXh0SGFuZGxlckFkZGVkJywgdGhpcy5jb250ZXh0SGFuZGxlckFkZGVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ2NvbnRleHRIYW5kbGVyUmVtb3ZlZCcsIHRoaXMuY29udGV4dEhhbmRsZXJSZW1vdmVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIHRoaXMucHJvdmlkZXIucmVnaXN0ZXIoJ25vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQnLCB0aGlzLm5vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25BZGRDb250ZXh0SGFuZGxlckFkZGVkJywgdGhpcy5vbkFkZENvbnRleHRIYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25EaXNjb25uZWN0SGFuZGxlckFkZGVkJywgdGhpcy5vbkRpc2Nvbm5lY3RIYW5kbGVyQWRkZWQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgdGhpcy5wcm92aWRlci5yZWdpc3Rlcignb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZCcsIHRoaXMub25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICB0aGlzLnByb3ZpZGVyLnJlZ2lzdGVyKCdjbGllbnREaXNjb25uZWN0aW5nJywgKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSA9PiB7XG5cdCAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2xpZW50RGlzY29ubmVjdGluZyhjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBicm9hZGNhc3QocGF5bG9hZCwgYnJvYWRjYXN0ZXJDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgY29udGV4dCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBjb25zdCBicm9hZGNhc3RlckNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShicm9hZGNhc3RlckNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWJyb2FkY2FzdGVyQ2xpZW50U3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDbGllbnQgd2l0aCBJZGVudGl0eTogJHticm9hZGNhc3RlckNsaWVudElkZW50aXR5LnV1aWR9ICR7YnJvYWRjYXN0ZXJDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBicm9hZGNhc3QsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0ID0gSW50ZXJvcEJyb2tlcl8xLkludGVyb3BCcm9rZXIuY2hlY2tDb250ZXh0SW50ZWdyaXR5KGNvbnRleHQpO1xuXHQgICAgICAgIGlmIChjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQuaXNWYWxpZCA9PT0gZmFsc2UpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gYnJvYWRjYXN0IC0gYmFkIENvbnRleHQuIFJlYXNvbjogJHtjb250ZXh0SW50ZWdyaXR5Q2hlY2tSZXN1bHQucmVhc29ufS4gQ29udGV4dDogJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5jb250ZXh0QnlDb250ZXh0VHlwZS5zZXQoY29udGV4dC50eXBlLCBjb250ZXh0KTtcblx0ICAgICAgICB0aGlzLmxhc3RDb250ZXh0ID0gY29udGV4dDtcblx0ICAgICAgICBBcnJheS5mcm9tKHRoaXMuY2xpZW50cy52YWx1ZXMoKSkuZm9yRWFjaCgoY3VyckNsaWVudFN0YXRlKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJJZHNGb3JDb250ZXh0VHlwZSA9IGN1cnJDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMuZ2V0KGNvbnRleHQudHlwZSk7XG5cdCAgICAgICAgICAgIGlmIChoYW5kbGVySWRzRm9yQ29udGV4dFR5cGUpIHtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJZHNGb3JDb250ZXh0VHlwZS5mb3JFYWNoKChoYW5kbGVySWQpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKGN1cnJDbGllbnRTdGF0ZS5jbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChjdXJyQ2xpZW50U3RhdGUuZ2xvYmFsSGFuZGxlcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjdXJyQ2xpZW50U3RhdGUuY2xpZW50SWRlbnRpdHksIGN1cnJDbGllbnRTdGF0ZS5nbG9iYWxIYW5kbGVyLCBjb250ZXh0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgZ2V0Q3VycmVudENvbnRleHQocGF5bG9hZCwgc2VuZGVyQ2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB7IGNvbnRleHRUeXBlIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShzZW5kZXJDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKCFjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke3NlbmRlckNsaWVudElkZW50aXR5LnV1aWR9ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkubmFtZX0sIHRyaWVkIHRvIGNhbGwgZ2V0Q3VycmVudENvbnRleHQsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGNvbnRleHRUeXBlICE9PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSB0aGlzLmNvbnRleHRCeUNvbnRleHRUeXBlLmdldChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgIGlmIChjdXJyZW50Q29udGV4dClcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50Q29udGV4dDtcblx0ICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB0aGlzLmxhc3RDb250ZXh0ID8gdGhpcy5sYXN0Q29udGV4dCA6IG51bGw7XG5cdCAgICB9XG5cdCAgICBjb250ZXh0SGFuZGxlckFkZGVkKHBheWxvYWQsIHNlbmRlckNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IHNlbmRlckNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShzZW5kZXJDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKCFzZW5kZXJDbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke3NlbmRlckNsaWVudElkZW50aXR5LnV1aWR9ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkubmFtZX0sIHRyaWVkIHRvIGNhbGwgYWRkQ29udGV4dExpc3RlbmVyLCBpcyBub3QgY29ubmVjdGVkIHRvIHRoaXMgUHJpdmF0ZSBDaGFubmVsYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50SGFuZGxlcnNMaXN0ID0gc2VuZGVyQ2xpZW50U3RhdGUuaGFuZGxlcklkc0J5Q29udGV4dFR5cGVzLmdldChjb250ZXh0VHlwZSkgfHwgW107XG5cdCAgICAgICAgICAgIHNlbmRlckNsaWVudFN0YXRlLmhhbmRsZXJJZHNCeUNvbnRleHRUeXBlcy5zZXQoY29udGV4dFR5cGUsIFsuLi5jdXJyZW50SGFuZGxlcnNMaXN0LCBoYW5kbGVySWRdKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIHNlbmRlckNsaWVudFN0YXRlLmdsb2JhbEhhbmRsZXIgPSBoYW5kbGVySWQ7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKS5mb3JFYWNoKChjdXJyQ2xpZW50U3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgaWYgKGN1cnJDbGllbnRTdGF0ZS5jbGllbnRJZGVudGl0eS5lbmRwb2ludElkICE9PSBzZW5kZXJDbGllbnRJZGVudGl0eS5lbmRwb2ludElkICYmXG5cdCAgICAgICAgICAgICAgICBjdXJyQ2xpZW50U3RhdGUub25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMucHJvdmlkZXIuZGlzcGF0Y2goY3VyckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LCBjdXJyQ2xpZW50U3RhdGUub25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQsIGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgYXN5bmMgY29udGV4dEhhbmRsZXJSZW1vdmVkKHBheWxvYWQsIHJlbW92aW5nQ2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICAvLyBNQzogTWFkZSB0aGlzIHJlbW92YWwgYXN5bmMgdG8gZW5zdXJlIHRoYXQgb25VbnN1YnNjcmliZSBoYW5kbGVycyBhcmUgaGl0IGJlZm9yZSBhbnl0aGluZyBlbHNlIGhhcHBlbnMuXG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgY29uc3QgcmVtb3ZpbmdDbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUocmVtb3ZpbmdDbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKHJlbW92aW5nQ2xpZW50U3RhdGUpIHtcblx0ICAgICAgICAgICAgbGV0IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICBpZiAocmVtb3ZpbmdDbGllbnRTdGF0ZS5nbG9iYWxIYW5kbGVyID09PSBoYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIHJlbW92aW5nQ2xpZW50U3RhdGUuZ2xvYmFsSGFuZGxlciA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2N1cnJDb250ZXh0VHlwZSwgaGFuZGxlcnNJZHNdIG9mIHJlbW92aW5nQ2xpZW50U3RhdGUuaGFuZGxlcklkc0J5Q29udGV4dFR5cGVzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBoYW5kbGVyc0lkcy5pbmRleE9mKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnNJZHMuc3BsaWNlKGluZGV4LCAxKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dFR5cGUgPSBjdXJyQ29udGV4dFR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIGdldHRpbmcgb25seSB2YWxpZCBjbGllbnQgY29ubmVjdGlvbnMgaGVyZSwgaXQgaXMgcG9zc2libGUgd2UgaGF2ZW4ndCByZW1vdmVkIGEgZGlzY29ubmVjdGVkIGNsaWVudCBmcm9tIHRoZSBtYXAgeWV0XG5cdCAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgdG8gZW5zdXJlIHdlIGRvbid0IGRpc3BhdGNoIHRvIGFueSBkaXNjb25uZWN0ZWQgY2xpZW50XG5cdCAgICAgICAgICAgIC8vIFRPRE86IFRha2UgYSBsb29rIGF0IG91ciBjbGllbnQgZGlzY29ubmVjdGlvbiBsb2dpYyBhbmQgc2VlIGlmIHdlIGNhbiBoYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3Rpb24gY2xlYW5seVxuXHQgICAgICAgICAgICBjb25zdCBjbGllbnRzVG9EaXNwYXRjaFRvID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWRDbGllbnRzKCk7XG5cdCAgICAgICAgICAgIGNvbnN0IGRpc3BhdGNoUHJvbWlzZXMgPSBjbGllbnRzVG9EaXNwYXRjaFRvLm1hcChhc3luYyAob3RoZXJDbGllbnRTdGF0ZSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgY2xpZW50SWRlbnRpdHk6IHsgZW5kcG9pbnRJZCB9LCBvblVuc3Vic2NyaWJlSGFuZGxlcklkIH0gPSBvdGhlckNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICAgICAgaWYgKGVuZHBvaW50SWQgIT09IHJlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCAmJiBvblVuc3Vic2NyaWJlSGFuZGxlcklkKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgb25VbnN1YnNjcmliZUhhbmRsZXJJZCwgY29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGRpc3BhdGNoUHJvbWlzZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgUHJvYmxlbSB3aGVuIGF0dGVtcHRpbmcgdG8gZGlzcGF0Y2ggdG8gb25VbnN1YnNjcmliZUhhbmRsZXJzLiBFcnJvcjogJHtlcnJvcn0gUmVtb3ZpbmcgQ2xpZW50OiAke2hhbmRsZXJJZH0uIHV1aWQ6ICR7cmVtb3ZpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtyZW1vdmluZ0NsaWVudElkZW50aXR5Lm5hbWV9LiBlbmRwb2ludElkOiAke3JlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH1gKTtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybihgVHJ5aW5nIHRvIHJlbW92ZSBhIGhhbmRsZXIgZnJvbSBhIGNsaWVudCB0aGF0IGlzbid0IG1hcHBlZC4gaGFuZGxlcklkOiAke2hhbmRsZXJJZH0uIHV1aWQ6ICR7cmVtb3ZpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtyZW1vdmluZ0NsaWVudElkZW50aXR5Lm5hbWV9LiBlbmRwb2ludElkOiAke3JlbW92aW5nQ2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH0uYCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgbm9uU3RhbmRhcmRIYW5kbGVyUmVtb3ZlZChwYXlsb2FkLCBpZCkge1xuXHQgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkIH0gPSBwYXlsb2FkO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShpZCk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGlmIChjbGllbnRTdGF0ZS5vbkRpc2Nvbm5lY3RIYW5kbGVySWQgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3RhdGUub25EaXNjb25uZWN0SGFuZGxlcklkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2UgaWYgKGNsaWVudFN0YXRlLm9uQWRkQ29udGV4dExpc3RlbmVySGFuZGxlcklkID09PSBoYW5kbGVySWQpIHtcblx0ICAgICAgICAgICAgICAgIGNsaWVudFN0YXRlLm9uQWRkQ29udGV4dExpc3RlbmVySGFuZGxlcklkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2UgaWYgKGNsaWVudFN0YXRlLm9uVW5zdWJzY3JpYmVIYW5kbGVySWQgPT09IGhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3RhdGUub25VbnN1YnNjcmliZUhhbmRsZXJJZCA9IHVuZGVmaW5lZDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKGBUcnlpbmcgdG8gcmVtb3ZlIGEgaGFuZGxlciBmcm9tIGEgY2xpZW50IHRoYXQgaXNuJ3QgbWFwcGVkLiBoYW5kbGVySWQ6ICR7aGFuZGxlcklkfS4gY2xpZW50SWRlbnRpdHk6ICR7aWR9YCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgb25BZGRDb250ZXh0SGFuZGxlckFkZGVkKHBheWxvYWQsIHNlbmRlckNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKHNlbmRlckNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjb25zdCB7IGhhbmRsZXJJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7c2VuZGVyQ2xpZW50SWRlbnRpdHkudXVpZH0gJHtzZW5kZXJDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBvbkFkZENvbnRleHRMaXN0ZW5lciwgaXMgbm90IGNvbm5lY3RlZCB0byB0aGlzIFByaXZhdGUgQ2hhbm5lbGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjbGllbnRTdGF0ZS5vbkFkZENvbnRleHRMaXN0ZW5lckhhbmRsZXJJZCA9IGhhbmRsZXJJZDtcblx0ICAgICAgICAvLyBGREMzIFNwZWMgc2F5cyB0aGF0IHRoZSBhZGRlZCBsaXN0ZW5lciBzaG91bGQgZmlyZSBmb3IgYWxsIHByZXZpb3VzbHktcmVnaXN0ZXJlZCBhZGRDb250ZXh0TGlzdGVuZXJzIGZyb20gdGhlIG90aGVyIGNsaWVudFxuXHQgICAgICAgIEFycmF5LmZyb20odGhpcy5jbGllbnRzLnZhbHVlcygpKS5mb3JFYWNoKChvdGhlckNsaWVudFN0YXRlKSA9PiB7XG5cdCAgICAgICAgICAgIGlmIChvdGhlckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LmVuZHBvaW50SWQgIT09IHNlbmRlckNsaWVudElkZW50aXR5LmVuZHBvaW50SWQpIHtcblx0ICAgICAgICAgICAgICAgIEFycmF5LmZyb20ob3RoZXJDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMua2V5cygpKS5mb3JFYWNoKChzdWJzY3JpYmVkQ29udGV4dFR5cGUpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3ZpZGVyLmRpc3BhdGNoKHNlbmRlckNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIHN1YnNjcmliZWRDb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgb25EaXNjb25uZWN0SGFuZGxlckFkZGVkKHBheWxvYWQsIGlkKSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGlkKTtcblx0ICAgICAgICBjb25zdCB7IGhhbmRsZXJJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICBpZiAoIWNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7aWQudXVpZH0gJHtpZC5uYW1lfSwgdHJpZWQgdG8gY2FsbCBvbkRpc2Nvbm5lY3QsIGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhpcyBQcml2YXRlIENoYW5uZWxgKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2xpZW50U3RhdGUub25EaXNjb25uZWN0SGFuZGxlcklkID0gaGFuZGxlcklkO1xuXHQgICAgfVxuXHQgICAgb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZChwYXlsb2FkLCBpZCkge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShpZCk7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgaWYgKCFjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2lkLnV1aWR9ICR7aWQubmFtZX0sIHRyaWVkIHRvIGNhbGwgb25VbnN1YnNjcmliZSwgaXMgbm90IGNvbm5lY3RlZCB0byB0aGlzIFByaXZhdGUgQ2hhbm5lbGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjbGllbnRTdGF0ZS5vblVuc3Vic2NyaWJlSGFuZGxlcklkID0gaGFuZGxlcklkO1xuXHQgICAgfVxuXHQgICAgcmVtb3ZlQ2xpZW50KGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS51dWlkfSAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS5uYW1lfSwgdHJpZWQgdG8gY2FsbCBkaXNjb25uZWN0LCBpcyBub3QgY29ubmVjdGVkIHRvIHRoaXMgUHJpdmF0ZSBDaGFubmVsYCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGRpc2Nvbm5lY3RpbmdDbGllbnRTdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMuY2xlYXIoKTtcblx0ICAgICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS5lbmRwb2ludElkKTtcblx0ICAgIH1cblx0ICAgIGFzeW5jIGZpcmVPbkRpc2Nvbm5lY3RGb3JPdGhlckNsaWVudHMoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgLy8gVE9ETzogY2FsbCBvbkRpc2Nvbm5lY3QgSGFuZGxlciBvZiB0aGUgb3RoZXIgY2xpZW50IG9ubHkuXG5cdCAgICAgICAgLy8gQ1VSUkVOVExZLCBqdXN0IGNhbGxpbmcgdGhlIG9uRGlzY29ubmVjdCBoYW5kbGVyIGZvciBhbGwgdGhlIG90aGVyIGNsaWVudHMuIE9uY2Ugd2UgbGltaXQgaXQgdG8ganVzdCBvbmUgb3RoZXIgY2xpZW50LCB3ZSBjYW4gZWxpbWluYXRlIGFsbCB0aGUgaXRlcmF0aW9uIGNvZGUuXG5cdCAgICAgICAgY29uc3QgeyBlbmRwb2ludElkIH0gPSBkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHk7XG5cdCAgICAgICAgLy8gZ2V0dGluZyBvbmx5IHZhbGlkIGNsaWVudCBjb25uZWN0aW9ucyBoZXJlLCBpdCBpcyBwb3NzaWJsZSB3ZSBoYXZlbid0IHJlbW92ZWQgYSBkaXNjb25uZWN0ZWQgY2xpZW50IGZyb20gdGhlIG1hcCB5ZXRcblx0ICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIGVuc3VyZSB3ZSBkb24ndCBkaXNwYXRjaCB0byBhbnkgZGlzY29ubmVjdGVkIGNsaWVudFxuXHQgICAgICAgIC8vIFRPRE86IFRha2UgYSBsb29rIGF0IG91ciBjbGllbnQgZGlzY29ubmVjdGlvbiBsb2dpYyBhbmQgc2VlIGlmIHdlIGNhbiBoYW5kbGUgY2xpZW50IGRpc2Nvbm5lY3Rpb24gY2xlYW5seVxuXHQgICAgICAgIGNvbnN0IGNsaWVudHNUb0Rpc3BhdGNoVG8gPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZENsaWVudHMoKTtcblx0ICAgICAgICBjb25zdCBkaXNwYXRjaFByb21pc2VzID0gY2xpZW50c1RvRGlzcGF0Y2hUby5tYXAoYXN5bmMgKG90aGVyQ2xpZW50U3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eTogeyBlbmRwb2ludElkOiBvdGhlckNsaWVudEVuZHBvaW50SWQgfSwgb25EaXNjb25uZWN0SGFuZGxlcklkIH0gPSBvdGhlckNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICBpZiAob3RoZXJDbGllbnRFbmRwb2ludElkICE9PSBlbmRwb2ludElkICYmIG9uRGlzY29ubmVjdEhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wcm92aWRlci5kaXNwYXRjaChvdGhlckNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5LCBvbkRpc2Nvbm5lY3RIYW5kbGVySWQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoZGlzcGF0Y2hQcm9taXNlcyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBQcm9ibGVtIHdoZW4gYXR0ZW1wdGluZyB0byBkaXNwYXRjaCB0byBvbkRpc2Nvbm5lY3RIYW5kbGVycy4gRXJyb3I6ICR7ZXJyb3J9IERpc2Nvbm5lY3RpbmcgQ2xpZW50OiB1dWlkOiAke2Rpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eS51dWlkfS4gbmFtZTogJHtkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkubmFtZX0uIGVuZHBvaW50SWQ6ICR7ZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5LmVuZHBvaW50SWR9YCk7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgdW5zdWJzY3JpYmVBbGwoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB7IGVuZHBvaW50SWQgfSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5jbGllbnRzLmdldChlbmRwb2ludElkKTtcblx0ICAgICAgICBpZiAoc3RhdGUpIHtcblx0ICAgICAgICAgICAgY29uc3QgY29udGV4dFR5cGVIYW5kbGVySWRzID0gQXJyYXkuZnJvbShzdGF0ZS5oYW5kbGVySWRzQnlDb250ZXh0VHlwZXMudmFsdWVzKCkpLmZsYXQoKTtcblx0ICAgICAgICAgICAgY29uc3QgZ2xvYmFsSGFuZGxlcklkID0gc3RhdGUuZ2xvYmFsSGFuZGxlcjtcblx0ICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlSGFuZGxlcklkcy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB1bnN1YlByb21pc2VzID0gY29udGV4dFR5cGVIYW5kbGVySWRzLm1hcChhc3luYyAoaGFuZGxlcklkKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dEhhbmRsZXJSZW1vdmVkKHsgaGFuZGxlcklkIH0sIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh1bnN1YlByb21pc2VzKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGdsb2JhbEhhbmRsZXJJZCkge1xuXHQgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmNvbnRleHRIYW5kbGVyUmVtb3ZlZCh7IGhhbmRsZXJJZDogZ2xvYmFsSGFuZGxlcklkIH0sIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IubWVzc2FnZSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBhc3luYyBoYW5kbGVDbGllbnREaXNjb25uZWN0aW5nKGRpc2Nvbm5lY3RpbmdDbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGF3YWl0IHRoaXMudW5zdWJzY3JpYmVBbGwoZGlzY29ubmVjdGluZ0NsaWVudElkZW50aXR5KTtcblx0ICAgICAgICB0aGlzLnJlbW92ZUNsaWVudChkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGF3YWl0IHRoaXMuZmlyZU9uRGlzY29ubmVjdEZvck90aGVyQ2xpZW50cyhkaXNjb25uZWN0aW5nQ2xpZW50SWRlbnRpdHkpO1xuXHQgICAgfVxuXHQgICAgcmVnaXN0ZXJOZXdDbGllbnQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBpZiAoIXRoaXMuY2xpZW50cy5oYXMoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCkpIHtcblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eSxcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJZHNCeUNvbnRleHRUeXBlczogbmV3IE1hcCgpLFxuXHQgICAgICAgICAgICAgICAgZ2xvYmFsSGFuZGxlcjogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICAgICAgb25BZGRDb250ZXh0TGlzdGVuZXJIYW5kbGVySWQ6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgICAgIG9uVW5zdWJzY3JpYmVIYW5kbGVySWQ6IHVuZGVmaW5lZCxcblx0ICAgICAgICAgICAgICAgIG9uRGlzY29ubmVjdEhhbmRsZXJJZDogdW5kZWZpbmVkXG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIHRoaXMuY2xpZW50cy5zZXQoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCwgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIGdldENvbm5lY3RlZENsaWVudHMoKSB7XG5cdCAgICAgICAgY29uc3QgYWxsQ2xpZW50SW5mbyA9IGF3YWl0IHRoaXMucHJvdmlkZXIuZ2V0QWxsQ2xpZW50SW5mbygpO1xuXHQgICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuY2xpZW50cy52YWx1ZXMoKSkuZmlsdGVyKChjbGllbnRTdGF0ZSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNsaWVudFN0YXRlLmNsaWVudElkZW50aXR5O1xuXHQgICAgICAgICAgICByZXR1cm4gYWxsQ2xpZW50SW5mby5zb21lKChjbGllbnRJbmZvKSA9PiB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmFtZSA9PT0gY2xpZW50SW5mby5uYW1lICYmIHV1aWQgPT09IGNsaWVudEluZm8udXVpZDtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBzdGF0aWMgaW5pdChjaGFubmVsUHJvdmlkZXIsIGlkKSB7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyKGNoYW5uZWxQcm92aWRlciwgaWQpO1xuXHQgICAgfVxuXHR9O1xuXHRQcml2YXRlQ2hhbm5lbFByb3ZpZGVyLlByaXZhdGVDaGFubmVsUHJvdmlkZXIgPSBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyJDE7XG5cdHJldHVybiBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyO1xufVxuXG52YXIgaGFzUmVxdWlyZWRJbnRlcm9wQnJva2VyO1xuXG5mdW5jdGlvbiByZXF1aXJlSW50ZXJvcEJyb2tlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEludGVyb3BCcm9rZXIpIHJldHVybiBJbnRlcm9wQnJva2VyO1xuXHRoYXNSZXF1aXJlZEludGVyb3BCcm9rZXIgPSAxO1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xuXHR9O1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZEdldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG5cdCAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG5cdCAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG5cdH07XG5cdHZhciBfX2ltcG9ydERlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnREZWZhdWx0KSB8fCBmdW5jdGlvbiAobW9kKSB7XG5cdCAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcblx0fTtcblx0dmFyIF9JbnRlcm9wQnJva2VyX2ZkYzNJbmZvLCBfSW50ZXJvcEJyb2tlcl9jb250ZXh0R3JvdXBzLCBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2U7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnRlcm9wQnJva2VyLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0SW50ZXJvcEJyb2tlci5JbnRlcm9wQnJva2VyID0gdm9pZCAwO1xuXHRjb25zdCBiYXNlXzEgPSBiYXNlO1xuXHRjb25zdCBTZXNzaW9uQ29udGV4dEdyb3VwQnJva2VyXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZVNlc3Npb25Db250ZXh0R3JvdXBCcm9rZXIoKSk7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHRjb25zdCBpc0VxdWFsXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMyk7XG5cdGNvbnN0IFByaXZhdGVDaGFubmVsUHJvdmlkZXJfMSA9IHJlcXVpcmVQcml2YXRlQ2hhbm5lbFByb3ZpZGVyKCk7XG5cdGNvbnN0IGxhenlfMSA9IGxhenk7XG5cdGNvbnN0IGRlZmF1bHRDb250ZXh0R3JvdXBzID0gW1xuXHQgICAge1xuXHQgICAgICAgIGlkOiAnZ3JlZW4nLFxuXHQgICAgICAgIGRpc3BsYXlNZXRhZGF0YToge1xuXHQgICAgICAgICAgICBjb2xvcjogJyMwMENDODgnLFxuXHQgICAgICAgICAgICBuYW1lOiAnZ3JlZW4nXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3B1cnBsZScsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnIzhDNjFGRicsXG5cdCAgICAgICAgICAgIG5hbWU6ICdwdXJwbGUnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ29yYW5nZScsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnI0ZGOEM0QycsXG5cdCAgICAgICAgICAgIG5hbWU6ICdvcmFuZ2UnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3JlZCcsXG5cdCAgICAgICAgZGlzcGxheU1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgIGNvbG9yOiAnI0ZGNUU2MCcsXG5cdCAgICAgICAgICAgIG5hbWU6ICdyZWQnXG5cdCAgICAgICAgfVxuXHQgICAgfSxcblx0ICAgIHtcblx0ICAgICAgICBpZDogJ3BpbmsnLFxuXHQgICAgICAgIGRpc3BsYXlNZXRhZGF0YToge1xuXHQgICAgICAgICAgICBjb2xvcjogJyNGRjhGQjgnLFxuXHQgICAgICAgICAgICBuYW1lOiAncGluaydcblx0ICAgICAgICB9XG5cdCAgICB9LFxuXHQgICAge1xuXHQgICAgICAgIGlkOiAneWVsbG93Jyxcblx0ICAgICAgICBkaXNwbGF5TWV0YWRhdGE6IHtcblx0ICAgICAgICAgICAgY29sb3I6ICcjRTlGRjhGJyxcblx0ICAgICAgICAgICAgbmFtZTogJ3llbGxvdydcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdF07XG5cdC8qKlxuXHQgKiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2VuYWJsZS1jb2xvci1saW5raW5nfVxuXHQgKlxuXHQgKiBUaGUgSW50ZXJvcCBCcm9rZXIgaXMgcmVzcG9uc2libGUgZm9yIGtlZXBpbmcgdHJhY2sgb2YgdGhlIEludGVyb3Agc3RhdGUgb2YgdGhlIFBsYXRmb3JtLCBhbmQgZm9yIGRpcmVjdGluZyBtZXNzYWdlcyB0byB0aGUgcHJvcGVyIGxvY2F0aW9ucy5cblx0ICpcblx0ICogQHJlbWFya3MgVGhpcyBjbGFzcyBjb250YWlucyBzb21lIHR5cGVzIHJlbGF0ZWQgdG8gRkRDMyB0aGF0IGFyZSBzcGVjaWZpYyB0byBPcGVuRmluLiB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXJzLm9wZW5maW4uY28vb2YtZG9jcy9kb2NzL2ZkYzMtc3VwcG9ydC1pbi1vcGVuZmluIE9wZW5GaW4ncyBGREMzIHN1cHBvcnR9IGlzIGZvcndhcmQtIGFuZCBiYWNrd2FyZC1jb21wYXRpYmxlLlxuXHQgKiBTdGFuZGFyZCB0eXBlcyBmb3Ige0BsaW5rIGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvIEZEQzN9IGRvIG5vdCBhcHBlYXIgaW4gT3BlbkZpbuKAmXMgQVBJIGRvY3VtZW50YXRpb24sIHRvIGF2b2lkIGR1cGxpY2F0aW9uLlxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogVGhlcmUgYXJlIDIgd2F5cyB0byBpbmplY3QgY3VzdG9tIGZ1bmN0aW9uYWxpdHkgaW50byB0aGUgSW50ZXJvcCBCcm9rZXI6XG5cdCAqXG5cdCAqICoqMS4gQ29uZmlndXJhdGlvbioqXG5cdCAqXG5cdCAqIEF0IHRoZSBtb21lbnQsIHlvdSBjYW4gY29uZmlndXJlIHRoZSBkZWZhdWx0IGNvbnRleHQgZ3JvdXBzIGZvciB0aGUgSW50ZXJvcCBCcm9rZXIgd2l0aG91dCBoYXZpbmcgdG8gb3ZlcnJpZGUgaXQuIFRvIGRvIHNvLCBpbmNsdWRlIHRoZSBgaW50ZXJvcEJyb2tlckNvbmZpZ3VyYXRpb25gIGBjb250ZXh0R3JvdXBzYCBvcHRpb24gaW4geW91ciBgcGxhdGZvcm1gIG9wdGlvbnMgaW4geW91ciBtYW5pZmVzdC4gVGhpcyBpcyB0aGUgcHJlZmVycmVkIG1ldGhvZC5cblx0ICogYGBganNcblx0ICoge1xuXHQgKiAgICAgIFwicnVudGltZVwiOiB7XG5cdCAqICAgICAgICAgIFwiYXJndW1lbnRzXCI6IFwiLS12PTEgLS1pbnNwZWN0XCIsXG5cdCAqICAgICAgICAgIFwidmVyc2lvblwiOiBcImFscGhhLXYxOVwiXG5cdCAqICAgICAgfSxcblx0ICogICAgICBcInBsYXRmb3JtXCI6IHtcblx0ICogICAgICAgICAgXCJ1dWlkXCI6IFwicGxhdGZvcm1fY3VzdG9taXphdGlvbl9sb2NhbFwiLFxuXHQgKiAgICAgICAgICBcImFwcGxpY2F0aW9uSWNvblwiOiBcImh0dHBzOi8vb3BlbmZpbi5naXRodWIuaW8vZ29sZGVuLXByb3RvdHlwZS9mYXZpY29uLmljb1wiLFxuXHQgKiAgICAgICAgICBcImF1dG9TaG93XCI6IGZhbHNlLFxuXHQgKiAgICAgICAgICBcInByb3ZpZGVyVXJsXCI6IFwiaHR0cDovL2xvY2FsaG9zdDo1NTU1L3Byb3ZpZGVyLmh0bWxcIixcblx0ICogICAgICAgICAgXCJpbnRlcm9wQnJva2VyQ29uZmlndXJhdGlvblwiOiB7XG5cdCAqICAgICAgICAgICAgICBcImNvbnRleHRHcm91cHNcIjogW1xuXHQgKiAgICAgICAgICAgICAgICAgIHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiBcImdyZWVuXCIsXG5cdCAqICAgICAgICAgICAgICAgICAgICAgIFwiZGlzcGxheU1ldGFkYXRhXCI6IHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgICAgIFwiY29sb3JcIjogXCIjMDBDQzg4XCIsXG5cdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBcIm5hbWVcIjogXCJncmVlblwiXG5cdCAqICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICogICAgICAgICAgICAgICAgICB9LFxuXHQgKiAgICAgICAgICAgICAgICAgIHtcblx0ICogICAgICAgICAgICAgICAgICAgICAgXCJpZFwiOiBcInB1cnBsZVwiLFxuXHQgKiAgICAgICAgICAgICAgICAgICAgICBcImRpc3BsYXlNZXRhZGF0YVwiOiB7XG5cdCAqICAgICAgICAgICAgICAgICAgICAgICAgICBcImNvbG9yXCI6IFwiIzhDNjFGRlwiLFxuXHQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgXCJuYW1lXCI6IFwicHVycGxlXCJcblx0ICogICAgICAgICAgICAgICAgICAgICAgfVxuXHQgKiAgICAgICAgICAgICAgICAgIH0sXG5cdCAqICAgICAgICAgICAgICBdXG5cdCAqICAgICAgICAgIH1cblx0ICogICAgICB9XG5cdCAqIH1cblx0ICogYGBgXG5cdCAqXG5cdCAqIEJ5IGRlZmF1bHQgdGhlIEludGVyb3AgQnJva2VyIGxvZ3MgYWxsIGFjdGlvbnMgdG8gdGhlIGNvbnNvbGUuIFlvdSBjYW4gZGlzYWJsZSB0aGlzIGJ5IHVzaW5nIHRoZSBsb2dnaW5nIG9wdGlvbiBpbiBgaW50ZXJvcEJyb2tlckNvbmZpZ3VyYXRpb25gOlxuXHQgKiBgYGBqc1xuXHQgKiB7XG5cdCAqICAgICAgXCJydW50aW1lXCI6IHtcblx0ICogICAgICAgICAgXCJhcmd1bWVudHNcIjogXCItLXY9MSAtLWluc3BlY3RcIixcblx0ICogICAgICAgICAgXCJ2ZXJzaW9uXCI6IFwiYWxwaGEtdjE5XCJcblx0ICogICAgICB9LFxuXHQgKiAgICAgIFwicGxhdGZvcm1cIjoge1xuXHQgKiAgICAgICAgICBcInV1aWRcIjogXCJwbGF0Zm9ybV9jdXN0b21pemF0aW9uX2xvY2FsXCIsXG5cdCAqICAgICAgICAgIFwiYXBwbGljYXRpb25JY29uXCI6IFwiaHR0cHM6Ly9vcGVuZmluLmdpdGh1Yi5pby9nb2xkZW4tcHJvdG90eXBlL2Zhdmljb24uaWNvXCIsXG5cdCAqICAgICAgICAgIFwiYXV0b1Nob3dcIjogZmFsc2UsXG5cdCAqICAgICAgICAgIFwicHJvdmlkZXJVcmxcIjogXCJodHRwOi8vbG9jYWxob3N0OjU1NTUvcHJvdmlkZXIuaHRtbFwiLFxuXHQgKlx0XHQgICAgXCJpbnRlcm9wQnJva2VyQ29uZmlndXJhdGlvblwiOiB7XG5cdCAqICAgICAgIFx0XHRcImxvZ2dpbmdcIjoge1xuXHQgKiAgIFx0XHRcdFx0XCJiZWZvcmVBY3Rpb25cIjoge1xuXHQgKiAgIFx0XHRcdFx0XHRcImVuYWJsZWRcIjogZmFsc2Vcblx0ICogICBcdFx0XHRcdH0sXG5cdCAqICAgXHRcdFx0XHRcImFmdGVyQWN0aW9uXCI6IHtcblx0ICogICBcdFx0XHRcdFx0XCJlbmFibGVkXCI6IGZhbHNlXG5cdCAqICAgXHRcdFx0XHR9XG5cdCAqICAgXHRcdFx0fVxuXHQgKlx0XHQgICAgfVxuXHQgKiAgICAgIH1cblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogLS0tXG5cdCAqICoqMi4gT3ZlcnJpZGluZyoqXG5cdCAqXG5cdCAqIFNpbWlsYXJseSB0byBob3cge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL2RvY3MvcGxhdGZvcm0tY3VzdG9taXphdGlvbiNzZWN0aW9uLWN1c3RvbWl6aW5nLXBsYXRmb3JtLWJlaGF2aW9yIFBsYXRmb3JtIE92ZXJyaWRpbmd9IHdvcmtzLCB5b3UgY2FuIG92ZXJyaWRlIGZ1bmN0aW9ucyBpbiB0aGUgSW50ZXJvcCBCcm9rZXIgaW4gYGZpbi5QbGF0Zm9ybS5pbml0YC4gQW4gZXhhbXBsZSBvZiB0aGF0IGlzIHNob3duIGJlbG93LiBPdmVycmlkaW5nIGBpc0Nvbm5lY3Rpb25BdXRob3JpemVkYCBhbmQgYGlzQWN0aW9uQXV0aG9yaXplZGAgd2lsbCBhbGxvdyB5b3UgdG8gY29udHJvbCBhbGxvd2VkIGNvbm5lY3Rpb25zIGFuZCBhbGxvd2VkIGFjdGlvbnMuXG5cdCAqXG5cdCAqIEhvd2V2ZXIsIGlmIHRoZXJlIGlzIGN1c3RvbSBmdW5jdGlvbmFsaXR5IHlvdSB3aXNoIHRvIGluY2x1ZGUgaW4gdGhlIEludGVyb3AgQnJva2VyLCBwbGVhc2UgbGV0IHVzIGtub3cuIFdlIHdvdWxkIGxpa2UgdG8gcHJvdmlkZSBiZXR0ZXIgY29uZmlndXJhdGlvbiBvcHRpb25zIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gY29udGludWFsbHkgbWFpbnRhaW4geW91ciBvd24gb3ZlcnJpZGUgY29kZS5cblx0ICpcblx0ICogYGBganNcblx0ICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgKiAgICAgb3ZlcnJpZGVDYWxsYmFjazogYXN5bmMgKFByb3ZpZGVyKSA9PiB7XG5cdCAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBQcm92aWRlciB7XG5cdCAqICAgICAgICAgICAgIGFzeW5jIGdldFNuYXBzaG90KCkge1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2JlZm9yZSBnZXRTbmFwc2hvdCcpXG5cdCAqICAgICAgICAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHN1cGVyLmdldFNuYXBzaG90KCk7XG5cdCAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYWZ0ZXIgZ2V0U25hcHNob3QnKVxuXHQgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHNuYXBzaG90O1xuXHQgKiAgICAgICAgICAgICB9XG5cdCAqXG5cdCAqICAgICAgICAgICAgIGFzeW5jIGFwcGx5U25hcHNob3QoeyBzbmFwc2hvdCwgb3B0aW9ucyB9KSB7XG5cdCAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYmVmb3JlIGFwcGx5U25hcHNob3QnKVxuXHQgKiAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxQcm9taXNlID0gc3VwZXIuYXBwbHlTbmFwc2hvdCh7IHNuYXBzaG90LCBvcHRpb25zIH0pO1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2FmdGVyIGFwcGx5U25hcHNob3QnKVxuXHQgKlxuXHQgKiAgICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsUHJvbWlzZTtcblx0ICogICAgICAgICAgICAgfVxuXHQgKiAgICAgICAgIH07XG5cdCAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgKiAgICAgfSxcblx0ICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgKiAgICAgICAgICAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKGNoYW5uZWxOYW1lID0gJ2RlZmF1bHQnLCB0YXJnZXQpIHtcblx0ICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdiZWZvcmUgc3VwZXIgam9pbkNvbnRleHRHcm91cCcpXG5cdCAqICAgICAgICAgICAgICAgICBzdXBlci5qb2luQ29udGV4dEdyb3VwKGNoYW5uZWxOYW1lLCB0YXJnZXQpO1xuXHQgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ2FmdGVyIHN1cGVyIGpvaW5Db250ZXh0R3JvdXAnKVxuXHQgKiAgICAgICAgICAgICB9XG5cdCAqICAgICAgICAgfVxuXHQgKlxuXHQgKiAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKCk7XG5cdCAqICAgfVxuXHQgKiB9KTtcblx0ICogYGBgXG5cdCAqXG5cdCAqIC0tLVxuXHQgKlxuXHQgKi9cblx0bGV0IEludGVyb3BCcm9rZXIkMSA9IGNsYXNzIEludGVyb3BCcm9rZXIgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICovXG5cdCAgICBjb25zdHJ1Y3Rvcih3aXJlLCBjcmVhdGVQcm92aWRlciwgb3B0aW9ucykge1xuXHQgICAgICAgIC8vIFRpcCBmcm9tIFBpZXJyZSBhbmQgTWljaGFlbCBmcm9tIHRoZSBvdmVycmlkZUNoZWNrIHdvcms6IERvbid0IHVzZSBib3VuZCBtZXRob2RzIGZvciBvdmVycmlkZWFibGUgSW50ZXJvcEJyb2tlciBmdW5jdGlvbnMuXG5cdCAgICAgICAgc3VwZXIod2lyZSk7XG5cdCAgICAgICAgX0ludGVyb3BCcm9rZXJfZmRjM0luZm8uc2V0KHRoaXMsIHZvaWQgMCk7XG5cdCAgICAgICAgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3Vwcy5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2Uuc2V0KHRoaXMsIHZvaWQgMCk7XG5cdCAgICAgICAgdGhpcy5nZXRQcm92aWRlciA9ICgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfcHJvdmlkZXJQcm9taXNlLCBcImZcIikuZ2V0VmFsdWUoKTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHRoaXMuaW50ZXJvcENsaWVudHMgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5jb250ZXh0R3JvdXBzQnlJZCA9IG5ldyBNYXAoKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQnJva2VyX2NvbnRleHRHcm91cHMsIG9wdGlvbnMuY29udGV4dEdyb3VwcyA/PyBbLi4uZGVmYXVsdENvbnRleHRHcm91cHNdLCBcImZcIik7XG5cdCAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfSW50ZXJvcEJyb2tlcl9mZGMzSW5mbywgb3B0aW9ucy5mZGMzSW5mbywgXCJmXCIpO1xuXHQgICAgICAgIGlmIChvcHRpb25zPy5sb2dnaW5nKSB7XG5cdCAgICAgICAgICAgIHRoaXMubG9nZ2luZyA9IG9wdGlvbnMubG9nZ2luZztcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhpcy5pbnRlbnRDbGllbnRNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgdGhpcy5sYXN0Q29udGV4dE1hcCA9IG5ldyBNYXAoKTtcblx0ICAgICAgICB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAgPSBuZXcgTWFwKCk7XG5cdCAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfSW50ZXJvcEJyb2tlcl9wcm92aWRlclByb21pc2UsIG5ldyBsYXp5XzEuTGF6eShjcmVhdGVQcm92aWRlciksIFwiZlwiKTtcblx0ICAgICAgICB0aGlzLnNldENvbnRleHRHcm91cE1hcCgpO1xuXHQgICAgICAgIHRoaXMuc2V0dXBDaGFubmVsUHJvdmlkZXIoKTtcblx0ICAgIH1cblx0ICAgIHN0YXRpYyBjcmVhdGVDbG9zZWRDb25zdHJ1Y3RvciguLi5hcmdzKSB7XG5cdCAgICAgICAgcmV0dXJuIGNsYXNzIE92ZXJyaWRlYWJsZUJyb2tlciBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICAgICAgICBjb25zdHJ1Y3RvciguLi51bnVzZWQpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh1bnVzZWQubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgW19pZ25vcmUxLCBpZ25vcmUyLCBvcHRzXSA9IHVudXNlZDtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAob3B0cyAmJiB0eXBlb2Ygb3B0cyA9PT0gJ29iamVjdCcgJiYgISgwLCBpc0VxdWFsXzEuZGVmYXVsdCkob3B0cywgYXJnc1syXSkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdZb3UgaGF2ZSBtb2RpZmllZCB0aGUgcGFyYW1ldGVycyBvZiB0aGUgSW50ZXJvcE92ZXJyaWRlIGNvbnN0cnVjdG9yLiBUaGlzIGJlaGF2aW9yIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLiBZb3UgY2FuIG1vZGlmeSB0aGVzZSBvcHRpb25zIGluIHlvdXIgbWFuaWZlc3QuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXIoYXJnc1swXSwgYXJnc1sxXSwgb3B0cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1lvdSBhcmUgYXR0ZW1wdGluZyB0byBwYXNzIGFyZ3VtZW50cyB0byB0aGUgSW50ZXJvcE92ZXJyaWRlIGNvbnN0cnVjdG9yLiBUaGlzIGlzIG5vdCBuZWNlc3NhcnksIGFuZCB0aGVzZSBwYXNzZWQgYXJndW1lbnRzIHdpbGwgYmUgaWdub3JlZC4gWW91IGFyZSBsaWtlbHkgdXNpbmcgYW4gb2xkZXIgSW50ZXJvcEJyb2tlciBvdmVycmlkZSBzY2hlbWUuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIHN1cGVyKC4uLmFyZ3MpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBDbGllbnQgQVBJXG5cdCAgICAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBTZXRzIGEgY29udGV4dCBmb3IgdGhlIGNvbnRleHQgZ3JvdXAgb2YgdGhlIGluY29taW5nIGN1cnJlbnQgZW50aXR5LlxuXHQgICAgICogQHBhcmFtIHNldENvbnRleHRPcHRpb25zIC0gTmV3IGNvbnRleHQgdG8gc2V0LlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBzZXRDb250ZXh0KHsgY29udGV4dCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1zZXQtY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlICYmIGNsaWVudFN0YXRlLmNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgY29udGV4dEdyb3VwSWQgfSA9IGNsaWVudFN0YXRlO1xuXHQgICAgICAgICAgICB0aGlzLnNldENvbnRleHRGb3JHcm91cCh7IGNvbnRleHQgfSwgY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIGlmIChjbGllbnRTdGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBDbGllbnQgaGFzIG5vdCBqb2luZWQgYW55IGNvbnRleHQgZ3JvdXAgYmVoYXZpb3IuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3Qgam9pbiBhIGNvbnRleHQgZ3JvdXAgYmVmb3JlIHlvdSBjYW4gc2V0IGNvbnRleHQuJyk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICAvLyBUaGlzIHNob3VsZG4ndCBnZXQgaGl0LlxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsaWVudCB3aXRoIElkZW50aXR5OiAke2NsaWVudElkZW50aXR5LnV1aWR9ICR7Y2xpZW50SWRlbnRpdHkubmFtZX0gbm90IGluIENsaWVudCBTdGF0ZSBNYXBgKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNldHMgYSBjb250ZXh0IGZvciB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqIEBwYXJhbSBzZXRDb250ZXh0T3B0aW9ucyAtIE5ldyBjb250ZXh0IHRvIHNldC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0R3JvdXBJZCAtIENvbnRleHQgZ3JvdXAgaWQuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBzZXRDb250ZXh0Rm9yR3JvdXAoeyBjb250ZXh0IH0sIGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtYnJva2VyLXNldC1jb250ZXh0LWZvci1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cFN0YXRlID0gdGhpcy5jb250ZXh0R3JvdXBzQnlJZC5nZXQoY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIGlmICghY29udGV4dEdyb3VwU3RhdGUpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gc2V0IGNvbnRleHQgZm9yIGNvbnRleHQgZ3JvdXAgdGhhdCBpc24ndCBpbiB0aGUgY29udGV4dCBncm91cCBtYXBwaW5nOiAke2NvbnRleHRHcm91cElkfS5gKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY29udGV4dEludGVncml0eUNoZWNrUmVzdWx0ID0gSW50ZXJvcEJyb2tlci5jaGVja0NvbnRleHRJbnRlZ3JpdHkoY29udGV4dCk7XG5cdCAgICAgICAgaWYgKGNvbnRleHRJbnRlZ3JpdHlDaGVja1Jlc3VsdC5pc1ZhbGlkID09PSBmYWxzZSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBzZXQgQ29udGV4dCAtIGJhZCBDb250ZXh0LiBSZWFzb246ICR7Y29udGV4dEludGVncml0eUNoZWNrUmVzdWx0LnJlYXNvbn0uIENvbnRleHQ6ICR7SlNPTi5zdHJpbmdpZnkoY29udGV4dCl9YCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNvbnN0IGJyb2FkY2FzdGVkQ29udGV4dFR5cGUgPSBjb250ZXh0LnR5cGU7XG5cdCAgICAgICAgY29udGV4dEdyb3VwU3RhdGUuc2V0KGJyb2FkY2FzdGVkQ29udGV4dFR5cGUsIGNvbnRleHQpO1xuXHQgICAgICAgIHRoaXMubGFzdENvbnRleHRNYXAuc2V0KGNvbnRleHRHcm91cElkLCBicm9hZGNhc3RlZENvbnRleHRUeXBlKTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5TYW1lQ29udGV4dEdyb3VwID0gQXJyYXkuZnJvbSh0aGlzLmludGVyb3BDbGllbnRzLnZhbHVlcygpKS5maWx0ZXIoKGNvbm5lY3RlZENsaWVudCkgPT4gY29ubmVjdGVkQ2xpZW50LmNvbnRleHRHcm91cElkID09PSBjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgY2xpZW50c0luU2FtZUNvbnRleHRHcm91cC5mb3JFYWNoKChjbGllbnQpID0+IHtcblx0ICAgICAgICAgICAgZm9yIChjb25zdCBbLCBoYW5kbGVySW5mb10gb2YgY2xpZW50LmNvbnRleHRIYW5kbGVycykge1xuXHQgICAgICAgICAgICAgICAgaWYgKEludGVyb3BCcm9rZXIuaXNDb250ZXh0VHlwZUNvbXBhdGlibGUoYnJvYWRjYXN0ZWRDb250ZXh0VHlwZSwgaGFuZGxlckluZm8uY29udGV4dFR5cGUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnZva2VDb250ZXh0SGFuZGxlcihjbGllbnQuY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJbmZvLmhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0IGN1cnJlbnQgY29udGV4dCBmb3IgYSBjbGllbnQgc3Vic2NyaWJlZCB0byBhIENvbnRleHQgR3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgSXQgdGFrZXMgYW4gb3B0aW9uYWwgQ29udGV4dCBUeXBlIGFyZ3VtZW50IGFuZCByZXR1cm5zIHRoZSBsYXN0IGNvbnRleHQgb2YgdGhhdCB0eXBlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBnZXRDb250ZXh0T3B0aW9ucyAtIE9wdGlvbnMgZm9yIGdldHRpbmcgY29udGV4dFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBnZXRDdXJyZW50Q29udGV4dChnZXRDdXJyZW50Q29udGV4dE9wdGlvbnMsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtYnJva2VyLWdldC1jdXJyZW50LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRTdGF0ZSA9IHRoaXMuZ2V0Q2xpZW50U3RhdGUoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIGlmICghY2xpZW50U3RhdGU/LmNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG11c3QgYmUgYSBtZW1iZXIgb2YgYSBjb250ZXh0IGdyb3VwIHRvIGNhbGwgZ2V0Q3VycmVudENvbnRleHQnKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgeyBjb250ZXh0R3JvdXBJZCB9ID0gY2xpZW50U3RhdGU7XG5cdCAgICAgICAgY29uc3QgY29udGV4dEdyb3VwU3RhdGUgPSB0aGlzLmNvbnRleHRHcm91cHNCeUlkLmdldChjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgY29uc3QgbGFzdENvbnRleHRUeXBlID0gdGhpcy5sYXN0Q29udGV4dE1hcC5nZXQoY29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRUeXBlID0gZ2V0Q3VycmVudENvbnRleHRPcHRpb25zPy5jb250ZXh0VHlwZSA/PyBsYXN0Q29udGV4dFR5cGU7XG5cdCAgICAgICAgcmV0dXJuIGNvbnRleHRHcm91cFN0YXRlICYmIGNvbnRleHRUeXBlID8gY29udGV4dEdyb3VwU3RhdGUuZ2V0KGNvbnRleHRUeXBlKSA6IHVuZGVmaW5lZDtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBQbGF0Zm9ybSBXaW5kb3cgQVBJc1xuXHQgICAgKi9cblx0ICAgIC8vIGpvaW5Db250ZXh0R3JvdXAgYW5kIGFkZENsaWVudFRvQ29udGV4dEdyb3VwIGFyZSBzZXBhcmF0ZSBmdW5jdGlvbnMgaGVyZSwgZm9yIGVhc2llciBvdmVycmlkZXMgYW5kIHNlcGFyYXRpb24gb2YgY29uY2VybnMuXG5cdCAgICAvLyBqb2luQ29udGV4dEdyb3VwIGNoZWNrcyBhbGwgY29ubmVjdGlvbnMgZm9yIG1hdGNoaW5nIGlkZW50aXRpZXMsIGluIGNhc2Ugd2UgaGF2ZSBtdWx0aXBsZSBjb25uZWN0aW9uIGZyb20gYW4gZW50aXR5LlxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFsbCBjb25uZWN0aW9ucyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgKG9yIGp1c3Qgb25lIGlmIGVuZHBvaW50SWQgcHJvdmlkZWQpIHRvIGNvbnRleHQgZ3JvdXAgYGNvbnRleHRHcm91cElkYC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IGFkZHMgdGhlIHNlbmRlciB0byB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqIGpvaW5Db250ZXh0R3JvdXAgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIGNvbm5lY3Rpb25zIGF0IHRoZSBpbmNvbWluZyBpZGVudGl0eS4gSXQgY2FsbHMge0BsaW5rIEludGVyb3BCcm9rZXIjYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAgSW50ZXJvcEJyb2tlci5hZGRDbGllbnRUb0NvbnRleHRHcm91cH0gdG8gYWN0dWFsbHkgZ3JvdXAgdGhlIGNsaWVudC5cblx0ICAgICAqIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gam9pbkNvbnRleHRHcm91cE9wdGlvbnMgLSBJZCBvZiB0aGUgQ29udGV4dCBHcm91cCBhbmQgaWRlbnRpdHkgb2YgdGhlIGVudGl0eSB0byBqb2luIHRvIHRoZSBncm91cC5cblx0ICAgICAqIEBwYXJhbSBzZW5kZXJJZGVudGl0eSAtIElkZW50aXR5IG9mIHRoZSBjbGllbnQgc2VuZGVyLlxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKHsgY29udGV4dEdyb3VwSWQsIHRhcmdldCB9LCBzZW5kZXJJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1qb2luLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBpZiAodGhpcy5zZXNzaW9uQ29udGV4dEdyb3VwTWFwLmhhcyhjb250ZXh0R3JvdXBJZCkpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5qb2luU2Vzc2lvbkNvbnRleHRHcm91cFdpdGhKb2luQ29udGV4dEdyb3VwKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKHRhcmdldCkge1xuXHQgICAgICAgICAgICAvLyBJZiBhbiBlbmRwb2ludElkIGlzIHByb3ZpZGVkLCB1c2UgdGhhdC4gVGhpcyB3aWxsIGxpa2VseSBiZSB1c2VkIGJ5IGV4dGVybmFsIGFkYXB0ZXJzLlxuXHQgICAgICAgICAgICBpZiAoSW50ZXJvcEJyb2tlci5oYXNFbmRwb2ludElkKHRhcmdldCkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAoeyBjb250ZXh0R3JvdXBJZCB9LCB0YXJnZXQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIC8vIFNhbml0eSBjaGVjayBoZXJlIGluIGNhc2UgYSBzaW5nbGUgYXBwIGhhcyBtdWx0aXBsZSBjb25uZWN0aW9uc1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgYWxsQ29ubmVjdGlvbnMgPSB0aGlzLmNoYW5uZWwuY29ubmVjdGlvbnMuZmlsdGVyKCh4KSA9PiB4LnV1aWQgPT09IHRhcmdldC51dWlkICYmIHgubmFtZSA9PT0gdGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgICAgICAgICAgaWYgKCFhbGxDb25uZWN0aW9ucy5sZW5ndGgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdpdmVuIElkZW50aXR5ICR7dGFyZ2V0LnV1aWR9ICR7dGFyZ2V0Lm5hbWV9IGlzIG5vdCBjb25uZWN0ZWQgdG8gdGhlIEludGVyb3AgQnJva2VyLmApO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgaWYgKGFsbENvbm5lY3Rpb25zLmxlbmd0aCA+IDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTaG91bGQgZmlndXJlIG91dCBob3cgd2Ugd2FudCB0byBoYW5kbGUgdGhpcyBzaXR1YXRpb24uIEluIHRoZSBtZWFudGltZSwganVzdCBjaGFuZ2UgY29udGV4dCBncm91cCBmb3IgYWxsIGNvbm5lY3Rpb25zLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgTW9yZSB0aGFuIG9uZSBjb25uZWN0aW9uIGZvdW5kIGZvciBpZGVudGl0eSAke3RhcmdldC51dWlkfSAke3RhcmdldC5uYW1lfWApO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblx0ICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBhbGxDb25uZWN0aW9ucykge1xuXHQgICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2godGhpcy5hZGRDbGllbnRUb0NvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0sIGNvbm5lY3Rpb24pKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIC8vIE5vIHRhcmdldCBwcm92aWRlZCwgYWRkIHRoZSBzZW5kZXIgdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAoeyBjb250ZXh0R3JvdXBJZCB9LCBzZW5kZXJJZGVudGl0eSk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gYWRkQ2xpZW50VG9Db250ZXh0R3JvdXAgZG9lcyB0aGUgYWN0dWFsIGFkZGl0aW9uIG9mIHRoZSBjbGllbnQgdG8gdGhlIENvbnRleHQgR3JvdXBcblx0ICAgIC8qKlxuXHQgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciB7QGxpbmsgSW50ZXJvcEJyb2tlciNqb2luQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIuam9pbkNvbnRleHRHcm91cH0uIERvZXMgdGhlIHdvcmsgb2YgYWN0dWFsbHkgYWRkaW5nIHRoZSBjbGllbnQgdG8gdGhlIENvbnRleHQgR3JvdXAuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGFkZENsaWVudFRvQ29udGV4dEdyb3VwT3B0aW9ucyAtIENvbnRhaW5zIHRoZSBjb250ZXh0R3JvdXBJZFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGFkZENsaWVudFRvQ29udGV4dEdyb3VwKHsgY29udGV4dEdyb3VwSWQgfSwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItYWRkLWNsaWVudC10by1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBpZiAoIWNsaWVudFN1YnNjcmlwdGlvblN0YXRlKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xpZW50IHdpdGggSWRlbnRpdHk6ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0gJHtjbGllbnRJZGVudGl0eS5uYW1lfSBub3QgaW4gQ2xpZW50IFN0YXRlIE1hcGApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoIXRoaXMuZ2V0Q29udGV4dEdyb3VwcygpLmZpbmQoKGNvbnRleHRHcm91cEluZm8pID0+IGNvbnRleHRHcm91cEluZm8uaWQgPT09IGNvbnRleHRHcm91cElkKSkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEF0dGVtcHRpbmcgdG8gam9pbiBhIGNvbnRleHQgZ3JvdXAgdGhhdCBkb2VzIG5vdCBleGlzdDogJHtjb250ZXh0R3JvdXBJZH0uIFlvdSBtYXkgb25seSBqb2luIGV4aXN0aW5nIGNvbnRleHQgZ3JvdXBzLmApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjb25zdCBvbGRDb250ZXh0R3JvdXBJZCA9IGNsaWVudFN1YnNjcmlwdGlvblN0YXRlLmNvbnRleHRHcm91cElkO1xuXHQgICAgICAgIGlmIChvbGRDb250ZXh0R3JvdXBJZCAhPT0gY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEdyb3VwSWQgPSBjb250ZXh0R3JvdXBJZDtcblx0ICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRDdXJyZW50Q29udGV4dEdyb3VwSW5DbGllbnRPcHRpb25zKGNsaWVudElkZW50aXR5LCBjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cE1hcCA9IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuZ2V0KGNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgZm9yIChjb25zdCBbLCBoYW5kbGVySW5mb10gb2YgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEhhbmRsZXJzKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRUeXBlLCBoYW5kbGVySWQgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBTZW5kIHRoaXMgc2luZ2xlIGhhbmRsZXIgYWxsIG9mIHRoZSBjb250ZXh0LCBiZWNhdXNlIGl0IGFjY2VwdHMgYWxsLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnRleHRHcm91cE1hcC5mb3JFYWNoKChjb250ZXh0LCBfKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBlbHNlIGlmIChjb250ZXh0R3JvdXBNYXAuaGFzKGNvbnRleHRUeXBlKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRleHRGb3JUeXBlID0gY29udGV4dEdyb3VwTWFwLmdldChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHRGb3JUeXBlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dEZvclR5cGUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIFJlbW92ZXMgdGhlIHRhcmdldCBmcm9tIGl0cyBjb250ZXh0IGdyb3VwLiBTaW1pbGFyIHN0cnVjdHVyZSB0byBqb2luQ29udGV4dEdyb3VwLlxuXHQgICAgLyoqXG5cdCAgICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgdGFyZ2V0IGZyb20gYSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogSWYgbm8gdGFyZ2V0IGlzIHNwZWNpZmllZCwgaXQgcmVtb3ZlcyB0aGUgc2VuZGVyIGZyb20gdGhlaXIgY29udGV4dCBncm91cC5cblx0ICAgICAqIHJlbW92ZUZyb21Db250ZXh0R3JvdXAgaXMgcmVzcG9uc2libGUgZm9yIGNoZWNraW5nIGNvbm5lY3Rpb25zIGF0IHRoZSBpbmNvbWluZyBpZGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBJdCBjYWxscyB7QGxpbmsgSW50ZXJvcEJyb2tlciNyZW1vdmVDbGllbnRGcm9tQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIucmVtb3ZlQ2xpZW50RnJvbUNvbnRleHRHcm91cH0gdG8gYWN0dWFsbHkgdW5ncm91cFxuXHQgICAgICogdGhlIGNsaWVudC4gVXNlZCBieSBQbGF0Zm9ybSBXaW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSByZW1vdmVGcm9tQ29udGV4dEdyb3VwT3B0aW9ucyAtIENvbnRhaW5zIHRoZSB0YXJnZXQgaWRlbnRpdHkgdG8gcmVtb3ZlLlxuXHQgICAgICogQHBhcmFtIHNlbmRlcklkZW50aXR5IC0gSWRlbnRpdHkgb2YgdGhlIGNsaWVudCBzZW5kZXIuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIHJlbW92ZUZyb21Db250ZXh0R3JvdXAoeyB0YXJnZXQgfSwgc2VuZGVySWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItcmVtb3ZlLWZyb20tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGlmICh0YXJnZXQpIHtcblx0ICAgICAgICAgICAgLy8gSWYgYW4gZW5kcG9pbnRJZCBpcyBwcm92aWRlZCwgdXNlIHRoYXQuIFRoaXMgd2lsbCBsaWtlbHkgYmUgdXNlZCBieSBleHRlcm5hbCBhZGFwdGVycy5cblx0ICAgICAgICAgICAgaWYgKEludGVyb3BCcm9rZXIuaGFzRW5kcG9pbnRJZCh0YXJnZXQpKSB7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAodGFyZ2V0KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2FuaXR5IGNoZWNrIGhlcmUgaW4gY2FzZSBhIHNpbmdsZSBhcHAgaGFzIG11bHRpcGxlIGNvbm5lY3Rpb25zXG5cdCAgICAgICAgICAgICAgICBjb25zdCBhbGxDb25uZWN0aW9ucyA9IHRoaXMuY2hhbm5lbC5jb25uZWN0aW9ucy5maWx0ZXIoKHgpID0+IHgudXVpZCA9PT0gdGFyZ2V0LnV1aWQgJiYgeC5uYW1lID09PSB0YXJnZXQubmFtZSk7XG5cdCAgICAgICAgICAgICAgICBpZiAoIWFsbENvbm5lY3Rpb25zLmxlbmd0aCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gY29ubmVjdGlvbiBmb3VuZCBmb3IgZ2l2ZW4gSWRlbnRpdHkgJHt0YXJnZXQudXVpZH0gJHt0YXJnZXQubmFtZX1gKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChhbGxDb25uZWN0aW9ucy5sZW5ndGggPiAxKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBNb3JlIHRoYW4gb25lIGNvbm5lY3Rpb24gZm91bmQgZm9yIGlkZW50aXR5ICR7dGFyZ2V0LnV1aWR9ICR7dGFyZ2V0Lm5hbWV9YCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuXHQgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGFsbENvbm5lY3Rpb25zKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaCh0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAoY29ubmVjdGlvbikpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgLy8gTm8gdGFyZ2V0IHByb3ZpZGVkLCByZW1vdmUgdGhlIHNlbmRlciBmcm9tIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAoc2VuZGVySWRlbnRpdHkpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIHJlbW92ZUNsaWVudEZyb21Db250ZXh0R3JvdXAgZG9lcyB0aGUgYWN0dWFsIHJlbW92ZSBvZiB0aGUgY2xpZW50IGZyb20gdGhlIENvbnRleHQgR3JvdXBcblx0ICAgIC8qKlxuXHQgICAgICogSGVscGVyIGZ1bmN0aW9uIGZvciB7QGxpbmsgSW50ZXJvcEJyb2tlciNyZW1vdmVGcm9tQ29udGV4dEdyb3VwIEludGVyb3BCcm9rZXIucmVtb3ZlRnJvbUNvbnRleHRHcm91cH0uIERvZXMgdGhlIHdvcmsgb2YgYWN0dWFsbHkgcmVtb3ZpbmcgdGhlIGNsaWVudCBmcm9tIHRoZSBDb250ZXh0IEdyb3VwLlxuXHQgICAgICogVXNlZCBieSBQbGF0Zm9ybSBXaW5kb3dzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7IENsaWVudElkZW50aXR5IH0gY2xpZW50SWRlbnRpdHkgLSBJZGVudGl0eSBvZiB0aGUgY2xpZW50IHNlbmRlci5cblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmVtb3ZlQ2xpZW50RnJvbUNvbnRleHRHcm91cChjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1yZW1vdmUtY2xpZW50LWZyb20tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGNsaWVudFN0YXRlLmNvbnRleHRHcm91cElkID0gdW5kZWZpbmVkO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBhd2FpdCB0aGlzLnNldEN1cnJlbnRDb250ZXh0R3JvdXBJbkNsaWVudE9wdGlvbnMoY2xpZW50SWRlbnRpdHksIG51bGwpO1xuXHQgICAgfVxuXHQgICAgLy8gVXNlZCBieSBwbGF0Zm9ybSB3aW5kb3dzIHRvIGtub3cgd2hhdCBjbGllbnQgZ3JvdXBzIHRoZSBwcm92aWRlciBoYXMgZGVjbGFyZWQuIEFsc28gdXNlZCBpbnRlcm5hbGx5IHRvIGFjY2VzcyBjb250ZXh0IGdyb3Vwcy4gT3ZlcnJpZGVhYmxlIHNvIHRoYXQgdGhlIHBsYXRmb3JtIGRldmVsb3BlciBjYW4gbW9kaWZ5IGl0LlxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBJbnRlcm9wLUJyb2tlci1kZWZpbmVkIGNvbnRleHQgZ3JvdXBzIGF2YWlsYWJsZSBmb3IgYW4gZW50aXR5IHRvIGpvaW4uIEJlY2F1c2UgdGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIHRoZSByZXN0IG9mIHRoZSBJbnRlcm9wIEJyb2tlciB0byBmZXRjaCB0aGUgQ29udGV4dCBHcm91cHMsIG92ZXJyaWRpbmcgdGhpcyBhbGxvd3MgeW91IHRvIGN1c3RvbWl6ZSB0aGUgQ29udGV4dCBHcm91cHMgZm9yIHRoZSBJbnRlcm9wIEJyb2tlci4gSG93ZXZlciwgd2UgcmVjb21tZW5kIGN1c3RvbWl6aW5nIHRoZSBjb250ZXh0IGdyb3VwcyB0aHJvdWdoIGNvbmZpZ3VyYXRpb24gaW5zdGVhZC5cblx0ICAgICAqIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBnZXRDb250ZXh0R3JvdXBzKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1nZXQtY29udGV4dC1ncm91cHMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvLyBDcmVhdGUgY29weSBmb3IgaW1tdXRhYmlsaXR5XG5cdCAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3VwcywgXCJmXCIpLm1hcCgoY29udGV4dEdyb3VwKSA9PiB7XG5cdCAgICAgICAgICAgIHJldHVybiB7IC4uLmNvbnRleHRHcm91cCB9O1xuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgLy8gVXNlZCB0byBieSBwbGF0Zm9ybSB3aW5kb3dzIHRvIGdldCBkaXNwbGF5IG1ldGFkYXRhIGZvciBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAvKipcblx0ICAgICAqIEdldHMgZGlzcGxheSBpbmZvIGZvciBhIGNvbnRleHQgZ3JvdXBcblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGdldEluZm9Gb3JDb250ZXh0R3JvdXBPcHRpb25zIC0gQ29udGFpbnMgY29udGV4dEdyb3VwSWQsIHRoZSBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBkaXNwbGF5IGluZm8gZm9yLlxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0pIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItZ2V0LWluZm8tZm9yLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gdGhpcy5nZXRDb250ZXh0R3JvdXBzKCkuZmluZCgoY29udGV4dEdyb3VwKSA9PiBjb250ZXh0R3JvdXAuaWQgPT09IGNvbnRleHRHcm91cElkKTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgYnkgcGxhdGZvcm0gd2luZG93cyB0byBnZXQgYWxsIGNsaWVudHMgZm9yIGEgY29udGV4dCBncm91cC5cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBhbGwgY2xpZW50cyBmb3IgYSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzICoqVGhpcyBpcyBwcmltYXJpbHkgdXNlZCBmb3IgcGxhdGZvcm0gd2luZG93cy4gVmlld3Mgd2l0aGluIGEgcGxhdGZvcm0gc2hvdWxkIG5vdCBoYXZlIHRvIHVzZSB0aGlzIEFQSS4qKlxuXHQgICAgICogUmV0dXJucyB0aGUgSW50ZXJvcC1Ccm9rZXItZGVmaW5lZCBjb250ZXh0IGdyb3VwcyBhdmFpbGFibGUgZm9yIGFuIGVudGl0eSB0byBqb2luLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBnZXRBbGxDbGllbnRzSW5Db250ZXh0R3JvdXBPcHRpb25zIC0gQ29udGFpbnMgY29udGV4dEdyb3VwSWQsIHRoZSBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBjbGllbnRzIGZvci5cblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCh7IGNvbnRleHRHcm91cElkIH0pIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItZ2V0LWFsbC1jbGllbnRzLWluLWNvbnRleHQtZ3JvdXAnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5Db250ZXh0R3JvdXAgPSBBcnJheS5mcm9tKHRoaXMuaW50ZXJvcENsaWVudHMudmFsdWVzKCkpXG5cdCAgICAgICAgICAgIC5maWx0ZXIoKGNvbm5lY3RlZENsaWVudCkgPT4gY29ubmVjdGVkQ2xpZW50LmNvbnRleHRHcm91cElkID09PSBjb250ZXh0R3JvdXBJZClcblx0ICAgICAgICAgICAgLm1hcCgoc3Vic2NyaXB0aW9uU3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvblN0YXRlLmNsaWVudElkZW50aXR5O1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBjbGllbnRzSW5Db250ZXh0R3JvdXA7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciBsYXVuY2hpbmcgb2YgYXBwbGljYXRpb25zIHRoYXQgY2FuIGhhbmRsZSBhIGdpdmVuIGludGVudCwgYW5kIGRlbGVnYXRpb24gb2YgaW50ZW50cyB0byB0aG9zZSBhcHBsaWNhdGlvbnMuXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gbWFrZSB0aGlzIGNhbGwgRkRDMy1Db21wbGlhbnQgaXQgd291bGQgbmVlZCB0byByZXR1cm4gYW4gSW50ZW50UmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogaW50ZXJmYWNlIEludGVudFJlc29sdXRpb24ge1xuXHQgICAgICogICBzb3VyY2U6IFRhcmdldEFwcDtcblx0ICAgICAqICAgLy8gZGVwcmVjYXRlZCwgbm90IGFzc2lnbmFibGUgZnJvbSBpbnRlbnQgbGlzdGVuZXJzXG5cdCAgICAgKiAgIGRhdGE/OiBvYmplY3Q7XG5cdCAgICAgKiAgIHZlcnNpb246IHN0cmluZztcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICpcblx0ICAgICAqIE1vcmUgaW5mb3JtYXRpb24gb24gdGhlIEludGVudFJlc29sdXRpb24gdHlwZSBjYW4gYmUgZm91bmQgaW4gdGhlIFtGREMzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL0ludGVudFJlc29sdXRpb24pLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgVGhlIGNvbWJpbmF0aW9uIG9mIGFuIGFjdGlvbiBhbmQgYSBjb250ZXh0IHRoYXQgaXMgcGFzc2VkIHRvIGFuIGFwcGxpY2F0aW9uIGZvciByZXNvbHV0aW9uLlxuXHQgICAgICogQHBhcmFtICBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIC8vIG92ZXJyaWRlIGNhbGwgc28gd2Ugc2V0IGludGVudCB0YXJnZXQgYW5kIGNyZWF0ZSB2aWV3IHRoYXQgd2lsbCBoYW5kbGUgaXRcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudChpbnRlbnQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBzdXBlci5zZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB7IHV1aWQ6ICdwbGF0Zm9ybS11dWlkJywgbmFtZTogJ2ludGVudC12aWV3JyB9KTtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyBuYW1lOiAnZm9vJywgdXVpZDogJ3BsYXRmb3JtLXV1aWQnIH0pO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRWaWV3ID0gYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh7IHVybDogJ2h0dHA6Ly9vcGVuZmluLmNvJywgbmFtZTogJ2ludGVudC12aWV3JyB9LCB3aW4uaWRlbnRpdHkpO1xuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIHJldHVybiBuZXcgT3ZlcnJpZGUoKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuXHQgICAgYXN5bmMgaGFuZGxlRmlyZWRJbnRlbnQoaW50ZW50LCBjbGllbnRJZGVudGl0eSAvLyBUT0RPKENPUkUtODExKTogcmVtb3ZlIGlubGluZSBpbnRlcnNlY3RlZCB0eXBlXG5cdCAgICApIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLnJhaXNlSW50ZW50JywgJ0ludGVyb3BCcm9rZXIuaGFuZGxlRmlyZWRJbnRlbnQnLCBjbGllbnRJZGVudGl0eSwgJ2ludGVyb3BDbGllbnQuZmlyZUludGVudCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG91bGQgYmUgY2FsbGVkIGluIHtAbGluayBJbnRlcm9wQnJva2VyI2hhbmRsZUZpcmVkSW50ZW50IEludGVyb3BCcm9rZXIuaGFuZGxlRmlyZWRJbnRlbnR9LlxuXHQgICAgICogV2hpbGUgaGFuZGxlRmlyZWRJbnRlbnQgaXMgcmVzcG9uc2libGUgZm9yIGxhdW5jaGluZyBhcHBsaWNhdGlvbnMsIHNldEludGVudFRhcmdldCBpcyB1c2VkIHRvIHRlbGwgdGhlIEludGVyb3BCcm9rZXIgd2hpY2ggYXBwbGljYXRpb24gc2hvdWxkIHJlY2VpdmUgdGhlIGludGVudCB3aGVuIGl0IGlzIHJlYWR5LlxuXHQgICAgICogQHBhcmFtIGludGVudCBUaGUgY29tYmluYXRpb24gb2YgYW4gYWN0aW9uIGFuZCBhIGNvbnRleHQgdGhhdCBpcyBwYXNzZWQgdG8gYW4gYXBwbGljYXRpb24gZm9yIHJlc29sdXRpb24uXG5cdCAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gSWRlbnRpdHkgb2YgdGhlIHRhcmdldCB0aGF0IHdpbGwgaGFuZGxlIHRoZSBpbnRlbnQuXG5cdCAgICAgKlxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB0YXJnZXQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItc2V0LWludGVudC10YXJnZXQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIHRoaXMgaXMgb25seSBmb3IgYXBpIGFuYWx5dGljcyBwdXJwb3Nlc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQodGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgIGNvbnN0IGhhbmRsZXJJZCA9IGBpbnRlbnQtaGFuZGxlci0ke2ludGVudC5uYW1lfWA7XG5cdCAgICAgICAgaWYgKCF0YXJnZXRJbmZvKSB7XG5cdCAgICAgICAgICAgIHRoaXMuaW50ZW50Q2xpZW50TWFwLnNldCh0YXJnZXQubmFtZSwgbmV3IE1hcCgpKTtcblx0ICAgICAgICAgICAgY29uc3QgbmV3SGFuZGxlckluZm9NYXAgPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQodGFyZ2V0Lm5hbWUpO1xuXHQgICAgICAgICAgICBpZiAobmV3SGFuZGxlckluZm9NYXApIHtcblx0ICAgICAgICAgICAgICAgIG5ld0hhbmRsZXJJbmZvTWFwLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogZmFsc2UsIHBlbmRpbmdJbnRlbnRzOiBbaW50ZW50XSB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgY29uc3QgaGFuZGxlckluZm8gPSB0YXJnZXRJbmZvLmdldChoYW5kbGVySWQpO1xuXHQgICAgICAgICAgICBpZiAoIWhhbmRsZXJJbmZvKSB7XG5cdCAgICAgICAgICAgICAgICB0YXJnZXRJbmZvLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogZmFsc2UsIHBlbmRpbmdJbnRlbnRzOiBbaW50ZW50XSB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJbmZvLnBlbmRpbmdJbnRlbnRzLnB1c2goaW50ZW50KTtcblx0ICAgICAgICAgICAgICAgIGlmIChoYW5kbGVySW5mby5jbGllbnRJZGVudGl0eSAmJiBoYW5kbGVySW5mby5pc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgcGVuZGluZ0ludGVudHMgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVudFRvU2VuZCA9IHBlbmRpbmdJbnRlbnRzW3BlbmRpbmdJbnRlbnRzLmxlbmd0aCAtIDFdO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmludm9rZUludGVudEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgaW50ZW50VG9TZW5kKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8ucGVuZGluZ0ludGVudHMgPSBbXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGludGVudCBoYW5kbGVyIGZvciBjbGllbnQgJHtjbGllbnRJZGVudGl0eS51dWlkfS8ke2NsaWVudElkZW50aXR5Lm5hbWV9LyR7Y2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZH1gKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8uaXNSZWFkeSA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJldHVybmluZyBpbmZvcm1hdGlvbiBvbiBhIHBhcnRpY3VsYXIgSW50ZW50LlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdoZW5ldmVyIEludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCBpcyBjYWxsZWQgdGhpcyBmdW5jdGlvbiB3aWxsIGZpcmUuIFRoZSBvcHRpb25zIGFyZ3VtZW50IGdpdmVzIHlvdVxuXHQgICAgICogYWNjZXNzIHRvIHRoZSBpbnRlbnQgbmFtZSBhbmQgYW55IG9wdGlvbmFsIGNvbnRleHQgdGhhdCB3YXMgcGFzc2VkIGFuZCBjbGllbnRJZGVudGl0eSBpcyB0aGUgaWRlbnRpdHkgb2YgdGhlIGNsaWVudFxuXHQgICAgICogdGhhdCBtYWRlIHRoZSBjYWxsLiBJZGVhbGx5IGhlcmUgeW91IHdvdWxkIGZldGNoIHRoZSBpbmZvIGZvciB0aGUgaW50ZW50IGFuZCByZXR1cm4gaXQgd2l0aCB0aGUgc2hhcGUgdGhhdCB0aGVcblx0ICAgICAqIEludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCBjYWxsIGlzIGV4cGVjdGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBBcHAgSW50ZW50OlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogTW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgQXBwSW50ZW50IHR5cGUgY2FuIGJlIGZvdW5kIGluIHRoZSBbRkRDMyBkb2N1bWVudGF0aW9uXShodHRwczovL2ZkYzMuZmlub3Mub3JnL2RvY3MvYXBpL3JlZi9BcHBJbnRlbnQpLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHkgSWRlbnRpdHkgb2YgdGhlIENsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdCAgICAgKiAgICAgaW50ZXJvcE92ZXJyaWRlOiBhc3luYyAoSW50ZXJvcEJyb2tlcikgPT4ge1xuXHQgICAgICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICogICAgICAgICAgICAgYXN5bmMgaGFuZGxlSW5mb0ZvckludGVudChvcHRpb25zLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIFlvdXIgY29kZSBnb2VzIGhlcmUuXG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBoYW5kbGVJbmZvRm9ySW50ZW50KG9wdGlvbnMsIGNsaWVudElkZW50aXR5IC8vIFRPRE8oQ09SRS04MTEpOiByZW1vdmUgaW5saW5lIGludGVyc2VjdGVkIHR5cGVcblx0ICAgICkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZmluZEludGVudCcsICdJbnRlcm9wQnJva2VyLmhhbmRsZUluZm9Gb3JJbnRlbnQnLCBjbGllbnRJZGVudGl0eSwgJ2ludGVyb3BDbGllbnQuZ2V0SW5mb0ZvckludGVudCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXNwb25zaWJsZSBmb3IgcmV0dXJuaW5nIGluZm9ybWF0aW9uIG9uIHdoaWNoIEludGVudHMgYXJlIG1lYW50IHRvIGhhbmRsZSBhIHNwZWNpZmljIENvbnRleHQuXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgUmVzcG9uc2libGUgZm9yIHJldHVybmluZyBpbmZvcm1hdGlvbiBvbiB3aGljaCBJbnRlbnRzIGFyZSBtZWFudCB0byBoYW5kbGUgYSBzcGVjaWZpYyBDb250ZXh0LiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKlxuXHQgICAgICogV2hlbmV2ZXIgSW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBpcyBjYWxsZWQgdGhpcyBmdW5jdGlvbiB3aWxsIGZpcmUuIFRoZSBjb250ZXh0IGFyZ3VtZW50IGdpdmVzIHlvdSBhY2Nlc3MgdG8gdGhlIGNvbnRleHQgdGhhdCB0aGUgY2xpZW50IHdhbnRzIGluZm9ybWF0aW9uIG9uIGFuZCBjbGllbnRJZGVudGl0eSBpcyB0aGUgaWRlbnRpdHkgb2YgdGhlIGNsaWVudCB0aGF0IG1hZGUgdGhlIGNhbGwuIElkZWFsbHkgaGVyZSB5b3Ugd291bGQgZmV0Y2ggdGhlIGluZm8gZm9yIGFueSBpbnRlbnQgdGhhdCBjYW4gaGFuZGxlIGFuZCByZXR1cm4gaXQgd2l0aCB0aGUgc2hhcGUgdGhhdCB0aGUgSW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBjYWxsIGlzIGV4cGVjdGluZy5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBhcnJheSBvZiBBcHBJbnRlbnRzOlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyBbe1xuXHQgICAgICogLy8gICAgIGludGVudDogeyBuYW1lOiBcIlN0YXJ0Q2FsbFwiLCBkaXNwbGF5TmFtZTogXCJDYWxsXCIgfSxcblx0ICAgICAqIC8vICAgICBhcHBzOiBbeyBuYW1lOiBcIlNreXBlXCIgfV1cblx0ICAgICAqIC8vIH0sXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfV07XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBNb3JlIGluZm9ybWF0aW9uIG9uIHRoZSBBcHBJbnRlbnQgdHlwZSBjYW4gYmUgZm91bmQgaW4gdGhlIFtGREMzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL0FwcEludGVudCkuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgRGF0YSBwYXNzZWQgYmV0d2VlbiBlbnRpdGllcyBhbmQgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IElkZW50aXR5IG9mIHRoZSBDbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgLy8gWW91ciBjb2RlIGdvZXMgaGVyZS5cblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKCk7XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICogfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIGNsaWVudElkZW50aXR5IC8vIFRPRE8oQ09SRS04MTEpOiByZW1vdmUgaW5saW5lIGludGVyc2VjdGVkIHR5cGVcblx0ICAgICkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZmluZEludGVudHNCeUNvbnRleHQnLCAnSW50ZXJvcEJyb2tlci5oYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcsIGNsaWVudElkZW50aXR5LCAnaW50ZXJvcENsaWVudC5nZXRJbmZvRm9ySW50ZW50c0J5Q29udGV4dCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBhbiBJbnRlbnQgYmFzZWQgb24gYSBzcGVjaWZpYyBDb250ZXh0LlxuXHQgICAgICogTXVzdCBiZSBvdmVycmlkZGVuLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFdoZW5ldmVyIEludGVyb3BDbGllbnQuZmlyZUludGVudEZvckNvbnRleHQgaXMgY2FsbGVkIHRoaXMgZnVuY3Rpb24gd2lsbCBmaXJlLiBUaGUgY29udGV4dEZvckludGVudCBhcmd1bWVudFxuXHQgICAgICogZ2l2ZXMgeW91IGFjY2VzcyB0byB0aGUgY29udGV4dCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgdG8gYW4gaW50ZW50LiBJdCBhbHNvIGNhbiBvcHRpb25hbGx5IGNvbnRhaW4gYW55IG1ldGFkYXRhIHJlbGV2YW50XG5cdCAgICAgKiB0byByZXNvbHZpbmcgaXQsIGxpa2UgYSBzcGVjaWZpYyBhcHAgdGhlIGNsaWVudCB3YW50cyB0aGUgY29udGV4dCB0byBiZSBoYW5kbGVkIGJ5LiBUaGUgY2xpZW50SWRlbnRpdHkgaXMgdGhlIGlkZW50aXR5XG5cdCAgICAgKiBvZiB0aGUgY2xpZW50IHRoYXQgbWFkZSB0aGUgY2FsbC5cblx0ICAgICAqXG5cdCAgICAgKiBUbyBtYWtlIHRoaXMgY2FsbCBGREMzLUNvbXBsaWFudCBpdCB3b3VsZCBuZWVkIHRvIHJldHVybiBhbiBJbnRlbnRSZXNvbHV0aW9uOlxuXHQgICAgICpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyB7XG5cdCAgICAgKiAvLyAgICAgaW50ZW50OiB7IG5hbWU6IFwiU3RhcnRDaGF0XCIsIGRpc3BsYXlOYW1lOiBcIkNoYXRcIiB9LFxuXHQgICAgICogLy8gICAgIGFwcHM6IFt7IG5hbWU6IFwiU2t5cGVcIiB9LCB7IG5hbWU6IFwiU3ltcGhvbnlcIiB9LCB7IG5hbWU6IFwiU2xhY2tcIiB9XVxuXHQgICAgICogLy8gfVxuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICogTW9yZSBpbmZvcm1hdGlvbiBvbiB0aGUgSW50ZW50UmVzb2x1dGlvbiB0eXBlIGNhbiBiZSBmb3VuZCBpbiB0aGUgW0ZEQzMgZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9mZGMzLmZpbm9zLm9yZy9kb2NzL2FwaS9yZWYvTWV0YWRhdGEjaW50ZW50cmVzb2x1dGlvbikuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRGb3JJbnRlbnQgRGF0YSBwYXNzZWQgYmV0d2VlbiBlbnRpdGllcyBhbmQgYXBwbGljYXRpb25zLlxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5IElkZW50aXR5IG9mIHRoZSBDbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGhhbmRsZUZpcmVkSW50ZW50Rm9yQ29udGV4dChjb250ZXh0Rm9ySW50ZW50LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICogICAgICAgICAgICAgICAgIC8vIFlvdXIgY29kZSBnb2VzIGhlcmUuXG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQoY29udGV4dEZvckludGVudCwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLnJhaXNlSW50ZW50Rm9yQ29udGV4dCcsICdJbnRlcm9wQnJva2VyLmhhbmRsZUZpcmVkSW50ZW50Rm9yQ29udGV4dCcsIGNsaWVudElkZW50aXR5LCAnaW50ZXJvcENsaWVudC5maXJlSW50ZW50Rm9yQ29udGV4dCcpO1xuXHQgICAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcblx0ICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnRGb3JDb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUHJvdmlkZXMgdGhlIGlkZW50aXR5IG9mIGFueSBJbnRlcm9wIENsaWVudCB0aGF0IGRpc2Nvbm5lY3RzIGZyb20gdGhlIEludGVyb3AgQnJva2VyLiBJdCBpcyBtZWFudCB0byBiZSBvdmVycmlkZW4uXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHlcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBjbGllbnREaXNjb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDbGllbnQgd2l0aCBpZGVudGl0eSAke3V1aWR9LyR7bmFtZX0gaGFzIGJlZW4gZGlzY29ubmVjdGVkYCk7XG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBjbGllbnREaXNjb25uZWN0ZWQoY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiBjaGFubmVsLm9uRGlzY29ubmVjdGlvbi5cblx0ICAgICAgICAvLyBJdCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIHRvIGluZm9ybSB3aGVuIGFuIEludGVyb3AgQ2xpZW50IGhhcyBiZWVuIGRpc2Nvbm5lY3RlZC5cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVzcG9uc2libGUgZm9yIHJlc29sdmluZyBhbiBmZGMzLm9wZW4gY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlbi5cblx0ICAgICAqIEBwYXJhbSBmZGMzT3Blbk9wdGlvbnMgZmRjMy5vcGVuIG9wdGlvbnNcblx0ICAgICAqIEBwYXJhbSBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGZkYzNIYW5kbGVPcGVuKHsgYXBwLCBjb250ZXh0IH0sIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3Qgd2FybmluZyA9ICgwLCB1dGlsc18xLmdlbmVyYXRlT3ZlcnJpZGVXYXJuaW5nKSgnZmRjMy5vcGVuJywgJ0ludGVyb3BCcm9rZXIuZmRjM0hhbmRsZU9wZW4nLCBjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcpO1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcih1dGlsc18xLkJST0tFUl9FUlJPUlMuZmRjM09wZW4pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIHRoZSBmZGMzLmZpbmRJbnN0YW5jZXMgY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlblxuXHQgICAgICogQHBhcmFtIGFwcCBBcHBJZGVudGlmaWVyIHRoYXQgd2FzIHBhc3NlZCB0byBmZGMzLmZpbmRJbnN0YW5jZXNcblx0ICAgICAqIEBwYXJhbSBjbGllbnRJZGVudGl0eSBJZGVudGl0eSBvZiB0aGUgQ2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cblx0ICAgICAqL1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGZkYzNIYW5kbGVGaW5kSW5zdGFuY2VzKGFwcCwgY2xpZW50SWRlbnRpdHkpIHtcblx0ICAgICAgICBjb25zdCB3YXJuaW5nID0gKDAsIHV0aWxzXzEuZ2VuZXJhdGVPdmVycmlkZVdhcm5pbmcpKCdmZGMzLm9wZW4nLCAnSW50ZXJvcEJyb2tlci5mZGMzSGFuZGxlRmluZEluc3RhbmNlcycsIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjb25zb2xlLndhcm4od2FybmluZyk7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5mZGMzRmluZEluc3RhbmNlcyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgdGhlIGZkYzMuZ2V0QXBwTWV0YWRhdGEgY2FsbC5cblx0ICAgICAqIE11c3QgYmUgb3ZlcnJpZGRlblxuXHQgICAgICogQHBhcmFtIGFwcCBBcHBJZGVudGlmaWVyIHRoYXQgd2FzIHBhc3NlZCB0byBmZGMzLmdldEFwcE1ldGFkYXRhXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHkgSWRlbnRpdHkgb2YgdGhlIENsaWVudCBtYWtpbmcgdGhlIHJlcXVlc3QuXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBmZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEoYXBwLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHdhcm5pbmcgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZU92ZXJyaWRlV2FybmluZykoJ2ZkYzMuZ2V0QXBwTWV0YWRhdGEnLCAnSW50ZXJvcEJyb2tlci5mZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEnLCBjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgY29uc29sZS53YXJuKHdhcm5pbmcpO1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcih1dGlsc18xLkJST0tFUl9FUlJPUlMuZmRjM0dldEFwcE1ldGFkYXRhKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIEludGVyb3AgQnJva2VyIHdoZW5ldmVyIGEgQ29udGV4dCBoYW5kbGVyIHdvdWxkIGZpcmUuXG5cdCAgICAgKiBGb3IgRkRDMyAyLjAgeW91IHdvdWxkIG5lZWQgdG8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBhbmQgYWRkIHRoZSBjb250ZXh0TWV0YWRhdGEgYXNcblx0ICAgICAqIHBhcnQgb2YgdGhlIENvbnRleHQgb2JqZWN0LiBUaGVuIHdvdWxkIHlvdSBuZWVkIHRvIGNhbGxcblx0ICAgICAqIHN1cGVyLmludm9rZUNvbnRleHRIYW5kbGVyIHBhc3NpbmcgaXQgdGhpcyBuZXcgQ29udGV4dCBvYmplY3QgYWxvbmcgd2l0aCB0aGUgY2xpZW50SWRlbnRpdHkgYW5kIGhhbmRsZXJJZFxuXHQgICAgICogQHBhcmFtIGNsaWVudElkZW50aXR5XG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlcklkXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLlBsYXRmb3JtLmluaXQoe1xuXHQgICAgICogICAgIGludGVyb3BPdmVycmlkZTogYXN5bmMgKEludGVyb3BCcm9rZXIpID0+IHtcblx0ICAgICAqICAgICAgICAgY2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBJbnRlcm9wQnJva2VyIHtcblx0ICAgICAqICAgICAgICAgICAgIGFzeW5jIGludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICByZXR1cm4gc3VwZXIuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAuLi5jb250ZXh0LFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICBjb250ZXh0TWV0YWRhdGE6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZToge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcElkOiAnb3BlbmZpbi1hcHAnLFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6ICczRDU0RDQ1NkQ5SFQwJ1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgKiAgICAgICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgcmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpIHtcblx0ICAgICAgICBjb25zdCBwcm92aWRlciA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIoKTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBhd2FpdCBwcm92aWRlci5kaXNwYXRjaChjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGNvbnRleHQgaGFuZGxlciAke2hhbmRsZXJJZH0gZm9yIGNvbnRleHQgdHlwZSAke2NvbnRleHQudHlwZX0gaW4gY2xpZW50ICR7Y2xpZW50SWRlbnRpdHkudXVpZH0vJHtjbGllbnRJZGVudGl0eS5uYW1lfS8ke2NsaWVudElkZW50aXR5LmVuZHBvaW50SWR9YCwgZXJyb3IpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIEludGVyb3AgQnJva2VyIHdoZW5ldmVyIGFuIEludGVudCBoYW5kbGVyIHdvdWxkIGZpcmUuXG5cdCAgICAgKiBGb3IgRkRDMyAyLjAgeW91IHdvdWxkIG5lZWQgdG8gb3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiBhbmQgYWRkIHRoZSBjb250ZXh0TWV0YWRhdGEgYXNcblx0ICAgICAqIHBhcnQgb2YgdGhlIENvbnRleHQgb2JqZWN0IGluc2lkZSB0aGUgSW50ZW50IG9iamVjdC4gVGhlbiB3b3VsZCB5b3UgbmVlZCB0byBjYWxsXG5cdCAgICAgKiBzdXBlci5pbnZva2VJbnRlbnRIYW5kbGVyIHBhc3NpbmcgaXQgdGhpcyBuZXcgSW50ZW50IG9iamVjdCBhbG9uZyB3aXRoIHRoZSBjbGllbnRJZGVudGl0eSBhbmQgaGFuZGxlcklkXG5cdCAgICAgKiBAcGFyYW0gQ2xpZW50SWRlbnRpdHlcblx0ICAgICAqIEBwYXJhbSBoYW5kbGVySWRcblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdCAgICAgKiAgICAgaW50ZXJvcE92ZXJyaWRlOiBhc3luYyAoSW50ZXJvcEJyb2tlcikgPT4ge1xuXHQgICAgICogICAgICAgICBjbGFzcyBPdmVycmlkZSBleHRlbmRzIEludGVyb3BCcm9rZXIge1xuXHQgICAgICogICAgICAgICAgICAgYXN5bmMgaW52b2tlSW50ZW50SGFuZGxlcihjbGllbnRJZGVudGl0eSwgaGFuZGxlcklkLCBjb250ZXh0KSB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgY29uc3QgeyBjb250ZXh0IH0gPSBpbnRlbnQ7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmludm9rZUludGVudEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwge1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAuLi5pbnRlbnQsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmNvbnRleHQsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0TWV0YWRhdGE6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwSWQ6ICdvcGVuZmluLWFwcCcsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6ICczRDU0RDQ1NkQ5SFQwJ1xuXHQgICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICogICAgICAgICAgICAgfVxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgICAgIHJldHVybiBuZXcgT3ZlcnJpZGUoKTtcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9KTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBpbnZva2VJbnRlbnRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudCkge1xuXHQgICAgICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgdGhpcy5nZXRQcm92aWRlcigpO1xuXHQgICAgICAgIGF3YWl0IHByb3ZpZGVyLmRpc3BhdGNoKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJlc3BvbnNpYmxlIGZvciByZXNvbHZpbmcgZmRjMy5nZXRJbmZvIGZvciBGREMzIDIuMFxuXHQgICAgICogV291bGQgbmVlZCB0byByZXR1cm4gdGhlIG9wdGlvbmFsRmVhdHVyZXMgYW5kIGFwcE1ldGFkYXRhIGZvciB0aGUge0BsaW5rIGh0dHBzOi8vZmRjMy5maW5vcy5vcmcvZG9jcy9hcGkvcmVmL01ldGFkYXRhI2ltcGxlbWVudGF0aW9ubWV0YWRhdGEgSW1wbGVtZW50YXRpb25NZXRhZGF0YX0uXG5cdCAgICAgKiBNdXN0IGJlIG92ZXJyaWRkZW4uXG5cdCAgICAgKiBAcGFyYW0gY2xpZW50SWRlbnRpdHlcblx0ICAgICAqXG5cdCAgICAgKi9cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG5cdCAgICBhc3luYyBmZGMzSGFuZGxlR2V0SW5mbyhwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IHsgZmRjM1ZlcnNpb24gfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgZmRjM1ZlcnNpb24sXG5cdCAgICAgICAgICAgIC4uLl9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BCcm9rZXJfZmRjM0luZm8sIFwiZlwiKSxcblx0ICAgICAgICAgICAgb3B0aW9uYWxGZWF0dXJlczoge1xuXHQgICAgICAgICAgICAgICAgT3JpZ2luYXRpbmdBcHBNZXRhZGF0YTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBVc2VyQ2hhbm5lbE1lbWJlcnNoaXBBUElzOiB0cnVlXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGFwcE1ldGFkYXRhOiB7XG5cdCAgICAgICAgICAgICAgICBhcHBJZDogJycsXG5cdCAgICAgICAgICAgICAgICBpbnN0YW5jZUlkOiAnJ1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhbiBhcnJheSBvZiBpbmZvIGZvciBlYWNoIEludGVyb3AgQ2xpZW50IGNvbm5lY3RlZCB0byB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKlxuXHQgICAgICogRkRDMyAyLjA6IFVzZSB0aGUgZW5kcG9pbnRJZCBpbiB0aGUgQ2xpZW50SW5mbyBhcyB0aGUgaW5zdGFuY2VJZCB3aGVuIGdlbmVyYXRpbmdcblx0ICAgICAqIGFuIEFwcElkZW50aWZpZXIuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgRkRDMyAyLjAgTm90ZTogV2hlbiBuZWVkaW5nIGFuIGluc3RhbmNlSWQgdG8gZ2VuZXJhdGUgYW4gQXBwSWRlbnRpZmllciB1c2UgdGhpcyBjYWxsIHRvXG5cdCAgICAgKiBnZXQgdGhlIGVuZHBvaW50SWQgYW5kIHVzZSBpdCBhcyB0aGUgaW5zdGFuY2VJZC4gSW4gdGhlIEV4YW1wbGUgYmVsb3cgd2Ugb3ZlcnJpZGUgaGFuZGxlRmlyZWRJbnRlbnRcblx0ICAgICAqIGFuZCB0aGVuIGNhbGwgc3VwZXIuZ2V0QWxsQ2xpZW50SW5mbyB0byBnZW5lcmF0ZSB0aGUgQXBwSWRlbnRpZmllciBmb3IgdGhlIEludGVudFJlc29sdXRpb24uXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogLy8gRkRDMyAyLjAgRXhhbXBsZTpcblx0ICAgICAqIGZpbi5QbGF0Zm9ybS5pbml0KHtcblx0ICAgICAqICAgICBpbnRlcm9wT3ZlcnJpZGU6IGFzeW5jIChJbnRlcm9wQnJva2VyLCAuLi5hcmdzKSA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNsYXNzIE92ZXJyaWRlIGV4dGVuZHMgSW50ZXJvcEJyb2tlciB7XG5cdCAgICAgKiAgICAgICAgICAgICBhc3luYyBoYW5kbGVGaXJlZEludGVudChpbnRlbnQpIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBzdXBlci5zZXRJbnRlbnRUYXJnZXQoaW50ZW50LCB7IHV1aWQ6ICdwbGF0Zm9ybS11dWlkJywgbmFtZTogJ2ludGVudC12aWV3JyB9KTtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBwbGF0Zm9ybSA9IGZpbi5QbGF0Zm9ybS5nZXRDdXJyZW50U3luYygpO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHdpbiA9IGZpbi5XaW5kb3cud3JhcFN5bmMoeyBuYW1lOiAnZm9vJywgdXVpZDogJ3BsYXRmb3JtLXV1aWQnIH0pO1xuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRWaWV3ID0gYXdhaXQgcGxhdGZvcm0uY3JlYXRlVmlldyh7IHVybDogJ2h0dHA6Ly9vcGVuZmluLmNvJywgbmFtZTogJ2ludGVudC12aWV3JyB9LCB3aW4uaWRlbnRpdHkpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBhbGxDbGllbnRJbmZvID0gYXdhaXQgc3VwZXIuZ2V0QWxsQ2xpZW50SW5mbygpO1xuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBpbmZvRm9yVGFyZ2V0ID0gYWxsQ2xpZW50SW5mby5maW5kKChjbGllbnRJbmZvKSA9PiB7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGllbnRJbmZvLnV1aWQgPT09ICdwbGF0Zm9ybS11dWlkJyAmJiBjbGllbnRJbmZvLm5hbWUgPT09ICdpbnRlbnQtdmlldyc7XG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgKlxuXHQgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgYXBwSWQ6ICdpbnRlbnQtdmlldycsXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQ6IGluZm9Gb3JUYXJnZXQuZW5kcG9pbnRJZFxuXHQgICAgICogICAgICAgICAgICAgICAgIH1cblx0ICAgICAqXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHtcblx0ICAgICAqICAgICAgICAgICAgICAgICAgICAgc291cmNlLFxuXHQgICAgICogICAgICAgICAgICAgICAgICAgICBpbnRlbnQ6IGludGVudC5uYW1lXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICAgICAgICAgIH1cblx0ICAgICAqICAgICAgICAgfVxuXHQgICAgICogICAgICAgICByZXR1cm4gbmV3IE92ZXJyaWRlKC4uLmFyZ3MpO1xuXHQgICAgICogICAgIH1cblx0ICAgICAqIH0pO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEFsbENsaWVudEluZm8oKSB7XG5cdCAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCB0aGlzLmdldFByb3ZpZGVyKCk7XG5cdCAgICAgICAgcmV0dXJuIHByb3ZpZGVyLmdldEFsbENsaWVudEluZm8oKTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBTbmFwc2hvdCBBUElzXG5cdCAgICAqL1xuXHQgICAgLy8gVXNlZCB0byBzYXZlIGludGVyb3AgYnJva2VyIHN0YXRlIGluIHNuYXBzaG90c1xuXHQgICAgZGVjb3JhdGVTbmFwc2hvdChzbmFwc2hvdCkge1xuXHQgICAgICAgIHJldHVybiB7IC4uLnNuYXBzaG90LCBpbnRlcm9wU25hcHNob3REZXRhaWxzOiB7IGNvbnRleHRHcm91cFN0YXRlczogdGhpcy5nZXRDb250ZXh0R3JvdXBTdGF0ZXMoKSB9IH07XG5cdCAgICB9XG5cdCAgICAvLyBVc2VkIHRvIHJlc3RvcmUgaW50ZXJvcCBicm9rZXIgc3RhdGUgaW4gc25hcHNob3RzLlxuXHQgICAgYXBwbHlTbmFwc2hvdChzbmFwc2hvdCwgb3B0aW9ucykge1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cFN0YXRlcyA9IHNuYXBzaG90Py5pbnRlcm9wU25hcHNob3REZXRhaWxzPy5jb250ZXh0R3JvdXBTdGF0ZXM7XG5cdCAgICAgICAgaWYgKGNvbnRleHRHcm91cFN0YXRlcykge1xuXHQgICAgICAgICAgICBpZiAoIW9wdGlvbnM/LmNsb3NlRXhpc3RpbmdXaW5kb3dzKSB7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUV4aXN0aW5nQ2xpZW50cyhjb250ZXh0R3JvdXBTdGF0ZXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMucmVoeWRyYXRlQ29udGV4dEdyb3VwU3RhdGVzKGNvbnRleHRHcm91cFN0YXRlcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgdXBkYXRlRXhpc3RpbmdDbGllbnRzKGNvbnRleHRHcm91cFN0YXRlcykge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudHMgPSB0aGlzLmludGVyb3BDbGllbnRzO1xuXHQgICAgICAgIGNsaWVudHMuZm9yRWFjaCgoc3ViU3RhdGUpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjbGllbnRJZGVudGl0eSwgY29udGV4dEdyb3VwSWQsIGNvbnRleHRIYW5kbGVycyB9ID0gc3ViU3RhdGU7XG5cdCAgICAgICAgICAgIGlmIChjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBDb250ZXh0cyA9IGNvbnRleHRHcm91cFN0YXRlc1tjb250ZXh0R3JvdXBJZF07XG5cdCAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFssIGNvbnRleHRdIG9mIE9iamVjdC5lbnRyaWVzKGdyb3VwQ29udGV4dHMpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzLmZvckVhY2goKGNvbnRleHRIYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9ID0gY29udGV4dEhhbmRsZXI7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJbnRlcm9wQnJva2VyLmlzQ29udGV4dFR5cGVDb21wYXRpYmxlKGNvbnRleHQudHlwZSwgY29udGV4dFR5cGUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludm9rZUNvbnRleHRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGNvbnRleHQpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgdG8gc3RvcmUgY29udGV4dCBncm91cCBzdGF0ZSBpbiBzbmFwc2hvdHNcblx0ICAgIGdldENvbnRleHRHcm91cFN0YXRlcygpIHtcblx0ICAgICAgICByZXR1cm4gSW50ZXJvcEJyb2tlci50b09iamVjdCh0aGlzLmNvbnRleHRHcm91cHNCeUlkKTtcblx0ICAgIH1cblx0ICAgIC8vIFVzZWQgdG8gcmVoeWRyYXRlIHRoZSBjb250ZXh0IHN0YXRlIGZyb20gYSBzbmFwc2hvdFxuXHQgICAgcmVoeWRyYXRlQ29udGV4dEdyb3VwU3RhdGVzKGluY29taW5nQ29udGV4dEdyb3VwU3RhdGVzKSB7XG5cdCAgICAgICAgY29uc3QgY29udGV4dEdyb3VwU3RhdGVzID0gT2JqZWN0LmVudHJpZXMoaW5jb21pbmdDb250ZXh0R3JvdXBTdGF0ZXMpO1xuXHQgICAgICAgIGZvciAoY29uc3QgW2NvbnRleHRHcm91cElkLCBjb250ZXh0c10gb2YgY29udGV4dEdyb3VwU3RhdGVzKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRPYmplY3RzID0gT2JqZWN0LmVudHJpZXMoY29udGV4dHMpO1xuXHQgICAgICAgICAgICBmb3IgKGNvbnN0IFtjb250ZXh0VHlwZSwgY29udGV4dF0gb2YgY29udGV4dE9iamVjdHMpIHtcblx0ICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHRHcm91cHNCeUlkLmhhcyhjb250ZXh0R3JvdXBJZCkpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Q29udGV4dEdyb3VwU3RhdGUgPSB0aGlzLmNvbnRleHRHcm91cHNCeUlkLmdldChjb250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgY3VycmVudENvbnRleHRHcm91cFN0YXRlLnNldChjb250ZXh0VHlwZSwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGxvZ2ljIHdpbGwgY2hhbmdlIHdoZW4gZHluYW1pYyBjb250ZXh0IGdyb3VwIGNyZWF0aW9uIGNvbWVzIGluLlxuXHQgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQXR0ZW1wdGluZyB0byBzZXQgYSBjb250ZXh0IGdyb3VwIHRoYXQgaXNuJ3QgaW4gdGhlIGNvbnRleHQgZ3JvdXAgbWFwcGluZy4gU2tpcHBpbmcgY29udGV4dCBncm91cCByZWh5ZHJhdGlvbiBmb3I6ICR7Y29udGV4dEdyb3VwSWR9YCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKlxuXHQgICAgSW50ZXJuYWwgQ29udGV4dCBIYW5kbGVyIEFQSXNcblx0ICAgICovXG5cdCAgICAvLyBVc2VkIHRvIGdpdmUgY29udGV4dCB0byBhIGNsaWVudCB0aGF0IGhhcyByZWdpc3RlcmVkIHRoZWlyIGNvbnRleHQgaGFuZGxlclxuXHQgICAgY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkKHsgY29udGV4dFR5cGUsIGhhbmRsZXJJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGhhbmRsZXJJbmZvID0geyBjb250ZXh0VHlwZSwgaGFuZGxlcklkIH07XG5cdCAgICAgICAgY29uc3QgY2xpZW50U3RhdGUgPSB0aGlzLmdldENsaWVudFN0YXRlKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICBjbGllbnRTdGF0ZT8uY29udGV4dEhhbmRsZXJzLnNldChoYW5kbGVySWQsIGhhbmRsZXJJbmZvKTtcblx0ICAgICAgICBpZiAoY2xpZW50U3RhdGUgJiYgY2xpZW50U3RhdGUuY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBjb250ZXh0R3JvdXBJZCB9ID0gY2xpZW50U3RhdGU7XG5cdCAgICAgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cE1hcCA9IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuZ2V0KGNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNlbmQgdGhpcyBzaW5nbGUgaGFuZGxlciBhbGwgb2YgdGhlIGNvbnRleHQsIGJlY2F1c2UgaXQgYWNjZXB0cyBhbGwuXG5cdCAgICAgICAgICAgICAgICBjb250ZXh0R3JvdXBNYXAuZm9yRWFjaCgoY29udGV4dCwgXykgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dCk7XG5cdCAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIGlmIChjb250ZXh0R3JvdXBNYXAuaGFzKGNvbnRleHRUeXBlKSkge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dEZvclR5cGUgPSBjb250ZXh0R3JvdXBNYXAuZ2V0KGNvbnRleHRUeXBlKTtcblx0ICAgICAgICAgICAgICAgIGlmIChjb250ZXh0Rm9yVHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMuaW52b2tlQ29udGV4dEhhbmRsZXIoY2xpZW50SWRlbnRpdHksIGhhbmRsZXJJZCwgY29udGV4dEZvclR5cGUpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGludGVudEhhbmRsZXJSZWdpc3RlcmVkKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSB7XG5cdCAgICAgICAgY29uc3QgeyBoYW5kbGVySWQgfSA9IHBheWxvYWQ7XG5cdCAgICAgICAgY29uc3QgY2xpZW50SW50ZW50SW5mbyA9IHRoaXMuaW50ZW50Q2xpZW50TWFwLmdldChjbGllbnRJZGVudGl0eS5uYW1lKTtcblx0ICAgICAgICBjb25zdCBoYW5kbGVySW5mbyA9IGNsaWVudEludGVudEluZm8/LmdldChoYW5kbGVySWQpO1xuXHQgICAgICAgIGlmICghY2xpZW50SW50ZW50SW5mbykge1xuXHQgICAgICAgICAgICB0aGlzLmludGVudENsaWVudE1hcC5zZXQoY2xpZW50SWRlbnRpdHkubmFtZSwgbmV3IE1hcCgpKTtcblx0ICAgICAgICAgICAgY29uc3QgbmV3SGFuZGxlckluZm9NYXAgPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQoY2xpZW50SWRlbnRpdHkubmFtZSk7XG5cdCAgICAgICAgICAgIGlmIChuZXdIYW5kbGVySW5mb01hcCkge1xuXHQgICAgICAgICAgICAgICAgbmV3SGFuZGxlckluZm9NYXAuc2V0KGhhbmRsZXJJZCwgeyBpc1JlYWR5OiB0cnVlLCBwZW5kaW5nSW50ZW50czogW10sIGNsaWVudElkZW50aXR5IH0pO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGVsc2UgaWYgKCFoYW5kbGVySW5mbykge1xuXHQgICAgICAgICAgICBjbGllbnRJbnRlbnRJbmZvLnNldChoYW5kbGVySWQsIHsgaXNSZWFkeTogdHJ1ZSwgcGVuZGluZ0ludGVudHM6IFtdLCBjbGllbnRJZGVudGl0eSB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgcGVuZGluZ0ludGVudHMgfSA9IGhhbmRsZXJJbmZvO1xuXHQgICAgICAgICAgICBoYW5kbGVySW5mby5jbGllbnRJZGVudGl0eSA9IGNsaWVudElkZW50aXR5O1xuXHQgICAgICAgICAgICBoYW5kbGVySW5mby5pc1JlYWR5ID0gdHJ1ZTtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGlmIChwZW5kaW5nSW50ZW50cy5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZW50VG9TZW5kID0gcGVuZGluZ0ludGVudHNbcGVuZGluZ0ludGVudHMubGVuZ3RoIC0gMV07XG5cdCAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5pbnZva2VJbnRlbnRIYW5kbGVyKGNsaWVudElkZW50aXR5LCBoYW5kbGVySWQsIGludGVudFRvU2VuZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFuZGxlckluZm8ucGVuZGluZ0ludGVudHMgPSBbXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGludm9raW5nIGludGVudCBoYW5kbGVyOiAke2hhbmRsZXJJZH0gZm9yIGNsaWVudCAke2NsaWVudElkZW50aXR5LnV1aWR9LyR7Y2xpZW50SWRlbnRpdHkubmFtZX0vJHtjbGllbnRJZGVudGl0eS5lbmRwb2ludElkfWApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLy8gVXNlZCB0byByZW1vdmUgYSBjb250ZXh0IGhhbmRsZXIgZm9yIGEgY2xpZW50XG5cdCAgICByZW1vdmVDb250ZXh0SGFuZGxlcih7IGhhbmRsZXJJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIGNvbnN0IGNsaWVudFN0YXRlID0gdGhpcy5nZXRDbGllbnRTdGF0ZShjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgaWYgKGNsaWVudFN0YXRlKSB7XG5cdCAgICAgICAgICAgIGNsaWVudFN0YXRlLmNvbnRleHRIYW5kbGVycy5kZWxldGUoaGFuZGxlcklkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICBoYW5kbGVKb2luU2Vzc2lvbkNvbnRleHRHcm91cCh7IHNlc3Npb25Db250ZXh0R3JvdXBJZCB9LCBjbGllbnRJZGVudGl0eSkge1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGlmICghc2Vzc2lvbkNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBqb2luIHNlc3Npb24gY29udGV4dCBncm91cDogbXVzdCBzcGVjaWZ5IGdyb3VwIGlkLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNvbnN0IHNlc3Npb25Db250ZXh0R3JvdXAgPSB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAuZ2V0KHNlc3Npb25Db250ZXh0R3JvdXBJZCk7XG5cdCAgICAgICAgICAgIGlmIChzZXNzaW9uQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICBzZXNzaW9uQ29udGV4dEdyb3VwLnJlZ2lzdGVyTmV3Q2xpZW50KGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb25Db250ZXh0R3JvdXBCcm9rZXIgPSBuZXcgU2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcl8xLmRlZmF1bHQodGhpcy5jaGFubmVsLCBzZXNzaW9uQ29udGV4dEdyb3VwSWQpO1xuXHQgICAgICAgICAgICAgICAgbmV3U2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlci5yZWdpc3Rlck5ld0NsaWVudChjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb25Db250ZXh0R3JvdXBNYXAuc2V0KHNlc3Npb25Db250ZXh0R3JvdXBJZCwgbmV3U2Vzc2lvbkNvbnRleHRHcm91cEJyb2tlcik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIHsgaGFzQ29uZmxpY3Q6IHRoaXMuY29udGV4dEdyb3Vwc0J5SWQuaGFzKHNlc3Npb25Db250ZXh0R3JvdXBJZCkgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLypcblx0ICAgIEludGVybmFsIFV0aWx0aWVzXG5cdCAgICAqL1xuXHQgICAgLy8gR2V0dGVyIGZvciBpbnRlcm9wIGluZm8gZm9yIGEgY2xpZW50LlxuXHQgICAgZ2V0Q2xpZW50U3RhdGUoaWQpIHtcblx0ICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm9wQ2xpZW50cy5nZXQoaWQuZW5kcG9pbnRJZCk7XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIGZvciBnZXRDb250ZXh0R3JvdXBTdGF0ZXMuIFNlcmlhbGl6ZXMgdGhlIGNvbnRleHRHcm91cFN0YXRlcyBvYmplY3Qgc28gd2UgY2FuIHN0b3JlIGl0LlxuXHQgICAgc3RhdGljIHRvT2JqZWN0KG1hcCkge1xuXHQgICAgICAgIGNvbnN0IG9iamVjdEZyb21NYXAgPSBPYmplY3QuZnJvbUVudHJpZXMobWFwKTtcblx0ICAgICAgICBjb25zdCBuZXdPYmplY3QgPSB7fTtcblx0ICAgICAgICBPYmplY3QuZW50cmllcyhvYmplY3RGcm9tTWFwKS5mb3JFYWNoKChbY29udGV4dEdyb3VwSWQsIGNvbnRleHRNYXBdKSA9PiB7XG5cdCAgICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHRPYmplY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoY29udGV4dE1hcCk7XG5cdCAgICAgICAgICAgIG5ld09iamVjdFtjb250ZXh0R3JvdXBJZF0gPSBuZXdDb250ZXh0T2JqZWN0O1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBuZXdPYmplY3Q7XG5cdCAgICB9XG5cdCAgICBzdGF0aWMgY2hlY2tDb250ZXh0SW50ZWdyaXR5KGNvbnRleHQpIHtcblx0ICAgICAgICBpZiAoIWNvbnRleHQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ05vIGNvbnRleHQgc3VwcGxpZWQnIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ0NvbnRleHQgbXVzdCBiZSBhbiBPYmplY3QnIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmICghY29udGV4dC50eXBlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCByZWFzb246ICdDb250ZXh0IG11c3QgaGF2ZSBhIHR5cGUgcHJvcGVydHknIH07XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0LmlkICYmIHR5cGVvZiBjb250ZXh0LmlkICE9PSAnb2JqZWN0Jykge1xuXHQgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgaXNWYWxpZDogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICByZWFzb246ICdDb250ZXh0IGlkIG11c3QgYmUgYW4gT2JqZWN0IHBvcHVsYXRlZCB3aXRoIGtleS12YWx1ZSBpZGVudGlmaWVycyAoaWYgc2V0KSdcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGNvbnRleHQuaWQpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBpZCB9ID0gY29udGV4dDtcblx0ICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGlkKTtcblx0ICAgICAgICAgICAgbGV0IGZvdW5kQmFkSWRlbnRpZmllciA9IGZhbHNlO1xuXHQgICAgICAgICAgICBpZiAoIWtleXMubGVuZ3RoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4geyBpc1ZhbGlkOiBmYWxzZSwgcmVhc29uOiAnQ29udGV4dCBpZCBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGtleS12YWx1ZSBpZGVudGlmaWVyJyB9O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGtleXMuZm9yRWFjaCgoa2V5KSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycgfHwgdHlwZW9mIGlkW2tleV0gIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgZm91bmRCYWRJZGVudGlmaWVyID0gdHJ1ZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIGlmIChmb3VuZEJhZElkZW50aWZpZXIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiB7IGlzVmFsaWQ6IGZhbHNlLCByZWFzb246ICdDb250ZXh0IGlkIGtleS12YWx1ZSBpZGVudGlmaWVycyBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nJyB9O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChjb250ZXh0Lm5hbWUgJiYgdHlwZW9mIGNvbnRleHQubmFtZSAhPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHsgaXNWYWxpZDogZmFsc2UsIHJlYXNvbjogJ0NvbnRleHQgbmFtZSBtdXN0IGJlIG9mIHN0cmluZyB0eXBlIChpZiBzZXQpJyB9O1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4geyBpc1ZhbGlkOiB0cnVlIH07XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIHRvIGNoZWNrIGEgY2xpZW50IGlkZW50aXR5LlxuXHQgICAgc3RhdGljIGhhc0VuZHBvaW50SWQodGFyZ2V0KSB7XG5cdCAgICAgICAgcmV0dXJuIHRhcmdldC5lbmRwb2ludElkICE9PSB1bmRlZmluZWQ7XG5cdCAgICB9XG5cdCAgICAvLyBVdGlsIHRvIGNoZWNrIGlmIHdlIHNob3VsZCBzZW5kIGEgY29udGV4dCB0byBhIGhhbmRsZXIuXG5cdCAgICBzdGF0aWMgaXNDb250ZXh0VHlwZUNvbXBhdGlibGUoY29udGV4dFR5cGUsIHJlZ2lzdGVyZWRDb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgcmVnaXN0ZXJlZENvbnRleHRUeXBlID09PSAndW5kZWZpbmVkJyB8fCBjb250ZXh0VHlwZSA9PT0gcmVnaXN0ZXJlZENvbnRleHRUeXBlO1xuXHQgICAgfVxuXHQgICAgLy8gU2V0dXAgZnVuY3Rpb24gZm9yIHN0YXRlIG1hcHBpbmdcblx0ICAgIHNldENvbnRleHRHcm91cE1hcCgpIHtcblx0ICAgICAgICAvLyBUaGlzIHdheSwgaWYgYSB1c2VyIG92ZXJyaWRlcyB0aGlzLmdldENvbnRleHRHcm91cHMsIGl0J3MgcmVmbGVjdGVkIGluIHRoZSBjb250ZXh0R3JvdXBNYXBwaW5nLlxuXHQgICAgICAgIGZvciAoY29uc3QgY29udGV4dEdyb3VwSW5mbyBvZiB0aGlzLmdldENvbnRleHRHcm91cHMoKSkge1xuXHQgICAgICAgICAgICB0aGlzLmNvbnRleHRHcm91cHNCeUlkLnNldChjb250ZXh0R3JvdXBJbmZvLmlkLCBuZXcgTWFwKCkpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIHNldEN1cnJlbnRDb250ZXh0R3JvdXBJbkNsaWVudE9wdGlvbnMoY2xpZW50SWRlbnRpdHksIGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3QgZW50aXR5SW5mbyA9IGF3YWl0IHRoaXMuZmluLlN5c3RlbS5nZXRFbnRpdHlJbmZvKGNsaWVudElkZW50aXR5LnV1aWQsIGNsaWVudElkZW50aXR5Lm5hbWUpO1xuXHQgICAgICAgICAgICBsZXQgZW50aXR5O1xuXHQgICAgICAgICAgICBpZiAoZW50aXR5SW5mby5lbnRpdHlUeXBlID09PSAndmlldycpIHtcblx0ICAgICAgICAgICAgICAgIGVudGl0eSA9IGF3YWl0IHRoaXMuZmluLlZpZXcud3JhcChjbGllbnRJZGVudGl0eSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgZWxzZSBpZiAoZW50aXR5SW5mby5lbnRpdHlUeXBlID09PSAnd2luZG93Jykge1xuXHQgICAgICAgICAgICAgICAgZW50aXR5ID0gYXdhaXQgdGhpcy5maW4uV2luZG93LndyYXAoY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChlbnRpdHkpIHtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IGVudGl0eS51cGRhdGVPcHRpb25zKHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnRlcm9wOiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDb250ZXh0R3JvdXA6IGNvbnRleHRHcm91cElkXG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIC8vICBNYXkgZmlsZSBpbiBpbnRlcm9wXG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgc2V0dXBDaGFubmVsUHJvdmlkZXIoKSB7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IGF3YWl0IHRoaXMuZ2V0UHJvdmlkZXIoKTtcblx0ICAgICAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDtcblx0ICAgICAgICAgICAgdGhpcy53aXJlQ2hhbm5lbChjaGFubmVsKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3Igc2V0dGluZyB1cCBJbnRlcm9wIEJyb2tlciBDaGFubmVsIFByb3ZpZGVyOiAke2Vycm9yfWApO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8vIFNldHVwIENoYW5uZWwgQ29ubmVjdGlvbiBMb2dpY1xuXHQgICAgd2lyZUNoYW5uZWwoY2hhbm5lbCkge1xuXHQgICAgICAgIGNoYW5uZWwub25Db25uZWN0aW9uKGFzeW5jIChjbGllbnRJZGVudGl0eSwgLy8gVE9ETyhDT1JFLTgxMSk6IHJlbW92ZSBpbmxpbmUgaW50ZXJzZWN0ZWQgdHlwZVxuXHQgICAgICAgIHBheWxvYWQpID0+IHtcblx0ICAgICAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5pc0Nvbm5lY3Rpb25BdXRob3JpemVkKGNsaWVudElkZW50aXR5LCBwYXlsb2FkKSkpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBub3QgYXV0aG9yaXplZCBmb3IgJHtjbGllbnRJZGVudGl0eS51dWlkfSwgJHtjbGllbnRJZGVudGl0eS5uYW1lfWApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmICghY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZXJzaW9uIHRvbyBvbGQgdG8gYmUgY29tcGF0aWJsZSB3aXRoIEludGVyb3AuIFBsZWFzZSB1cGdyYWRlIHlvdXIgcnVudGltZSB0byBhIG1vcmUgcmVjZW50IHZlcnNpb24uJyk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjb250ZXh0R3JvdXBJZDogdW5kZWZpbmVkLFxuXHQgICAgICAgICAgICAgICAgY29udGV4dEhhbmRsZXJzOiBuZXcgTWFwKCksXG5cdCAgICAgICAgICAgICAgICBjbGllbnRJZGVudGl0eVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICAvLyBPbmx5IGFsbG93IHRoZSBjbGllbnQgdG8gam9pbiBhIGNvbnRleHRHcm91cCB0aGF0IGFjdHVhbGx5IGV4aXN0cy5cblx0ICAgICAgICAgICAgaWYgKHBheWxvYWQ/LmN1cnJlbnRDb250ZXh0R3JvdXAgJiYgdGhpcy5jb250ZXh0R3JvdXBzQnlJZC5oYXMocGF5bG9hZC5jdXJyZW50Q29udGV4dEdyb3VwKSkge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50U3Vic2NyaXB0aW9uU3RhdGUuY29udGV4dEdyb3VwSWQgPSBwYXlsb2FkPy5jdXJyZW50Q29udGV4dEdyb3VwO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuaW50ZXJvcENsaWVudHMuc2V0KGNsaWVudElkZW50aXR5LmVuZHBvaW50SWQsIGNsaWVudFN1YnNjcmlwdGlvblN0YXRlKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjaGFubmVsLm9uRGlzY29ubmVjdGlvbigoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgdGhpcy5pbnRlcm9wQ2xpZW50cy5kZWxldGUoY2xpZW50SWRlbnRpdHkuZW5kcG9pbnRJZCk7XG5cdCAgICAgICAgICAgIGNvbnN0IHRhcmdldEluZm8gPSB0aGlzLmludGVudENsaWVudE1hcC5nZXQoY2xpZW50SWRlbnRpdHkubmFtZSk7XG5cdCAgICAgICAgICAgIGlmICh0YXJnZXRJbmZvICYmIGNsaWVudElkZW50aXR5LnV1aWQgPT09IHRoaXMuZmluLm1lLnV1aWQpIHtcblx0ICAgICAgICAgICAgICAgIHRhcmdldEluZm8uZm9yRWFjaCgoaGFuZGxlcikgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuaXNSZWFkeSA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGhpcy5zZXNzaW9uQ29udGV4dEdyb3VwTWFwLmZvckVhY2goKHNlc3Npb25Db250ZXh0R3JvdXApID0+IHtcblx0ICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXAub25EaXNjb25uZWN0aW9uKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIHRoaXMuY2xpZW50RGlzY29ubmVjdGVkKGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjaGFubmVsLmJlZm9yZUFjdGlvbihhc3luYyAoYWN0aW9uLCBwYXlsb2FkLCBjbGllbnRJZGVudGl0eSkgPT4ge1xuXHQgICAgICAgICAgICBpZiAoIShhd2FpdCB0aGlzLmlzQWN0aW9uQXV0aG9yaXplZChhY3Rpb24sIHBheWxvYWQsIGNsaWVudElkZW50aXR5KSkpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQWN0aW9uICgke2FjdGlvbn0pIG5vdCBhdXRob3JpemVkIGZvciAke2NsaWVudElkZW50aXR5LnV1aWR9LCAke2NsaWVudElkZW50aXR5Lm5hbWV9YCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9nZ2luZz8uYmVmb3JlQWN0aW9uPy5lbmFibGVkKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhhY3Rpb24sIHBheWxvYWQsIGNsaWVudElkZW50aXR5KTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNoYW5uZWwuYWZ0ZXJBY3Rpb24oKGFjdGlvbiwgcGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgaWYgKHRoaXMubG9nZ2luZz8uYWZ0ZXJBY3Rpb24/LmVuYWJsZWQpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGFjdGlvbiwgcGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy8gQ2xpZW50IGZ1bmN0aW9uc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ3NldENvbnRleHQnLCB0aGlzLnNldENvbnRleHQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZmlyZUludGVudCcsIHRoaXMuaGFuZGxlRmlyZWRJbnRlbnQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZ2V0Q3VycmVudENvbnRleHQnLCB0aGlzLmdldEN1cnJlbnRDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEluZm9Gb3JJbnRlbnQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZ2V0SW5mb0ZvckludGVudHNCeUNvbnRleHQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ZpcmVJbnRlbnRGb3JDb250ZXh0JywgdGhpcy5oYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gUGxhdGZvcm0gd2luZG93IGZ1bmN0aW9uc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldENvbnRleHRHcm91cHMnLCB0aGlzLmdldENvbnRleHRHcm91cHMuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3Rlcignam9pbkNvbnRleHRHcm91cCcsIHRoaXMuam9pbkNvbnRleHRHcm91cC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdyZW1vdmVGcm9tQ29udGV4dEdyb3VwJywgdGhpcy5yZW1vdmVGcm9tQ29udGV4dEdyb3VwLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCcsIHRoaXMuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldEluZm9Gb3JDb250ZXh0R3JvdXAnLCB0aGlzLmdldEluZm9Gb3JDb250ZXh0R3JvdXAuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gSW50ZXJuYWwgbWV0aG9kc1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2NvbnRleHRIYW5kbGVyUmVnaXN0ZXJlZCcsIHRoaXMuY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkLmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ludGVudEhhbmRsZXJSZWdpc3RlcmVkJywgdGhpcy5pbnRlbnRIYW5kbGVyUmVnaXN0ZXJlZC5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdyZW1vdmVDb250ZXh0SGFuZGxlcicsIHRoaXMucmVtb3ZlQ29udGV4dEhhbmRsZXIuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3Rlcignc2Vzc2lvbkNvbnRleHRHcm91cDpjcmVhdGVJZk5lZWRlZCcsIHRoaXMuaGFuZGxlSm9pblNlc3Npb25Db250ZXh0R3JvdXAuYmluZCh0aGlzKSk7XG5cdCAgICAgICAgLy8gZmRjMyBvbmx5IG1ldGhvZHNcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzT3BlbicsIHRoaXMuZmRjM0hhbmRsZU9wZW4uYmluZCh0aGlzKSk7XG5cdCAgICAgICAgY2hhbm5lbC5yZWdpc3RlcignZmRjM3YyRmluZEludGVudHNCeUNvbnRleHQnLCB0aGlzLmhhbmRsZUluZm9Gb3JJbnRlbnRzQnlDb250ZXh0LmJpbmQodGhpcykpO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2ZkYzNGaW5kSW5zdGFuY2VzJywgdGhpcy5mZGMzSGFuZGxlRmluZEluc3RhbmNlcy5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzR2V0QXBwTWV0YWRhdGEnLCB0aGlzLmZkYzNIYW5kbGVHZXRBcHBNZXRhZGF0YS5iaW5kKHRoaXMpKTtcblx0ICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdmZGMzdjJHZXRJbmZvJywgYXN5bmMgKHBheWxvYWQsIGNsaWVudElkZW50aXR5KSA9PiB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLmZkYzNIYW5kbGVHZXRJbmZvLmJpbmQodGhpcykocGF5bG9hZCwgY2xpZW50SWRlbnRpdHkpO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2NyZWF0ZVByaXZhdGVDaGFubmVsUHJvdmlkZXInLCBhc3luYyAocGF5bG9hZCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IGNoYW5uZWxJZCB9ID0gcGF5bG9hZDtcblx0ICAgICAgICAgICAgY29uc3QgY2hhbm5lbFByb3ZpZGVyID0gYXdhaXQgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShjaGFubmVsSWQpO1xuXHQgICAgICAgICAgICBQcml2YXRlQ2hhbm5lbFByb3ZpZGVyXzEuUHJpdmF0ZUNoYW5uZWxQcm92aWRlci5pbml0KGNoYW5uZWxQcm92aWRlciwgY2hhbm5lbElkKTtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQ2FuIGJlIHVzZWQgdG8gY29tcGxldGVseSBwcmV2ZW50IGEgY29ubmVjdGlvbi4gUmV0dXJuIGZhbHNlIHRvIHByZXZlbnQgY29ubmVjdGlvbnMuIEFsbG93cyBhbGwgY29ubmVjdGlvbnMgYnkgZGVmYXVsdC5cblx0ICAgICAqIEBwYXJhbSBfaWQgdGhlIGlkZW50aXR5IHRyeWluYyB0byBjb25uZWN0XG5cdCAgICAgKiBAcGFyYW0gX2Nvbm5lY3Rpb25QYXlsb2FkIG9wdGlvbmFsIHBheWxvYWQgdG8gdXNlIGluIGN1c3RvbSBpbXBsZW1lbnRhdGlvbnMsIHdpbGwgYmUgdW5kZWZpbmVkIGJ5IGRlZmF1bHRcblx0ICAgICAqL1xuXHQgICAgaXNDb25uZWN0aW9uQXV0aG9yaXplZChfaWQsIF9jb25uZWN0aW9uUGF5bG9hZCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWJyb2tlci1pcy1jb25uZWN0aW9uLWF1dGhvcml6ZWQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBDYWxsZWQgYmVmb3JlIGV2ZXJ5IGFjdGlvbiB0byBjaGVjayBpZiB0aGlzIGVudGl0eSBzaG91bGQgYmUgYWxsb3dlZCB0byB0YWtlIHRoZSBhY3Rpb24uXG5cdCAgICAgKiBSZXR1cm4gZmFsc2UgdG8gcHJldmVudCB0aGUgYWN0aW9uXG5cdCAgICAgKiBAcGFyYW0gX2FjdGlvbiB0aGUgc3RyaW5nIGFjdGlvbiB0byBhdXRob3JpemUgaW4gY2FtZWwgY2FzZVxuXHQgICAgICogQHBhcmFtIF9wYXlsb2FkIHRoZSBkYXRhIGJlaW5nIHNlbnQgZm9yIHRoaXMgYWN0aW9uXG5cdCAgICAgKiBAcGFyYW0gX2lkZW50aXR5IHRoZSBjb25uZWN0aW9uIGF0dGVtcHRpbmcgdG8gZGlzcGF0Y2ggdGhpcyBhY3Rpb25cblx0ICAgICAqL1xuXHQgICAgaXNBY3Rpb25BdXRob3JpemVkKF9hY3Rpb24sIF9wYXlsb2FkLCBfaWRlbnRpdHkpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1icm9rZXItaXMtYWN0aW9uLWF1dGhvcml6ZWQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuXHQgICAgfVxuXHR9O1xuXHRJbnRlcm9wQnJva2VyLkludGVyb3BCcm9rZXIgPSBJbnRlcm9wQnJva2VyJDE7XG5cdF9JbnRlcm9wQnJva2VyX2ZkYzNJbmZvID0gbmV3IFdlYWtNYXAoKSwgX0ludGVyb3BCcm9rZXJfY29udGV4dEdyb3VwcyA9IG5ldyBXZWFrTWFwKCksIF9JbnRlcm9wQnJva2VyX3Byb3ZpZGVyUHJvbWlzZSA9IG5ldyBXZWFrTWFwKCk7XG5cdHJldHVybiBJbnRlcm9wQnJva2VyO1xufVxuXG52YXIgSW50ZXJvcENsaWVudCA9IHt9O1xuXG52YXIgU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxID0ge307XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMiA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2U7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmNvbnN0IGJhc2VfMSQyID0gYmFzZTtcbmNvbnN0IHV0aWxzXzEkMiA9IHV0aWxzJDM7XG5jbGFzcyBTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50IGV4dGVuZHMgYmFzZV8xJDIuQmFzZSB7XG4gICAgY29uc3RydWN0b3Iod2lyZSwgY2xpZW50LCBpZCkge1xuICAgICAgICBzdXBlcih3aXJlKTtcbiAgICAgICAgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZS5zZXQodGhpcywgdm9pZCAwKTtcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDIodGhpcywgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSwgY2xpZW50LCBcImZcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgYSBjb250ZXh0IGZvciB0aGUgc2Vzc2lvbiBjb250ZXh0IGdyb3VwLlxuICAgICAqIEBwYXJhbSBjb250ZXh0IC0gTmV3IGNvbnRleHQgdG8gc2V0LlxuICAgICAqXG4gICAgICogQHR1dG9yaWFsIGludGVyb3Auc2V0Q29udGV4dFxuICAgICAqL1xuICAgIGFzeW5jIHNldENvbnRleHQoY29udGV4dCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1zZXNzaW9uLWNvbnRleHQtZ3JvdXAtc2V0LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDIodGhpcywgX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKGBzZXNzaW9uQ29udGV4dEdyb3VwOnNldENvbnRleHQtJHt0aGlzLmlkfWAsIHtcbiAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXBJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0KHR5cGUpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3Atc2Vzc2lvbi1jb250ZXh0LWdyb3VwLWdldC1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQyKHRoaXMsIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaChgc2Vzc2lvbkNvbnRleHRHcm91cDpnZXRDb250ZXh0LSR7dGhpcy5pZH1gLCB7XG4gICAgICAgICAgICBzZXNzaW9uQ29udGV4dEdyb3VwSWQ6IHRoaXMuaWQsXG4gICAgICAgICAgICB0eXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBhZGRDb250ZXh0SGFuZGxlcihjb250ZXh0SGFuZGxlciwgY29udGV4dFR5cGUpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3Atc2Vzc2lvbi1jb250ZXh0LWdyb3VwLWFkZC1oYW5kbGVyJykuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0SGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm9uLWZ1bmN0aW9uIGFyZ3VtZW50IHBhc3NlZCB0byB0aGUgZmlyc3QgcGFyYW1ldGVyICdoYW5kbGVyJy4gQmUgYXdhcmUgdGhhdCB0aGUgYXJndW1lbnQgb3JkZXIgZG9lcyBub3QgbWF0Y2ggdGhlIEZEQzMgc3RhbmRhcmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMih0aGlzLCBfU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG4gICAgICAgIGxldCBoYW5kbGVySWQ7XG4gICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYHNlc3Npb25Db250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfS0ke2NvbnRleHRUeXBlfS0keygwLCB1dGlsc18xJDIuZ2VuZXJhdGVJZCkoKX1gO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYHNlc3Npb25Db250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfWA7XG4gICAgICAgIH1cbiAgICAgICAgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgKDAsIHV0aWxzXzEkMi53cmFwQ29udGV4dEhhbmRsZXIpKGNvbnRleHRIYW5kbGVyLCBoYW5kbGVySWQpKTtcbiAgICAgICAgYXdhaXQgY2xpZW50LmRpc3BhdGNoKGBzZXNzaW9uQ29udGV4dEdyb3VwOmhhbmRsZXJBZGRlZC0ke3RoaXMuaWR9YCwgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0pO1xuICAgICAgICByZXR1cm4geyB1bnN1YnNjcmliZTogYXdhaXQgdGhpcy5jcmVhdGVVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICB9XG4gICAgYXN5bmMgY3JlYXRlVW5zdWJzY3JpYmVDYihoYW5kbGVySWQpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQyKHRoaXMsIF9TZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcbiAgICAgICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaChgc2Vzc2lvbkNvbnRleHRHcm91cDpoYW5kbGVyUmVtb3ZlZC0ke3RoaXMuaWR9YCwgeyBoYW5kbGVySWQgfSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGdldFVzZXJJbnN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICAgICAgc2V0Q29udGV4dDogKDAsIHV0aWxzXzEkMi53cmFwSW5UcnlDYXRjaCkodGhpcy5zZXRDb250ZXh0LmJpbmQodGhpcyksICdGYWlsZWQgdG8gc2V0IGNvbnRleHQ6ICcpLFxuICAgICAgICAgICAgZ2V0Q3VycmVudENvbnRleHQ6ICgwLCB1dGlsc18xJDIud3JhcEluVHJ5Q2F0Y2gpKHRoaXMuZ2V0Q3VycmVudENvbnRleHQuYmluZCh0aGlzKSwgJ0ZhaWxlZCB0byBnZXQgY29udGV4dDogJyksXG4gICAgICAgICAgICBhZGRDb250ZXh0SGFuZGxlcjogKDAsIHV0aWxzXzEkMi53cmFwSW5UcnlDYXRjaCkodGhpcy5hZGRDb250ZXh0SGFuZGxlci5iaW5kKHRoaXMpLCAnRmFpbGVkIHRvIGFkZCBjb250ZXh0IGhhbmRsZXI6ICcpXG4gICAgICAgIH07XG4gICAgfVxufVxuU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudCQxLmRlZmF1bHQgPSBTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50O1xuX1Nlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfY2xpZW50UHJvbWlzZSA9IG5ldyBXZWFrTWFwKCk7XG5cbnZhciBmZGMzMV8yID0ge307XG5cbnZhciBmZGMzQ29tbW9uID0ge307XG5cbnZhciB1dGlscyQyID0ge307XG5cbnZhciBQcml2YXRlQ2hhbm5lbENsaWVudCQxID0ge307XG5cbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jcmVhdGVCaW5kaW5nKSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XG4gICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuICAgIH1cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIG9bazJdID0gbVtrXTtcbn0pKTtcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xufSkgOiBmdW5jdGlvbihvLCB2KSB7XG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xufSk7XG52YXIgX19pbXBvcnRTdGFyID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0U3RhcikgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KFByaXZhdGVDaGFubmVsQ2xpZW50JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuUHJpdmF0ZUNoYW5uZWxDbGllbnQkMS5Qcml2YXRlQ2hhbm5lbENsaWVudCA9IHZvaWQgMDtcbmNvbnN0IHV0aWxzJDEgPSBfX2ltcG9ydFN0YXIodXRpbHMkMyk7XG5jbGFzcyBQcml2YXRlQ2hhbm5lbENsaWVudCB7XG4gICAgY29uc3RydWN0b3IoY2xpZW50LCBpZCkge1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgICAgICB0aGlzLmxpc3RlbmVycyA9IG5ldyBNYXAoKTtcbiAgICB9XG4gICAgYXN5bmMgYnJvYWRjYXN0KGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmRpc3BhdGNoKCdicm9hZGNhc3QnLCB7IGNvbnRleHQgfSk7XG4gICAgfVxuICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0KGNvbnRleHRUeXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5kaXNwYXRjaCgnZ2V0Q3VycmVudENvbnRleHQnLCB7IGNvbnRleHRUeXBlIH0pO1xuICAgIH1cbiAgICBhc3luYyBhZGRDb250ZXh0TGlzdGVuZXIoY29udGV4dFR5cGUsIGhhbmRsZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb24tZnVuY3Rpb24gYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBzZWNvbmQgcGFyYW1ldGVyICdoYW5kbGVyJy4gQmUgYXdhcmUgdGhhdCB0aGUgYXJndW1lbnQgb3JkZXIgZG9lcyBub3QgbWF0Y2ggdGhlIEZEQzMgc3RhbmRhcmQuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBoYW5kbGVySWQ7XG4gICAgICAgIGlmIChjb250ZXh0VHlwZSkge1xuICAgICAgICAgICAgaGFuZGxlcklkID0gYGNvbnRleHRIYW5kbGVyOmludm9rZS0ke3RoaXMuaWR9LSR7Y29udGV4dFR5cGV9LSR7dXRpbHMkMS5nZW5lcmF0ZUlkKCl9YDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhhbmRsZXJJZCA9IGBjb250ZXh0SGFuZGxlcjppbnZva2UtJHt0aGlzLmlkfS0ke3V0aWxzJDEuZ2VuZXJhdGVJZCgpfWA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGllbnQucmVnaXN0ZXIoaGFuZGxlcklkLCB1dGlscyQxLndyYXBDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBoYW5kbGVySWQpKTtcbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB7IHVuc3Vic2NyaWJlOiBhd2FpdCB0aGlzLmNyZWF0ZUNvbnRleHRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICBhd2FpdCB0aGlzLmNsaWVudC5kaXNwYXRjaChgY29udGV4dEhhbmRsZXJBZGRlZGAsIHsgaGFuZGxlcklkLCBjb250ZXh0VHlwZSB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuICAgIH1cbiAgICBjcmVhdGVOb25TdGFuZGFyZFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ25vblN0YW5kYXJkSGFuZGxlclJlbW92ZWQnLCB7IGhhbmRsZXJJZCB9KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgY3JlYXRlQ29udGV4dFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB7XG4gICAgICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5yZW1vdmUoaGFuZGxlcklkKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ2NvbnRleHRIYW5kbGVyUmVtb3ZlZCcsIHsgaGFuZGxlcklkIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBvbkFkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXJJZCA9IGBvbkNvbnRleHRIYW5kbGVyQWRkZWQ6aW52b2tlLSR7dGhpcy5pZH0tJHt1dGlscyQxLmdlbmVyYXRlSWQoKX1gO1xuICAgICAgICB0aGlzLmNsaWVudC5yZWdpc3RlcihoYW5kbGVySWQsIGhhbmRsZXIpO1xuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHsgdW5zdWJzY3JpYmU6IHRoaXMuY3JlYXRlTm9uU3RhbmRhcmRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICB0aGlzLmNsaWVudC5kaXNwYXRjaChgb25BZGRDb250ZXh0SGFuZGxlckFkZGVkYCwgeyBoYW5kbGVySWQgfSk7XG4gICAgICAgIHJldHVybiBsaXN0ZW5lcjtcbiAgICB9XG4gICAgb25EaXNjb25uZWN0KGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYG9uRGlzY29ubmVjdDppbnZva2UtJHt0aGlzLmlkfS0ke3V0aWxzJDEuZ2VuZXJhdGVJZCgpfWA7XG4gICAgICAgIHRoaXMuY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgaGFuZGxlcik7XG4gICAgICAgIGNvbnN0IGxpc3RlbmVyID0geyB1bnN1YnNjcmliZTogdGhpcy5jcmVhdGVOb25TdGFuZGFyZFVuc3Vic2NyaWJlQ2IoaGFuZGxlcklkKSB9O1xuICAgICAgICB0aGlzLmxpc3RlbmVycy5zZXQoaGFuZGxlcklkLCBsaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuY2xpZW50LmRpc3BhdGNoKGBvbkRpc2Nvbm5lY3RIYW5kbGVyQWRkZWRgLCB7IGhhbmRsZXJJZCB9KTtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuICAgIH1cbiAgICBvblVuc3Vic2NyaWJlKGhhbmRsZXIpIHtcbiAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYG9uVW5zdWJzY3JpYmU6aW52b2tlLSR7dGhpcy5pZH0tJHt1dGlscyQxLmdlbmVyYXRlSWQoKX1gO1xuICAgICAgICB0aGlzLmNsaWVudC5yZWdpc3RlcihoYW5kbGVySWQsIGhhbmRsZXIpO1xuICAgICAgICBjb25zdCBsaXN0ZW5lciA9IHsgdW5zdWJzY3JpYmU6IHRoaXMuY3JlYXRlTm9uU3RhbmRhcmRVbnN1YnNjcmliZUNiKGhhbmRsZXJJZCkgfTtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMuc2V0KGhhbmRsZXJJZCwgbGlzdGVuZXIpO1xuICAgICAgICB0aGlzLmNsaWVudC5kaXNwYXRjaChgb25VbnN1YnNjcmliZUhhbmRsZXJBZGRlZGAsIHsgaGFuZGxlcklkIH0pO1xuICAgICAgICByZXR1cm4gbGlzdGVuZXI7XG4gICAgfVxuICAgIGFzeW5jIGNsZWFuVXBBbGxTdWJzKCkge1xuICAgICAgICBjb25zdCBsaXN0ZW5lclVuc3Vic2NyaWJlcnMgPSBBcnJheS5mcm9tKHRoaXMubGlzdGVuZXJzLmtleXMoKSk7XG4gICAgICAgIGxpc3RlbmVyVW5zdWJzY3JpYmVycy5mb3JFYWNoKChoYW5kbGVySWQpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xpZW50LnJlbW92ZShoYW5kbGVySWQpO1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMuZGVsZXRlKGhhbmRsZXJJZCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBhc3luYyBkaXNjb25uZWN0KCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuZGlzcGF0Y2goJ2NsaWVudERpc2Nvbm5lY3RpbmcnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xlYW5VcEFsbFN1YnMoKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblByaXZhdGVDaGFubmVsQ2xpZW50JDEuUHJpdmF0ZUNoYW5uZWxDbGllbnQgPSBQcml2YXRlQ2hhbm5lbENsaWVudDtcblxuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdHZhciBfX2ltcG9ydERlZmF1bHQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19pbXBvcnREZWZhdWx0KSB8fCBmdW5jdGlvbiAobW9kKSB7XG5cdCAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFwiZGVmYXVsdFwiOiBtb2QgfTtcblx0fTtcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRleHBvcnRzLmdldEludGVudFJlc29sdXRpb24gPSBleHBvcnRzLmlzQ2hhbm5lbCA9IGV4cG9ydHMuaXNDb250ZXh0ID0gZXhwb3J0cy5jb25uZWN0UHJpdmF0ZUNoYW5uZWwgPSBleHBvcnRzLmJ1aWxkQXBwQ2hhbm5lbE9iamVjdCA9IGV4cG9ydHMuYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdCA9IGV4cG9ydHMuQ2hhbm5lbEVycm9yID0gZXhwb3J0cy5SZXN1bHRFcnJvciA9IGV4cG9ydHMuVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IgPSBleHBvcnRzLmdldFVuc3VwcG9ydGVkQ2hhbm5lbEFwaXMgPSB2b2lkIDA7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHRjb25zdCBQcml2YXRlQ2hhbm5lbENsaWVudF8xID0gUHJpdmF0ZUNoYW5uZWxDbGllbnQkMTtcblx0Y29uc3QgaXNFcXVhbF8xID0gX19pbXBvcnREZWZhdWx0KHJlcXVpcmUkJDMpO1xuXHRjb25zdCBnZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzID0gKGNoYW5uZWxUeXBlKSA9PiB7XG5cdCAgICByZXR1cm4ge1xuXHQgICAgICAgIGFkZENvbnRleHRMaXN0ZW5lcjogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IoJ0NoYW5uZWwuYWRkQ29udGV4dExpc3RlbmVyJywgY2hhbm5lbFR5cGUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgYnJvYWRjYXN0OiAoKSA9PiB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZENoYW5uZWxBcGlFcnJvcignQ2hhbm5lbC5icm9hZGNhc3QnLCBjaGFubmVsVHlwZSk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBnZXRDdXJyZW50Q29udGV4dDogKCkgPT4ge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IoJ0NoYW5uZWwuZ2V0Q3VycmVudENvbnRleHQnLCBjaGFubmVsVHlwZSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy5nZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzID0gZ2V0VW5zdXBwb3J0ZWRDaGFubmVsQXBpcztcblx0Y2xhc3MgVW5zdXBwb3J0ZWRDaGFubmVsQXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdCAgICBjb25zdHJ1Y3RvcihhcGlOYW1lLCBjaGFubmVsVHlwZSA9ICdTeXN0ZW0nKSB7XG5cdCAgICAgICAgc3VwZXIoYXBpTmFtZSk7XG5cdCAgICAgICAgdGhpcy5tZXNzYWdlID0gYENhbGxpbmcgJHthcGlOYW1lfSBvbiBhbiBpbnN0YW5jZSBvZiBhICR7Y2hhbm5lbFR5cGV9IENoYW5uZWwgcmV0dXJuZWQgYnkgZmRjMy5nZXQke2NoYW5uZWxUeXBlfUNoYW5uZWxzIGlzIG5vdCBzdXBwb3J0ZWQuIElmIHlvdSB3b3VsZCBsaWtlIHRvIHVzZSBhICR7Y2hhbm5lbFR5cGV9IENoYW5uZWwsIHBsZWFzZSB1c2UgZmRjMy5qb2luQ2hhbm5lbCwgZmRjMy5hZGRDb250ZXh0TGlzdGVuZXIsIGFuZCBmZGMzLmJyb2FkY2FzdCBpbnN0ZWFkLmA7XG5cdCAgICB9XG5cdH1cblx0ZXhwb3J0cy5VbnN1cHBvcnRlZENoYW5uZWxBcGlFcnJvciA9IFVuc3VwcG9ydGVkQ2hhbm5lbEFwaUVycm9yO1xuXHR2YXIgUmVzdWx0RXJyb3I7XG5cdChmdW5jdGlvbiAoUmVzdWx0RXJyb3IpIHtcblx0ICAgIC8qKiBSZXR1cm5lZCBpZiB0aGUgYEludGVudEhhbmRsZXJgIGV4aXRlZCB3aXRob3V0IHJldHVybmluZyBhIFByb21pc2Ugb3IgdGhhdFxuXHQgICAgICogIFByb21pc2Ugd2FzIG5vdCByZXNvbHZlZCB3aXRoIGEgQ29udGV4dCBvciBDaGFubmVsIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgUmVzdWx0RXJyb3JbXCJOb1Jlc3VsdFJldHVybmVkXCJdID0gXCJOb1Jlc3VsdFJldHVybmVkXCI7XG5cdCAgICAvKiogUmV0dXJuZWQgaWYgdGhlIGBJbnRlbnRIYW5kbGVyYCBmdW5jdGlvbiBwcm9jZXNzaW5nIHRoZSByYWlzZWQgaW50ZW50XG5cdCAgICAgKiAgdGhyb3dzIGFuIGVycm9yIG9yIHJlamVjdHMgdGhlIFByb21pc2UgaXQgcmV0dXJuZWQuXG5cdCAgICAgKi9cblx0ICAgIFJlc3VsdEVycm9yW1wiSW50ZW50SGFuZGxlclJlamVjdGVkXCJdID0gXCJJbnRlbnRIYW5kbGVyUmVqZWN0ZWRcIjtcblx0fSkoUmVzdWx0RXJyb3IgPSBleHBvcnRzLlJlc3VsdEVycm9yIHx8IChleHBvcnRzLlJlc3VsdEVycm9yID0ge30pKTtcblx0KGZ1bmN0aW9uIChDaGFubmVsRXJyb3IpIHtcblx0ICAgIC8qKiBSZXR1cm5lZCBpZiB0aGUgc3BlY2lmaWVkIGNoYW5uZWwgaXMgbm90IGZvdW5kIHdoZW4gYXR0ZW1wdGluZyB0byBqb2luIGFcblx0ICAgICAqICBjaGFubmVsIHZpYSB0aGUgYGpvaW5Vc2VyQ2hhbm5lbGAgZnVuY3Rpb24gb2YgdGhlIERlc2t0b3BBZ2VudCAoYGZkYzNgKS5cblx0ICAgICAqL1xuXHQgICAgQ2hhbm5lbEVycm9yW1wiTm9DaGFubmVsRm91bmRcIl0gPSBcIk5vQ2hhbm5lbEZvdW5kXCI7XG5cdCAgICAvKiogU0hPVUxEIGJlIHJldHVybmVkIHdoZW4gYSByZXF1ZXN0IHRvIGpvaW4gYSB1c2VyIGNoYW5uZWwgb3IgdG8gYSByZXRyaWV2ZVxuXHQgICAgICogIGEgQ2hhbm5lbCBvYmplY3QgdmlhIHRoZSBgam9pblVzZXJDaGFubmVsYCBvciBgZ2V0T3JDcmVhdGVDaGFubmVsYCBtZXRob2RzXG5cdCAgICAgKiAgb2YgdGhlIERlc2t0b3BBZ2VudCAoYGZkYzNgKSBvYmplY3QgaXMgZGVuaWVkLlxuXHQgICAgICovXG5cdCAgICBDaGFubmVsRXJyb3JbXCJBY2Nlc3NEZW5pZWRcIl0gPSBcIkFjY2Vzc0RlbmllZFwiO1xuXHQgICAgLyoqIFNIT1VMRCBiZSByZXR1cm5lZCB3aGVuIGEgY2hhbm5lbCBjYW5ub3QgYmUgY3JlYXRlZCBvciByZXRyaWV2ZWQgdmlhIHRoZVxuXHQgICAgICogIGBnZXRPckNyZWF0ZUNoYW5uZWxgIG1ldGhvZCBvZiB0aGUgRGVza3RvcEFnZW50IChgZmRjM2ApLlxuXHQgICAgICovXG5cdCAgICBDaGFubmVsRXJyb3JbXCJDcmVhdGlvbkZhaWxlZFwiXSA9IFwiQ3JlYXRpb25GYWlsZWRcIjtcblx0fSkoZXhwb3J0cy5DaGFubmVsRXJyb3IgfHwgKGV4cG9ydHMuQ2hhbm5lbEVycm9yID0ge30pKTtcblx0Y29uc3QgYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdCA9IChwcml2YXRlQ2hhbm5lbENsaWVudCkgPT4ge1xuXHQgICAgbGV0IGNsaWVudERpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuXHQgICAgY29uc3QgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCA9ICgpID0+IHtcblx0ICAgICAgICBpZiAoY2xpZW50RGlzY29ubmVjdGVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUHJpdmF0ZSBDaGFubmVsIENsaWVudCBoYXMgYmVlbiBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgUHJpdmF0ZSBDaGFubmVsJyk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgaWQ6IHByaXZhdGVDaGFubmVsQ2xpZW50LmlkLFxuXHQgICAgICAgIHR5cGU6ICdwcml2YXRlJyxcblx0ICAgICAgICBicm9hZGNhc3Q6IGFzeW5jIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50LmJyb2FkY2FzdChjb250ZXh0KTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGdldEN1cnJlbnRDb250ZXh0OiBhc3luYyAoY29udGV4dFR5cGUpID0+IHtcblx0ICAgICAgICAgICAgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCgpO1xuXHQgICAgICAgICAgICByZXR1cm4gcHJpdmF0ZUNoYW5uZWxDbGllbnQuZ2V0Q3VycmVudENvbnRleHQoY29udGV4dFR5cGUpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUT0RPIFtDT1JFLTE1MjRdXG5cdCAgICAgICAgYWRkQ29udGV4dExpc3RlbmVyOiBhc3luYyAoY29udGV4dFR5cGUsIGhhbmRsZXIpID0+IHtcblx0ICAgICAgICAgICAgY2hlY2tJZkNsaWVudERpc2Nvbm5lY3RlZCgpO1xuXHQgICAgICAgICAgICBsZXQgaGFuZGxlckluVXNlID0gaGFuZGxlcjtcblx0ICAgICAgICAgICAgbGV0IGNvbnRleHRUeXBlSW5Vc2UgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgICAgIGhhbmRsZXJJblVzZSA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICAgICAgY29udGV4dFR5cGVJblVzZSA9IG51bGw7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBwcml2YXRlQ2hhbm5lbENsaWVudC5hZGRDb250ZXh0TGlzdGVuZXIoY29udGV4dFR5cGVJblVzZSwgaGFuZGxlckluVXNlKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGxpc3RlbmVyO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgb25BZGRDb250ZXh0TGlzdGVuZXI6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uQWRkQ29udGV4dExpc3RlbmVyKGhhbmRsZXIpO1xuXHQgICAgICAgIH0sXG5cdCAgICAgICAgZGlzY29ubmVjdDogYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICBjaGVja0lmQ2xpZW50RGlzY29ubmVjdGVkKCk7XG5cdCAgICAgICAgICAgIGNsaWVudERpc2Nvbm5lY3RlZCA9IHRydWU7XG5cdCAgICAgICAgICAgIHJldHVybiBwcml2YXRlQ2hhbm5lbENsaWVudC5kaXNjb25uZWN0KCk7XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBvbkRpc2Nvbm5lY3Q6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uRGlzY29ubmVjdChoYW5kbGVyKTtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIG9uVW5zdWJzY3JpYmU6IChoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGNoZWNrSWZDbGllbnREaXNjb25uZWN0ZWQoKTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByaXZhdGVDaGFubmVsQ2xpZW50Lm9uVW5zdWJzY3JpYmUoaGFuZGxlcik7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblx0fTtcblx0ZXhwb3J0cy5idWlsZFByaXZhdGVDaGFubmVsT2JqZWN0ID0gYnVpbGRQcml2YXRlQ2hhbm5lbE9iamVjdDtcblx0Y29uc3QgYnVpbGRBcHBDaGFubmVsT2JqZWN0ID0gKHNlc3Npb25Db250ZXh0R3JvdXApID0+IHtcblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgaWQ6IHNlc3Npb25Db250ZXh0R3JvdXAuaWQsXG5cdCAgICAgICAgdHlwZTogJ2FwcCcsXG5cdCAgICAgICAgYnJvYWRjYXN0OiBzZXNzaW9uQ29udGV4dEdyb3VwLnNldENvbnRleHQsXG5cdCAgICAgICAgZ2V0Q3VycmVudENvbnRleHQ6IGFzeW5jIChjb250ZXh0VHlwZSkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgc2Vzc2lvbkNvbnRleHRHcm91cC5nZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgICAgIHJldHVybiBjb250ZXh0ID09PSB1bmRlZmluZWQgPyBudWxsIDogY29udGV4dDtcblx0ICAgICAgICB9LFxuXHQgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETyBbQ09SRS0xNTI0XVxuXHQgICAgICAgIGFkZENvbnRleHRMaXN0ZW5lcjogKGNvbnRleHRUeXBlLCBoYW5kbGVyKSA9PiB7XG5cdCAgICAgICAgICAgIGxldCByZWFsSGFuZGxlcjtcblx0ICAgICAgICAgICAgbGV0IHJlYWxUeXBlO1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2FkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGFkZENvbnRleHRMaXN0ZW5lcihudWxsLCBoYW5kbGVyKScpO1xuXHQgICAgICAgICAgICAgICAgcmVhbEhhbmRsZXIgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHJlYWxIYW5kbGVyID0gaGFuZGxlcjtcblx0ICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVhbFR5cGUgPSBjb250ZXh0VHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IChhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCBzZXNzaW9uQ29udGV4dEdyb3VwLmdldEN1cnJlbnRDb250ZXh0KHJlYWxUeXBlKTtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRIYW5kbGVyID0gKGNvbnRleHQsIGNvbnRleHRNZXRhZGF0YSkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKDAsIGlzRXF1YWxfMS5kZWZhdWx0KShjdXJyZW50Q29udGV4dCwgY29udGV4dCkpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVhbEhhbmRsZXIoY29udGV4dCwgY29udGV4dE1ldGFkYXRhKTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc2Vzc2lvbkNvbnRleHRHcm91cC5hZGRDb250ZXh0SGFuZGxlcih3cmFwcGVkSGFuZGxlciwgcmVhbFR5cGUpO1xuXHQgICAgICAgICAgICB9KSgpO1xuXHQgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgLi4ubGlzdGVuZXIsXG5cdCAgICAgICAgICAgICAgICB1bnN1YnNjcmliZTogKCkgPT4gbGlzdGVuZXIudGhlbigobCkgPT4gbC51bnN1YnNjcmliZSgpKVxuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cdH07XG5cdGV4cG9ydHMuYnVpbGRBcHBDaGFubmVsT2JqZWN0ID0gYnVpbGRBcHBDaGFubmVsT2JqZWN0O1xuXHRjb25zdCBjb25uZWN0UHJpdmF0ZUNoYW5uZWwgPSBhc3luYyAoY2hhbm5lbElkKSA9PiB7XG5cdCAgICB0cnkge1xuXHQgICAgICAgIGNvbnN0IGNoYW5uZWxDbGllbnQgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbElkKTtcblx0ICAgICAgICBjb25zdCBwcml2YXRlQ2hhbm5lbENsaWVudCA9IG5ldyBQcml2YXRlQ2hhbm5lbENsaWVudF8xLlByaXZhdGVDaGFubmVsQ2xpZW50KGNoYW5uZWxDbGllbnQsIGNoYW5uZWxJZCk7XG5cdCAgICAgICAgcmV0dXJuICgwLCBleHBvcnRzLmJ1aWxkUHJpdmF0ZUNoYW5uZWxPYmplY3QpKHByaXZhdGVDaGFubmVsQ2xpZW50KTtcblx0ICAgIH1cblx0ICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJpdmF0ZSBDaGFubmVsIHdpdGggaWQ6ICR7Y2hhbm5lbElkfSBkb2Vzbid0IGV4aXN0YCk7XG5cdCAgICB9XG5cdH07XG5cdGV4cG9ydHMuY29ubmVjdFByaXZhdGVDaGFubmVsID0gY29ubmVjdFByaXZhdGVDaGFubmVsO1xuXHRjb25zdCBpc0NvbnRleHQgPSAoY29udGV4dCkgPT4ge1xuXHQgICAgaWYgKGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiBjb250ZXh0KSB7XG5cdCAgICAgICAgY29uc3QgeyB0eXBlIH0gPSBjb250ZXh0O1xuXHQgICAgICAgIHJldHVybiB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZyc7XG5cdCAgICB9XG5cdCAgICByZXR1cm4gZmFsc2U7XG5cdH07XG5cdGV4cG9ydHMuaXNDb250ZXh0ID0gaXNDb250ZXh0O1xuXHRjb25zdCBpc0NoYW5uZWwgPSAoY2hhbm5lbCkgPT4ge1xuXHQgICAgaWYgKGNoYW5uZWwgJiYgdHlwZW9mIGNoYW5uZWwgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiBjaGFubmVsICYmICdpZCcgaW4gY2hhbm5lbCkge1xuXHQgICAgICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGNoYW5uZWw7XG5cdCAgICAgICAgcmV0dXJuIHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgaWQgPT09ICdzdHJpbmcnICYmICh0eXBlID09PSAnYXBwJyB8fCB0eXBlID09PSAncHJpdmF0ZScpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIGZhbHNlO1xuXHR9O1xuXHRleHBvcnRzLmlzQ2hhbm5lbCA9IGlzQ2hhbm5lbDtcblx0Y29uc3QgZ2V0SW50ZW50UmVzb2x1dGlvbiA9IGFzeW5jIChpbnRlcm9wTW9kdWxlLCBjb250ZXh0LCBhcHAsIGludGVudCkgPT4ge1xuXHQgICAgLy8gR2VuZXJhdGUgYW4gSUQgdG8gbWFrZSBhIHNlc3Npb24gY29udGV4dCBncm91cCB3aXRoLiBXZSB3aWxsIHBhc3MgdGhhdCBJRCB0byB0aGUgQnJva2VyLlxuXHQgICAgLy8gVGhlIGJyb2tlciB3aWxsIHRoZW4gc2V0Q29udGV4dCBvbiB0aGF0IHNlc3Npb24gY29udGV4dCBncm91cCBsYXRlciB3aXRoIG91ciBJbnRlbnQgUmVzdWx0LFxuXHQgICAgY29uc3QgZ3VpZCA9ICgwLCB1dGlsc18xLmdlbmVyYXRlSWQpKCk7IC8vIFRPRE8gbWFrZSB0aGlzIHVuZGVmaW5lZCBpbiB3ZWJcblx0ICAgIC8vIFByb21pc2Ugd2UnbGwgdXNlIGluIGdldFJlc3VsdFxuXHQgICAgY29uc3QgZ2V0UmVzdWx0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0ICAgICAgICBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5zdWJzY3JpYmUoeyB1dWlkOiAnKicgfSwgZ3VpZCwgKGludGVudFJlc3VsdCkgPT4ge1xuXHQgICAgICAgICAgICByZXNvbHZlKGludGVudFJlc3VsdCk7XG5cdCAgICAgICAgfSkuY2F0Y2goKCkgPT4gcmVqZWN0KG5ldyBFcnJvcignZ2V0UmVzdWx0IGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudCcpKSk7XG5cdCAgICB9KTtcblx0ICAgIC8vIEFkZGluZyB0aGUgaW50ZW50UmVzb2x1dGlvblJlc3VsdElkIHRvIHRoZSBpbnRlbnRPYmouIEJlY2F1c2UgZmlyZUludGVudCBvbmx5IGFjY2VwdHMgYSBzaW5nbGUgYXJnLCB3ZSBoYXZlIHRvIHNsYXAgaXQgaW4gaGVyZS5cblx0ICAgIGNvbnN0IG1ldGFkYXRhID0gYXBwID8geyB0YXJnZXQ6IGFwcCwgaW50ZW50UmVzb2x1dGlvblJlc3VsdElkOiBndWlkIH0gOiB7IGludGVudFJlc29sdXRpb25SZXN1bHRJZDogZ3VpZCB9O1xuXHQgICAgY29uc3QgaW50ZW50T2JqID0gaW50ZW50ID8geyBuYW1lOiBpbnRlbnQsIGNvbnRleHQsIG1ldGFkYXRhIH0gOiB7IC4uLmNvbnRleHQsIG1ldGFkYXRhIH07XG5cdCAgICAvLyBTZXQgdXAgdGhlIGdldFJlc3VsdCBjYWxsLlxuXHQgICAgY29uc3QgZ2V0UmVzdWx0ID0gYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgIGxldCBpbnRlbnRSZXN1bHQgPSBhd2FpdCBnZXRSZXN1bHRQcm9taXNlO1xuXHQgICAgICAgIGlmICghaW50ZW50UmVzdWx0IHx8IHR5cGVvZiBpbnRlbnRSZXN1bHQgIT09ICdvYmplY3QnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihSZXN1bHRFcnJvci5Ob1Jlc3VsdFJldHVybmVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgeyBlcnJvciB9ID0gaW50ZW50UmVzdWx0O1xuXHQgICAgICAgIGlmIChlcnJvcikge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoUmVzdWx0RXJyb3IuSW50ZW50SGFuZGxlclJlamVjdGVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCgwLCBleHBvcnRzLmlzQ2hhbm5lbCkoaW50ZW50UmVzdWx0KSkge1xuXHQgICAgICAgICAgICBjb25zdCB7IGlkLCB0eXBlIH0gPSBpbnRlbnRSZXN1bHQ7XG5cdCAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuXHQgICAgICAgICAgICAgICAgY2FzZSAncHJpdmF0ZSc6IHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnRlbnRSZXN1bHQgPSBhd2FpdCAoMCwgZXhwb3J0cy5jb25uZWN0UHJpdmF0ZUNoYW5uZWwpKGlkKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNhc2UgJ2FwcCc6IHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uQ29udGV4dEdyb3VwID0gYXdhaXQgaW50ZXJvcE1vZHVsZS5qb2luU2Vzc2lvbkNvbnRleHRHcm91cChpZCk7XG5cdCAgICAgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gKDAsIGV4cG9ydHMuYnVpbGRBcHBDaGFubmVsT2JqZWN0KShzZXNzaW9uQ29udGV4dEdyb3VwKTtcblx0ICAgICAgICAgICAgICAgICAgICBicmVhaztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIGlmICghKDAsIGV4cG9ydHMuaXNDb250ZXh0KShpbnRlbnRSZXN1bHQpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihSZXN1bHRFcnJvci5Ob1Jlc3VsdFJldHVybmVkKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGludGVudFJlc3VsdDtcblx0ICAgIH07XG5cdCAgICAvLyBGaW5hbGx5IGZpcmUgdGhlIGludGVudC5cblx0ICAgIGNvbnN0IGludGVudFJlc29sdXRpb25JbmZvRnJvbUJyb2tlciA9IGludGVudFxuXHQgICAgICAgID8gYXdhaXQgaW50ZXJvcE1vZHVsZS5maXJlSW50ZW50KGludGVudE9iailcblx0ICAgICAgICA6IGF3YWl0IGludGVyb3BNb2R1bGUuZmlyZUludGVudEZvckNvbnRleHQoaW50ZW50T2JqKTtcblx0ICAgIGlmICh0eXBlb2YgaW50ZW50UmVzb2x1dGlvbkluZm9Gcm9tQnJva2VyICE9PSAnb2JqZWN0Jykge1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHNvdXJjZToge1xuXHQgICAgICAgICAgICAgICAgYXBwSWQ6ICcnLFxuXHQgICAgICAgICAgICAgICAgaW5zdGFuY2VJZDogJydcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgaW50ZW50OiAnJyxcblx0ICAgICAgICAgICAgdmVyc2lvbjogJzIuMCcsXG5cdCAgICAgICAgICAgIGdldFJlc3VsdFxuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICByZXR1cm4geyAuLi5pbnRlbnRSZXNvbHV0aW9uSW5mb0Zyb21Ccm9rZXIsIGdldFJlc3VsdCB9O1xuXHR9O1xuXHRleHBvcnRzLmdldEludGVudFJlc29sdXRpb24gPSBnZXRJbnRlbnRSZXNvbHV0aW9uOyBcbn0gKHV0aWxzJDIpKTtcblxudmFyIGhhc1JlcXVpcmVkRmRjM0NvbW1vbjtcblxuZnVuY3Rpb24gcmVxdWlyZUZkYzNDb21tb24gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGZGMzQ29tbW9uKSByZXR1cm4gZmRjM0NvbW1vbjtcblx0aGFzUmVxdWlyZWRGZGMzQ29tbW9uID0gMTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xuXHR9O1xuXHR2YXIgX19jbGFzc1ByaXZhdGVGaWVsZFNldCA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcblx0ICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xuXHR9O1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdHZhciBfRkRDM01vZHVsZUJhc2VfcHJvZHVjZXI7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmZGMzQ29tbW9uLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0ZmRjM0NvbW1vbi5GREMzTW9kdWxlQmFzZSA9IHZvaWQgMDtcblx0Y29uc3QgdXRpbHNfMSA9IHV0aWxzJDI7XG5cdGNvbnN0IHV0aWxzXzIgPSB1dGlscyQzO1xuXHRjb25zdCBJbnRlcm9wQ2xpZW50XzEgPSByZXF1aXJlSW50ZXJvcENsaWVudCgpO1xuXHRjb25zdCBpc0VxdWFsXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMyk7XG5cdGNsYXNzIEZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIGdldCBjbGllbnQoKSB7XG5cdCAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLCBcImZcIikuY2FsbCh0aGlzKTtcblx0ICAgIH1cblx0ICAgIGdldCBmaW4oKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMud2lyZS5nZXRGaW4oKTtcblx0ICAgIH1cblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNvbnN0cnVjdG9yXG5cdCAgICBjb25zdHJ1Y3Rvcihwcm9kdWNlciwgd2lyZSkge1xuXHQgICAgICAgIHRoaXMud2lyZSA9IHdpcmU7XG5cdCAgICAgICAgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLnNldCh0aGlzLCB2b2lkIDApO1xuXHQgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX0ZEQzNNb2R1bGVCYXNlX3Byb2R1Y2VyLCBwcm9kdWNlciwgXCJmXCIpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBCcm9hZGNhc3RzIGEgY29udGV4dCBmb3IgdGhlIGNoYW5uZWwgb2YgdGhlIGN1cnJlbnQgZW50aXR5LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgLSBOZXcgY29udGV4dCB0byBzZXQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYnJvYWRjYXN0XG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGJyb2FkY2FzdChjb250ZXh0KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYnJvYWRjYXN0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LnNldENvbnRleHQoY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIExhdW5jaGVzIGFuIGFwcCB3aXRoIHRhcmdldCBpbmZvcm1hdGlvbiwgd2hpY2ggY2FuIGVpdGhlciBiZSBhIHN0cmluZyBvciBhbiBBcHBNZXRhZGF0YSBvYmplY3QuXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLm9wZW5cblx0ICAgICAqL1xuXHQgICAgYXN5bmMgX29wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtb3BlbicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCBJbnRlcm9wQ2xpZW50XzEuSW50ZXJvcENsaWVudC5mZXJyeUZkYzNDYWxsKHRoaXMuY2xpZW50LCAnZmRjM09wZW4nLCB7IGFwcCwgY29udGV4dCB9KTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGVycm9yVG9UaHJvdyA9IGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzIuQlJPS0VSX0VSUk9SUy5mZGMzT3BlbiA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIGFzeW5jIF9nZXRDaGFubmVscygpIHtcblx0ICAgICAgICBjb25zdCBjaGFubmVscyA9IGF3YWl0IHRoaXMuY2xpZW50LmdldENvbnRleHRHcm91cHMoKTtcblx0ICAgICAgICAvLyBmZGMzIGltcGxlbWVudGF0aW9uIG9mIGdldFN5c3RlbUNoYW5uZWxzIHJldHVybnMgYW4gYXJyYXkgb2YgY2hhbm5lbHMsIGhhdmUgdG8gZGVjb3JhdGUgb3ZlclxuXHQgICAgICAgIC8vIHRoaXMgc28gcGVvcGxlIGtub3cgdGhhdCB0aGVzZSBBUElzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdCAgICAgICAgcmV0dXJuIGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4geyAuLi5jaGFubmVsLCB0eXBlOiAnc3lzdGVtJywgLi4uKDAsIHV0aWxzXzEuZ2V0VW5zdXBwb3J0ZWRDaGFubmVsQXBpcykoKSB9O1xuXHQgICAgICAgIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIGEgQ2hhbm5lbCBvYmplY3QgZm9yIHRoZSBzcGVjaWZpZWQgY2hhbm5lbCwgY3JlYXRpbmcgaXQgYXMgYW4gQXBwIENoYW5uZWwgaWYgaXQgZG9lcyBub3QgZXhpc3QuXG5cdCAgICAgKiBAcGFyYW0gY2hhbm5lbElkXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZ2V0T3JDcmVhdGVDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldE9yQ3JlYXRlQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtb3ItY3JlYXRlLWNoYW5uZWwnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBzeXN0ZW1DaGFubmVscyA9IGF3YWl0IHRoaXMuX2dldENoYW5uZWxzKCk7XG5cdCAgICAgICAgY29uc3QgdXNlckNoYW5uZWwgPSBzeXN0ZW1DaGFubmVscy5maW5kKChjaGFubmVsKSA9PiBjaGFubmVsLmlkID09PSBjaGFubmVsSWQpO1xuXHQgICAgICAgIGlmICh1c2VyQ2hhbm5lbCkge1xuXHQgICAgICAgICAgICByZXR1cm4geyAuLi51c2VyQ2hhbm5lbCwgdHlwZTogJ3N5c3RlbScsIC4uLigwLCB1dGlsc18xLmdldFVuc3VwcG9ydGVkQ2hhbm5lbEFwaXMpKCkgfTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkNvbnRleHRHcm91cCA9IGF3YWl0IHRoaXMuY2xpZW50LmpvaW5TZXNzaW9uQ29udGV4dEdyb3VwKGNoYW5uZWxJZCk7XG5cdCAgICAgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMS5idWlsZEFwcENoYW5uZWxPYmplY3QpKHNlc3Npb25Db250ZXh0R3JvdXApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQ2hhbm5lbEVycm9yLkNyZWF0aW9uRmFpbGVkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIEludGVyb3AtQnJva2VyLWRlZmluZWQgY29udGV4dCBncm91cHMgYXZhaWxhYmxlIGZvciBhbiBlbnRpdHkgdG8gam9pbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRTeXN0ZW1DaGFubmVsc1xuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRTeXN0ZW1DaGFubmVscygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtc3lzdGVtLWNoYW5uZWxzJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxzKCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEpvaW4gYWxsIEludGVyb3AgQ2xpZW50cyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgdG8gY29udGV4dCBncm91cCBgY29udGV4dEdyb3VwSWRgLlxuXHQgICAgICogSWYgbm8gdGFyZ2V0IGlzIHNwZWNpZmllZCwgaXQgYWRkcyB0aGUgc2VuZGVyIHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogQmVjYXVzZSBtdWx0aXBsZSBDaGFubmVsIGNvbm5lY3Rpb25zL0ludGVyb3AgQ2xpZW50cyBjYW4gcG90ZW50aWFsbHkgZXhpc3QgYXQgYSBgdXVpZGAvYG5hbWVgIGNvbWJvLCB3ZSBjdXJyZW50bHkgam9pbiBhbGwgQ2hhbm5lbCBjb25uZWN0aW9ucy9JbnRlcm9wIENsaWVudHMgYXQgdGhlIGdpdmVuIGlkZW50aXR5IHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogSWYgYW4gYGVuZHBvaW50SWRgIGlzIHByb3ZpZGVkICh3aGljaCBpcyB1bmxpa2VseSwgdW5sZXNzIHRoZSBjYWxsIGlzIGNvbWluZyBmcm9tIGFuIGV4dGVybmFsIGFkYXB0ZXIpLCB0aGVuIHdlIG9ubHkgam9pbiB0aGF0IHNpbmdsZSBjb25uZWN0aW9uIHRvIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICogRm9yIGFsbCBpbnRlbnRzIGFuZCBwdXJwb3NlcywgdGhlcmUgd2lsbCBvbmx5IGJlIDEgY29ubmVjdGlvbiBwcmVzZW50IGluIFBsYXRmb3JtIGFuZCBCcm93c2VyIGltcGxlbWVudGF0aW9ucywgc28gdGhpcyBwb2ludCBpcyBtb3JlLW9yLWxlc3MgbW9vdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWQgLSBJZCBvZiB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5qb2luQ2hhbm5lbFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1qb2luLWNoYW5uZWwnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuam9pbkNvbnRleHRHcm91cChjaGFubmVsSWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzIuQlJPS0VSX0VSUk9SUy5qb2luU2Vzc2lvbkNvbnRleHRHcm91cFdpdGhKb2luQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdUaGUgQ2hhbm5lbCB5b3UgaGF2ZSB0cmllZCB0byBqb2luIGlzIGFuIEFwcCBDaGFubmVsLiBDdXN0b20gQ2hhbm5lbHMgY2FuIG9ubHkgYmUgZGVmaW5lZCBieSB0aGUgSW50ZXJvcCBCcm9rZXIgdGhyb3VnaCBjb2RlIG9yIG1hbmlmZXN0IGNvbmZpZ3VyYXRpb24uIFBsZWFzZSB1c2UgZ2V0T3JDcmVhdGVDaGFubmVsLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvci5tZXNzYWdlKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZS5zdGFydHNXaXRoKCdBdHRlbXB0aW5nIHRvIGpvaW4gYSBjb250ZXh0IGdyb3VwIHRoYXQgZG9lcyBub3QgZXhpc3QnKSkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHV0aWxzXzEuQ2hhbm5lbEVycm9yLk5vQ2hhbm5lbEZvdW5kKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodXRpbHNfMS5DaGFubmVsRXJyb3IuQWNjZXNzRGVuaWVkKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIENoYW5uZWwgdGhhdCB0aGUgZW50aXR5IGlzIHN1YnNjcmliZWQgdG8uIFJldHVybnMgbnVsbCBpZiBub3Qgam9pbmVkIHRvIGEgY2hhbm5lbC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRDdXJyZW50Q2hhbm5lbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRDdXJyZW50Q2hhbm5lbCgpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtY3VycmVudC1jaGFubmVsJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY3VycmVudENvbnRleHRHcm91cEluZm8gPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKCk7XG5cdCAgICAgICAgaWYgKCFjdXJyZW50Q29udGV4dEdyb3VwSW5mbykge1xuXHQgICAgICAgICAgICByZXR1cm4gbnVsbDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRDaGFubmVsT2JqZWN0KGN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHRhcmdldCBmcm9tIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IHJlbW92ZXMgdGhlIHNlbmRlciBmcm9tIHRoZWlyIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMubGVhdmVDdXJyZW50Q2hhbm5lbFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyBsZWF2ZUN1cnJlbnRDaGFubmVsKCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWxlYXZlLWN1cnJlbnQtY2hhbm5lbCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5yZW1vdmVGcm9tQ29udGV4dEdyb3VwKCk7XG5cdCAgICB9XG5cdCAgICAvLyB1dGlsc1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcblx0ICAgIGFzeW5jIGdldEN1cnJlbnRDb250ZXh0R3JvdXBJbmZvKCkge1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRHcm91cHMgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRDb250ZXh0R3JvdXBzKCk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50c0luQ3R4R3JvdXBzUHJvbWlzZSA9IGNvbnRleHRHcm91cHMubWFwKGFzeW5jIChjdHhHcm91cCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKGN0eEdyb3VwLmlkKTtcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnRzSW5DdHhHcm91cHMgPSBhd2FpdCBQcm9taXNlLmFsbChjbGllbnRzSW5DdHhHcm91cHNQcm9taXNlKTtcblx0ICAgICAgICBjb25zdCBjbGllbnRJZHggPSBjbGllbnRzSW5DdHhHcm91cHMuZmluZEluZGV4KChjbGllbnRJZGVudGl0eUFycikgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xpZW50SWRlbnRpdHlBcnIuc29tZSgoY2xpZW50SWRlbnRpdHkpID0+IHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gY2xpZW50SWRlbnRpdHk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53aXJlLm1lLnV1aWQgPT09IHV1aWQgJiYgdGhpcy53aXJlLm1lLm5hbWUgPT09IG5hbWU7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHJldHVybiBjb250ZXh0R3JvdXBzW2NsaWVudElkeF07XG5cdCAgICB9XG5cdCAgICBhc3luYyBidWlsZENoYW5uZWxPYmplY3QoY3VycmVudENvbnRleHRHcm91cEluZm8pIHtcblx0ICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLi4uY3VycmVudENvbnRleHRHcm91cEluZm8sXG5cdCAgICAgICAgICAgIHR5cGU6ICdzeXN0ZW0nLFxuXHQgICAgICAgICAgICBhZGRDb250ZXh0TGlzdGVuZXI6ICguLi5bY29udGV4dFR5cGUsIGhhbmRsZXJdKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBsZXQgcmVhbEhhbmRsZXI7XG5cdCAgICAgICAgICAgICAgICBsZXQgcmVhbFR5cGU7XG5cdCAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRleHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgICAgICAgICByZWFsSGFuZGxlciA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmVhbEhhbmRsZXIgPSBoYW5kbGVyO1xuXHQgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxUeXBlID0gY29udGV4dFR5cGU7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSAoYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCB0aGlzLmNsaWVudC5nZXRDdXJyZW50Q29udGV4dChyZWFsVHlwZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZEhhbmRsZXIgPSAoY29udGV4dCwgY29udGV4dE1ldGFkYXRhKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoMCwgaXNFcXVhbF8xLmRlZmF1bHQpKGN1cnJlbnRDb250ZXh0LCBjb250ZXh0KSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlYWxIYW5kbGVyKGNvbnRleHQsIGNvbnRleHRNZXRhZGF0YSk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIsIHJlYWxUeXBlKTtcblx0ICAgICAgICAgICAgICAgIH0pKCk7XG5cdCAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgICAgICAgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgICAgICAgICAgLi4ubGlzdGVuZXIsXG5cdCAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IGxpc3RlbmVyLnRoZW4oKGwpID0+IGwudW5zdWJzY3JpYmUoKSlcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGJyb2FkY2FzdDogdGhpcy5icm9hZGNhc3QuYmluZCh0aGlzKSxcblx0ICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUeXBlc2NyaXB0IGZhaWxzIHRvIGluZmVyIHRoZSByZXR1cm50eXBlIGlzIGEgUHJvbWlzZVxuXHQgICAgICAgICAgICBnZXRDdXJyZW50Q29udGV4dDogYXN5bmMgKGNvbnRleHRUeXBlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0Q3VycmVudENvbnRleHQoY29udGV4dFR5cGUpO1xuXHQgICAgICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBUeXBlc2NyaXB0IGZhaWxzIHRvIGluZmVyIHRoZSByZXR1cm50eXBlIGlzIGEgUHJvbWlzZVxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb250ZXh0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0fVxuXHRmZGMzQ29tbW9uLkZEQzNNb2R1bGVCYXNlID0gRkRDM01vZHVsZUJhc2U7XG5cdF9GREMzTW9kdWxlQmFzZV9wcm9kdWNlciA9IG5ldyBXZWFrTWFwKCk7XG5cdHJldHVybiBmZGMzQ29tbW9uO1xufVxuXG52YXIgaGFzUmVxdWlyZWRGZGMzMV8yO1xuXG5mdW5jdGlvbiByZXF1aXJlRmRjMzFfMiAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZkYzMxXzIpIHJldHVybiBmZGMzMV8yO1xuXHRoYXNSZXF1aXJlZEZkYzMxXzIgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZmRjMzFfMiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdGZkYzMxXzIuRmRjM01vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgdXRpbHNfMSA9IHV0aWxzJDM7XG5cdGNvbnN0IGZkYzNfY29tbW9uXzEgPSByZXF1aXJlRmRjM0NvbW1vbigpO1xuXHQvKipcblx0ICogQHZlcnNpb24gMS4yXG5cdCAqIFRoZSBGREMzIENsaWVudCBMaWJyYXJ5IHByb3ZpZGVzIGEgc2V0IEFQSXMgdG8gYmUgdXNlZCBmb3IgRkRDMyBjb21wbGlhbmNlLFxuXHQgKiB3aGlsZSB1c2luZyBvdXIgSW50ZXJvcCBBUEkgdW5kZXIgdGhlIGhvb2QuIEluIG9yZGVyIHRvIHVzZSB0aGlzIHNldCBvZiBBUElzXG5cdCAqIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHVwIHlvdXIgb3duIHtAbGluayBJbnRlcm9wQnJva2VyIEludGVyb3BCcm9rZXJ9IG9yIHVzZSBhIFBsYXRmb3JtIGFwcGxpY2F0aW9uLCB3aGljaCBkb2VzIHRoZSBzZXR1cCBmb3IgeW91LiBSZWZlciB0byBvdXIgZG9jdW1lbnRhdGlvbiBvblxuXHQgKiBvdXIge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL29mLWRvY3MvZG9jcy9lbmFibGUtY29sb3ItbGlua2luZyBJbnRlcm9wIEFQSX0uXG5cdCAqXG5cdCAqIFRvIGVuYWJsZSB0aGUgRkRDMyBBUElzIGluIGEge0BsaW5rIFdpbmRvdyBXaW5kb3d9IG9yIHtAbGluayBWaWV3IFZpZXd9LCBhZGQgdGhlIGZkYzNJbnRlcm9wQXBpXG5cdCAqIHByb3BlcnR5IHRvIGl0cyBvcHRpb25zOlxuXHQgKlxuXHQgKiBgYGBqc1xuXHQgKiB7XG5cdCAqICAgICBhdXRvU2hvdzogZmFsc2UsXG5cdCAqICAgICBzYXZlV2luZG93U3RhdGU6IHRydWUsXG5cdCAqICAgICB1cmw6ICdodHRwczovL29wZW5maW4uY28nLFxuXHQgKiAgICAgZmRjM0ludGVyb3BBcGk6ICcxLjInXG5cdCAqIH1cblx0ICogYGBgXG5cdCAqXG5cdCAqIElmIHVzaW5nIGEge0BsaW5rIFBsYXRmb3JtIFBsYXRmb3JtIH0gYXBwbGljYXRpb24sIHlvdSBjYW4gc2V0IHRoaXMgcHJvcGVydHkgaW4gZGVmYXVsdFdpbmRvd09wdGlvbnMgYW5kIGRlZmF1bHRWaWV3T3B0aW9ucy5cblx0ICpcblx0ICogSW4gb3JkZXIgdG8gZW5zdXJlIHRoYXQgdGhlIEZEQzMgQXBpIGlzIHJlYWR5IGJlZm9yZSB1c2UsIHlvdSBjYW4gdXNlIHRoZSAnZmRjM1JlYWR5JyBldmVudCBmaXJlZCBvbiB0aGUgRE9NIFdpbmRvdyBvYmplY3Q6XG5cdCAqXG5cdCAqIGBgYGpzXG5cdCAqIGZ1bmN0aW9uIGZkYzNBY3Rpb24oKSB7XG5cdCAqICAgICAvLyBNYWtlIHNvbWUgZmRjMyBBUEkgY2FsbHMgaGVyZVxuXHQgKiB9XG5cdCAqXG5cdCAqIGlmICh3aW5kb3cuZmRjMykge1xuXHQgKiAgICBmZGMzQWN0aW9uKCk7XG5cdCAqIH0gZWxzZSB7XG5cdCAqICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdmZGMzUmVhZHknLCBmZGMzQWN0aW9uKTtcblx0ICogfVxuXHQgKiBgYGBcblx0ICovXG5cdGNsYXNzIEZkYzNNb2R1bGUgZXh0ZW5kcyBmZGMzX2NvbW1vbl8xLkZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIGFzeW5jIG9wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgYXdhaXQgc3VwZXIuX29wZW4oYXBwLCBjb250ZXh0KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkIGEgY29udGV4dCBoYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LiBJZiBhbiBlbnRpdHkgaXMgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAsIGFuZCB0aGVuIHNldHMgaXRzIGNvbnRleHQgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuIElmIHlvdSB3aXNoIHRvIGxpc3RlbiBmb3IgYWxsIGluY29taW5nIGNvbnRleHRzLCBwYXNzIGBudWxsYCBmb3IgdGhlIGNvbnRleHRUeXBlIGFyZ3VtZW50LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlIC0gVGhlIHR5cGUgb2YgY29udGV4dCB5b3Ugd2lzaCB0byBoYW5kbGUuXG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlciAtIEhhbmRsZXIgZm9yIGluY29taW5nIGNvbnRleHQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYWRkQ29udGV4dExpc3RlbmVyXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKi9cblx0ICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVE9ETyBbQ09SRS0xNTI0XVxuXHQgICAgYWRkQ29udGV4dExpc3RlbmVyKGNvbnRleHRUeXBlLCBoYW5kbGVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYWRkLWNvbnRleHQtbGlzdGVuZXInKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBsZXQgbGlzdGVuZXI7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHQgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2FkZENvbnRleHRMaXN0ZW5lcihoYW5kbGVyKSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGFkZENvbnRleHRMaXN0ZW5lcihudWxsLCBoYW5kbGVyKScpO1xuXHQgICAgICAgICAgICBsaXN0ZW5lciA9IHRoaXMuY2xpZW50LmFkZENvbnRleHRIYW5kbGVyKGNvbnRleHRUeXBlKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIGxpc3RlbmVyID0gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlciwgY29udGV4dFR5cGUgPT09IG51bGwgPyB1bmRlZmluZWQgOiBjb250ZXh0VHlwZSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIC4uLmxpc3RlbmVyLFxuXHQgICAgICAgICAgICB1bnN1YnNjcmliZTogKCkgPT4gbGlzdGVuZXIudGhlbigobCkgPT4gbC51bnN1YnNjcmliZSgpKVxuXHQgICAgICAgIH07XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEFkZHMgYSBsaXN0ZW5lciBmb3IgaW5jb21pbmcgSW50ZW50cy5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgLSBOYW1lIG9mIHRoZSBJbnRlbnRcblx0ICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gSGFuZGxlciBmb3IgaW5jb21pbmcgSW50ZW50XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuYWRkSW50ZW50TGlzdGVuZXJcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqL1xuXHQgICAgYWRkSW50ZW50TGlzdGVuZXIoaW50ZW50LCBoYW5kbGVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtYWRkLWludGVudC1saXN0ZW5lcicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNvbnRleHRIYW5kbGVyID0gKHJhaXNlZEludGVudCkgPT4ge1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHQsIG1ldGFkYXRhOiBpbnRlbnRNZXRhZGF0YSB9ID0gcmFpc2VkSW50ZW50O1xuXHQgICAgICAgICAgICBjb25zdCB7IG1ldGFkYXRhIH0gPSBjb250ZXh0O1xuXHQgICAgICAgICAgICBjb25zdCBpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQgPSBpbnRlbnRNZXRhZGF0YT8uaW50ZW50UmVzb2x1dGlvblJlc3VsdElkIHx8IG1ldGFkYXRhPy5pbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQ7XG5cdCAgICAgICAgICAgIGlmIChpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMucHVibGlzaChpbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQsIG51bGwpLmNhdGNoKCgpID0+IG51bGwpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGhhbmRsZXIocmFpc2VkSW50ZW50LmNvbnRleHQpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgbGlzdGVuZXIgPSB0aGlzLmNsaWVudC5yZWdpc3RlckludGVudEhhbmRsZXIoY29udGV4dEhhbmRsZXIsIGludGVudCwge1xuXHQgICAgICAgICAgICBmZGMzVmVyc2lvbjogJzEuMidcblx0ICAgICAgICB9KTtcblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAuLi5saXN0ZW5lcixcblx0ICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IGxpc3RlbmVyLnRoZW4oKGwpID0+IGwudW5zdWJzY3JpYmUoKSlcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSYWlzZXMgYSBzcGVjaWZpYyBpbnRlbnQuXG5cdCAgICAgKiBAcGFyYW0gaW50ZW50IE5hbWUgb2YgdGhlIEludGVudC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0IENvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSBJbnRlbnQuXG5cdCAgICAgKiBAcGFyYW0gIGFwcCBBcHAgdGhhdCB3aWxsIHJlc29sdmUgdGhlIEludGVudC4gVGhpcyBpcyBhZGRlZCBhcyBtZXRhZGF0YSB0byB0aGUgSW50ZW50LiBDYW4gYmUgYWNjZXNzZWQgYnkgdGhlIGFwcCBwcm92aWRlciBpbiB7QGxpbmsgSW50ZXJvcEJyb2tlciNoYW5kbGVGaXJlZEludGVudCBJbnRlcm9wQnJva2VyLmhhbmRsZUZpcmVkSW50ZW50fS5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5yYWlzZUludGVudFxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICovXG5cdCAgICBhc3luYyByYWlzZUludGVudChpbnRlbnQsIGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGludGVudE9iaiA9IGFwcFxuXHQgICAgICAgICAgICA/IHsgbmFtZTogaW50ZW50LCBjb250ZXh0LCBtZXRhZGF0YTogeyB0YXJnZXQ6IGFwcCB9IH1cblx0ICAgICAgICAgICAgOiB7IG5hbWU6IGludGVudCwgY29udGV4dCB9O1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5maXJlSW50ZW50KGludGVudE9iaik7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmluZCBvdXQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBhIHBhcnRpY3VsYXIgaW50ZW50IGJ5IHBhc3NpbmcgaXRzIG5hbWUsIGFuZCBvcHRpb25hbGx5IGl0cyBjb250ZXh0LlxuXHQgICAgICogQHBhcmFtIGludGVudCBOYW1lIG9mIHRoZSBJbnRlbnRcblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZmluZEludGVudFxuXHQgICAgICovXG5cdCAgICBhc3luYyBmaW5kSW50ZW50KGludGVudCwgY29udGV4dCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWZpbmQtaW50ZW50JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmdldEluZm9Gb3JJbnRlbnQoeyBuYW1lOiBpbnRlbnQsIGNvbnRleHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZ2V0SW5mb0ZvckludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogRmluZCBhbGwgdGhlIGF2YWlsYWJsZSBpbnRlbnRzIGZvciBhIHBhcnRpY3VsYXIgY29udGV4dC5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0XG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuZmluZEludGVudHNCeUNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZmluZEludGVudHNCeUNvbnRleHQoY29udGV4dCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWZpbmQtaW50ZW50cy1ieS1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0ID8gJ1Jlc29sdmVyVW5hdmFpbGFibGUnIDogZXJyb3IubWVzc2FnZTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yVG9UaHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBGaW5kcyBhbmQgcmFpc2VzIGFuIGludGVudCBhZ2FpbnN0IGEgdGFyZ2V0IGFwcCBiYXNlZCBwdXJlbHkgb24gY29udGV4dCBkYXRhLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRcblx0ICAgICAqIEBwYXJhbSBhcHBcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5yYWlzZUludGVudEZvckNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmFpc2VJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudC1mb3ItY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5maXJlSW50ZW50Rm9yQ29udGV4dCh7IC4uLmNvbnRleHQsIG1ldGFkYXRhOiB7IHRhcmdldDogYXBwIH0gfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudEZvckNvbnRleHQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBDaGFubmVsIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFubmVsLCBjcmVhdGluZyBpdCBhcyBhbiBBcHAgQ2hhbm5lbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRPckNyZWF0ZUNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0T3JDcmVhdGVDaGFubmVsKGNoYW5uZWxJZCkge1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRPckNyZWF0ZUNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBtZXRhZGF0YSByZWxhdGluZyB0byB0aGUgRkRDMyBvYmplY3QgYW5kIGl0cyBwcm92aWRlciwgaW5jbHVkaW5nIHRoZSBzdXBwb3J0ZWQgdmVyc2lvbiBvZiB0aGUgRkRDMyBzcGVjaWZpY2F0aW9uIGFuZCB0aGUgbmFtZSBvZiB0aGUgcHJvdmlkZXIgb2YgdGhlIGltcGxlbWVudGF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldEluZm9cblx0ICAgICAqL1xuXHQgICAgZ2V0SW5mbygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtaW5mbycpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLndpcmUuZW52aXJvbm1lbnQuZ2V0QWRhcHRlclZlcnNpb25TeW5jKCk7XG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgcHJvdmlkZXJWZXJzaW9uOiB2ZXJzaW9uLFxuXHQgICAgICAgICAgICBwcm92aWRlcjogYG9wZW5maW4tJHt0aGlzLndpcmUubWUudXVpZH1gLFxuXHQgICAgICAgICAgICBmZGMzVmVyc2lvbjogJzEuMidcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHR9XG5cdGZkYzMxXzIuRmRjM01vZHVsZSA9IEZkYzNNb2R1bGU7XG5cdHJldHVybiBmZGMzMV8yO1xufVxuXG52YXIgZmRjMzJfMCA9IHt9O1xuXG52YXIgaGFzUmVxdWlyZWRGZGMzMl8wO1xuXG5mdW5jdGlvbiByZXF1aXJlRmRjMzJfMCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZkYzMyXzApIHJldHVybiBmZGMzMl8wO1xuXHRoYXNSZXF1aXJlZEZkYzMyXzAgPSAxO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZmRjMzJfMCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdGZkYzMyXzAuRmRjM01vZHVsZTIgPSB2b2lkIDA7XG5cdGNvbnN0IGZkYzNfY29tbW9uXzEgPSByZXF1aXJlRmRjM0NvbW1vbigpO1xuXHRjb25zdCB1dGlsc18xID0gdXRpbHMkMztcblx0Y29uc3QgSW50ZXJvcENsaWVudF8xID0gcmVxdWlyZUludGVyb3BDbGllbnQoKTtcblx0Y29uc3QgdXRpbHNfMiA9IHV0aWxzJDI7XG5cdGNvbnN0IFByaXZhdGVDaGFubmVsQ2xpZW50XzEgPSBQcml2YXRlQ2hhbm5lbENsaWVudCQxO1xuXHQvKipcblx0ICogQHZlcnNpb24gMi4wXG5cdCAqIFRoZSBGREMzIENsaWVudCBMaWJyYXJ5IHByb3ZpZGVzIGEgc2V0IEFQSXMgdG8gYmUgdXNlZCBmb3IgRkRDMyBjb21wbGlhbmNlLFxuXHQgKiB3aGlsZSB1c2luZyBvdXIgSW50ZXJvcCBBUEkgdW5kZXIgdGhlIGhvb2QuIEluIG9yZGVyIHRvIHVzZSB0aGlzIHNldCBvZiBBUElzXG5cdCAqIHlvdSB3aWxsIG5lZWQgdG8gc2V0IHVwIHlvdXIgb3duIHtAbGluayBJbnRlcm9wQnJva2VyIEludGVyb3BCcm9rZXJ9IG9yIHVzZSBhIFBsYXRmb3JtIGFwcGxpY2F0aW9uLCB3aGljaCBkb2VzIHRoZSBzZXR1cCBmb3IgeW91LiBSZWZlciB0byBvdXIgZG9jdW1lbnRhdGlvbiBvblxuXHQgKiBvdXIge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVycy5vcGVuZmluLmNvL29mLWRvY3MvZG9jcy9lbmFibGUtY29udGV4dC1zaGFyaW5nIEludGVyb3AgQVBJfS5cblx0ICpcblx0ICogVG8gZW5hYmxlIHRoZSBGREMzIEFQSXMgaW4gYSB7QGxpbmsgV2luZG93IFdpbmRvd30gb3Ige0BsaW5rIFZpZXcgVmlld30sIGFkZCB0aGUgZmRjM0ludGVyb3BBcGlcblx0ICogcHJvcGVydHkgdG8gaXRzIG9wdGlvbnM6XG5cdCAqXG5cdCAqIGBgYGpzXG5cdCAqIHtcblx0ICogICAgIGF1dG9TaG93OiBmYWxzZSxcblx0ICogICAgIHNhdmVXaW5kb3dTdGF0ZTogdHJ1ZSxcblx0ICogICAgIHVybDogJ2h0dHBzOi8vb3BlbmZpbi5jbycsXG5cdCAqICAgICBmZGMzSW50ZXJvcEFwaTogJzIuMCdcblx0ICogfVxuXHQgKiBgYGBcblx0ICpcblx0ICogSWYgdXNpbmcgYSB7QGxpbmsgUGxhdGZvcm0gUGxhdGZvcm0gfSBhcHBsaWNhdGlvbiwgeW91IGNhbiBzZXQgdGhpcyBwcm9wZXJ0eSBpbiBkZWZhdWx0V2luZG93T3B0aW9ucyBhbmQgZGVmYXVsdFZpZXdPcHRpb25zLlxuXHQgKlxuXHQgKiBJbiBvcmRlciB0byBlbnN1cmUgdGhhdCB0aGUgRkRDMyBBcGkgaXMgcmVhZHkgYmVmb3JlIHVzZSwgeW91IGNhbiB1c2UgdGhlICdmZGMzUmVhZHknIGV2ZW50IGZpcmVkIG9uIHRoZSBET00gV2luZG93IG9iamVjdDpcblx0ICpcblx0ICogYGBganNcblx0ICogZnVuY3Rpb24gZmRjM0FjdGlvbigpIHtcblx0ICogICAgIC8vIE1ha2Ugc29tZSBmZGMzIEFQSSBjYWxscyBoZXJlXG5cdCAqIH1cblx0ICpcblx0ICogaWYgKHdpbmRvdy5mZGMzKSB7XG5cdCAqICAgIGZkYzNBY3Rpb24oKTtcblx0ICogfSBlbHNlIHtcblx0ICogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2ZkYzNSZWFkeScsIGZkYzNBY3Rpb24pO1xuXHQgKiB9XG5cdCAqIGBgYFxuXHQgKi9cblx0Y2xhc3MgRmRjM01vZHVsZTIgZXh0ZW5kcyBmZGMzX2NvbW1vbl8xLkZEQzNNb2R1bGVCYXNlIHtcblx0ICAgIC8qKlxuXHQgICAgICogTGF1bmNoZXMgYW4gYXBwLCBzcGVjaWZpZWQgdmlhIGFuIEFwcElkZW50aWZpZXIgb2JqZWN0LlxuXHQgICAgICogQHBhcmFtIGFwcFxuXHQgICAgICogQHBhcmFtIGNvbnRleHRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5vcGVuXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIG9wZW4oYXBwLCBjb250ZXh0KSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBhcHAgPT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFzc2luZyBhIHN0cmluZyBhcyB0aGUgYXBwIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGFuIEFwcElkZW50aWZpZXIgKHsgYXBwSWQ6IHN0cmluZzsgaW5zdGFuY2VJZD86IHN0cmluZyB9KS4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG5cdCAgICAgICAgcmV0dXJuIHN1cGVyLl9vcGVuKGFwcCwgY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmQgYWxsIHRoZSBhdmFpbGFibGUgaW5zdGFuY2VzIGZvciBhIHBhcnRpY3VsYXIgYXBwbGljYXRpb24uXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5maW5kSW5zdGFuY2VzXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnN0YW5jZXMoYXBwKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtZmluZC1pbnN0YW5jZXMnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgSW50ZXJvcENsaWVudF8xLkludGVyb3BDbGllbnQuZmVycnlGZGMzQ2FsbCh0aGlzLmNsaWVudCwgJ2ZkYzNGaW5kSW5zdGFuY2VzJywgYXBwKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGVycm9yVG9UaHJvdyA9IGVycm9yLm1lc3NhZ2UgPT09IHV0aWxzXzEuQlJPS0VSX0VSUk9SUy5mZGMzRmluZEluc3RhbmNlcyA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0cmlldmVzIHRoZSBBcHBNZXRhZGF0YSBmb3IgYW4gQXBwSWRlbnRpZmllciwgd2hpY2ggcHJvdmlkZXMgYWRkaXRpb25hbCBtZXRhZGF0YSAoc3VjaCBhcyBpY29ucywgYSB0aXRsZSBhbmQgZGVzY3JpcHRpb24pIGZyb20gdGhlIEFwcCBEaXJlY3RvcnkgcmVjb3JkIGZvciB0aGUgYXBwbGljYXRpb24sIHRoYXQgbWF5IGJlIHVzZWQgZm9yIGRpc3BsYXkgcHVycG9zZXMuXG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRBcHBNZXRhZGF0YVxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRBcHBNZXRhZGF0YShhcHApIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1nZXQtYXBwLW1ldGFkYXRhJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzR2V0QXBwTWV0YWRhdGEnLCBhcHApO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmZkYzNHZXRBcHBNZXRhZGF0YSA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkIGEgY29udGV4dCBoYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LiBJZiBhbiBlbnRpdHkgaXMgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAsIGFuZCB0aGVuIHNldHMgaXRzIGNvbnRleHQgaGFuZGxlciwgaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuIElmIHlvdSB3aXNoIHRvIGxpc3RlbiBmb3IgYWxsIGluY29taW5nIGNvbnRleHRzLCBwYXNzIGBudWxsYCBmb3IgdGhlIGNvbnRleHRUeXBlIGFyZ3VtZW50LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlXG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlclxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmFkZENvbnRleHRMaXN0ZW5lclxuXHQgICAgICovXG5cdCAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgIGFzeW5jIGFkZENvbnRleHRMaXN0ZW5lcihjb250ZXh0VHlwZSwgaGFuZGxlcikge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLWFkZC1jb250ZXh0LWxpc3RlbmVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgLy8gVGhlIEZEQzMgQ29udGV4dEhhbmRsZXIgb25seSBleHBlY3RzIHRoZSBjb250ZXh0IGFuZCBvcHRpb25hbCBDb250ZXh0TWV0YWRhdGEsIHNvIHdlIHdyYXAgdGhlIGhhbmRsZXJcblx0ICAgICAgICAvLyBoZXJlIHNvIGl0IG9ubHkgZ2V0cyBwYXNzZWQgdGhlc2UgcGFyYW1ldGVyc1xuXHQgICAgICAgIGNvbnN0IGdldFdyYXBwZWRIYW5kbGVyID0gKGhhbmRsZXJUb1dyYXApID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRNZXRhZGF0YSwgLi4ucmVzdCB9ID0gY29udGV4dDtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBjb250ZXh0TWV0YWRhdGEgPyBbeyAuLi5yZXN0IH0sIGNvbnRleHRNZXRhZGF0YV0gOiBbY29udGV4dCwgbnVsbF07XG5cdCAgICAgICAgICAgICAgICBoYW5kbGVyVG9XcmFwKC4uLmFyZ3MpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgbGV0IGFjdHVhbEhhbmRsZXIgPSBoYW5kbGVyO1xuXHQgICAgICAgIGxldCB3cmFwcGVkSGFuZGxlciA9IGdldFdyYXBwZWRIYW5kbGVyKGFjdHVhbEhhbmRsZXIpO1xuXHQgICAgICAgIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdmdW5jdGlvbicpIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKCdhZGRDb250ZXh0TGlzdGVuZXIoaGFuZGxlcikgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBhZGRDb250ZXh0TGlzdGVuZXIobnVsbCwgaGFuZGxlciknKTtcblx0ICAgICAgICAgICAgYWN0dWFsSGFuZGxlciA9IGNvbnRleHRUeXBlO1xuXHQgICAgICAgICAgICB3cmFwcGVkSGFuZGxlciA9IGdldFdyYXBwZWRIYW5kbGVyKGFjdHVhbEhhbmRsZXIpO1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuYWRkQ29udGV4dEhhbmRsZXIod3JhcHBlZEhhbmRsZXIsIGNvbnRleHRUeXBlID09PSBudWxsID8gdW5kZWZpbmVkIDogY29udGV4dFR5cGUpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBGaW5kIG91dCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGEgcGFydGljdWxhciBpbnRlbnQgYnkgcGFzc2luZyBpdHMgbmFtZSwgYW5kIG9wdGlvbmFsbHkgaXRzIGNvbnRleHQgYW5kIHJlc3VsdFR5cGUuXG5cdCAgICAgKiBAcGFyYW0gaW50ZW50IE5hbWUgb2YgdGhlIEludGVudFxuXHQgICAgICogQHBhcmFtIGNvbnRleHQgQ29udGV4dFxuXHQgICAgICogQHBhcmFtIHJlc3VsdFR5cGUgVGhlIHR5cGUgb2YgcmVzdWx0IHJldHVybmVkIGZvciBhbnkgaW50ZW50IHNwZWNpZmllZCBkdXJpbmcgcmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5maW5kSW50ZW50XG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnRlbnQoaW50ZW50LCBjb250ZXh0LCByZXN1bHRUeXBlKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ZkYzMtZmluZC1pbnRlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuZ2V0SW5mb0ZvckludGVudCh7IG5hbWU6IGludGVudCwgY29udGV4dCwgbWV0YWRhdGE6IHsgcmVzdWx0VHlwZSB9IH0pO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmQgYWxsIHRoZSBhdmFpbGFibGUgaW50ZW50cyBmb3IgYSBwYXJ0aWN1bGFyIGNvbnRleHQuXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICogQHBhcmFtIHJlc3VsdFR5cGUgVGhlIHR5cGUgb2YgcmVzdWx0IHJldHVybmVkIGZvciBhbnkgaW50ZW50IHNwZWNpZmllZCBkdXJpbmcgcmVzb2x1dGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjM3YyLmZpbmRJbnRlbnRzQnlDb250ZXh0XG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpbmRJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQsIHJlc3VsdFR5cGUpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1maW5kLWludGVudHMtYnktY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IHBheWxvYWQgPSByZXN1bHRUeXBlID8geyBjb250ZXh0LCBtZXRhZGF0YTogeyByZXN1bHRUeXBlIH0gfSA6IGNvbnRleHQ7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgcmV0dXJuIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzdjJGaW5kSW50ZW50c0J5Q29udGV4dCcsIHBheWxvYWQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0ID8gJ1Jlc29sdmVyVW5hdmFpbGFibGUnIDogZXJyb3IubWVzc2FnZTtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yVG9UaHJvdyk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSYWlzZXMgYSBzcGVjaWZpYyBpbnRlbnQgZm9yIHJlc29sdXRpb24gYWdhaW5zdCBhcHBzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgZGVza3RvcCBhZ2VudC5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgTmFtZSBvZiB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCBDb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5yYWlzZUludGVudFxuXHQgICAgICovXG5cdCAgICBhc3luYyByYWlzZUludGVudChpbnRlbnQsIGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdmZGMzLXJhaXNlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIHdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGlzIGVycm9yLCBqdXN0IGNvbnRpbnVlIGlmIHRoaXMgYW5hbHl0aWNzLW9ubHkgY2FsbCBmYWlsc1xuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgYXBwID09PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdQYXNzaW5nIGEgc3RyaW5nIGFzIHRoZSBhcHAgcGFyYW1ldGVyIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSB1c2UgYW4gQXBwSWRlbnRpZmllciAoeyBhcHBJZDogc3RyaW5nOyBpbnN0YW5jZUlkPzogc3RyaW5nIH0pLicpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMi5nZXRJbnRlbnRSZXNvbHV0aW9uKSh0aGlzLmNsaWVudCwgY29udGV4dCwgYXBwLCBpbnRlbnQpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBjYXRjaCAoZXJyb3IpIHtcblx0ICAgICAgICAgICAgY29uc3QgZXJyb3JUb1Rocm93ID0gZXJyb3IubWVzc2FnZSA9PT0gdXRpbHNfMS5CUk9LRVJfRVJST1JTLmZpcmVJbnRlbnQgPyAnUmVzb2x2ZXJVbmF2YWlsYWJsZScgOiBlcnJvci5tZXNzYWdlO1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JUb1Rocm93KTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEZpbmRzIGFuZCByYWlzZXMgYW4gaW50ZW50IGFnYWluc3QgYXBwcyByZWdpc3RlcmVkIHdpdGggdGhlIGRlc2t0b3AgYWdlbnQgYmFzZWQgcHVyZWx5IG9uIHRoZSB0eXBlIG9mIHRoZSBjb250ZXh0IGRhdGEuXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCBDb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gYXBwXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5yYWlzZUludGVudEZvckNvbnRleHRcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgcmFpc2VJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQsIGFwcCkge1xuXHQgICAgICAgIC8vIFRPRE86IFdlIGhhdmUgdG8gZG8gdGhlIHNhbWUgdGhpbmcgd2UgZG8gZm9yIHJhaXNlSW50ZW50IGhlcmUgYXMgd2VsbC5cblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1yYWlzZS1pbnRlbnQtZm9yLWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyB3ZSBkbyBub3Qgd2FudCB0byBleHBvc2UgdGhpcyBlcnJvciwganVzdCBjb250aW51ZSBpZiB0aGlzIGFuYWx5dGljcy1vbmx5IGNhbGwgZmFpbHNcblx0ICAgICAgICB9KTtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGFwcCA9PT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUGFzc2luZyBhIHN0cmluZyBhcyB0aGUgYXBwIHBhcmFtZXRlciBpcyBkZXByZWNhdGVkLCBwbGVhc2UgdXNlIGFuIEFwcElkZW50aWZpZXIgKHsgYXBwSWQ6IHN0cmluZzsgaW5zdGFuY2VJZD86IHN0cmluZyB9KS4nKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICByZXR1cm4gKDAsIHV0aWxzXzIuZ2V0SW50ZW50UmVzb2x1dGlvbikodGhpcy5jbGllbnQsIGNvbnRleHQsIGFwcCk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICBjb25zdCBlcnJvclRvVGhyb3cgPSBlcnJvci5tZXNzYWdlID09PSB1dGlsc18xLkJST0tFUl9FUlJPUlMuZmlyZUludGVudCA/ICdSZXNvbHZlclVuYXZhaWxhYmxlJyA6IGVycm9yLm1lc3NhZ2U7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclRvVGhyb3cpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogQWRkcyBhIGxpc3RlbmVyIGZvciBpbmNvbWluZyBpbnRlbnRzLlxuXHQgICAgICogQHBhcmFtIGludGVudCAgTmFtZSBvZiB0aGUgSW50ZW50XG5cdCAgICAgKiBAcGFyYW0gaGFuZGxlciBBIGNhbGxiYWNrIHRoYXQgaGFuZGxlcyBhIGNvbnRleHQgZXZlbnQgYW5kIG1heSByZXR1cm4gYSBwcm9taXNlIG9mIGEgQ29udGV4dCBvciBDaGFubmVsIG9iamVjdCB0byBiZSByZXR1cm5lZCB0byB0aGUgYXBwbGljYXRpb24gdGhhdCByYWlzZWQgdGhlIGludGVudC5cblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5hZGRJbnRlbnRMaXN0ZW5lclxuXHQgICAgICovXG5cdCAgICBhc3luYyBhZGRJbnRlbnRMaXN0ZW5lcihpbnRlbnQsIGhhbmRsZXIpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignZmRjMy1hZGQtaW50ZW50LWxpc3RlbmVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gd2UgZG8gbm90IHdhbnQgdG8gZXhwb3NlIHRoaXMgZXJyb3IsIGp1c3QgY29udGludWUgaWYgdGhpcyBhbmFseXRpY3Mtb25seSBjYWxsIGZhaWxzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBpbnRlbnQgIT09ICdzdHJpbmcnKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhbiBJbnRlbnQgbmFtZScpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICAvLyBUaGUgRkRDMyBJbnRlbnRlciBoYW5kbGVyIG9ubHkgZXhwZWN0cyB0aGUgY29udGV4dCBhbmQgY29udGV4dE1ldGFkYXRhIHRvIGJlIHBhc3NlZCB0byB0aGUgaGFuZGxlcixcblx0ICAgICAgICAvLyBzbyB3ZSB3cmFwIGl0IGhlcmUgYW5kIG9ubHkgcGFzcyB0aG9zZSBwYXJhbWF0ZXJzLlxuXHQgICAgICAgIGNvbnN0IGNvbnRleHRIYW5kbGVyID0gYXN5bmMgKHJhaXNlZEludGVudCkgPT4ge1xuXHQgICAgICAgICAgICBsZXQgaW50ZW50UmVzdWx0O1xuXHQgICAgICAgICAgICBsZXQgaW50ZW50UmVzdWx0VG9TZW5kO1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHQsIG1ldGFkYXRhOiBpbnRlbnRNZXRhZGF0YSB9ID0gcmFpc2VkSW50ZW50O1xuXHQgICAgICAgICAgICBjb25zdCB7IGNvbnRleHRNZXRhZGF0YSwgbWV0YWRhdGEsIC4uLnJlc3QgfSA9IGNvbnRleHQ7XG5cdCAgICAgICAgICAgIGNvbnN0IGludGVudFJlc29sdXRpb25SZXN1bHRJZCA9IGludGVudE1ldGFkYXRhPy5pbnRlbnRSZXNvbHV0aW9uUmVzdWx0SWQgfHwgbWV0YWRhdGE/LmludGVudFJlc29sdXRpb25SZXN1bHRJZDtcblx0ICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSBtZXRhZGF0YSA/IHsgbWV0YWRhdGEsIC4uLnJlc3QgfSA6IHsgLi4ucmVzdCB9O1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gYXdhaXQgaGFuZGxlcihuZXdDb250ZXh0LCBjb250ZXh0TWV0YWRhdGEpO1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0VG9TZW5kID0gaW50ZW50UmVzdWx0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICAgICAgaW50ZW50UmVzdWx0ID0gZXJyb3I7XG5cdCAgICAgICAgICAgICAgICBpbnRlbnRSZXN1bHRUb1NlbmQgPSB7IGVycm9yOiB0cnVlIH07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGludGVudFJlc29sdXRpb25SZXN1bHRJZCkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5wdWJsaXNoKGludGVudFJlc29sdXRpb25SZXN1bHRJZCwgaW50ZW50UmVzdWx0VG9TZW5kKS5jYXRjaCgoKSA9PiBudWxsKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoaW50ZW50UmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihpbnRlbnRSZXN1bHQubWVzc2FnZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgcmV0dXJuIGludGVudFJlc3VsdDtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5yZWdpc3RlckludGVudEhhbmRsZXIoY29udGV4dEhhbmRsZXIsIGludGVudCwgeyBmZGMzVmVyc2lvbjogJzIuMCcgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgYSBDaGFubmVsIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBjaGFubmVsLCBjcmVhdGluZyBpdCBhcyBhbiBBcHAgQ2hhbm5lbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblx0ICAgICAqIEBwYXJhbSBjaGFubmVsSWRcblx0ICAgICAqXG5cdCAgICAgKiBAdHV0b3JpYWwgZmRjMy5nZXRPckNyZWF0ZUNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0T3JDcmVhdGVDaGFubmVsKGNoYW5uZWxJZCkge1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRPckNyZWF0ZUNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmV0dXJucyBhIENoYW5uZWwgd2l0aCBhbiBhdXRvLWdlbmVyYXRlZCBpZGVudGl0eSB0aGF0IGlzIGludGVuZGVkIGZvciBwcml2YXRlIGNvbW11bmljYXRpb24gYmV0d2VlbiBhcHBsaWNhdGlvbnMuIFByaW1hcmlseSB1c2VkIHRvIGNyZWF0ZSBjaGFubmVscyB0aGF0IHdpbGwgYmUgcmV0dXJuZWQgdG8gb3RoZXIgYXBwbGljYXRpb25zIHZpYSBhbiBJbnRlbnRSZXNvbHV0aW9uIGZvciBhIHJhaXNlZCBpbnRlbnQuXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5jcmVhdGVQcml2YXRlQ2hhbm5lbFxuXHQgICAgICovXG5cdCAgICBhc3luYyBjcmVhdGVQcml2YXRlQ2hhbm5lbCgpIHtcblx0ICAgICAgICBjb25zdCBjaGFubmVsSWQgPSAoMCwgdXRpbHNfMS5nZW5lcmF0ZUlkKSgpO1xuXHQgICAgICAgIGF3YWl0IEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdjcmVhdGVQcml2YXRlQ2hhbm5lbFByb3ZpZGVyJywgeyBjaGFubmVsSWQgfSk7XG5cdCAgICAgICAgY29uc3QgY2hhbm5lbENsaWVudCA9IGF3YWl0IHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxJZCk7XG5cdCAgICAgICAgY29uc3QgbmV3UHJpdmF0ZUNoYW5uZWxDbGllbnQgPSBuZXcgUHJpdmF0ZUNoYW5uZWxDbGllbnRfMS5Qcml2YXRlQ2hhbm5lbENsaWVudChjaGFubmVsQ2xpZW50LCBjaGFubmVsSWQpO1xuXHQgICAgICAgIHJldHVybiAoMCwgdXRpbHNfMi5idWlsZFByaXZhdGVDaGFubmVsT2JqZWN0KShuZXdQcml2YXRlQ2hhbm5lbENsaWVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdGhlIFVzZXIgQ2hhbm5lbHMgYXZhaWxhYmxlIGZvciB0aGUgYXBwIHRvIGpvaW4uXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRVc2VyQ2hhbm5lbHNcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0VXNlckNoYW5uZWxzKCkge1xuXHQgICAgICAgIGNvbnN0IGNoYW5uZWxzID0gYXdhaXQgdGhpcy5jbGllbnQuZ2V0Q29udGV4dEdyb3VwcygpO1xuXHQgICAgICAgIC8vIGZkYzMgaW1wbGVtZW50YXRpb24gb2YgZ2V0VXNlckNoYW5uZWxzIHJldHVybnMgb24gYXJyYXkgb2YgY2hhbm5lbHMsIGhhdmUgdG8gZGVjb3JhdGUgb3ZlclxuXHQgICAgICAgIC8vIHRoaXMgc28gcGVvcGxlIGtub3cgdGhhdCB0aGVzZSBBUElzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdCAgICAgICAgcmV0dXJuIGNoYW5uZWxzLm1hcCgoY2hhbm5lbCkgPT4ge1xuXHQgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIFRPRE8gW0NPUkUtMTUyNF1cblx0ICAgICAgICAgICAgcmV0dXJuIHsgLi4uY2hhbm5lbCwgdHlwZTogJ3VzZXInLCAuLi4oMCwgdXRpbHNfMi5nZXRVbnN1cHBvcnRlZENoYW5uZWxBcGlzKSgnVXNlcicpIH07XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdGhlIFVzZXIgQ2hhbm5lbHMgYXZhaWxhYmxlIGZvciB0aGUgYXBwIHRvIGpvaW4uXG5cdCAgICAgKlxuXHQgICAgICogQGRlcHJlY2F0ZWQgUGxlYXNlIHVzZSB7QGxpbmsgZmRjMy5nZXRVc2VyQ2hhbm5lbHMgZmRjMy5nZXRVc2VyQ2hhbm5lbHN9IGluc3RlYWRcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldFN5c3RlbUNoYW5uZWxzXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldFN5c3RlbUNoYW5uZWxzKCkge1xuXHQgICAgICAgIGNvbnNvbGUud2FybignVGhpcyBBUEkgaGFzIGJlZW4gZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBmZGMzLmdldFVzZXJDaGFubmVscyBpbnN0ZWFkLicpO1xuXHQgICAgICAgIHJldHVybiBzdXBlci5nZXRTeXN0ZW1DaGFubmVscygpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFuIGFwcCB0byBhIHNwZWNpZmllZCBVc2VyIGNoYW5uZWwuXG5cdCAgICAgKiBAcGFyYW0gY2hhbm5lbElkIENoYW5uZWwgbmFtZVxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzdjIuam9pblVzZXJDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGpvaW5Vc2VyQ2hhbm5lbChjaGFubmVsSWQpIHtcblx0ICAgICAgICByZXR1cm4gc3VwZXIuam9pbkNoYW5uZWwoY2hhbm5lbElkKTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogSm9pbiBhbiBhcHAgdG8gYSBzcGVjaWZpZWQgVXNlciBjaGFubmVsLlxuXHQgICAgICogQHBhcmFtIGNoYW5uZWxJZCBDaGFubmVsIG5hbWVcblx0ICAgICAqIEBkZXByZWNhdGVkIFBsZWFzZSB1c2Uge0BsaW5rIGZkYzMuam9pblVzZXJDaGFubmVsIGZkYzMuam9pblVzZXJDaGFubmVsfSBpbnN0ZWFkXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzMuam9pbkNoYW5uZWxcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgam9pbkNoYW5uZWwoY2hhbm5lbElkKSB7XG5cdCAgICAgICAgY29uc29sZS53YXJuKCdUaGlzIEFQSSBoYXMgYmVlbiBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGZkYzMuam9pblVzZXJDaGFubmVsIGluc3RlYWQuJyk7XG5cdCAgICAgICAgcmV0dXJuIHN1cGVyLmpvaW5DaGFubmVsKGNoYW5uZWxJZCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFJldHVybnMgdGhlIENoYW5uZWwgb2JqZWN0IGZvciB0aGUgY3VycmVudCBVc2VyIGNoYW5uZWwgbWVtYmVyc2hpcFxuXHQgICAgICpcblx0ICAgICAqIEB0dXRvcmlhbCBmZGMzLmdldEN1cnJlbnRDaGFubmVsXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEN1cnJlbnRDaGFubmVsKCkge1xuXHQgICAgICAgIGNvbnN0IGN1cnJlbnRDaGFubmVsID0gYXdhaXQgc3VwZXIuZ2V0Q3VycmVudENoYW5uZWwoKTtcblx0ICAgICAgICBpZiAoIWN1cnJlbnRDaGFubmVsKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBudWxsO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAuLi5jdXJyZW50Q2hhbm5lbCxcblx0ICAgICAgICAgICAgdHlwZTogJ3VzZXInLFxuXHQgICAgICAgICAgICBicm9hZGNhc3Q6IHRoaXMuYnJvYWRjYXN0LmJpbmQodGhpcylcblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBSZXRyaWV2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIEZEQzMgaW1wbGVtZW50YXRpb24sIGluY2x1ZGluZyB0aGUgc3VwcG9ydGVkIHZlcnNpb24gb2YgdGhlIEZEQzMgc3BlY2lmaWNhdGlvbiwgdGhlIG5hbWUgb2YgdGhlIHByb3ZpZGVyIG9mIHRoZSBpbXBsZW1lbnRhdGlvbiwgaXRzIG93biB2ZXJzaW9uIG51bWJlciwgZGV0YWlscyBvZiB3aGV0aGVyIG9wdGlvbmFsIEFQSSBmZWF0dXJlcyBhcmUgaW1wbGVtZW50ZWQgYW5kIHRoZSBtZXRhZGF0YSBvZiB0aGUgY2FsbGluZyBhcHBsaWNhdGlvbiBhY2NvcmRpbmcgdG8gdGhlIGRlc2t0b3AgYWdlbnQuXG5cdCAgICAgKiBmZGMzSGFuZGxlR2V0SW5mbyBtdXN0IGJlIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3BCcm9rZXIgc28gdGhhdCB0aGUgSW1wbGVtZW50YXRpb25NZXRhZGF0YSB3aWxsIGhhdmUgdGhlIGFwcE1ldGFkYXRhIGluZm8uXG5cdCAgICAgKlxuXHQgICAgICogQHR1dG9yaWFsIGZkYzN2Mi5nZXRJbmZvXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEluZm8oKSB7XG5cdCAgICAgICAgcmV0dXJuIEludGVyb3BDbGllbnRfMS5JbnRlcm9wQ2xpZW50LmZlcnJ5RmRjM0NhbGwodGhpcy5jbGllbnQsICdmZGMzdjJHZXRJbmZvJywgeyBmZGMzVmVyc2lvbjogJzIuMCcgfSk7XG5cdCAgICB9XG5cdH1cblx0ZmRjMzJfMC5GZGMzTW9kdWxlMiA9IEZkYzNNb2R1bGUyO1xuXHRyZXR1cm4gZmRjMzJfMDtcbn1cblxudmFyIGhhc1JlcXVpcmVkSW50ZXJvcENsaWVudDtcblxuZnVuY3Rpb24gcmVxdWlyZUludGVyb3BDbGllbnQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRJbnRlcm9wQ2xpZW50KSByZXR1cm4gSW50ZXJvcENsaWVudDtcblx0aGFzUmVxdWlyZWRJbnRlcm9wQ2xpZW50ID0gMTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRTZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcblx0ICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcblx0ICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcblx0ICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcblx0fTtcblx0dmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZEdldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xuXHQgICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuXHQgICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG5cdCAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xuXHR9O1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdHZhciBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3Vwcztcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KEludGVyb3BDbGllbnQsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRJbnRlcm9wQ2xpZW50LkludGVyb3BDbGllbnQgPSB2b2lkIDA7XG5cdGNvbnN0IGJhc2VfMSA9IGJhc2U7XG5cdGNvbnN0IFNlc3Npb25Db250ZXh0R3JvdXBDbGllbnRfMSA9IF9faW1wb3J0RGVmYXVsdChTZXNzaW9uQ29udGV4dEdyb3VwQ2xpZW50JDEpO1xuXHRjb25zdCBmZGMzXzFfMl8xID0gcmVxdWlyZUZkYzMxXzIoKTtcblx0Y29uc3QgZmRjM18yXzBfMSA9IHJlcXVpcmVGZGMzMl8wKCk7XG5cdGNvbnN0IHV0aWxzXzEgPSB1dGlscyQzO1xuXHQvKipcblx0ICogVGhlIEludGVyb3AgQ2xpZW50IEFQSSBpcyBicm9rZW4gdXAgaW50byB0d28gZ3JvdXBzOlxuXHQgKlxuXHQgKiAqKkNvbnRlbnQgRmFjaW5nIEFQSXMqKiAtIEZvciBBcHBsaWNhdGlvbiBEZXZlbG9wZXJzIHB1dHRpbmcgVmlld3MgaW50byBhIFBsYXRmb3JtIFdpbmRvdywgd2hvIGNhcmUgYWJvdXQgQ29udGV4dC4gVGhlc2UgYXJlIEFQSXMgdGhhdCBzZW5kIG91dCBhbmQgcmVjZWl2ZSB0aGUgQ29udGV4dCBkYXRhIHRoYXQgZmxvd3MgYmV0d2VlbiBhcHBsaWNhdGlvbnMuIFRoaW5rIG9mIHRoaXMgYXMgdGhlIFdhdGVyIGluIHRoZSBJbnRlcm9wIFBpcGVzLlxuXHQgKlxuXHQgKiAqKkNvbnRleHQgR3JvdXBpbmcgQVBJcyoqIC0gRm9yIFBsYXRmb3JtIERldmVsb3BlcnMsIHRvIGFkZCBhbmQgcmVtb3ZlIFZpZXdzIHRvIGFuZCBmcm9tIENvbnRleHQgR3JvdXBzLiBUaGVzZSBBUElzIGFyZSB1dGlsaXplZCB1bmRlci10aGUtaG9vZCBpbiBQbGF0Zm9ybXMsIHNvIHRoZXkgZG9uJ3QgbmVlZCB0byBiZSB1c2VkIHRvIHBhcnRpY2lwYXRlIGluIEludGVyb3AuIFRoZXNlIGFyZSB0aGUgQVBJcyB0aGF0IGRlY2lkZSB3aGljaCBlbnRpdGllcyB0aGUgY29udGV4dCBkYXRhIGZsb3dzIGJldHdlZW4uIFRoaW5rIG9mIHRoZXNlIGFzIHRoZSB2YWx2ZXMgb3IgcGlwZXMgdGhhdCBjb250cm9sIHRoZSBmbG93IG9mIENvbnRleHQgRGF0YSBmb3IgSW50ZXJvcC5cblx0ICpcblx0ICogLS0tXG5cdCAqXG5cdCAqIEFsbCBBUElzIGFyZSBhdmFpbGFibGUgYXQgdGhlIGBmaW4ubWUuaW50ZXJvcGAgbmFtZXNwYWNlLlxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogKipZb3Ugb25seSBuZWVkIDIgdGhpbmdzIHRvIHBhcnRpY2lwYXRlIGluIEludGVyb3AgQ29udGV4dCBHcm91cGluZzoqKlxuXHQgKiAqIEEgQ29udGV4dCBIYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0OiB7QGxpbmsgSW50ZXJvcENsaWVudCNhZGRDb250ZXh0SGFuZGxlciBhZGRDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBjb250ZXh0VHlwZT8pfVxuXHQgKiAqIENhbGwgc2V0Q29udGV4dCBvbiB5b3VyIGNvbnRleHQgZ3JvdXAgd2hlbiB5b3Ugd2FudCB0byBzaGFyZSBjb250ZXh0IHdpdGggb3RoZXIgZ3JvdXAgbWVtYmVyczoge0BsaW5rIEludGVyb3BDbGllbnQjc2V0Q29udGV4dCBzZXRDb250ZXh0KGNvbnRleHQpfVxuXHQgKlxuXHQgKiAtLS1cblx0ICpcblx0ICogIyMjIyMgQ29uc3RydWN0b3Jcblx0ICogUmV0dXJuZWQgYnkge0BsaW5rIEludGVyb3AuY29ubmVjdFN5bmMgSW50ZXJvcC5jb25uZWN0U3luY30uXG5cdCAqXG5cdCAqIC0tLVxuXHQgKlxuXHQgKiAjIyMjIyBJbnRlcm9wIG1ldGhvZHMgaW50ZW5kZWQgZm9yIFZpZXdzXG5cdCAqXG5cdCAqXG5cdCAqICoqQ29udGV4dCBHcm91cHMgQVBJKipcblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjYWRkQ29udGV4dEhhbmRsZXIgYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlciwgY29udGV4dFR5cGU/KX1cblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjc2V0Q29udGV4dCBzZXRDb250ZXh0KGNvbnRleHQpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNnZXRDdXJyZW50Q29udGV4dCBnZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZT8pfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNqb2luU2Vzc2lvbkNvbnRleHRHcm91cCBqb2luU2Vzc2lvbkNvbnRleHRHcm91cChzZXNzaW9uQ29udGV4dEdyb3VwSWQpfVxuXHQgKlxuXHQgKlxuXHQgKiAqKkludGVudHMgQVBJKipcblx0ICogICoge0BsaW5rIEludGVyb3BDbGllbnQjZmlyZUludGVudCBmaXJlSW50ZW50KGludGVudCl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I3JlZ2lzdGVySW50ZW50SGFuZGxlciByZWdpc3RlckludGVudEhhbmRsZXIoaW50ZW50SGFuZGxlciwgaW50ZW50TmFtZSl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JJbnRlbnQgZ2V0SW5mb0ZvckludGVudChpbmZvRm9ySW50ZW50T3B0aW9ucyl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0IGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNmaXJlSW50ZW50Rm9yQ29udGV4dCBmaXJlSW50ZW50Rm9yQ29udGV4dChjb250ZXh0Rm9ySW50ZW50KX1cblx0ICpcblx0ICogIyMjIyMgSW50ZXJvcCBtZXRob2RzIGludGVuZGVkIGZvciBXaW5kb3dzXG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldENvbnRleHRHcm91cHMgZ2V0Q29udGV4dEdyb3VwcygpfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNqb2luQ29udGV4dEdyb3VwIGpvaW5Db250ZXh0R3JvdXAoY29udGV4dEdyb3VwSWQsIHRhcmdldD8pfVxuXHQgKiAgKiB7QGxpbmsgSW50ZXJvcENsaWVudCNyZW1vdmVGcm9tQ29udGV4dEdyb3VwIHJlbW92ZUZyb21Db250ZXh0R3JvdXAodGFyZ2V0Pyl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEluZm9Gb3JDb250ZXh0R3JvdXAgZ2V0SW5mb0ZvckNvbnRleHRHcm91cChjb250ZXh0R3JvdXBJZCl9XG5cdCAqICAqIHtAbGluayBJbnRlcm9wQ2xpZW50I2dldEFsbENsaWVudHNJbkNvbnRleHRHcm91cCBnZXRBbGxDbGllbnRzSW5Db250ZXh0R3JvdXAoY29udGV4dEdyb3VwSWQpfVxuXHQgKlxuXHQgKi9cblx0bGV0IEludGVyb3BDbGllbnQkMSA9IGNsYXNzIEludGVyb3BDbGllbnQgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICovXG5cdCAgICBjb25zdHJ1Y3Rvcih3aXJlLCBjbGllbnRQcm9taXNlKSB7XG5cdCAgICAgICAgc3VwZXIod2lyZSk7XG5cdCAgICAgICAgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZS5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3Vwcy5zZXQodGhpcywgdm9pZCAwKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X3Nlc3Npb25Db250ZXh0R3JvdXBzLCBuZXcgTWFwKCksIFwiZlwiKTtcblx0ICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIGNsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgIH1cblx0ICAgIC8qXG5cdCAgICBDbGllbnQgQVBJc1xuXHQgICAgKi9cblx0ICAgIC8qKlxuXHQgICAgICogU2V0cyBhIGNvbnRleHQgZm9yIHRoZSBjb250ZXh0IGdyb3VwIG9mIHRoZSBjdXJyZW50IGVudGl0eS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBUaGUgZW50aXR5IG11c3QgYmUgcGFydCBvZiBhIGNvbnRleHQgZ3JvdXAgaW4gb3JkZXIgc2V0IGEgY29udGV4dC5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dCAtIE5ldyBjb250ZXh0IHRvIHNldC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIHNldEluc3RydW1lbnRDb250ZXh0ID0gYXN5bmMgKHRpY2tlcikgPT4ge1xuXHQgICAgICogICAgIGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoe3R5cGU6ICdpbnN0cnVtZW50JywgaWQ6IHt0aWNrZXJ9fSlcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiAvLyBUaGUgdXNlciBjbGlja3MgYW4gaW5zdHJ1bWVudCBvZiBpbnRlcmVzdC4gV2Ugd2FudCB0byBzZXQgdGhhdCBJbnN0cnVtZW50IGNvbnRleHQgc28gdGhhdCB0aGUgcmVzdCBvZiBvdXIgd29ya2Zsb3cgdXBkYXRlcyB3aXRoIGluZm9ybWF0aW9uIGZvciB0aGF0IGluc3RydW1lbnRcblx0ICAgICAqIGluc3RydW1lbnRFbGVtZW50Lm9uKCdjbGljaycsIChldnQpID0+IHtcblx0ICAgICAqICAgICBzZXRJbnN0cnVtZW50Q29udGV4dChldnQudGlja2VyKVxuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBzZXRDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtc2V0LWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdzZXRDb250ZXh0JywgeyBjb250ZXh0IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBBZGQgYSBjb250ZXh0IGhhbmRsZXIgZm9yIGluY29taW5nIGNvbnRleHQuIElmIGFuIGVudGl0eSBpcyBwYXJ0IG9mIGEgY29udGV4dCBncm91cCwgYW5kIHRoZW4gc2V0cyBpdHMgY29udGV4dCBoYW5kbGVyLFxuXHQgICAgICogaXQgd2lsbCByZWNlaXZlIGFsbCBvZiBpdHMgZGVjbGFyZWQgY29udGV4dHMuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGhhbmRsZXIgLSBIYW5kbGVyIGZvciBpbmNvbWluZyBjb250ZXh0LlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlIC0gVGhlIHR5cGUgb2YgY29udGV4dCB5b3Ugd2lzaCB0byBoYW5kbGUuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmdW5jdGlvbiBoYW5kbGVJbmNvbWluZ0NvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBzd2l0Y2ggKHR5cGUpIHtcblx0ICAgICAqICAgICAgICAgY2FzZSAnaW5zdHJ1bWVudCc6XG5cdCAgICAgKiAgICAgICAgICAgICBoYW5kbGVJbnN0cnVtZW50Q29udGV4dChjb250ZXh0SW5mbyk7XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqICAgICAgICAgY2FzZSAnY291bnRyeSc6XG5cdCAgICAgKiAgICAgICAgICAgICBoYW5kbGVDb3VudHJ5Q29udGV4dChjb250ZXh0SW5mbyk7XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqXG5cdCAgICAgKiAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgKiAgICAgICAgICAgICBicmVhaztcblx0ICAgICAqICAgICB9XG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIGZ1bmN0aW9uIGhhbmRsZUluc3RydW1lbnRDb250ZXh0KGNvbnRleHRJbmZvKSB7XG5cdCAgICAgKiAgICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gY29udGV4dEluZm87XG5cdCAgICAgKiAgICAgY29uc29sZS5sb2coJ2NvbnRleHRJbmZvIGZvciBpbnN0cnVtZW50JywgY29udGV4dEluZm8pXG5cdCAgICAgKiB9XG5cdCAgICAgKlxuXHQgICAgICogZnVuY3Rpb24gaGFuZGxlQ291bnRyeUNvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygnY29udGV4dEluZm8gZm9yIGNvdW50cnknLCBjb250ZXh0SW5mbylcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5hZGRDb250ZXh0SGFuZGxlcihoYW5kbGVJbmNvbWluZ0NvbnRleHQpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKlxuXHQgICAgICpcblx0ICAgICAqIFBhc3NpbmcgaW4gYSBjb250ZXh0IHR5cGUgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgd2lsbCBjYXVzZSB0aGUgaGFuZGxlciB0byBvbmx5IGJlIGludm9rZWQgd2l0aCB0aGF0IGNvbnRleHQgdHlwZS5cblx0ICAgICAqXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZnVuY3Rpb24gaGFuZGxlSW5zdHJ1bWVudENvbnRleHQoY29udGV4dEluZm8pIHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBjb250ZXh0SW5mbztcblx0ICAgICAqICAgICBjb25zb2xlLmxvZygnY29udGV4dEluZm8gZm9yIGluc3RydW1lbnQnLCBjb250ZXh0SW5mbylcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBmdW5jdGlvbiBoYW5kbGVDb3VudHJ5Q29udGV4dChjb250ZXh0SW5mbykge1xuXHQgICAgICogICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IGNvbnRleHRJbmZvO1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKCdjb250ZXh0SW5mbyBmb3IgY291bnRyeScsIGNvbnRleHRJbmZvKVxuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5hZGRDb250ZXh0SGFuZGxlcihoYW5kbGVJbnN0cnVtZW50Q29udGV4dCwgJ2luc3RydW1lbnQnKVxuXHQgICAgICogZmluLm1lLmludGVyb3AuYWRkQ29udGV4dEhhbmRsZXIoaGFuZGxlQ291bnRyeUNvbnRleHQsICdjb3VudHJ5Jylcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBhZGRDb250ZXh0SGFuZGxlcihoYW5kbGVyLCBjb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1hZGQtY29udGV4dC1oYW5kbGVyJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vbi1mdW5jdGlvbiBhcmd1bWVudCBwYXNzZWQgdG8gdGhlIGZpcnN0IHBhcmFtZXRlciAnaGFuZGxlcicuIEJlIGF3YXJlIHRoYXQgdGhlIGFyZ3VtZW50IG9yZGVyIGRvZXMgbm90IG1hdGNoIHRoZSBGREMzIHN0YW5kYXJkLlwiKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgbGV0IGhhbmRsZXJJZDtcblx0ICAgICAgICBpZiAoY29udGV4dFR5cGUpIHtcblx0ICAgICAgICAgICAgaGFuZGxlcklkID0gYGludm9rZUNvbnRleHRIYW5kbGVyLSR7Y29udGV4dFR5cGV9LSR7KDAsIHV0aWxzXzEuZ2VuZXJhdGVJZCkoKX1gO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBlbHNlIHtcblx0ICAgICAgICAgICAgaGFuZGxlcklkID0gJ2ludm9rZUNvbnRleHRIYW5kbGVyJztcblx0ICAgICAgICB9XG5cdCAgICAgICAgY29uc3Qgd3JhcHBlZEhhbmRsZXIgPSAoMCwgdXRpbHNfMS53cmFwQ29udGV4dEhhbmRsZXIpKGhhbmRsZXIsIGhhbmRsZXJJZCk7XG5cdCAgICAgICAgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgd3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgIGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnY29udGV4dEhhbmRsZXJSZWdpc3RlcmVkJywgeyBoYW5kbGVySWQsIGNvbnRleHRUeXBlIH0pO1xuXHQgICAgICAgIHJldHVybiB7XG5cdCAgICAgICAgICAgIHVuc3Vic2NyaWJlOiBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjbGllbnQucmVtb3ZlKGhhbmRsZXJJZCk7XG5cdCAgICAgICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ3JlbW92ZUNvbnRleHRIYW5kbGVyJywgeyBoYW5kbGVySWQgfSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9O1xuXHQgICAgfVxuXHQgICAgLypcblx0ICAgIFBsYXRmb3JtIFdpbmRvdyBBUElzXG5cdCAgICAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBSZXR1cm5zIHRoZSBJbnRlcm9wLUJyb2tlci1kZWZpbmVkIGNvbnRleHQgZ3JvdXBzIGF2YWlsYWJsZSBmb3IgYW4gZW50aXR5IHRvIGpvaW4uXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBmaW4ubWUuaW50ZXJvcC5nZXRDb250ZXh0R3JvdXBzKClcblx0ICAgICAqICAgICAgICAgLnRoZW4oY29udGV4dEdyb3VwcyA9PiB7XG5cdCAgICAgKiAgICAgICAgICAgICBjb250ZXh0R3JvdXBzLmZvckVhY2goY29udGV4dEdyb3VwID0+IHtcblx0ICAgICAqICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhjb250ZXh0R3JvdXAuZGlzcGxheU1ldGFkYXRhLm5hbWUpXG5cdCAgICAgKiAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwLmRpc3BsYXlNZXRhZGF0YS5jb2xvcilcblx0ICAgICAqICAgICAgICAgICAgIH0pXG5cdCAgICAgKiAgICAgICAgIH0pXG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0Q29udGV4dEdyb3VwcygpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZ2V0LWNvbnRleHQtZ3JvdXBzJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0Q29udGV4dEdyb3VwcycpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIGFsbCBJbnRlcm9wIENsaWVudHMgYXQgdGhlIGdpdmVuIGlkZW50aXR5IHRvIGNvbnRleHQgZ3JvdXAgYGNvbnRleHRHcm91cElkYC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IGFkZHMgdGhlIHNlbmRlciB0byB0aGUgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBCZWNhdXNlIG11bHRpcGxlIENoYW5uZWwgY29ubmVjdGlvbnMvSW50ZXJvcCBDbGllbnRzIGNhbiBwb3RlbnRpYWxseSBleGlzdCBhdCBhIGB1dWlkYC9gbmFtZWAgY29tYm8sIHdlIGN1cnJlbnRseSBqb2luIGFsbCBDaGFubmVsIGNvbm5lY3Rpb25zL0ludGVyb3AgQ2xpZW50cyBhdCB0aGUgZ2l2ZW4gaWRlbnRpdHkgdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBJZiBhbiBgZW5kcG9pbnRJZGAgaXMgcHJvdmlkZWQgKHdoaWNoIGlzIHVubGlrZWx5LCB1bmxlc3MgdGhlIGNhbGwgaXMgY29taW5nIGZyb20gYW4gZXh0ZXJuYWwgYWRhcHRlciksIHRoZW4gd2Ugb25seSBqb2luIHRoYXQgc2luZ2xlIGNvbm5lY3Rpb24gdG8gdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBGb3IgYWxsIGludGVudHMgYW5kIHB1cnBvc2VzLCB0aGVyZSB3aWxsIG9ubHkgYmUgMSBjb25uZWN0aW9uIHByZXNlbnQgaW4gUGxhdGZvcm0gYW5kIEJyb3dzZXIgaW1wbG1lbnRhdGlvbnMsIHNvIHRoaXMgcG9pbnQgaXMgbW9yZS1vci1sZXNzIG1vb3QuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRHcm91cElkIC0gSWQgb2YgdGhlIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBAcGFyYW0gdGFyZ2V0IC0gSWRlbnRpdHkgb2YgdGhlIGVudGl0eSB5b3Ugd2lzaCB0byBqb2luIHRvIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICogYGBganNcblx0ICAgICAqIGpvaW5WaWV3VG9Db250ZXh0R3JvdXAgPSBhc3luYyAoY29udGV4dEdyb3VwSWQsIHZpZXcpID0+IHtcblx0ICAgICAqICAgICBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkLCB2aWV3KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRMYXN0Rm9jdXNlZFZpZXcoKVxuXHQgICAgICogICAgIC50aGVuKGxhc3RGb2N1c2VkVmlld0lkZW50aXR5ID0+IHtcblx0ICAgICAqICAgICAgICAgam9pblZpZXdUb0NvbnRleHRHcm91cCgncmVkJywgbGFzdEZvY3VzZWRWaWV3SWRlbnRpdHkpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkLCB0YXJnZXQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtam9pbi1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgaWYgKCFjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbnRleHRHcm91cElkIHNwZWNpZmllZCBmb3Igam9pbkNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnam9pbkNvbnRleHRHcm91cCcsIHsgY29udGV4dEdyb3VwSWQsIHRhcmdldCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIHRhcmdldCBmcm9tIGEgY29udGV4dCBncm91cC5cblx0ICAgICAqIElmIG5vIHRhcmdldCBpcyBzcGVjaWZpZWQsIGl0IHJlbW92ZXMgdGhlIHNlbmRlciBmcm9tIHRoZWlyIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKiBVc2VkIGJ5IFBsYXRmb3JtIFdpbmRvd3MuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHRhcmdldCAtIElkZW50aXR5IG9mIHRoZSBlbnRpdHkgeW91IHdpc2ggdG8gam9pbiB0byBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiByZW1vdmVWaWV3RnJvbUNvbnRleHRHcm91cCA9IGFzeW5jICh2aWV3KSA9PiB7XG5cdCAgICAgKiAgICAgYXdhaXQgZmluLm1lLmludGVyb3AucmVtb3ZlRnJvbUNvbnRleHRHcm91cCh2aWV3KTtcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBnZXRMYXN0Rm9jdXNlZFZpZXcoKVxuXHQgICAgICogICAgIC50aGVuKGxhc3RGb2N1c2VkVmlld0lkZW50aXR5ID0+IHtcblx0ICAgICAqICAgICAgICAgcmVtb3ZlVmlld0Zyb21Db250ZXh0R3JvdXAobGFzdEZvY3VzZWRWaWV3SWRlbnRpdHkpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyByZW1vdmVGcm9tQ29udGV4dEdyb3VwKHRhcmdldCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1yZW1vdmUtZnJvbS1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgncmVtb3ZlRnJvbUNvbnRleHRHcm91cCcsIHsgdGFyZ2V0IH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGFsbCBjbGllbnRzIGZvciBhIGNvbnRleHQgZ3JvdXAuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgKipUaGlzIGlzIHByaW1hcmlseSB1c2VkIGZvciBwbGF0Zm9ybSB3aW5kb3dzLiBWaWV3cyB3aXRoaW4gYSBwbGF0Zm9ybSBzaG91bGQgbm90IGhhdmUgdG8gdXNlIHRoaXMgQVBJLioqXG5cdCAgICAgKlxuXHQgICAgICogUmV0dXJucyB0aGUgSW50ZXJvcC1Ccm9rZXItZGVmaW5lZCBjb250ZXh0IGdyb3VwcyBhdmFpbGFibGUgZm9yIGFuIGVudGl0eSB0byBqb2luLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRHcm91cElkIC0gVGhlIGlkIG9mIGNvbnRleHQgZ3JvdXAgeW91IHdpc2ggdG8gZ2V0IGNsaWVudHMgZm9yLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLm1lLmludGVyb3AuZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwKCdyZWQnKVxuXHQgICAgICogICAgIC50aGVuKGNsaWVudHNJbkNvbnRleHRHcm91cCA9PiB7XG5cdCAgICAgKiAgICAgICAgIGNvbnNvbGUubG9nKGNsaWVudHNJbkNvbnRleHRHcm91cClcblx0ICAgICAqICAgICB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cChjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1nZXQtYWxsLWNsaWVudHMtaW4tY29udGV4dC1ncm91cCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuXHQgICAgICAgIGlmICghY29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjb250ZXh0R3JvdXBJZCBzcGVjaWZpZWQgZm9yIGdldEFsbENsaWVudHNJbkNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0QWxsQ2xpZW50c0luQ29udGV4dEdyb3VwJywgeyBjb250ZXh0R3JvdXBJZCB9KTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBkaXNwbGF5IGluZm8gZm9yIGEgY29udGV4dCBncm91cFxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIFVzZWQgYnkgUGxhdGZvcm0gV2luZG93cy5cblx0ICAgICAqIEBwYXJhbSBjb250ZXh0R3JvdXBJZCAtIFRoZSBpZCBvZiBjb250ZXh0IGdyb3VwIHlvdSB3aXNoIHRvIGdldCBkaXNwbGF5IGluZm8gZm9yLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogZmluLm1lLmludGVyb3AuZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgncmVkJylcblx0ICAgICAqICAgICAudGhlbihjb250ZXh0R3JvdXBJbmZvID0+IHtcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mby5kaXNwbGF5TWV0YWRhdGEubmFtZSlcblx0ICAgICAqICAgICAgICAgY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mby5kaXNwbGF5TWV0YWRhdGEuY29sb3IpXG5cdCAgICAgKiAgICAgfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRJbmZvRm9yQ29udGV4dEdyb3VwKGNvbnRleHRHcm91cElkKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWdldC1pbmZvLWZvci1jb250ZXh0LWdyb3VwJykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgaWYgKCFjb250ZXh0R3JvdXBJZCkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNvbnRleHRHcm91cElkIHNwZWNpZmllZCBmb3IgZ2V0SW5mb0ZvckNvbnRleHRHcm91cC4nKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0SW5mb0ZvckNvbnRleHRHcm91cCcsIHsgY29udGV4dEdyb3VwSWQgfSk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNlbmRzIGFuIGludGVudCB0byB0aGUgSW50ZXJvcCBCcm9rZXIgdG8gcmVzb2x2ZS5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnQgLSBUaGUgY29tYmluYXRpb24gb2YgYW4gYWN0aW9uIGFuZCBhIGNvbnRleHQgdGhhdCBpcyBwYXNzZWQgdG8gYW4gYXBwbGljYXRpb24gZm9yIHJlc29sdXRpb24uXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAvLyBWaWV3IHdhbnRzIHRvIGZpcmUgYW4gSW50ZW50IGFmdGVyIGEgdXNlciBjbGlja3Mgb24gYSB0aWNrZXJcblx0ICAgICAqIHRpY2tlckVsZW1lbnQub24oJ2NsaWNrJywgKGVsZW1lbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB0aWNrZXIgPSBlbGVtZW50LmlubmVyVGV4dDtcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnQgPSB7XG5cdCAgICAgKiAgICAgICAgIG5hbWU6ICdWaWV3Q2hhcnQnLFxuXHQgICAgICogICAgICAgICBjb250ZXh0OiB7dHlwZTogJ2ZkYzMuaW5zdHJ1bWVudCcsIGlkOiB7IHRpY2tlciB9fVxuXHQgICAgICogICAgIH1cblx0ICAgICAqXG5cdCAgICAgKiAgICAgZmluLm1lLmludGVyb3AuZmlyZUludGVudChpbnRlbnQpO1xuXHQgICAgICogfSlcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBmaXJlSW50ZW50KGludGVudCkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1maXJlLWludGVudCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgdGhpcyBpcyBvbmx5IGZvciBhcGkgYW5hbHl0aWNzIHB1cnBvc2VzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZmlyZUludGVudCcsIGludGVudCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEFkZHMgYW4gaW50ZW50IGhhbmRsZXIgZm9yIGluY29taW5nIGludGVudHMuIFRoZSBsYXN0IGludGVudCBzZW50IG9mIHRoZSBuYW1lIHN1YnNjcmliZWQgdG8gd2lsbCBiZSByZWNlaXZlZC5cblx0ICAgICAqIEBwYXJhbSBoYW5kbGVyIC0gUmVnaXN0ZXJlZCBmdW5jdGlvbiBtZWFudCB0byBoYW5kbGUgYSBzcGVjaWZpYyBpbnRlbnQgdHlwZS5cblx0ICAgICAqIEBwYXJhbSBpbnRlbnROYW1lIC0gVGhlIG5hbWUgb2YgYW4gaW50ZW50LlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgaW50ZW50SGFuZGxlciA9IChpbnRlbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB7IGNvbnRleHQgfSA9IGludGVudDtcblx0ICAgICAqICAgICBteVZpZXdDaGFydEhhbmRsZXIoY29udGV4dCk7XG5cdCAgICAgKiB9O1xuXHQgICAgICpcblx0ICAgICAqIGNvbnN0IHN1YnNjcmlwdGlvbiA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLnJlZ2lzdGVySW50ZW50SGFuZGxlcihpbnRlbnRIYW5kbGVyLCAnVmlld0NoYXJ0Jyk7XG5cdCAgICAgKlxuXHQgICAgICogZnVuY3Rpb24gbXlBcHBDbG9zZVNlcXVlbmNlKCkge1xuXHQgICAgICogICAgIC8vIHRvIHVuc3Vic2NyaWJlIHRoZSBoYW5kbGVyLCBzaW1wbHkgY2FsbDpcblx0ICAgICAqICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcblx0ICAgICAqIH1cblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyByZWdpc3RlckludGVudEhhbmRsZXIoaGFuZGxlciwgaW50ZW50TmFtZSwgb3B0aW9ucykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1yZWdpc3Rlci1pbnRlbnQtaGFuZGxlcicpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgdGhpcyBpcyBvbmx5IGZvciBhcGkgYW5hbHl0aWNzIHB1cnBvc2VzXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgY29uc3QgaGFuZGxlcklkID0gYGludGVudC1oYW5kbGVyLSR7aW50ZW50TmFtZX1gO1xuXHQgICAgICAgIGNvbnN0IHdyYXBwZWRIYW5kbGVyID0gKDAsIHV0aWxzXzEud3JhcEludGVudEhhbmRsZXIpKGhhbmRsZXIsIGhhbmRsZXJJZCk7XG5cdCAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgYXdhaXQgY2xpZW50LnJlZ2lzdGVyKGhhbmRsZXJJZCwgd3JhcHBlZEhhbmRsZXIpO1xuXHQgICAgICAgICAgICBhd2FpdCBjbGllbnQuZGlzcGF0Y2goJ2ludGVudEhhbmRsZXJSZWdpc3RlcmVkJywgeyBoYW5kbGVySWQsIC4uLm9wdGlvbnMgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGNhdGNoIChlcnJvcikge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byByZWdpc3RlciBpbnRlbnQgaGFuZGxlcicpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICB1bnN1YnNjcmliZTogYXN5bmMgKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgY2xpZW50LnJlbW92ZShoYW5kbGVySWQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyB0aGUgbGFzdCBjb250ZXh0IG9mIHRoZSBDb250ZXh0IEdyb3VwIGN1cnJlbnRseSBzdWJzY3JpYmVkIHRvLiBJdCB0YWtlcyBhbiBvcHRpb25hbCBDb250ZXh0IFR5cGUgYW5kIHJldHVybnMgdGhlXG5cdCAgICAgKiBsYXN0IGNvbnRleHQgb2YgdGhhdCB0eXBlLlxuXHQgICAgICogQHBhcmFtIGNvbnRleHRUeXBlXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKCd5ZWxsb3cnKTtcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoeyB0eXBlOiAnaW5zdHJ1bWVudCcsIGlkOiB7IHRpY2tlcjogJ0ZPTycgfX0pO1xuXHQgICAgICogY29uc3QgY3VycmVudENvbnRleHQgPSBhd2FpdCBmaW4ubWUuaW50ZXJvcC5nZXRDdXJyZW50Q29udGV4dCgpO1xuXHQgICAgICpcblx0ICAgICAqIC8vIHdpdGggYSBzcGVjaWZpYyBjb250ZXh0XG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5qb2luQ29udGV4dEdyb3VwKCd5ZWxsb3cnKTtcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLnNldENvbnRleHQoeyB0eXBlOiAnY291bnRyeScsIGlkOiB7IElTT0FMUEhBMzogJ1VTJyB9fSk7XG5cdCAgICAgKiBhd2FpdCBmaW4ubWUuaW50ZXJvcC5zZXRDb250ZXh0KHsgdHlwZTogJ2luc3RydW1lbnQnLCBpZDogeyB0aWNrZXI6ICdGT08nIH19KTtcblx0ICAgICAqIGNvbnN0IGN1cnJlbnRDb250ZXh0ID0gYXdhaXQgZmluLm1lLmludGVyb3AuZ2V0Q3VycmVudENvbnRleHQoJ2NvdW50cnknKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBnZXRDdXJyZW50Q29udGV4dChjb250ZXh0VHlwZSkge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNsaWVudC1nZXQtY3VycmVudC1jb250ZXh0JykuY2F0Y2goKGUpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaCgnZ2V0Q3VycmVudENvbnRleHQnLCB7IGNvbnRleHRUeXBlIH0pO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXQgaW5mb3JtYXRpb24gZm9yIGEgcGFydGljdWxhciBJbnRlbnQgZnJvbSB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVJbmZvRm9ySW50ZW50IGlzIG1lYW50IHRvIGJlIG92ZXJyaWRkZW4gaW4gdGhlIEludGVyb3AgQnJva2VyLlxuXHQgICAgICogVGhlIGZvcm1hdCBmb3IgdGhlIHJlc3BvbnNlIHdpbGwgYmUgZGV0ZXJtaW5lZCBieSB0aGUgQXBwIFByb3ZpZGVyIG92ZXJyaWRpbmcgdGhlIGZ1bmN0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBvcHRpb25zXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBpbnRlbnRJbmZvID0gYXdhaXQgZmluLm1lLmludGVyb3AuZ2V0SW5mb0ZvckludGVudCgnVmlld0NoYXJ0Jyk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgZ2V0SW5mb0ZvckludGVudChvcHRpb25zKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWdldC1pbmZvLWZvci1pbnRlbnQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdnZXRJbmZvRm9ySW50ZW50Jywgb3B0aW9ucyk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEdldCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBJbnRlcm9wIEJyb2tlciBvbiBhbGwgSW50ZW50cyB0aGF0IGFyZSBtZWFudCB0byBoYW5kbGUgYSBwYXJ0aWN1bGFyIGNvbnRleHQuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVJbmZvRm9ySW50ZW50c0J5Q29udGV4dCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIGluIHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoZSBmb3JtYXQgZm9yIHRoZSByZXNwb25zZSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIEFwcCBQcm92aWRlciBvdmVycmlkaW5nIHRoZSBmdW5jdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogdGlja2VyRWxlbWVudC5vbignY2xpY2snLCAoZWxlbWVudCkgPT4ge1xuXHQgICAgICogICAgIGNvbnN0IHRpY2tlciA9IGVsZW1lbnQuaW5uZXJUZXh0O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBjb250ZXh0ID0ge1xuXHQgICAgICogICAgICAgICB0eXBlOiAnZmRjMy5pbnN0cnVtZW50Jyxcblx0ICAgICAqICAgICAgICAgaWQ6IHtcblx0ICAgICAqICAgICAgICAgICAgIHRpY2tlclxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnRzSW5mbyA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLmdldEluZm9Gb3JJbnRlbnRCeUNvbnRleHQoY29udGV4dCk7XG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGdldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZ2V0LWluZm8tZm9yLWludGVudHMtYnktY29udGV4dCcpLmNhdGNoKChlKSA9PiB7XG5cdCAgICAgICAgICAgIC8vIGRvbid0IGV4cG9zZSwgYW5hbHl0aWNzLW9ubHkgY2FsbFxuXHQgICAgICAgIH0pO1xuXHQgICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSwgXCJmXCIpO1xuXHQgICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2dldEluZm9Gb3JJbnRlbnRzQnlDb250ZXh0JywgY29udGV4dCk7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIFNlbmRzIGEgQ29udGV4dCB0aGF0IHdpbGwgYmUgcmVzb2x2ZWQgdG8gYW4gSW50ZW50IGJ5IHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoaXMgY29udGV4dCBhY2NlcHRzIGEgbWV0YWRhdGEgcHJvcGVydHkuXG5cdCAgICAgKlxuXHQgICAgICogQHJlbWFya3MgVG8gcmVzb2x2ZSB0aGlzIGluZm8sIHRoZSBmdW5jdGlvbiBoYW5kbGVGaXJlZEludGVudEJ5Q29udGV4dCBpcyBtZWFudCB0byBiZSBvdmVycmlkZGVuIGluIHRoZSBJbnRlcm9wIEJyb2tlci5cblx0ICAgICAqIFRoZSBmb3JtYXQgZm9yIHRoZSByZXNwb25zZSB3aWxsIGJlIGRldGVybWluZWQgYnkgdGhlIEFwcCBQcm92aWRlciBvdmVycmlkaW5nIHRoZSBmdW5jdGlvbi5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0gY29udGV4dFxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogdGlja2VyRWxlbWVudC5vbignY2xpY2snLCAoZWxlbWVudCkgPT4ge1xuXHQgICAgICogICAgIGNvbnN0IHRpY2tlciA9IGVsZW1lbnQuaW5uZXJUZXh0O1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBjb250ZXh0ID0ge1xuXHQgICAgICogICAgICAgICB0eXBlOiAnZmRjMy5pbnN0cnVtZW50Jyxcblx0ICAgICAqICAgICAgICAgaWQ6IHtcblx0ICAgICAqICAgICAgICAgICAgIHRpY2tlclxuXHQgICAgICogICAgICAgICB9XG5cdCAgICAgKiAgICAgfVxuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBpbnRlbnRSZXNvbHV0aW9uID0gYXdhaXQgZmluLm1lLmludGVyb3AuZmlyZUludGVudEZvckNvbnRleHQoY29udGV4dCk7XG5cdCAgICAgKiB9KVxuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGZpcmVJbnRlbnRGb3JDb250ZXh0KGNvbnRleHQpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1jbGllbnQtZmlyZS1pbnRlbnQtZm9yLWNvbnRleHQnKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50LmRpc3BhdGNoKCdmaXJlSW50ZW50Rm9yQ29udGV4dCcsIGNvbnRleHQpO1xuXHQgICAgfVxuXHQgICAgLyoqXG5cdCAgICAgKiBKb2luIHRoZSBjdXJyZW50IGVudGl0eSB0byBzZXNzaW9uIGNvbnRleHQgZ3JvdXAgYHNlc3Npb25Db250ZXh0R3JvdXBJZGAgYW5kIHJldHVybiBhIHNlc3Npb25Db250ZXh0R3JvdXAgaW5zdGFuY2UuXG5cdCAgICAgKiBJZiB0aGUgc2Vzc2lvbkNvbnRleHRHcm91cCBkb2Vzbid0IGV4aXN0LCBvbmUgd2lsbCBnZXQgY3JlYXRlZC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrcyBTZXNzaW9uIENvbnRleHQgR3JvdXBzIGRvIG5vdCBwZXJzaXN0IGJldHdlZW4gcnVucyBhbmQgYXJlbid0IHByZXNlbnQgb24gc25hcHNob3RzLlxuXHQgICAgICogQHBhcmFtIHNlc3Npb25Db250ZXh0R3JvdXBJZCAtIElkIG9mIHRoZSBjb250ZXh0IGdyb3VwLlxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBTYXkgd2Ugd2FudCB0byBoYXZlIGEgU2Vzc2lvbiBDb250ZXh0IEdyb3VwIHRoYXQgaG9sZHMgVUkgdGhlbWUgaW5mb3JtYXRpb24gZm9yIGFsbCBhcHBzIHRvIGNvbnN1bWU6XG5cdCAgICAgKlxuXHQgICAgICogTXkgY29sb3ItcGlja2VyIFZpZXc6XG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogICAgIGNvbnN0IHRoZW1lU2Vzc2lvbkNvbnRleHRHcm91cCA9IGF3YWl0IGZpbi5tZS5pbnRlcm9wLmpvaW5TZXNzaW9uQ29udGV4dEdyb3VwKCd0aGVtZScpO1xuXHQgICAgICpcblx0ICAgICAqICAgICBjb25zdCBteUNvbG9yUGlja2VyRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb2xvci1wYWxldHRlLXBpY2tlcicpO1xuXHQgICAgICogICAgIG15Q29sb3JQaWNrZXJFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGV2ZW50ID0+IHtcblx0ICAgICAqICAgICAgICAgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwLnNldENvbnRleHQoeyB0eXBlOiAnY29sb3ItcGFsZXR0ZScsIHNlbGVjdGlvbjogZXZlbnQudmFsdWUgfSk7XG5cdCAgICAgKiAgICAgfSk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqXG5cdCAgICAgKiBJbiBvdGhlciB2aWV3czpcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiAgICAgY29uc3QgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwID0gYXdhaXQgZmluLm1lLmludGVyb3Auam9pblNlc3Npb25Db250ZXh0R3JvdXAoJ3RoZW1lJyk7XG5cdCAgICAgKlxuXHQgICAgICogICAgIGNvbnN0IGNoYW5nZUNvbG9yUGFsZXR0ZSA9ICh7IHNlbGVjdGlvbiB9KSA9PiB7XG5cdCAgICAgKiAgICAgICAgIC8vIGNoYW5nZSB0aGUgY29sb3IgcGFsZXR0ZSB0byB0aGUgc2VsZWN0aW9uXG5cdCAgICAgKiAgICAgfTtcblx0ICAgICAqXG5cdCAgICAgKiAgICAgLy8gSWYgdGhlIGNvbnRleHQgaXMgYWxyZWFkeSBzZXQgYnkgdGhlIHRpbWUgdGhlIGhhbmRsZXIgd2FzIHNldCwgdGhlIGhhbmRsZXIgd2lsbCBnZXQgaW52b2tlZCBpbW1lZGlhdGVseSB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQuXG5cdCAgICAgKiAgICAgdGhlbWVTZXNzaW9uQ29udGV4dEdyb3VwLmFkZENvbnRleHRIYW5kbGVyKGNoYW5nZUNvbG9yUGFsZXR0ZSwgJ2NvbG9yLXBhbGV0dGUnKTtcblx0ICAgICAqIGBgYFxuXHQgICAgICovXG5cdCAgICBhc3luYyBqb2luU2Vzc2lvbkNvbnRleHRHcm91cChzZXNzaW9uQ29udGV4dEdyb3VwSWQpIHtcblx0ICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICBjb25zdCBjdXJyZW50U2Vzc2lvbkNvbnRleHRHcm91cCA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX0ludGVyb3BDbGllbnRfc2Vzc2lvbkNvbnRleHRHcm91cHMsIFwiZlwiKS5nZXQoc2Vzc2lvbkNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgaWYgKGN1cnJlbnRTZXNzaW9uQ29udGV4dEdyb3VwKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFNlc3Npb25Db250ZXh0R3JvdXAuZ2V0VXNlckluc3RhbmNlKCk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgICAgIGNvbnN0IHsgaGFzQ29uZmxpY3QgfSA9IGF3YWl0IGNsaWVudC5kaXNwYXRjaCgnc2Vzc2lvbkNvbnRleHRHcm91cDpjcmVhdGVJZk5lZWRlZCcsIHtcblx0ICAgICAgICAgICAgICAgIHNlc3Npb25Db250ZXh0R3JvdXBJZFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgaWYgKGhhc0NvbmZsaWN0KSB7XG5cdCAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYEEgKG5vbi1zZXNzaW9uKSBjb250ZXh0IGdyb3VwIHdpdGggdGhlIG5hbWUgXCIke3Nlc3Npb25Db250ZXh0R3JvdXBJZH1cIiBhbHJlYWR5IGV4aXN0cy4gSWYgeW91IGFyZSB0cnlpbmcgdG8gam9pbiBhIENvbnRleHQgR3JvdXAsIGNhbGwgam9pbkNvbnRleHRHcm91cCBpbnN0ZWFkLmApO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNvbnN0IG5ld1Nlc3Npb25Db250ZXh0R3JvdXAgPSBuZXcgU2Vzc2lvbkNvbnRleHRHcm91cENsaWVudF8xLmRlZmF1bHQodGhpcy53aXJlLCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKSwgc2Vzc2lvbkNvbnRleHRHcm91cElkKTtcblx0ICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfSW50ZXJvcENsaWVudF9zZXNzaW9uQ29udGV4dEdyb3VwcywgXCJmXCIpLnNldChzZXNzaW9uQ29udGV4dEdyb3VwSWQsIG5ld1Nlc3Npb25Db250ZXh0R3JvdXApO1xuXHQgICAgICAgICAgICByZXR1cm4gbmV3U2Vzc2lvbkNvbnRleHRHcm91cC5nZXRVc2VySW5zdGFuY2UoKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG5cdCAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHRocm93biB0cnlpbmcgdG8gY3JlYXRlIFNlc3Npb24gQ29udGV4dCBHcm91cCB3aXRoIGlkIFwiJHtzZXNzaW9uQ29udGV4dEdyb3VwSWR9XCI6ICR7ZXJyb3J9YCk7XG5cdCAgICAgICAgICAgIHRocm93IGVycm9yO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblx0ICAgIC8qKlxuXHQgICAgICogUmVnaXN0ZXIgYSBsaXN0ZW5lciB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBJbnRlcm9wIENsaWVudCBoYXMgYmVlbiBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKiBPbmx5IG9uZSBsaXN0ZW5lciBwZXIgSW50ZXJvcCBDbGllbnQgY2FuIGJlIHNldC5cblx0ICAgICAqIEBwYXJhbSBsaXN0ZW5lclxuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKiBgYGBqc1xuXHQgICAgICogY29uc3QgbGlzdGVuZXIgPSAoZXZlbnQpID0+IHtcblx0ICAgICAqICAgICBjb25zdCB7IHR5cGUsIHRvcGljLCBicm9rZXJOYW1lfSA9IGV2ZW50O1xuXHQgICAgICogICAgIGNvbnNvbGUubG9nKGBEaXNjb25uZWN0ZWQgZnJvbSBJbnRlcm9wIEJyb2tlciAke2Jyb2tlck5hbWV9IGApO1xuXHQgICAgICogfVxuXHQgICAgICpcblx0ICAgICAqIGF3YWl0IGZpbi5tZS5pbnRlcm9wLm9uRGlzY29ubmVjdGlvbihsaXN0ZW5lcik7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgYXN5bmMgb25EaXNjb25uZWN0aW9uKGxpc3RlbmVyKSB7XG5cdCAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ2ludGVyb3AtY2xpZW50LWFkZC1vbmRpc2Nvbm5lY3Rpb24tbGlzdGVuZXInKS5jYXRjaCgoZSkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9JbnRlcm9wQ2xpZW50X2NsaWVudFByb21pc2UsIFwiZlwiKTtcblx0ICAgICAgICByZXR1cm4gY2xpZW50Lm9uRGlzY29ubmVjdGlvbigoZXZlbnQpID0+IHtcblx0ICAgICAgICAgICAgY29uc3QgeyB1dWlkIH0gPSBldmVudDtcblx0ICAgICAgICAgICAgbGlzdGVuZXIoeyB0eXBlOiAnaW50ZXJvcC1icm9rZXInLCB0b3BpYzogJ2Rpc2Nvbm5lY3RlZCcsIGJyb2tlck5hbWU6IHV1aWQgfSk7XG5cdCAgICAgICAgfSk7XG5cdCAgICB9XG5cdCAgICBnZXRGREMzU3luYyh2ZXJzaW9uKSB7XG5cdCAgICAgICAgc3dpdGNoICh2ZXJzaW9uKSB7XG5cdCAgICAgICAgICAgIGNhc2UgJzEuMic6XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGZkYzNfMV8yXzEuRmRjM01vZHVsZSgoKSA9PiB0aGlzLCB0aGlzLndpcmUpO1xuXHQgICAgICAgICAgICBjYXNlICcyLjAnOlxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBmZGMzXzJfMF8xLkZkYzNNb2R1bGUyKCgpID0+IHRoaXMsIHRoaXMud2lyZSk7XG5cdCAgICAgICAgICAgIGRlZmF1bHQ6XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgRkRDMyB2ZXJzaW9uIHByb3ZpZGVkOiAke3ZlcnNpb259LiBNdXN0IGJlICcxLjInIG9yICcyLjAnYCk7XG5cdCAgICAgICAgfVxuXHQgICAgfVxuXHQgICAgYXN5bmMgZ2V0RkRDMyh2ZXJzaW9uKSB7XG5cdCAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RkRDM1N5bmModmVyc2lvbik7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIEBpbnRlcm5hbFxuXHQgICAgICpcblx0ICAgICAqIFVzZWQgdG8gZmVycnkgZmRjMy1vbmx5IGNhbGxzIGZyb20gdGhlIGZkYzMgc2hpbSB0byB0aGUgSW50ZXJvcCBCcm9rZXJcblx0ICAgICAqL1xuXHQgICAgc3RhdGljIGFzeW5jIGZlcnJ5RmRjM0NhbGwoaW50ZXJvcENsaWVudCwgYWN0aW9uLCBwYXlsb2FkKSB7XG5cdCAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldChpbnRlcm9wQ2xpZW50LCBfSW50ZXJvcENsaWVudF9jbGllbnRQcm9taXNlLCBcImZcIik7XG5cdCAgICAgICAgcmV0dXJuIGNsaWVudC5kaXNwYXRjaChhY3Rpb24sIHBheWxvYWQgfHwgbnVsbCk7XG5cdCAgICB9XG5cdH07XG5cdEludGVyb3BDbGllbnQuSW50ZXJvcENsaWVudCA9IEludGVyb3BDbGllbnQkMTtcblx0X0ludGVyb3BDbGllbnRfY2xpZW50UHJvbWlzZSA9IG5ldyBXZWFrTWFwKCksIF9JbnRlcm9wQ2xpZW50X3Nlc3Npb25Db250ZXh0R3JvdXBzID0gbmV3IFdlYWtNYXAoKTtcblx0cmV0dXJuIEludGVyb3BDbGllbnQ7XG59XG5cbnZhciBvdmVycmlkZUNoZWNrID0ge307XG5cbnZhciBoYXNSZXF1aXJlZE92ZXJyaWRlQ2hlY2s7XG5cbmZ1bmN0aW9uIHJlcXVpcmVPdmVycmlkZUNoZWNrICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkT3ZlcnJpZGVDaGVjaykgcmV0dXJuIG92ZXJyaWRlQ2hlY2s7XG5cdGhhc1JlcXVpcmVkT3ZlcnJpZGVDaGVjayA9IDE7XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvdmVycmlkZUNoZWNrLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0b3ZlcnJpZGVDaGVjay5vdmVycmlkZUNoZWNrID0gb3ZlcnJpZGVDaGVjay5jaGVja0ZEQzMyT3ZlcnJpZGVzID0gb3ZlcnJpZGVDaGVjay5nZXREZWZhdWx0Vmlld0ZkYzNWZXJzaW9uRnJvbUFwcEluZm8gPSB2b2lkIDA7XG5cdGNvbnN0IEludGVyb3BCcm9rZXJfMSA9IHJlcXVpcmVJbnRlcm9wQnJva2VyKCk7XG5cdGZ1bmN0aW9uIGdldERlZmF1bHRWaWV3RmRjM1ZlcnNpb25Gcm9tQXBwSW5mbyh7IG1hbmlmZXN0LCBpbml0aWFsT3B0aW9ucyB9KSB7XG5cdCAgICBjb25zdCBzZXRWZXJzaW9uID0gbWFuaWZlc3Q/LnBsYXRmb3JtPy5kZWZhdWx0Vmlld09wdGlvbnM/LmZkYzNJbnRlcm9wQXBpID8/IGluaXRpYWxPcHRpb25zLmRlZmF1bHRWaWV3T3B0aW9ucz8uZmRjM0ludGVyb3BBcGk7XG5cdCAgICByZXR1cm4gWycxLjInLCAnMi4wJ10uaW5jbHVkZXMoc2V0VmVyc2lvbiA/PyAnJykgPyBzZXRWZXJzaW9uIDogdW5kZWZpbmVkO1xuXHR9XG5cdG92ZXJyaWRlQ2hlY2suZ2V0RGVmYXVsdFZpZXdGZGMzVmVyc2lvbkZyb21BcHBJbmZvID0gZ2V0RGVmYXVsdFZpZXdGZGMzVmVyc2lvbkZyb21BcHBJbmZvO1xuXHRmdW5jdGlvbiBjaGVja0ZEQzMyT3ZlcnJpZGVzKG92ZXJyaWRkZW5Ccm9rZXIpIHtcblx0ICAgIC8vIFRoZXNlIGFyZSB0aGUgQVBJcyB0aGF0IG11c3QgYmUgb3ZlcnJpZGRlbiBmb3IgRkRDMyAyLjAgY29tcGxpYW5jZVxuXHQgICAgY29uc3QgbXVzdE92ZXJyaWRlQVBJcyA9IFtcblx0ICAgICAgICAnZmRjM0hhbmRsZUZpbmRJbnN0YW5jZXMnLFxuXHQgICAgICAgICdoYW5kbGVJbmZvRm9ySW50ZW50Jyxcblx0ICAgICAgICAnaGFuZGxlSW5mb0ZvckludGVudHNCeUNvbnRleHQnLFxuXHQgICAgICAgICdmZGMzSGFuZGxlR2V0QXBwTWV0YWRhdGEnLFxuXHQgICAgICAgICdmZGMzSGFuZGxlR2V0SW5mbycsXG5cdCAgICAgICAgJ2ZkYzNIYW5kbGVPcGVuJyxcblx0ICAgICAgICAnaGFuZGxlRmlyZWRJbnRlbnQnLFxuXHQgICAgICAgICdoYW5kbGVGaXJlZEludGVudEZvckNvbnRleHQnXG5cdCAgICBdO1xuXHQgICAgcmV0dXJuIG11c3RPdmVycmlkZUFQSXMuZmlsdGVyKChhcGkpID0+IHtcblx0ICAgICAgICByZXR1cm4gb3ZlcnJpZGRlbkJyb2tlclthcGldID09PSBJbnRlcm9wQnJva2VyXzEuSW50ZXJvcEJyb2tlci5wcm90b3R5cGVbYXBpXTtcblx0ICAgIH0pO1xuXHR9XG5cdG92ZXJyaWRlQ2hlY2suY2hlY2tGREMzMk92ZXJyaWRlcyA9IGNoZWNrRkRDMzJPdmVycmlkZXM7XG5cdGZ1bmN0aW9uIG92ZXJyaWRlQ2hlY2skMShvdmVycmlkZGVuQnJva2VyLCBmZGMzSW50ZXJvcEFwaSkge1xuXHQgICAgaWYgKGZkYzNJbnRlcm9wQXBpICYmIGZkYzNJbnRlcm9wQXBpID09PSAnMi4wJykge1xuXHQgICAgICAgIGNvbnN0IG5vdE92ZXJyaWRkZW4gPSBjaGVja0ZEQzMyT3ZlcnJpZGVzKG92ZXJyaWRkZW5Ccm9rZXIpO1xuXHQgICAgICAgIGlmIChub3RPdmVycmlkZGVuLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgY29uc29sZS53YXJuKGBXQVJOSU5HOiBGREMzIDIuMCBoYXMgYmVlbiBzZXQgYXMgYSBkZWZhdWx0IG9wdGlvbiBmb3IgVmlld3MgaW4gdGhpcyBQbGF0Zm9ybSwgYnV0IHRoZSByZXF1aXJlZCBJbnRlcm9wQnJva2VyIEFQSXMgZm9yIEZEQzMgMi4wIGNvbXBsaWFuY2UgaGF2ZSBub3QgYWxsIGJlZW4gb3ZlcnJpZGRlbi5cXG5UaGUgZm9sbG93aW5nIEFQSXMgbmVlZCB0byBiZSBvdmVycmlkZGVuOlxcbiR7bm90T3ZlcnJpZGRlbi5qb2luKCdcXG4nKX1gKTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cdH1cblx0b3ZlcnJpZGVDaGVjay5vdmVycmlkZUNoZWNrID0gb3ZlcnJpZGVDaGVjayQxO1xuXHRyZXR1cm4gb3ZlcnJpZGVDaGVjaztcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFjdG9yeTtcblxuZnVuY3Rpb24gcmVxdWlyZUZhY3RvcnkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGYWN0b3J5KSByZXR1cm4gRmFjdG9yeSQxO1xuXHRoYXNSZXF1aXJlZEZhY3RvcnkgPSAxO1xuXHR2YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuXHQgICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBcImRlZmF1bHRcIjogbW9kIH07XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5JDEsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuXHRGYWN0b3J5JDEuSW50ZXJvcE1vZHVsZSA9IHZvaWQgMDtcblx0Y29uc3QgY2xvbmVEZWVwXzEgPSBfX2ltcG9ydERlZmF1bHQocmVxdWlyZSQkMCQxKTtcblx0Y29uc3QgaW5hY2Nlc3NpYmxlT2JqZWN0XzEgPSBpbmFjY2Vzc2libGVPYmplY3Q7XG5cdGNvbnN0IGJhc2VfMSA9IGJhc2U7XG5cdGNvbnN0IEludGVyb3BCcm9rZXJfMSA9IHJlcXVpcmVJbnRlcm9wQnJva2VyKCk7XG5cdGNvbnN0IEludGVyb3BDbGllbnRfMSA9IHJlcXVpcmVJbnRlcm9wQ2xpZW50KCk7XG5cdGNvbnN0IG92ZXJyaWRlQ2hlY2tfMSA9IHJlcXVpcmVPdmVycmlkZUNoZWNrKCk7XG5cdGNvbnN0IGNvbW1vbl91dGlsc18xID0gY29tbW9uVXRpbHM7XG5cdGNvbnN0IGRlZmF1bHRPdmVycmlkZSA9IChDbGFzcykgPT4gbmV3IENsYXNzKCk7XG5cdGNvbnN0IEJyb2tlclBhcmFtQWNjZXNzRXJyb3IgPSAnWW91IGhhdmUgYXR0ZW1wdGVkIHRvIHVzZSBvciBtb2RpZnkgSW50ZXJvcEJyb2tlciBwYXJhbWV0ZXJzLCB3aGljaCBpcyBub3QgYWxsb3dlZC4gWW91IGFyZSBsaWtlbHkgdXNpbmcgYW4gb2xkZXIgSW50ZXJvcEJyb2tlciBvdmVycmlkZSBzY2hlbWUuIFBsZWFzZSBjb25zdWx0IG91ciBJbnRlcm9wIGRvY3MgZm9yIGd1aWRhbmNlIG9uIG1pZ3JhdGluZyB0byB0aGUgbmV3IG92ZXJyaWRlIHNjaGVtZS4nO1xuXHQvKipcblx0ICogTWFuYWdlcyBjcmVhdGlvbiBvZiBJbnRlcm9wIEJyb2tlcnMgYW5kIEludGVyb3AgQ2xpZW50cy4gVGhlc2UgQVBJcyBhcmUgY2FsbGVkIHVuZGVyLXRoZS1ob29kIGluIFBsYXRmb3Jtcy5cblx0ICpcblx0ICovXG5cdGNsYXNzIEludGVyb3BNb2R1bGUgZXh0ZW5kcyBiYXNlXzEuQmFzZSB7XG5cdCAgICAvKipcblx0ICAgICAqIEluaXRpYWxpemVzIGFuIEludGVyb3AgQnJva2VyLiBUaGlzIGlzIGNhbGxlZCB1bmRlci10aGUtaG9vZCBmb3IgUGxhdGZvcm1zLlxuXHQgICAgICpcblx0ICAgICAqIEByZW1hcmtzIEZvciBQbGF0Zm9ybXMsIHRoaXMgaXMgc2V0IHVwIGF1dG9tYXRpY2FsbHkuIFdlIGFkdmlzZSB0byBvbmx5IGNyZWF0ZSB5b3VyIG93biBJbnRlcm9wIEJyb2tlclxuXHQgICAgICogd2hlbiBub3QgdXNpbmcgYSBQbGF0Zm9ybSBhcHAuIFlvdSBjYW4gb3ZlcnJpZGUgZnVuY3Rpb25zIGluIHRoZSBJbnRlcm9wIEJyb2tlci4gTW9yZSBpbmZvIHtAbGluayBJbnRlcm9wQnJva2VyIGhlcmV9LlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSBuYW1lIC0gTmFtZSBvZiB0aGUgSW50ZXJvcCBCcm9rZXIuXG5cdCAgICAgKiBAcGFyYW0gb3ZlcnJpZGUgLSBBIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGFycmF5IG9mIGNhbGxiYWNrIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGV4dGVuZCBvciByZXBsYWNlIGRlZmF1bHQgSW50ZXJvcCBCcm9rZXIgYmVoYXZpb3IuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYCBqc1xuXHQgICAgICogY29uc3QgaW50ZXJvcEJyb2tlciA9IGF3YWl0IGZpbi5JbnRlcm9wLmluaXQoJ29wZW5maW4nKTtcblx0ICAgICAqIGNvbnN0IGNvbnRleHRHcm91cHMgPSBhd2FpdCBpbnRlcm9wQnJva2VyLmdldENvbnRleHRHcm91cHMoKTtcblx0ICAgICAqIGNvbnNvbGUubG9nKGNvbnRleHRHcm91cHMpO1xuXHQgICAgICogYGBgXG5cdCAgICAgKi9cblx0ICAgIGFzeW5jIGluaXQobmFtZSwgb3ZlcnJpZGUgPSBkZWZhdWx0T3ZlcnJpZGUpIHtcblx0ICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignaW50ZXJvcC1pbml0JykuY2F0Y2goKCkgPT4ge1xuXHQgICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcblx0ICAgICAgICB9KTtcblx0ICAgICAgICAvLyBBbGxvd3MgZm9yIG1hbmlmZXN0LWxldmVsIGNvbmZpZ3VyYXRpb24sIHdpdGhvdXQgaGF2aW5nIHRvIG92ZXJyaWRlLiAoZS5nLiBzcGVjaWZ5aW5nIGN1c3RvbSBjb250ZXh0IGdyb3Vwcylcblx0ICAgICAgICBjb25zdCBvcHRpb25zID0gYXdhaXQgdGhpcy53aXJlLmVudmlyb25tZW50LmdldEludGVyb3BJbmZvKHRoaXMud2lyZS5nZXRGaW4oKSk7XG5cdCAgICAgICAgY29uc3Qgb2JqZWN0VGhhdFRocm93cyA9ICgwLCBpbmFjY2Vzc2libGVPYmplY3RfMS5jcmVhdGVVbnVzYWJsZU9iamVjdCkoQnJva2VyUGFyYW1BY2Nlc3NFcnJvcik7XG5cdCAgICAgICAgY29uc3Qgd2FybmluZ09wdHNDbG9uZSA9ICgwLCBpbmFjY2Vzc2libGVPYmplY3RfMS5jcmVhdGVXYXJuaW5nT2JqZWN0KShCcm9rZXJQYXJhbUFjY2Vzc0Vycm9yLCAoMCwgY2xvbmVEZWVwXzEuZGVmYXVsdCkob3B0aW9ucykpO1xuXHQgICAgICAgIGNvbnN0IGdldFByb3ZpZGVyID0gKCkgPT4ge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShgaW50ZXJvcC1icm9rZXItJHtuYW1lfWApO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgdGhyb3dpbmdHZXRQcm92aWRlciA9IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcblx0ICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEJyb2tlclBhcmFtQWNjZXNzRXJyb3IpO1xuXHQgICAgICAgIH07XG5cdCAgICAgICAgY29uc3QgT3ZlcnJpZGVhYmxlQnJva2VyID0gSW50ZXJvcEJyb2tlcl8xLkludGVyb3BCcm9rZXIuY3JlYXRlQ2xvc2VkQ29uc3RydWN0b3IodGhpcy53aXJlLCBnZXRQcm92aWRlciwgb3B0aW9ucyk7XG5cdCAgICAgICAgbGV0IGJyb2tlcjtcblx0ICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvdmVycmlkZSkpIHtcblx0ICAgICAgICAgICAgY29uc3QgQnJva2VyQ29uc3RydWN0b3IgPSAoMCwgY29tbW9uX3V0aWxzXzEub3ZlcnJpZGVGcm9tQ29tcG9zYWJsZXMpKC4uLm92ZXJyaWRlKShPdmVycmlkZWFibGVCcm9rZXIpO1xuXHQgICAgICAgICAgICAvLyBXZSBuZWVkIHRvIHVzZSB0aGVzZSBvYmplY3RzIGJlY2F1c2UgcmVtb3ZpbmcgdGhlbSBlbnRpcmVseSB3b3VsZCBiZSBhIGJyZWFraW5nIGNoYW5nZSBhbmQgd2Ugd2FudCBhbiBpbmZvcm1hdGl2ZSBlcnJvclxuXHQgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG5cdCAgICAgICAgICAgIGJyb2tlciA9IG5ldyBCcm9rZXJDb25zdHJ1Y3RvcihvYmplY3RUaGF0VGhyb3dzLCB0aHJvd2luZ0dldFByb3ZpZGVyLCB3YXJuaW5nT3B0c0Nsb25lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgZWxzZSB7XG5cdCAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gdXNlIHRoZXNlIG9iamVjdHMgYmVjYXVzZSByZW1vdmluZyB0aGVtIGVudGlyZWx5IHdvdWxkIGJlIGEgYnJlYWtpbmcgY2hhbmdlIGFuZCB3ZSB3YW50IGFuIGluZm9ybWF0aXZlIGVycm9yXG5cdCAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3Jcblx0ICAgICAgICAgICAgYnJva2VyID0gYXdhaXQgb3ZlcnJpZGUoT3ZlcnJpZGVhYmxlQnJva2VyLCBvYmplY3RUaGF0VGhyb3dzLCB0aHJvd2luZ0dldFByb3ZpZGVyLCB3YXJuaW5nT3B0c0Nsb25lKTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgKDAsIG92ZXJyaWRlQ2hlY2tfMS5vdmVycmlkZUNoZWNrKShicm9rZXIsIG9wdGlvbnMuZmRjM1ZlcnNpb24pO1xuXHQgICAgICAgIHJldHVybiBicm9rZXI7XG5cdCAgICB9XG5cdCAgICAvKipcblx0ICAgICAqIENvbm5lY3RzIGEgY2xpZW50IHRvIGFuIEludGVyb3AgYnJva2VyLiBUaGlzIGlzIGNhbGxlZCB1bmRlci10aGUtaG9vZCBmb3IgVmlld3MgaW4gYSBQbGF0Zm9ybS5cblx0ICAgICAqXG5cdCAgICAgKiBAcmVtYXJrc1xuXHQgICAgICogQHBhcmFtIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgSW50ZXJvcCBCcm9rZXIgdG8gY29ubmVjdCB0by4gRm9yIFBsYXRmb3JtcywgdGhpcyB3aWxsIGRlZmF1bHQgdG8gdGhlIHV1aWQgb2YgdGhlIFBsYXRmb3JtLlxuXHQgICAgICogQHBhcmFtIGludGVyb3BDb25maWcgLSBJbmZvcm1hdGlvbiByZWxldmFudCB0byB0aGUgSW50ZXJvcCBCcm9rZXIuIFR5cGljYWxseSBhIGRlY2xhcmF0aW9uIG9mXG5cdCAgICAgKiB3aGF0IGNvbnRleHQocykgdGhlIGVudGl0eSB3YW50cyB0byBzdWJzY3JpYmUgdG8sIGFuZCB0aGUgY3VycmVudCBDb250ZXh0IEdyb3VwIG9mIHRoZSBlbnRpdHkuXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqIGBgYGpzXG5cdCAgICAgKiBjb25zdCBpbnRlcm9wQ29uZmlnID0ge1xuXHQgICAgICogICAgIGN1cnJlbnRDb250ZXh0R3JvdXA6ICdncmVlbidcblx0ICAgICAqIH1cblx0ICAgICAqXG5cdCAgICAgKiBjb25zdCBpbnRlcm9wQnJva2VyID0gYXdhaXQgZmluLkludGVyb3AuaW5pdCgnb3BlbmZpbicpO1xuXHQgICAgICogY29uc3QgY2xpZW50ID0gYXdhaXQgZmluLkludGVyb3AuY29ubmVjdFN5bmMoJ29wZW5maW4nLCBpbnRlcm9wQ29uZmlnKTtcblx0ICAgICAqIGNvbnN0IGNvbnRleHRHcm91cEluZm8gPSBhd2FpdCBjbGllbnQuZ2V0SW5mb0ZvckNvbnRleHRHcm91cCgpO1xuXHQgICAgICogY29uc29sZS5sb2coY29udGV4dEdyb3VwSW5mbyk7XG5cdCAgICAgKiBgYGBcblx0ICAgICAqL1xuXHQgICAgY29ubmVjdFN5bmMobmFtZSwgaW50ZXJvcENvbmZpZykge1xuXHQgICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdpbnRlcm9wLWNvbm5lY3Qtc3luYycpLmNhdGNoKCgpID0+IHtcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG5cdCAgICAgICAgfSk7XG5cdCAgICAgICAgcmV0dXJuIG5ldyBJbnRlcm9wQ2xpZW50XzEuSW50ZXJvcENsaWVudCh0aGlzLndpcmUsIHRoaXMud2lyZS5lbnZpcm9ubWVudC53aGVuUmVhZHkoKS50aGVuKCgpID0+IHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGBpbnRlcm9wLWJyb2tlci0ke25hbWV9YCwge1xuXHQgICAgICAgICAgICAgICAgcGF5bG9hZDogaW50ZXJvcENvbmZpZ1xuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9KSk7XG5cdCAgICB9XG5cdH1cblx0RmFjdG9yeSQxLkludGVyb3BNb2R1bGUgPSBJbnRlcm9wTW9kdWxlO1xuXHRyZXR1cm4gRmFjdG9yeSQxO1xufVxuXG52YXIgaGFzUmVxdWlyZWRJbnRlcm9wO1xuXG5mdW5jdGlvbiByZXF1aXJlSW50ZXJvcCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEludGVyb3ApIHJldHVybiBpbnRlcm9wO1xuXHRoYXNSZXF1aXJlZEludGVyb3AgPSAxO1xuXHQoZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0XHQvKipcblx0XHQgKiBFbnRyeSBwb2ludCBmb3IgdGhlIE9wZW5GaW4gYEludGVyb3BgIEFQSSAoYGZpbi5JbnRlcm9wYCkuXG5cdFx0ICpcblx0XHQgKiAqIHtAbGluayBJbnRlcm9wTW9kdWxlfSBjb250YWlucyBzdGF0aWMgbWVtYmVycyBvZiB0aGUgYEludGVyb3BgIEFQSSAoYXZhaWxhYmxlIHVuZGVyIGBmaW4uSW50ZXJvcGApXG5cdFx0ICogKiB7QGxpbmsgSW50ZXJvcENsaWVudH0gYW5kIHtAbGluayBJbnRlcm9wQnJva2VyfSBkb2N1bWVudCBpbnN0YW5jZXMgb2YgdGhlaXIgcmVzcGVjdGl2ZSBjbGFzc2VzLlxuXHRcdCAqXG5cdFx0ICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG5cdFx0ICovXG5cdFx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdFx0ICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XG5cdFx0ICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcblx0XHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0XHQgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xuXHRcdCAgICB9XG5cdFx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdFx0fSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcblx0XHQgICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcblx0XHQgICAgb1trMl0gPSBtW2tdO1xuXHRcdH0pKTtcblx0XHR2YXIgX19leHBvcnRTdGFyID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fZXhwb3J0U3RhcikgfHwgZnVuY3Rpb24obSwgZXhwb3J0cykge1xuXHRcdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdFx0fTtcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5cdFx0X19leHBvcnRTdGFyKHJlcXVpcmVGYWN0b3J5KCksIGV4cG9ydHMpO1xuXHRcdF9fZXhwb3J0U3RhcihyZXF1aXJlSW50ZXJvcENsaWVudCgpLCBleHBvcnRzKTtcblx0XHRfX2V4cG9ydFN0YXIocmVxdWlyZUludGVyb3BCcm9rZXIoKSwgZXhwb3J0cyk7IFxuXHR9IChpbnRlcm9wKSk7XG5cdHJldHVybiBpbnRlcm9wO1xufVxuXG52YXIgc25hcHNob3RTb3VyY2UgPSB7fTtcblxudmFyIEZhY3RvcnkgPSB7fTtcblxudmFyIEluc3RhbmNlID0ge307XG5cbnZhciB1dGlscyA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkodXRpbHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xudXRpbHMuZ2V0U25hcHNob3RTb3VyY2VDaGFubmVsTmFtZSA9IHZvaWQgMDtcbmNvbnN0IGNoYW5uZWxQcmVmaXggPSAnc25hcHNob3Qtc291cmNlLXByb3ZpZGVyLSc7XG5jb25zdCBnZXRTbmFwc2hvdFNvdXJjZUNoYW5uZWxOYW1lID0gKGlkKSA9PiBgJHtjaGFubmVsUHJlZml4fSR7aWQudXVpZH1gO1xudXRpbHMuZ2V0U25hcHNob3RTb3VyY2VDaGFubmVsTmFtZSA9IGdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWU7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0JDEgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19jbGFzc1ByaXZhdGVGaWVsZFNldCkgfHwgZnVuY3Rpb24gKHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XG59O1xudmFyIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KSB8fCBmdW5jdGlvbiAocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XG59O1xudmFyIF9TbmFwc2hvdFNvdXJjZV9pZGVudGl0eSwgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIF9TbmFwc2hvdFNvdXJjZV9nZXRDbGllbnQsIF9TbmFwc2hvdFNvdXJjZV9zdGFydENvbm5lY3Rpb24sIF9TbmFwc2hvdFNvdXJjZV9zZXRVcENvbm5lY3Rpb25MaXN0ZW5lcjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShJbnN0YW5jZSwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5JbnN0YW5jZS5TbmFwc2hvdFNvdXJjZSA9IHZvaWQgMDtcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cbmNvbnN0IGJhc2VfMSQxID0gYmFzZTtcbmNvbnN0IHV0aWxzXzEkMSA9IHV0aWxzO1xuY29uc3QgY29ubmVjdGlvbk1hcCA9IG5ldyBNYXAoKTtcbi8qKlxuICogRW5hYmxlcyBjb25maWd1cmluZyBhIFNuYXBzaG90U291cmNlIHdpdGggY3VzdG9tIGdldFNuYXBzaG90IGFuZCBhcHBseVNuYXBzaG90IG1ldGhvZHMuXG4gKlxuICogQHR5cGVQYXJhbSBTbmFwc2hvdCBJbXBsZW1lbnRhdGlvbi1kZWZpbmVkIHNoYXBlIG9mIGFuIGFwcGxpY2F0aW9uIHNuYXBzaG90LiAgQWxsb3dzXG4gKiBjdXN0b20gc25hcHNob3QgaW1wbGVtZW50YXRpb25zIGZvciBsZWdhY3kgYXBwbGljYXRpb25zIHRvIGRlZmluZSB0aGVpciBvd24gc25hcHNob3QgZm9ybWF0LlxuICovXG5jbGFzcyBTbmFwc2hvdFNvdXJjZSBleHRlbmRzIGJhc2VfMSQxLkJhc2Uge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUsIGlkKSB7XG4gICAgICAgIHN1cGVyKHdpcmUpO1xuICAgICAgICBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHkuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLnNldCh0aGlzLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWNvbm5lY3Rpb25NYXAuaGFzKHRoaXMuaWRlbnRpdHkudXVpZCkpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uTWFwLnNldCh0aGlzLmlkZW50aXR5LnV1aWQsIHsgZXZlbnRGaXJlZDogbnVsbCwgY2xpZW50UHJvbWlzZTogbnVsbCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb25uZWN0aW9uTWFwLmdldCh0aGlzLmlkZW50aXR5LnV1aWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgX1NuYXBzaG90U291cmNlX2dldENsaWVudC5zZXQodGhpcywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmNsaWVudFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmNsaWVudFByb21pc2UgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLCBcImZcIikuY2FsbCh0aGlzKS5jbGllbnRQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbi5zZXQodGhpcywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSAoMCwgdXRpbHNfMSQxLmdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWUpKHRoaXMuaWRlbnRpdHkpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX3NldFVwQ29ubmVjdGlvbkxpc3RlbmVyLCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5maW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNvbm5lY3QoY2hhbm5lbE5hbWUsIHsgd2FpdDogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgY2xpZW50Lm9uRGlzY29ubmVjdGlvbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuY2xpZW50UHJvbWlzZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNsaWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDb25uZWN0aW9uLCBcImZcIikuY2FsbCh0aGlzKS5jbGllbnRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgdGFyZ2V0ZWQgU25hcHNob3RTb3VyY2UgaXMgbm90IGN1cnJlbnRseSBpbml0aWFsaXplZC4gQXdhaXQgdGhpcyBvYmplY3QncyByZWFkeSgpIG1ldGhvZC5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfU25hcHNob3RTb3VyY2Vfc2V0VXBDb25uZWN0aW9uTGlzdGVuZXIuc2V0KHRoaXMsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gKDAsIHV0aWxzXzEkMS5nZXRTbmFwc2hvdFNvdXJjZUNoYW5uZWxOYW1lKSh0aGlzLmlkZW50aXR5KTtcbiAgICAgICAgICAgIGxldCByZXNvbHZlO1xuICAgICAgICAgICAgbGV0IHJlamVjdDtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RmlyZWQgPSBuZXcgUHJvbWlzZSgoeSwgbikgPT4ge1xuICAgICAgICAgICAgICAgIHJlc29sdmUgPSB5O1xuICAgICAgICAgICAgICAgIHJlamVjdCA9IG47XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q29ubmVjdGlvbiwgXCJmXCIpLmNhbGwodGhpcykuZXZlbnRGaXJlZCA9IGV2ZW50RmlyZWQ7XG4gICAgICAgICAgICBjb25zdCBsaXN0ZW5lciA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUuY2hhbm5lbE5hbWUgPT09IGNoYW5uZWxOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwucmVtb3ZlTGlzdGVuZXIoJ2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwub24oJ2Nvbm5lY3RlZCcsIGxpc3RlbmVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHksIGlkLCBcImZcIik7XG4gICAgfVxuICAgIGdldCBpZGVudGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfaWRlbnRpdHksIFwiZlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRvIGRldGVybWluZSBpZiB0aGUgU25hcHNob3RTb3VyY2UgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuXG4gICAgICpcbiAgICAgKiBAcmVtYXJrcyBVc2Ugd2hlbiB0aGUgcGFyZW50IGFwcGxpY2F0aW9uIGlzIHN0YXJ0aW5nIHVwIHRvIGVuc3VyZSB0aGUgU25hcHNob3RTb3VyY2UgaXMgYWJsZSB0byBhY2NlcHQgYW5kXG4gICAgICogYXBwbHkgYSBzbmFwc2hvdCB1c2luZyB0aGUge0BsaW5rIFNuYXBzaG90U291cmNlI2FwcGx5U25hcHNob3QgYXBwbHlTbmFwc2hvdH0gbWV0aG9kLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGBqc1xuICAgICAqIGxldCBzbmFwc2hvdFNvdXJjZSA9IGZpbi5TbmFwc2hvdFNvdXJjZS53cmFwU3luYyhmaW4ubWUpO1xuICAgICAqXG4gICAgICogY29uc3Qgc25hcHNob3RQcm92aWRlciA9IHtcbiAgICAgKiAgICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7IHJldHVybiAnZm9vJyB9LFxuICAgICAqICAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICogICAgICAgY29uc29sZS5sb2coc25hcHNob3QpO1xuICAgICAqICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICogICAgIH1cbiAgICAgKiB9XG4gICAgICogYXdhaXQgZmluLlNuYXBzaG90U291cmNlLmluaXQoc25hcHNob3RQcm92aWRlcik7XG4gICAgICpcbiAgICAgKiB0cnkge1xuICAgICAqICAgYXdhaXQgc25hcHNob3RTb3VyY2UucmVhZHkoKTtcbiAgICAgKiAgIGF3YWl0IHNuYXBzaG90U291cmNlLmFwcGx5U25hcHNob3QoJ2ZvbycpO1xuICAgICAqIH0gY2F0Y2ggKGVycikge1xuICAgICAqICAgY29uc29sZS5sb2coZXJyKVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyByZWFkeSgpIHtcbiAgICAgICAgdGhpcy53aXJlLnNlbmRBY3Rpb24oJ3NuYXBzaG90LXNvdXJjZS1yZWFkeScpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hc3luYy1wcm9taXNlLWV4ZWN1dG9yXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBJZiBnZXRDbGllbnQgd2FzIGFscmVhZHkgY2FsbGVkIGJlZm9yZSB0aGlzLCBkbyB3ZSBoYXZlIGEgdGltaW5nIGlzc3VlIHdoZXJlIHRoZSBjaGFubmVsIG1pZ2h0IGhhdmUgYmVlbiBjcmVhdGVkIGJ1dCB3ZSBtaXNzZWQgdGhlIGV2ZW50IGJ1dCB0aGlzIHN0aWxsIGZhaWxzP1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCQxKHRoaXMsIF9TbmFwc2hvdFNvdXJjZV9nZXRDbGllbnQsIFwiZlwiKS5jYWxsKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBpdCB3YXMgbm90IHJ1bm5pbmcuXG4gICAgICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24sIFwiZlwiKS5jYWxsKHRoaXMpLmV2ZW50RmlyZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbCB0aGUgU25hcHNob3RTb3VyY2UncyBnZXRTbmFwc2hvdCBtZXRob2QgZGVmaW5lZCBieSB7QGxpbmsgU25hcHNob3RTb3VyY2UuU25hcHNob3RTb3VyY2VNb2R1bGUjaW5pdCBpbml0fS5cbiAgICAgKlxuICAgICAqL1xuICAgIGFzeW5jIGdldFNuYXBzaG90KCkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLWdldC1zbmFwc2hvdCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGF3YWl0IF9fY2xhc3NQcml2YXRlRmllbGRHZXQkMSh0aGlzLCBfU25hcHNob3RTb3VyY2VfZ2V0Q2xpZW50LCBcImZcIikuY2FsbCh0aGlzKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgY2xpZW50LmRpc3BhdGNoKCdnZXQtc25hcHNob3QnKSk7XG4gICAgICAgIHJldHVybiAoYXdhaXQgcmVzcG9uc2UpLnNuYXBzaG90O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoZSBTbmFwc2hvdFNvdXJjZSdzIGFwcGx5U25hcHNob3QgbWV0aG9kIGRlZmluZWQgYnkge0BsaW5rIFNuYXBzaG90U291cmNlLlNuYXBzaG90U291cmNlTW9kdWxlI2luaXQgaW5pdH0uXG4gICAgICpcbiAgICAgKi9cbiAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzbmFwc2hvdC1zb3VyY2UtYXBwbHktc25hcHNob3QnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjbGllbnQgPSBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0JDEodGhpcywgX1NuYXBzaG90U291cmNlX2dldENsaWVudCwgXCJmXCIpLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiBjbGllbnQuZGlzcGF0Y2goJ2FwcGx5LXNuYXBzaG90JywgeyBzbmFwc2hvdCB9KTtcbiAgICB9XG59XG5JbnN0YW5jZS5TbmFwc2hvdFNvdXJjZSA9IFNuYXBzaG90U291cmNlO1xuX1NuYXBzaG90U291cmNlX2lkZW50aXR5ID0gbmV3IFdlYWtNYXAoKSwgX1NuYXBzaG90U291cmNlX2dldENvbm5lY3Rpb24gPSBuZXcgV2Vha01hcCgpLCBfU25hcHNob3RTb3VyY2VfZ2V0Q2xpZW50ID0gbmV3IFdlYWtNYXAoKSwgX1NuYXBzaG90U291cmNlX3N0YXJ0Q29ubmVjdGlvbiA9IG5ldyBXZWFrTWFwKCksIF9TbmFwc2hvdFNvdXJjZV9zZXRVcENvbm5lY3Rpb25MaXN0ZW5lciA9IG5ldyBXZWFrTWFwKCk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWN0b3J5LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbkZhY3RvcnkuU25hcHNob3RTb3VyY2VNb2R1bGUgPSB2b2lkIDA7XG5jb25zdCBiYXNlXzEgPSBiYXNlO1xuY29uc3QgSW5zdGFuY2VfMSA9IEluc3RhbmNlO1xuY29uc3QgdXRpbHNfMSA9IHV0aWxzO1xuLyoqXG4gKiBTdGF0aWMgbmFtZXNwYWNlIGZvciBPcGVuRmluIEFQSSBtZXRob2RzIHRoYXQgaW50ZXJhY3Qgd2l0aCB0aGUge0BsaW5rIFNuYXBzaG90U291cmNlfSBjbGFzcywgYXZhaWxhYmxlIHVuZGVyIGBmaW4uU25hcHNob3RTb3VyY2VgLlxuICovXG5jbGFzcyBTbmFwc2hvdFNvdXJjZU1vZHVsZSBleHRlbmRzIGJhc2VfMS5CYXNlIHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhIFNuYXBzaG90U291cmNlIHdpdGggdGhlIGdldFNuYXBzaG90IGFuZCBhcHBseVNuYXBzaG90IG1ldGhvZHMgZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIEB0eXBlUGFyYW0gU25hcHNob3QgSW1wbGVtZW50YXRpb24tZGVmaW5lZCBzaGFwZSBvZiBhbiBhcHBsaWNhdGlvbiBzbmFwc2hvdC4gIEFsbG93c1xuICAgICAqIGN1c3RvbSBzbmFwc2hvdCBpbXBsZW1lbnRhdGlvbnMgZm9yIGxlZ2FjeSBhcHBsaWNhdGlvbnMgdG8gZGVmaW5lIHRoZWlyIG93biBzbmFwc2hvdCBmb3JtYXQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgc25hcHNob3RQcm92aWRlciA9IHtcbiAgICAgKiAgICAgYXN5bmMgZ2V0U25hcHNob3QoKSB7XG4gICAgICogICAgICAgY29uc3QgYm91bmRzID0gYXdhaXQgZmluLm1lLmdldEJvdW5kcygpO1xuICAgICAqICAgICAgIHJldHVybiBib3VuZHM7XG4gICAgICogICAgICB9LFxuICAgICAqICAgICBhc3luYyBhcHBseVNuYXBzaG90KHNuYXBzaG90KSB7XG4gICAgICogICAgICAgYXdhaXQgZmluLm1lLnNldEJvdW5kcyhzbmFwc2hvdCk7XG4gICAgICogICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgKiAgICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGF3YWl0IGZpbi5TbmFwc2hvdFNvdXJjZS5pbml0KHNuYXBzaG90UHJvdmlkZXIpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICovXG4gICAgYXN5bmMgaW5pdChwcm92aWRlcikge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLWluaXQnKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgLy8gZG9uJ3QgZXhwb3NlLCBhbmFseXRpY3Mtb25seSBjYWxsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZW9mIHByb3ZpZGVyICE9PSAnb2JqZWN0JyB8fFxuICAgICAgICAgICAgdHlwZW9mIHByb3ZpZGVyLmdldFNuYXBzaG90ICE9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICAgICB0eXBlb2YgcHJvdmlkZXIuYXBwbHlTbmFwc2hvdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd5b3UgbXVzdCBwYXNzIGluIGEgdmFsaWQgU25hcHNob3RQcm92aWRlcicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWwgPSBhd2FpdCB0aGlzLmZpbi5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwuY3JlYXRlKCgwLCB1dGlsc18xLmdldFNuYXBzaG90U291cmNlQ2hhbm5lbE5hbWUpKHRoaXMuZmluLm1lKSk7XG4gICAgICAgIGNoYW5uZWwucmVnaXN0ZXIoJ2dldC1zbmFwc2hvdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgcHJvdmlkZXIuZ2V0U25hcHNob3QoKTtcbiAgICAgICAgICAgIHJldHVybiB7IHNuYXBzaG90IH07XG4gICAgICAgIH0pO1xuICAgICAgICBjaGFubmVsLnJlZ2lzdGVyKCdhcHBseS1zbmFwc2hvdCcsICh7IHNuYXBzaG90IH0pID0+IHByb3ZpZGVyLmFwcGx5U25hcHNob3Qoc25hcHNob3QpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luY2hyb25vdXNseSByZXR1cm5zIGEgU25hcHNob3RTb3VyY2Ugb2JqZWN0IHRoYXQgcmVwcmVzZW50cyB0aGUgY3VycmVudCBTbmFwc2hvdFNvdXJjZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBganNcbiAgICAgKiBjb25zdCBzbmFwc2hvdFNvdXJjZSA9IGZpbi5TbmFwc2hvdFNvdXJjZS53cmFwU3luYyhmaW4ubWUpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlJ3MgZ2V0U25hcHNob3QgbWV0aG9kLCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc25hcHNob3RTb3VyY2UuZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICB3cmFwU3luYyhpZGVudGl0eSkge1xuICAgICAgICB0aGlzLndpcmUuc2VuZEFjdGlvbignc25hcHNob3Qtc291cmNlLXdyYXAtc3luYycpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSW5zdGFuY2VfMS5TbmFwc2hvdFNvdXJjZSh0aGlzLndpcmUsIGlkZW50aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXN5bmNocm9ub3VzbHkgcmV0dXJucyBhIFNuYXBzaG90U291cmNlIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgU25hcHNob3RTb3VyY2UuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3Qgc25hcHNob3RTb3VyY2UgPSBhd2FpdCBmaW4uU25hcHNob3RTb3VyY2Uud3JhcChmaW4ubWUpO1xuICAgICAqIC8vIFVzZSB3cmFwcGVkIGluc3RhbmNlJ3MgZ2V0U25hcHNob3QgbWV0aG9kLCBlLmcuOlxuICAgICAqIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc25hcHNob3RTb3VyY2UuZ2V0U25hcHNob3QoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBhc3luYyB3cmFwKGlkZW50aXR5KSB7XG4gICAgICAgIHRoaXMud2lyZS5zZW5kQWN0aW9uKCdzbmFwc2hvdC1zb3VyY2Utd3JhcCcpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAvLyBkb24ndCBleHBvc2UsIGFuYWx5dGljcy1vbmx5IGNhbGxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLndyYXBTeW5jKGlkZW50aXR5KTtcbiAgICB9XG59XG5GYWN0b3J5LlNuYXBzaG90U291cmNlTW9kdWxlID0gU25hcHNob3RTb3VyY2VNb2R1bGU7XG5cbihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQvKipcblx0ICogRW50cnkgcG9pbnRzIGZvciB0aGUgT3BlbkZpbiBgU25hcHNob3RTb3VyY2VgIEFQSSAoYGZpbi5TbmFwc2hvdFNvdXJjZWApLlxuXHQgKlxuXHQgKiAqIHtAbGluayBTbmFwc2hvdFNvdXJjZU1vZHVsZX0gY29udGFpbnMgc3RhdGljIG1lbWJlcnMgb2YgdGhlIGBTbmFwc2hvdFNvdXJjZWAgQVBJLCBhY2Nlc3NpYmxlIHRocm91Z2ggYGZpbi5TbmFwc2hvdFNvdXJjZWAuXG5cdCAqICoge0BsaW5rIFNuYXBzaG90U291cmNlfSBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gT3BlbkZpbiBTbmFwc2hvdFNvdXJjZSwgZS5nLiBhcyByZXR1cm5lZCBieSBgZmluLlNuYXBzaG90U291cmNlLndyYXBgLlxuXHQgKlxuXHQgKiBUaGVzZSBhcmUgc2VwYXJhdGUgY29kZSBlbnRpdGllcywgYW5kIGFyZSBkb2N1bWVudGVkIHNlcGFyYXRlbHkuICBJbiB0aGUgW3ByZXZpb3VzIHZlcnNpb24gb2YgdGhlIEFQSSBkb2N1bWVudGF0aW9uXShodHRwczovL2Nkbi5vcGVuZmluLmNvL2RvY3MvamF2YXNjcmlwdC8zMi4xMTQuNzYuMTAvaW5kZXguaHRtbCksXG5cdCAqIGJvdGggb2YgdGhlc2Ugd2VyZSBkb2N1bWVudGVkIG9uIHRoZSBzYW1lIHBhZ2UuXG5cdCAqXG5cdCAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuXHQgKi9cblx0dmFyIF9fY3JlYXRlQmluZGluZyA9IChjb21tb25qc0dsb2JhbCAmJiBjb21tb25qc0dsb2JhbC5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xuXHQgICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcblx0ICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcblx0ICAgIH1cblx0ICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XG5cdH0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG5cdCAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuXHQgICAgb1trMl0gPSBtW2tdO1xuXHR9KSk7XG5cdHZhciBfX2V4cG9ydFN0YXIgPSAoY29tbW9uanNHbG9iYWwgJiYgY29tbW9uanNHbG9iYWwuX19leHBvcnRTdGFyKSB8fCBmdW5jdGlvbihtLCBleHBvcnRzKSB7XG5cdCAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG5cdH07XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcblx0X19leHBvcnRTdGFyKEZhY3RvcnksIGV4cG9ydHMpO1xuXHRfX2V4cG9ydFN0YXIoSW5zdGFuY2UsIGV4cG9ydHMpOyBcbn0gKHNuYXBzaG90U291cmNlKSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShmaW4kMiwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgRmluXzEgPSBmaW4kMi5GaW4gPSB2b2lkIDA7XG5jb25zdCBldmVudHNfMSQzID0gcmVxdWlyZSQkMDtcbi8vIEltcG9ydCBmcm9tIHRoZSBmaWxlIHJhdGhlciB0aGFuIHRoZSBkaXJlY3RvcnkgaW4gY2FzZSBzb21lb25lIGNvbnN1bWluZyB0eXBlcyBpcyB1c2luZyBtb2R1bGUgcmVzb2x1dGlvbiBvdGhlciB0aGFuIFwibm9kZVwiXG5jb25zdCBpbmRleF8xID0gc3lzdGVtO1xuY29uc3QgaW5kZXhfMiA9IHJlcXVpcmVXaW5kb3coKTtcbmNvbnN0IGluZGV4XzMgPSByZXF1aXJlQXBwbGljYXRpb24oKTtcbmNvbnN0IGluZGV4XzQgPSBpbnRlcmFwcGJ1cztcbmNvbnN0IGluZGV4XzUgPSBjbGlwYm9hcmQ7XG5jb25zdCBpbmRleF82ID0gZXh0ZXJuYWxBcHBsaWNhdGlvbjtcbmNvbnN0IGluZGV4XzcgPSBmcmFtZTtcbmNvbnN0IGluZGV4XzggPSBnbG9iYWxIb3RrZXk7XG5jb25zdCBpbmRleF85ID0gcmVxdWlyZVZpZXcoKTtcbmNvbnN0IGluZGV4XzEwID0gcGxhdGZvcm07XG5jb25zdCBtZV8xJDIgPSBtZTtcbmNvbnN0IGludGVyb3BfMSA9IHJlcXVpcmVJbnRlcm9wKCk7XG5jb25zdCBzbmFwc2hvdF9zb3VyY2VfMSA9IHNuYXBzaG90U291cmNlO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgRmluIGV4dGVuZHMgZXZlbnRzXzEkMy5FdmVudEVtaXR0ZXIge1xuICAgIC8qKlxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHdpcmUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy53aXJlID0gd2lyZTtcbiAgICAgICAgdGhpcy5TeXN0ZW0gPSBuZXcgaW5kZXhfMS5TeXN0ZW0od2lyZSk7XG4gICAgICAgIHRoaXMuV2luZG93ID0gbmV3IGluZGV4XzIuX1dpbmRvd01vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5BcHBsaWNhdGlvbiA9IG5ldyBpbmRleF8zLkFwcGxpY2F0aW9uTW9kdWxlKHdpcmUpO1xuICAgICAgICB0aGlzLkludGVyQXBwbGljYXRpb25CdXMgPSBuZXcgaW5kZXhfNC5JbnRlckFwcGxpY2F0aW9uQnVzKHdpcmUpO1xuICAgICAgICB0aGlzLkNsaXBib2FyZCA9IG5ldyBpbmRleF81LkNsaXBib2FyZCh3aXJlKTtcbiAgICAgICAgdGhpcy5FeHRlcm5hbEFwcGxpY2F0aW9uID0gbmV3IGluZGV4XzYuRXh0ZXJuYWxBcHBsaWNhdGlvbk1vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5GcmFtZSA9IG5ldyBpbmRleF83Ll9GcmFtZU1vZHVsZSh3aXJlKTtcbiAgICAgICAgdGhpcy5HbG9iYWxIb3RrZXkgPSBuZXcgaW5kZXhfOC5HbG9iYWxIb3RrZXkod2lyZSk7XG4gICAgICAgIHRoaXMuUGxhdGZvcm0gPSBuZXcgaW5kZXhfMTAuUGxhdGZvcm1Nb2R1bGUod2lyZSwgdGhpcy5JbnRlckFwcGxpY2F0aW9uQnVzLkNoYW5uZWwpO1xuICAgICAgICB0aGlzLlZpZXcgPSBuZXcgaW5kZXhfOS5WaWV3TW9kdWxlKHdpcmUpO1xuICAgICAgICB0aGlzLkludGVyb3AgPSBuZXcgaW50ZXJvcF8xLkludGVyb3BNb2R1bGUod2lyZSk7XG4gICAgICAgIHRoaXMuU25hcHNob3RTb3VyY2UgPSBuZXcgc25hcHNob3Rfc291cmNlXzEuU25hcHNob3RTb3VyY2VNb2R1bGUod2lyZSk7XG4gICAgICAgIHdpcmUucmVnaXN0ZXJGaW4odGhpcyk7XG4gICAgICAgIHRoaXMubWUgPSAoMCwgbWVfMSQyLmdldE1lKSh3aXJlKTtcbiAgICAgICAgLy8gSGFuZGxlIGRpc2Nvbm5lY3QgZXZlbnRzXG4gICAgICAgIHdpcmUub24oJ2Rpc2Nvbm5lY3RlZCcsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdGVkJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbkZpbl8xID0gZmluJDIuRmluID0gRmluO1xuXG52YXIgdHJhbnNwb3J0ID0ge307XG5cbnZhciB3aXJlID0ge307XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aXJlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbndpcmUuaXNJbnRlcm5hbENvbm5lY3RDb25maWcgPSB3aXJlLmlzUG9ydERpc2NvdmVyeUNvbmZpZyA9IHdpcmUuaXNOZXdDb25uZWN0Q29uZmlnID0gd2lyZS5pc0NvbmZpZ1dpdGhSZWNlaXZlciA9IHdpcmUuaXNSZW1vdGVDb25maWcgPSB3aXJlLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnID0gd2lyZS5pc0V4dGVybmFsQ29uZmlnID0gdm9pZCAwO1xuZnVuY3Rpb24gaXNFeHRlcm5hbENvbmZpZyhjb25maWcpIHtcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5tYW5pZmVzdFVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbndpcmUuaXNFeHRlcm5hbENvbmZpZyA9IGlzRXh0ZXJuYWxDb25maWc7XG5mdW5jdGlvbiBpc0V4aXN0aW5nQ29ubmVjdENvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaGFzVXVpZChjb25maWcpICYmIHR5cGVvZiBjb25maWcuYWRkcmVzcyA9PT0gJ3N0cmluZyc7XG59XG53aXJlLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnID0gaXNFeGlzdGluZ0Nvbm5lY3RDb25maWc7XG5mdW5jdGlvbiBpc1JlbW90ZUNvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaXNFeGlzdGluZ0Nvbm5lY3RDb25maWcoY29uZmlnKSAmJiB0eXBlb2YgY29uZmlnLnRva2VuID09PSAnc3RyaW5nJztcbn1cbndpcmUuaXNSZW1vdGVDb25maWcgPSBpc1JlbW90ZUNvbmZpZztcbmZ1bmN0aW9uIGlzQ29uZmlnV2l0aFJlY2VpdmVyKGNvbmZpZykge1xuICAgIHJldHVybiB0eXBlb2YgY29uZmlnLnJlY2VpdmVyID09PSAnb2JqZWN0JyAmJiBpc1JlbW90ZUNvbmZpZyh7IC4uLmNvbmZpZywgYWRkcmVzczogJycgfSk7XG59XG53aXJlLmlzQ29uZmlnV2l0aFJlY2VpdmVyID0gaXNDb25maWdXaXRoUmVjZWl2ZXI7XG5mdW5jdGlvbiBoYXNVdWlkKGNvbmZpZykge1xuICAgIHJldHVybiB0eXBlb2YgY29uZmlnLnV1aWQgPT09ICdzdHJpbmcnO1xufVxuZnVuY3Rpb24gaGFzUnVudGltZVZlcnNpb24oY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ydW50aW1lICYmIHR5cGVvZiBjb25maWcucnVudGltZS52ZXJzaW9uID09PSAnc3RyaW5nJztcbn1cbmZ1bmN0aW9uIGlzTmV3Q29ubmVjdENvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gaGFzVXVpZChjb25maWcpICYmIGhhc1J1bnRpbWVWZXJzaW9uKGNvbmZpZyk7XG59XG53aXJlLmlzTmV3Q29ubmVjdENvbmZpZyA9IGlzTmV3Q29ubmVjdENvbmZpZztcbmZ1bmN0aW9uIGlzUG9ydERpc2NvdmVyeUNvbmZpZyhjb25maWcpIHtcbiAgICByZXR1cm4gKGlzRXh0ZXJuYWxDb25maWcoY29uZmlnKSAmJiBoYXNSdW50aW1lVmVyc2lvbihjb25maWcpKSB8fCBpc05ld0Nvbm5lY3RDb25maWcoY29uZmlnKTtcbn1cbndpcmUuaXNQb3J0RGlzY292ZXJ5Q29uZmlnID0gaXNQb3J0RGlzY292ZXJ5Q29uZmlnO1xuZnVuY3Rpb24gaXNJbnRlcm5hbENvbm5lY3RDb25maWcoY29uZmlnKSB7XG4gICAgcmV0dXJuIGlzRXhpc3RpbmdDb25uZWN0Q29uZmlnKGNvbmZpZykgfHwgaXNOZXdDb25uZWN0Q29uZmlnKGNvbmZpZyk7XG59XG53aXJlLmlzSW50ZXJuYWxDb25uZWN0Q29uZmlnID0gaXNJbnRlcm5hbENvbm5lY3RDb25maWc7XG5cbnZhciBldmVudEFnZ3JlZ2F0b3IgPSB7fTtcblxudmFyIGVtaXR0ZXJNYXAgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGVtaXR0ZXJNYXAsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZW1pdHRlck1hcC5FbWl0dGVyTWFwID0gdm9pZCAwO1xuY29uc3QgZXZlbnRzXzEkMiA9IHJlcXVpcmUkJDA7XG5jbGFzcyBFbWl0dGVyTWFwIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zdG9yYWdlID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2xhc3MtbWV0aG9kcy11c2UtdGhpc1xuICAgIGhhc2hLZXlzKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaGVkID0ga2V5cy5tYXAobm9ybWFsaXplU3RyaW5nKTtcbiAgICAgICAgcmV0dXJuIGhhc2hlZC5qb2luKCcvJyk7XG4gICAgfVxuICAgIGdldE9yQ3JlYXRlKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaEtleXMoa2V5cyk7XG4gICAgICAgIGlmICghdGhpcy5zdG9yYWdlLmhhcyhoYXNoKSkge1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLnNldChoYXNoLCBuZXcgZXZlbnRzXzEkMi5FdmVudEVtaXR0ZXIoKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2Ugc2V0IGl0IGFib3ZlXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZ2V0KGhhc2gpO1xuICAgIH1cbiAgICBoYXMoa2V5cykge1xuICAgICAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmhhcyh0aGlzLmhhc2hLZXlzKGtleXMpKTtcbiAgICB9XG4gICAgZGVsZXRlKGtleXMpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuaGFzaEtleXMoa2V5cyk7XG4gICAgICAgIHJldHVybiB0aGlzLnN0b3JhZ2UuZGVsZXRlKGhhc2gpO1xuICAgIH1cbn1cbmVtaXR0ZXJNYXAuRW1pdHRlck1hcCA9IEVtaXR0ZXJNYXA7XG5mdW5jdGlvbiBub3JtYWxpemVTdHJpbmcocykge1xuICAgIGNvbnN0IGIgPSBCdWZmZXIuZnJvbShzKTtcbiAgICByZXR1cm4gYi50b1N0cmluZygnYmFzZTY0Jyk7XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShldmVudEFnZ3JlZ2F0b3IsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuY29uc3QgZW1pdHRlck1hcF8xID0gZW1pdHRlck1hcDtcbmZ1bmN0aW9uIGlzRXZlbnRNZXNzYWdlKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbWVzc2FnZS5hY3Rpb24gPT09ICdwcm9jZXNzLWRlc2t0b3AtZXZlbnQnO1xufVxuZnVuY3Rpb24gbWFwS2V5RnJvbUV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgeyB0b3BpYyB9ID0gZXZlbnQ7XG4gICAgaWYgKHRvcGljID09PSAnZnJhbWUnIHx8IHRvcGljID09PSAnd2luZG93JyB8fCB0b3BpYyA9PT0gJ3ZpZXcnKSB7XG4gICAgICAgIGNvbnN0IHsgdXVpZCwgbmFtZSB9ID0gZXZlbnQ7XG4gICAgICAgIHJldHVybiBbdG9waWMsIHV1aWQsIG5hbWVdO1xuICAgIH1cbiAgICBpZiAodG9waWMgPT09ICdhcHBsaWNhdGlvbicpIHtcbiAgICAgICAgY29uc3QgeyB1dWlkIH0gPSBldmVudDtcbiAgICAgICAgcmV0dXJuIFt0b3BpYywgdXVpZF07XG4gICAgfVxuICAgIHJldHVybiBbdG9waWNdO1xufVxuY2xhc3MgRXZlbnRBZ2dyZWdhdG9yIGV4dGVuZHMgZW1pdHRlck1hcF8xLkVtaXR0ZXJNYXAge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQgPSAobWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzRXZlbnRNZXNzYWdlKG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwYXlsb2FkIH0gPSBtZXNzYWdlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjY2Vzc29yID0gbWFwS2V5RnJvbUV2ZW50KHBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhcyhhY2Nlc3NvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRPckNyZWF0ZShhY2Nlc3NvcikuZW1pdChwYXlsb2FkLnR5cGUsIHBheWxvYWQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgfVxufVxuZXZlbnRBZ2dyZWdhdG9yLmRlZmF1bHQgPSBFdmVudEFnZ3JlZ2F0b3I7XG5cbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRTZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xufTtcbnZhciBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9fY2xhc3NQcml2YXRlRmllbGRHZXQpIHx8IGZ1bmN0aW9uIChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcbn07XG52YXIgX19pbXBvcnREZWZhdWx0ID0gKGNvbW1vbmpzR2xvYmFsICYmIGNvbW1vbmpzR2xvYmFsLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgXCJkZWZhdWx0XCI6IG1vZCB9O1xufTtcbnZhciBfVHJhbnNwb3J0X3dpcmUsIF9UcmFuc3BvcnRfZmluO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHRyYW5zcG9ydCwgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG52YXIgVHJhbnNwb3J0XzEgPSB0cmFuc3BvcnQuVHJhbnNwb3J0ID0gdm9pZCAwO1xuY29uc3QgZXZlbnRzXzEkMSA9IHJlcXVpcmUkJDA7XG5jb25zdCB3aXJlXzEgPSB3aXJlO1xuY29uc3QgdHJhbnNwb3J0X2Vycm9yc18xID0gdHJhbnNwb3J0RXJyb3JzO1xuY29uc3QgZXZlbnRBZ2dyZWdhdG9yXzEgPSBfX2ltcG9ydERlZmF1bHQoZXZlbnRBZ2dyZWdhdG9yKTtcbmNvbnN0IG1lXzEkMSA9IG1lO1xuY29uc3QgZXJyb3JzXzEgPSBlcnJvcnM7XG5jbGFzcyBUcmFuc3BvcnQgZXh0ZW5kcyBldmVudHNfMSQxLkV2ZW50RW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IoV2lyZVR5cGUsIGVudmlyb25tZW50LCBjb25maWcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy53aXJlTGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLnRvcGljUmVmTWFwID0gbmV3IE1hcCgpO1xuICAgICAgICB0aGlzLmV2ZW50QWdncmVnYXRvciA9IG5ldyBldmVudEFnZ3JlZ2F0b3JfMS5kZWZhdWx0KCk7XG4gICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXJzID0gW3RoaXMuZXZlbnRBZ2dyZWdhdG9yLmRpc3BhdGNoRXZlbnRdO1xuICAgICAgICBfVHJhbnNwb3J0X3dpcmUuc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIC8vIFR5cGluZyBhcyB1bmtub3duIHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHNob3VsZCBub3QgYmUgdXNlZCBkaXJlY3RseS5cbiAgICAgICAgX1RyYW5zcG9ydF9maW4uc2V0KHRoaXMsIHZvaWQgMCk7XG4gICAgICAgIHRoaXMuY29ubmVjdFN5bmMgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3aXJlID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKTtcbiAgICAgICAgICAgIHdpcmUuY29ubmVjdFN5bmMoKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IHVzZWQgaW4gb3VyIHRlc3RzLlxuICAgICAgICB0aGlzLmdldFBvcnQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3aXJlID0gX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKTtcbiAgICAgICAgICAgIHJldHVybiB3aXJlLmdldFBvcnQoKTtcbiAgICAgICAgfTtcbiAgICAgICAgX19jbGFzc1ByaXZhdGVGaWVsZFNldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIG5ldyBXaXJlVHlwZSh0aGlzLm9ubWVzc2FnZS5iaW5kKHRoaXMpKSwgXCJmXCIpO1xuICAgICAgICB0aGlzLmVudmlyb25tZW50ID0gZW52aXJvbm1lbnQ7XG4gICAgICAgIHRoaXMuc2VuZFJhdyA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIikuc2VuZC5iaW5kKF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIikpO1xuICAgICAgICB0aGlzLnJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIodGhpcy5oYW5kbGVNZXNzYWdlLmJpbmQodGhpcykpO1xuICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpLm9uKCdkaXNjb25uZWN0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFssIHsgaGFuZGxlTmFjayB9XSBvZiB0aGlzLndpcmVMaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgICAgICBoYW5kbGVOYWNrKHsgcmVhc29uOiAnUmVtb3RlIGNvbm5lY3Rpb24gaGFzIGNsb3NlZCcgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndpcmVMaXN0ZW5lcnMuY2xlYXIoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdGVkJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB7IHV1aWQsIG5hbWUgfSA9IGNvbmZpZztcbiAgICAgICAgY29uc3QgZW50aXR5VHlwZSA9IHRoaXMuZW52aXJvbm1lbnQuZ2V0Q3VycmVudEVudGl0eVR5cGUoKTtcbiAgICAgICAgdGhpcy5tZSA9ICgwLCBtZV8xJDEuZ2V0QmFzZU1lKShlbnRpdHlUeXBlLCB1dWlkLCBuYW1lKTtcbiAgICB9XG4gICAgZ2V0RmluKCkge1xuICAgICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIFwiZlwiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBGaW4gb2JqZWN0IHJlZ2lzdGVyZWQgZm9yIHRoaXMgdHJhbnNwb3J0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIFwiZlwiKTtcbiAgICB9XG4gICAgcmVnaXN0ZXJGaW4oX2Zpbikge1xuICAgICAgICBpZiAoX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X2ZpbiwgXCJmXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpbiBvYmplY3QgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkIGZvciB0aGlzIHRyYW5zcG9ydCcpO1xuICAgICAgICB9XG4gICAgICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQodGhpcywgX1RyYW5zcG9ydF9maW4sIF9maW4sIFwiZlwiKTtcbiAgICB9XG4gICAgc2h1dGRvd24oKSB7XG4gICAgICAgIGNvbnN0IHdpcmUgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpO1xuICAgICAgICByZXR1cm4gd2lyZS5zaHV0ZG93bigpO1xuICAgIH1cbiAgICBhc3luYyBjb25uZWN0KGNvbmZpZykge1xuICAgICAgICBpZiAoKDAsIHdpcmVfMS5pc0NvbmZpZ1dpdGhSZWNlaXZlcikoY29uZmlnKSkge1xuICAgICAgICAgICAgYXdhaXQgX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfVHJhbnNwb3J0X3dpcmUsIFwiZlwiKS5jb25uZWN0KGNvbmZpZy5yZWNlaXZlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdXRob3JpemUoY29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoKDAsIHdpcmVfMS5pc1JlbW90ZUNvbmZpZykoY29uZmlnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdFJlbW90ZShjb25maWcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoMCwgd2lyZV8xLmlzRXhpc3RpbmdDb25uZWN0Q29uZmlnKShjb25maWcpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0QnlQb3J0KGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCgwLCB3aXJlXzEuaXNOZXdDb25uZWN0Q29uZmlnKShjb25maWcpKSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0ID0gYXdhaXQgdGhpcy5lbnZpcm9ubWVudC5yZXRyaWV2ZVBvcnQoY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RCeVBvcnQoeyAuLi5jb25maWcsIGFkZHJlc3M6IGB3czovL2xvY2FsaG9zdDoke3BvcnR9YCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBhc3luYyBjb25uZWN0UmVtb3RlKGNvbmZpZykge1xuICAgICAgICBhd2FpdCBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpLmNvbm5lY3QobmV3ICh0aGlzLmVudmlyb25tZW50LmdldFdzQ29uc3RydWN0b3IoKSkoY29uZmlnLmFkZHJlc3MpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0aG9yaXplKGNvbmZpZyk7XG4gICAgfVxuICAgIGFzeW5jIGNvbm5lY3RCeVBvcnQoY29uZmlnKSB7XG4gICAgICAgIGNvbnN0IHsgYWRkcmVzcywgdXVpZCB9ID0gY29uZmlnO1xuICAgICAgICBjb25zdCByZXFBdXRoUGF5bG9hZCA9IHsgLi4uY29uZmlnLCB0eXBlOiAnZmlsZS10b2tlbicgfTtcbiAgICAgICAgY29uc3Qgd2lyZSA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIik7XG4gICAgICAgIGF3YWl0IHdpcmUuY29ubmVjdChuZXcgKHRoaXMuZW52aXJvbm1lbnQuZ2V0V3NDb25zdHJ1Y3RvcigpKShjb25maWcuYWRkcmVzcykpO1xuICAgICAgICBjb25zdCByZXF1ZXN0RXh0QXV0aFJldCA9IGF3YWl0IHRoaXMuc2VuZEFjdGlvbigncmVxdWVzdC1leHRlcm5hbC1hdXRob3JpemF0aW9uJywge1xuICAgICAgICAgICAgdXVpZCxcbiAgICAgICAgICAgIHR5cGU6ICdmaWxlLXRva2VuJ1xuICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgaWYgKHJlcXVlc3RFeHRBdXRoUmV0LmFjdGlvbiAhPT0gJ2V4dGVybmFsLWF1dGhvcml6YXRpb24tcmVzcG9uc2UnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgdHJhbnNwb3J0X2Vycm9yc18xLlVuZXhwZWN0ZWRBY3Rpb25FcnJvcihyZXF1ZXN0RXh0QXV0aFJldC5hY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMuZW52aXJvbm1lbnQud3JpdGVUb2tlbihyZXF1ZXN0RXh0QXV0aFJldC5wYXlsb2FkLmZpbGUsIHJlcXVlc3RFeHRBdXRoUmV0LnBheWxvYWQudG9rZW4pO1xuICAgICAgICByZXR1cm4gdGhpcy5hdXRob3JpemUocmVxQXV0aFBheWxvYWQpO1xuICAgIH1cbiAgICBhc3luYyBhdXRob3JpemUocmVxQXV0aFBheWxvYWQpIHtcbiAgICAgICAgY29uc3QgcmVxdWVzdEF1dGhSZXQgPSBhd2FpdCB0aGlzLnNlbmRBY3Rpb24oJ3JlcXVlc3QtYXV0aG9yaXphdGlvbicsIHJlcUF1dGhQYXlsb2FkLCB0cnVlKTtcbiAgICAgICAgaWYgKHJlcXVlc3RBdXRoUmV0LmFjdGlvbiAhPT0gJ2F1dGhvcml6YXRpb24tcmVzcG9uc2UnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgdHJhbnNwb3J0X2Vycm9yc18xLlVuZXhwZWN0ZWRBY3Rpb25FcnJvcihyZXF1ZXN0QXV0aFJldC5hY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJlcXVlc3RBdXRoUmV0LnBheWxvYWQuc3VjY2VzcyAhPT0gdHJ1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5SdW50aW1lRXJyb3IocmVxdWVzdEF1dGhSZXQucGF5bG9hZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2VuZEFjdGlvbihhY3Rpb24sIHBheWxvYWQgPSB7fSwgdW5jb3JyZWxhdGVkID0gZmFsc2VcbiAgICAvLyBzcGVjaWFsUmVzcG9uc2UgdHlwZSBpcyBvbmx5IHVzZWQgZm9yICdyZXF1ZXN0QXV0aG9yaXphdGlvbidcbiAgICApIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICAgICAgICBsZXQgY2FuY2VsID0gKCkgPT4geyB9O1xuICAgICAgICAvLyBXZSB3YW50IHRoZSBjYWxsc2l0ZSBmcm9tIHRoZSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiwgbm90IGZyb20gaGVyZS5cbiAgICAgICAgY29uc3QgY2FsbFNpdGVzID0gdHJhbnNwb3J0X2Vycm9yc18xLlJ1bnRpbWVFcnJvci5nZXRDYWxsU2l0ZSgxKTtcbiAgICAgICAgY29uc3QgbWVzc2FnZUlkID0gdGhpcy5lbnZpcm9ubWVudC5nZXROZXh0TWVzc2FnZUlkKCk7XG4gICAgICAgIGNvbnN0IHByb20gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjYW5jZWwgPSByZWplY3Q7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgd2lyZSA9IF9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1RyYW5zcG9ydF93aXJlLCBcImZcIik7XG4gICAgICAgICAgICB0aGlzLmFkZFdpcmVMaXN0ZW5lcihtZXNzYWdlSWQsIHJlc29sdmUsIChwYXlsb2FkKSA9PiB0aGlzLm5hY2tIYW5kbGVyKHBheWxvYWQsIHJlamVjdCwgY2FsbFNpdGVzKSwgdW5jb3JyZWxhdGVkKTtcbiAgICAgICAgICAgIHJldHVybiB3aXJlLnNlbmQobXNnKS5jYXRjaChyZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocHJvbSwgeyBjYW5jZWwsIG1lc3NhZ2VJZCB9KTtcbiAgICB9XG4gICAgbmFja0hhbmRsZXIocGF5bG9hZE9yTWVzc2FnZSwgcmVqZWN0LCBjYWxsU2l0ZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkT3JNZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgLy8gTk9URTogdGhpcyBpcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdG8gc3VwcG9ydCBwbGFpbiBzdHJpbmcgcmVqZWN0aW9uc1xuICAgICAgICAgICAgcmVqZWN0KHBheWxvYWRPck1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyB0cmFuc3BvcnRfZXJyb3JzXzEuUnVudGltZUVycm9yKHBheWxvYWRPck1lc3NhZ2UsIGNhbGxTaXRlcykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZlcnJ5QWN0aW9uKG9yaWdEYXRhKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMuZW52aXJvbm1lbnQuZ2V0TmV4dE1lc3NhZ2VJZCgpO1xuICAgICAgICAgICAgb3JpZ0RhdGEubWVzc2FnZUlkID0gaWQ7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlciA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnBheWxvYWQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHdpcmUgPSBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9UcmFuc3BvcnRfd2lyZSwgXCJmXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHdpcmVcbiAgICAgICAgICAgICAgICAuc2VuZChvcmlnRGF0YSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmFkZFdpcmVMaXN0ZW5lcihpZCwgcmVzb2x2ZXIsIChwYXlsb2FkKSA9PiB0aGlzLm5hY2tIYW5kbGVyKHBheWxvYWQsIHJlamVjdCksIGZhbHNlKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2gocmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xuICAgIH1cbiAgICBhZGRXaXJlTGlzdGVuZXIoaWQsIHJlc29sdmUsIGhhbmRsZU5hY2ssIHVuY29ycmVsYXRlZCkge1xuICAgICAgICBpZiAodW5jb3JyZWxhdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnVuY29ycmVsYXRlZExpc3RlbmVyID0gcmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLndpcmVMaXN0ZW5lcnMuaGFzKGlkKSkge1xuICAgICAgICAgICAgaGFuZGxlTmFjayh7XG4gICAgICAgICAgICAgICAgcmVhc29uOiAnRHVwbGljYXRlIGhhbmRsZXIgaWQnLFxuICAgICAgICAgICAgICAgIGVycm9yOiAoMCwgZXJyb3JzXzEuZXJyb3JUb1BPSk8pKG5ldyB0cmFuc3BvcnRfZXJyb3JzXzEuRHVwbGljYXRlQ29ycmVsYXRpb25FcnJvcihTdHJpbmcoaWQpKSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53aXJlTGlzdGVuZXJzLnNldChpZCwgeyByZXNvbHZlLCBoYW5kbGVOYWNrIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRpbWVvdXQgYW5kIHJlamVjdCgpP1xuICAgIH1cbiAgICAvLyBUaGlzIG1ldGhvZCBleGVjdXRlcyBtZXNzYWdlIGhhbmRsZXJzIHVudGlsIHRoZSBfb25lXyB0aGF0IGhhbmRsZXMgdGhlIG1lc3NhZ2UgKHJldHVybnMgdHJ1dGh5KSBoYXMgcnVuXG4gICAgb25tZXNzYWdlKGRhdGEpIHtcbiAgICAgICAgZm9yIChjb25zdCBoIG9mIHRoaXMubWVzc2FnZUhhbmRsZXJzKSB7XG4gICAgICAgICAgICBoLmNhbGwobnVsbCwgZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlTWVzc2FnZShkYXRhKSB7XG4gICAgICAgIGNvbnN0IGlkID0gZGF0YS5jb3JyZWxhdGlvbklkIHx8IE5hTjtcbiAgICAgICAgaWYgKCEoJ2NvcnJlbGF0aW9uSWQnIGluIGRhdGEpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy51bmNvcnJlbGF0ZWRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHRoaXMudW5jb3JyZWxhdGVkTGlzdGVuZXIuY2FsbChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudW5jb3JyZWxhdGVkTGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZW1wdHkgYmxvY2tcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRoaXMud2lyZUxpc3RlbmVycy5oYXMoaWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBXZSBqdXN0IGNoZWNrZWQgZm9yIGV4aXN0ZW5jZSBhYm92ZVxuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIGNvbnN0IHsgcmVzb2x2ZSwgaGFuZGxlTmFjayB9ID0gdGhpcy53aXJlTGlzdGVuZXJzLmdldChpZCk7XG4gICAgICAgICAgICBpZiAoZGF0YS5hY3Rpb24gIT09ICdhY2snKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlTmFjayh7IHJlYXNvbjogJ0RpZCBub3QgcmVjZWl2ZSBhY2sgYWN0aW9uJywgZXJyb3I6ICgwLCBlcnJvcnNfMS5lcnJvclRvUE9KTykobmV3IHRyYW5zcG9ydF9lcnJvcnNfMS5Ob0Fja0Vycm9yKGRhdGEuYWN0aW9uKSkgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghKCdwYXlsb2FkJyBpbiBkYXRhKSkge1xuICAgICAgICAgICAgICAgIC8vIEknbSBub3Qgc3VyZSB3aGVuIHRoaXMgY29kZSB3b3VsZCBhY3R1YWxseSBydW4sIGJ1dCBwYXNzaW5nIGluIHNvbWV0aGluZyB0aGF0IGRvZWVzbid0IGhhdmUgYSByZWFzb24gdG8gdGhlIHJ1bnRpbWVlcnJvciBjb25zdHJ1Y3RvciB3aWxsIG5vdCBlbmQgd2VsbC5cbiAgICAgICAgICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnJlYXNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFjayhkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUmVjZWl2ZWQgaW52YWxpZCByZXNwb25zZSBmcm9tIGNvcmUnLCBkYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlTmFjayh7IHJlYXNvbjogJ2ludmFsaWQgcmVzcG9uc2Ugc2hhcGUnIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFkYXRhLnBheWxvYWQuc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIGhhbmRsZU5hY2soZGF0YS5wYXlsb2FkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc29sdmUuY2FsbChudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2lyZUxpc3RlbmVycy5kZWxldGUoaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cblRyYW5zcG9ydF8xID0gdHJhbnNwb3J0LlRyYW5zcG9ydCA9IFRyYW5zcG9ydDtcbl9UcmFuc3BvcnRfd2lyZSA9IG5ldyBXZWFrTWFwKCksIF9UcmFuc3BvcnRfZmluID0gbmV3IFdlYWtNYXAoKTtcblxudmFyIG1vY2tFbnZpcm9ubWVudCA9IHt9O1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkobW9ja0Vudmlyb25tZW50LCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNb2NrRW52aXJvbm1lbnRfMSA9IG1vY2tFbnZpcm9ubWVudC5Nb2NrRW52aXJvbm1lbnQgPSB2b2lkIDA7XG5jb25zdCBtZV8xID0gbWU7XG5jbGFzcyBNb2NrRW52aXJvbm1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAnb3RoZXInO1xuICAgICAgICB0aGlzLmNoaWxkVmlld3MgPSB0cnVlO1xuICAgIH1cbiAgICBnZXRBZGFwdGVyVmVyc2lvblN5bmMoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXN5bmMgZ2V0SW50ZXJvcEluZm8oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0RGVmYXVsdENoYW5uZWxPcHRpb25zKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGdldFJ0Y1BlZXIoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgbGF5b3V0QWxsb3dlZEluQ29udGV4dChfZmluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgaW5pdExheW91dE1hbmFnZXIoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXBwbHlMYXlvdXRTbmFwc2hvdCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBhc3luYyBjcmVhdGVMYXlvdXQoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgYXN5bmMgZGVzdHJveUxheW91dCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBhc3luYyByZXNvbHZlTGF5b3V0KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGluaXRQbGF0Zm9ybSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBvYnNlcnZlQm91bmRzKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIHdyaXRlVG9rZW4ocGF0aCwgdG9rZW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICByZXRyaWV2ZVBvcnQoY29uZmlnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0TmV4dE1lc3NhZ2VJZCgpIHtcbiAgICAgICAgcmV0dXJuIGBtb2NrLW1lc3NhZ2UtaWQtJHtNYXRoLnJhbmRvbSgpfWA7XG4gICAgfVxuICAgIGdldFJhbmRvbUlkKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGNyZWF0ZUNoaWxkQ29udGVudChvcHRpb25zKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0V2ViV2luZG93KGlkZW50aXR5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0Q3VycmVudEVudGl0eUlkZW50aXR5KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIGdldEN1cnJlbnRFbnRpdHlUeXBlKCkge1xuICAgICAgICByZXR1cm4gJ3Vua25vd24nO1xuICAgIH1cbiAgICByYWlzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnRBcmdzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZV8xLmVudmlyb25tZW50VW5zdXBwb3J0ZWRNZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0VXJsKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVfMS5lbnZpcm9ubWVudFVuc3VwcG9ydGVkTWVzc2FnZSk7XG4gICAgfVxuICAgIHdoZW5SZWFkeSgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lXzEuZW52aXJvbm1lbnRVbnN1cHBvcnRlZE1lc3NhZ2UpO1xuICAgIH1cbiAgICBnZXRXc0NvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gICAgfVxufVxuTW9ja0Vudmlyb25tZW50XzEgPSBtb2NrRW52aXJvbm1lbnQuTW9ja0Vudmlyb25tZW50ID0gTW9ja0Vudmlyb25tZW50O1xuXG52YXIgbW9ja1dpcmUgPSB7fTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vY2tXaXJlLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbnZhciBNb2NrV2lyZV8xID0gbW9ja1dpcmUuTW9ja1dpcmUgPSB2b2lkIDA7XG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbmNvbnN0IGV2ZW50c18xID0gcmVxdWlyZSQkMDtcbmNsYXNzIE1vY2tXaXJlIGV4dGVuZHMgZXZlbnRzXzEuRXZlbnRFbWl0dGVyIHtcbiAgICBjb25uZWN0KCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IHJ1bm5pbmcgaW4gT3BlbkZpbi4nKTtcbiAgICB9XG4gICAgY29ubmVjdFN5bmMoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignWW91IGFyZSBub3QgcnVubmluZyBpbiBPcGVuRmluLicpO1xuICAgIH1cbiAgICBzZW5kKGRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgYXJlIG5vdCBydW5uaW5nIGluIE9wZW5GaW4uJyk7XG4gICAgfVxuICAgIHNodXRkb3duKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBhcmUgbm90IHJ1bm5pbmcgaW4gT3BlbkZpbi4nKTtcbiAgICB9XG4gICAgZ2V0UG9ydCgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHRyYW5zcG9ydCBoYXMgbm8gcG9ydCcpO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1jb25zdHJ1Y3RvclxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cbn1cbk1vY2tXaXJlXzEgPSBtb2NrV2lyZS5Nb2NrV2lyZSA9IE1vY2tXaXJlO1xuXG5jb25zdCBmaW4kMSA9ICgodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Py5maW4pIHx8XG4gICAgKCgpID0+IHtcbiAgICAgICAgY29uc3QgZW52aXJvbm1lbnQgPSBuZXcgTW9ja0Vudmlyb25tZW50XzEoKTtcbiAgICAgICAgY29uc3QgdHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydF8xKE1vY2tXaXJlXzEsIGVudmlyb25tZW50LCB7XG4gICAgICAgICAgICB1dWlkOiAnJyxcbiAgICAgICAgICAgIG5hbWU6ICcnXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IEZpbl8xKHRyYW5zcG9ydCk7XG4gICAgfSkoKSk7XG5cbmV4cG9ydHMuT3BlbkZpbiA9IE9wZW5GaW4kMTtcbmV4cG9ydHMuZGVmYXVsdCA9IE9wZW5GaW4kMTtcbmV4cG9ydHMuZmluID0gZmluJDE7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBEYXRhVmlldyA9IGdldE5hdGl2ZShyb290LCAnRGF0YVZpZXcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhVmlldztcbiIsInZhciBoYXNoQ2xlYXIgPSByZXF1aXJlKCcuL19oYXNoQ2xlYXInKSxcbiAgICBoYXNoRGVsZXRlID0gcmVxdWlyZSgnLi9faGFzaERlbGV0ZScpLFxuICAgIGhhc2hHZXQgPSByZXF1aXJlKCcuL19oYXNoR2V0JyksXG4gICAgaGFzaEhhcyA9IHJlcXVpcmUoJy4vX2hhc2hIYXMnKSxcbiAgICBoYXNoU2V0ID0gcmVxdWlyZSgnLi9faGFzaFNldCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBoYXNoIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gSGFzaChlbnRyaWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gIHRoaXMuY2xlYXIoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC5cbkhhc2gucHJvdG90eXBlLmNsZWFyID0gaGFzaENsZWFyO1xuSGFzaC5wcm90b3R5cGVbJ2RlbGV0ZSddID0gaGFzaERlbGV0ZTtcbkhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7XG5IYXNoLnByb3RvdHlwZS5oYXMgPSBoYXNoSGFzO1xuSGFzaC5wcm90b3R5cGUuc2V0ID0gaGFzaFNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBIYXNoO1xuIiwidmFyIGxpc3RDYWNoZUNsZWFyID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlQ2xlYXInKSxcbiAgICBsaXN0Q2FjaGVEZWxldGUgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVEZWxldGUnKSxcbiAgICBsaXN0Q2FjaGVHZXQgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVHZXQnKSxcbiAgICBsaXN0Q2FjaGVIYXMgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVIYXMnKSxcbiAgICBsaXN0Q2FjaGVTZXQgPSByZXF1aXJlKCcuL19saXN0Q2FjaGVTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGxpc3QgY2FjaGUgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBMaXN0Q2FjaGUoZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgTGlzdENhY2hlYC5cbkxpc3RDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBsaXN0Q2FjaGVDbGVhcjtcbkxpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlO1xuTGlzdENhY2hlLnByb3RvdHlwZS5nZXQgPSBsaXN0Q2FjaGVHZXQ7XG5MaXN0Q2FjaGUucHJvdG90eXBlLmhhcyA9IGxpc3RDYWNoZUhhcztcbkxpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IExpc3RDYWNoZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgTWFwID0gZ2V0TmF0aXZlKHJvb3QsICdNYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXA7XG4iLCJ2YXIgbWFwQ2FjaGVDbGVhciA9IHJlcXVpcmUoJy4vX21hcENhY2hlQ2xlYXInKSxcbiAgICBtYXBDYWNoZURlbGV0ZSA9IHJlcXVpcmUoJy4vX21hcENhY2hlRGVsZXRlJyksXG4gICAgbWFwQ2FjaGVHZXQgPSByZXF1aXJlKCcuL19tYXBDYWNoZUdldCcpLFxuICAgIG1hcENhY2hlSGFzID0gcmVxdWlyZSgnLi9fbWFwQ2FjaGVIYXMnKSxcbiAgICBtYXBDYWNoZVNldCA9IHJlcXVpcmUoJy4vX21hcENhY2hlU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICovXG5mdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gIHRoaXMuY2xlYXIoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBNYXBDYWNoZWAuXG5NYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyO1xuTWFwQ2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IG1hcENhY2hlRGVsZXRlO1xuTWFwQ2FjaGUucHJvdG90eXBlLmdldCA9IG1hcENhY2hlR2V0O1xuTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzO1xuTWFwQ2FjaGUucHJvdG90eXBlLnNldCA9IG1hcENhY2hlU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcENhY2hlO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBQcm9taXNlID0gZ2V0TmF0aXZlKHJvb3QsICdQcm9taXNlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgU2V0ID0gZ2V0TmF0aXZlKHJvb3QsICdTZXQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBTZXQ7XG4iLCJ2YXIgTWFwQ2FjaGUgPSByZXF1aXJlKCcuL19NYXBDYWNoZScpLFxuICAgIHNldENhY2hlQWRkID0gcmVxdWlyZSgnLi9fc2V0Q2FjaGVBZGQnKSxcbiAgICBzZXRDYWNoZUhhcyA9IHJlcXVpcmUoJy4vX3NldENhY2hlSGFzJyk7XG5cbi8qKlxuICpcbiAqIENyZWF0ZXMgYW4gYXJyYXkgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gU2V0Q2FjaGUodmFsdWVzKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gdmFsdWVzID09IG51bGwgPyAwIDogdmFsdWVzLmxlbmd0aDtcblxuICB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHRoaXMuYWRkKHZhbHVlc1tpbmRleF0pO1xuICB9XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBTZXRDYWNoZWAuXG5TZXRDYWNoZS5wcm90b3R5cGUuYWRkID0gU2V0Q2FjaGUucHJvdG90eXBlLnB1c2ggPSBzZXRDYWNoZUFkZDtcblNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhcztcblxubW9kdWxlLmV4cG9ydHMgPSBTZXRDYWNoZTtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBzdGFja0NsZWFyID0gcmVxdWlyZSgnLi9fc3RhY2tDbGVhcicpLFxuICAgIHN0YWNrRGVsZXRlID0gcmVxdWlyZSgnLi9fc3RhY2tEZWxldGUnKSxcbiAgICBzdGFja0dldCA9IHJlcXVpcmUoJy4vX3N0YWNrR2V0JyksXG4gICAgc3RhY2tIYXMgPSByZXF1aXJlKCcuL19zdGFja0hhcycpLFxuICAgIHN0YWNrU2V0ID0gcmVxdWlyZSgnLi9fc3RhY2tTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc3RhY2sgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gU3RhY2soZW50cmllcykge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG59XG5cbi8vIEFkZCBtZXRob2RzIHRvIGBTdGFja2AuXG5TdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuU3RhY2sucHJvdG90eXBlWydkZWxldGUnXSA9IHN0YWNrRGVsZXRlO1xuU3RhY2sucHJvdG90eXBlLmdldCA9IHN0YWNrR2V0O1xuU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuU3RhY2sucHJvdG90eXBlLnNldCA9IHN0YWNrU2V0O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0YWNrO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIFN5bWJvbCA9IHJvb3QuU3ltYm9sO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN5bWJvbDtcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBVaW50OEFycmF5ID0gcm9vdC5VaW50OEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFVpbnQ4QXJyYXk7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIFdlYWtNYXAgPSBnZXROYXRpdmUocm9vdCwgJ1dlYWtNYXAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBXZWFrTWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZm9yRWFjaGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RWFjaDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheUZpbHRlcihhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICByZXNJbmRleCA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUZpbHRlcjtcbiIsInZhciBiYXNlVGltZXMgPSByZXF1aXJlKCcuL19iYXNlVGltZXMnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vX2lzSW5kZXgnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGluaGVyaXRlZCBTcGVjaWZ5IHJldHVybmluZyBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VLZXlzKHZhbHVlLCBpbmhlcml0ZWQpIHtcbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICBpc0J1ZmYgPSAhaXNBcnIgJiYgIWlzQXJnICYmIGlzQnVmZmVyKHZhbHVlKSxcbiAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmICgoaW5oZXJpdGVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgIGtleSA9PSAnbGVuZ3RoJyB8fFxuICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy5cbiAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgaXNJbmRleChrZXksIGxlbmd0aClcbiAgICAgICAgKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlMaWtlS2V5cztcbiIsIi8qKlxuICogQXBwZW5kcyB0aGUgZWxlbWVudHMgb2YgYHZhbHVlc2AgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtvZmZzZXQgKyBpbmRleF0gPSB2YWx1ZXNbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVB1c2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAqIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5U29tZTtcbiIsInZhciBiYXNlQXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19iYXNlQXNzaWduVmFsdWUnKSxcbiAgICBlcSA9IHJlcXVpcmUoJy4vZXEnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBc3NpZ25zIGB2YWx1ZWAgdG8gYGtleWAgb2YgYG9iamVjdGAgaWYgdGhlIGV4aXN0aW5nIHZhbHVlIGlzIG5vdCBlcXVpdmFsZW50XG4gKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gKi9cbmZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XTtcbiAgaWYgKCEoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYgZXEob2JqVmFsdWUsIHZhbHVlKSkgfHxcbiAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NpZ25WYWx1ZTtcbiIsInZhciBlcSA9IHJlcXVpcmUoJy4vZXEnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgYGtleWAgaXMgZm91bmQgaW4gYGFycmF5YCBvZiBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSBrZXkgVGhlIGtleSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHtcbiAgICAgIHJldHVybiBsZW5ndGg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NvY0luZGV4T2Y7XG4iLCJ2YXIgY29weU9iamVjdCA9IHJlcXVpcmUoJy4vX2NvcHlPYmplY3QnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXNcbiAqIG9yIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25JbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnbkluKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ25JbjtcbiIsInZhciBkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2RlZmluZVByb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGFzc2lnblZhbHVlYCBhbmQgYGFzc2lnbk1lcmdlVmFsdWVgIHdpdGhvdXRcbiAqIHZhbHVlIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgPT0gJ19fcHJvdG9fXycgJiYgZGVmaW5lUHJvcGVydHkpIHtcbiAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIGtleSwge1xuICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAnZW51bWVyYWJsZSc6IHRydWUsXG4gICAgICAndmFsdWUnOiB2YWx1ZSxcbiAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFzc2lnblZhbHVlO1xuIiwidmFyIFN0YWNrID0gcmVxdWlyZSgnLi9fU3RhY2snKSxcbiAgICBhcnJheUVhY2ggPSByZXF1aXJlKCcuL19hcnJheUVhY2gnKSxcbiAgICBhc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Fzc2lnblZhbHVlJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ24nKSxcbiAgICBiYXNlQXNzaWduSW4gPSByZXF1aXJlKCcuL19iYXNlQXNzaWduSW4nKSxcbiAgICBjbG9uZUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQnVmZmVyJyksXG4gICAgY29weUFycmF5ID0gcmVxdWlyZSgnLi9fY29weUFycmF5JyksXG4gICAgY29weVN5bWJvbHMgPSByZXF1aXJlKCcuL19jb3B5U3ltYm9scycpLFxuICAgIGNvcHlTeW1ib2xzSW4gPSByZXF1aXJlKCcuL19jb3B5U3ltYm9sc0luJyksXG4gICAgZ2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2dldEFsbEtleXMnKSxcbiAgICBnZXRBbGxLZXlzSW4gPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzSW4nKSxcbiAgICBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZUFycmF5JyksXG4gICAgaW5pdENsb25lQnlUYWcgPSByZXF1aXJlKCcuL19pbml0Q2xvbmVCeVRhZycpLFxuICAgIGluaXRDbG9uZU9iamVjdCA9IHJlcXVpcmUoJy4vX2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc01hcCA9IHJlcXVpcmUoJy4vaXNNYXAnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKSxcbiAgICBpc1NldCA9IHJlcXVpcmUoJy4vaXNTZXQnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgY2xvbmluZy4gKi9cbnZhciBDTE9ORV9ERUVQX0ZMQUcgPSAxLFxuICAgIENMT05FX0ZMQVRfRkxBRyA9IDIsXG4gICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBzdXBwb3J0ZWQgYnkgYF8uY2xvbmVgLiAqL1xudmFyIGNsb25lYWJsZVRhZ3MgPSB7fTtcbmNsb25lYWJsZVRhZ3NbYXJnc1RhZ10gPSBjbG9uZWFibGVUYWdzW2FycmF5VGFnXSA9XG5jbG9uZWFibGVUYWdzW2FycmF5QnVmZmVyVGFnXSA9IGNsb25lYWJsZVRhZ3NbZGF0YVZpZXdUYWddID1cbmNsb25lYWJsZVRhZ3NbYm9vbFRhZ10gPSBjbG9uZWFibGVUYWdzW2RhdGVUYWddID1cbmNsb25lYWJsZVRhZ3NbZmxvYXQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID1cbmNsb25lYWJsZVRhZ3NbaW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDMyVGFnXSA9IGNsb25lYWJsZVRhZ3NbbWFwVGFnXSA9XG5jbG9uZWFibGVUYWdzW251bWJlclRhZ10gPSBjbG9uZWFibGVUYWdzW29iamVjdFRhZ10gPVxuY2xvbmVhYmxlVGFnc1tyZWdleHBUYWddID0gY2xvbmVhYmxlVGFnc1tzZXRUYWddID1cbmNsb25lYWJsZVRhZ3Nbc3RyaW5nVGFnXSA9IGNsb25lYWJsZVRhZ3Nbc3ltYm9sVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG5jbG9uZWFibGVUYWdzW3VpbnQxNlRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xuY2xvbmVhYmxlVGFnc1tlcnJvclRhZ10gPSBjbG9uZWFibGVUYWdzW2Z1bmNUYWddID1cbmNsb25lYWJsZVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgYW5kIGBfLmNsb25lRGVlcGAgd2hpY2ggdHJhY2tzXG4gKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gKiAgMSAtIERlZXAgY2xvbmVcbiAqICAyIC0gRmxhdHRlbiBpbmhlcml0ZWQgcHJvcGVydGllc1xuICogIDQgLSBDbG9uZSBzeW1ib2xzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjbG9uaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgcGFyZW50IG9iamVjdCBvZiBgdmFsdWVgLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGFuZCB0aGVpciBjbG9uZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgb2JqZWN0LCBzdGFjaykge1xuICB2YXIgcmVzdWx0LFxuICAgICAgaXNEZWVwID0gYml0bWFzayAmIENMT05FX0RFRVBfRkxBRyxcbiAgICAgIGlzRmxhdCA9IGJpdG1hc2sgJiBDTE9ORV9GTEFUX0ZMQUcsXG4gICAgICBpc0Z1bGwgPSBiaXRtYXNrICYgQ0xPTkVfU1lNQk9MU19GTEFHO1xuXG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QsIHN0YWNrKSA6IGN1c3RvbWl6ZXIodmFsdWUpO1xuICB9XG4gIGlmIChyZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSk7XG4gIGlmIChpc0Fycikge1xuICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgcmV0dXJuIGNvcHlBcnJheSh2YWx1ZSwgcmVzdWx0KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHRhZyA9IGdldFRhZyh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7XG5cbiAgICBpZiAoaXNCdWZmZXIodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY2xvbmVCdWZmZXIodmFsdWUsIGlzRGVlcCk7XG4gICAgfVxuICAgIGlmICh0YWcgPT0gb2JqZWN0VGFnIHx8IHRhZyA9PSBhcmdzVGFnIHx8IChpc0Z1bmMgJiYgIW9iamVjdCkpIHtcbiAgICAgIHJlc3VsdCA9IChpc0ZsYXQgfHwgaXNGdW5jKSA/IHt9IDogaW5pdENsb25lT2JqZWN0KHZhbHVlKTtcbiAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgIHJldHVybiBpc0ZsYXRcbiAgICAgICAgICA/IGNvcHlTeW1ib2xzSW4odmFsdWUsIGJhc2VBc3NpZ25JbihyZXN1bHQsIHZhbHVlKSlcbiAgICAgICAgICA6IGNvcHlTeW1ib2xzKHZhbHVlLCBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjbG9uZWFibGVUYWdzW3RhZ10pIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBpc0RlZXApO1xuICAgIH1cbiAgfVxuICAvLyBDaGVjayBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyBhbmQgcmV0dXJuIGl0cyBjb3JyZXNwb25kaW5nIGNsb25lLlxuICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICB2YXIgc3RhY2tlZCA9IHN0YWNrLmdldCh2YWx1ZSk7XG4gIGlmIChzdGFja2VkKSB7XG4gICAgcmV0dXJuIHN0YWNrZWQ7XG4gIH1cbiAgc3RhY2suc2V0KHZhbHVlLCByZXN1bHQpO1xuXG4gIGlmIChpc1NldCh2YWx1ZSkpIHtcbiAgICB2YWx1ZS5mb3JFYWNoKGZ1bmN0aW9uKHN1YlZhbHVlKSB7XG4gICAgICByZXN1bHQuYWRkKGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3ViVmFsdWUsIHZhbHVlLCBzdGFjaykpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKGlzTWFwKHZhbHVlKSkge1xuICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0LnNldChrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBrZXlzRnVuYyA9IGlzRnVsbFxuICAgID8gKGlzRmxhdCA/IGdldEFsbEtleXNJbiA6IGdldEFsbEtleXMpXG4gICAgOiAoaXNGbGF0ID8ga2V5c0luIDoga2V5cyk7XG5cbiAgdmFyIHByb3BzID0gaXNBcnIgPyB1bmRlZmluZWQgOiBrZXlzRnVuYyh2YWx1ZSk7XG4gIGFycmF5RWFjaChwcm9wcyB8fCB2YWx1ZSwgZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgIGlmIChwcm9wcykge1xuICAgICAga2V5ID0gc3ViVmFsdWU7XG4gICAgICBzdWJWYWx1ZSA9IHZhbHVlW2tleV07XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IHBvcHVsYXRlIGNsb25lIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgYXNzaWduVmFsdWUocmVzdWx0LCBrZXksIGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCB2YWx1ZSwgc3RhY2spKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNsb25lO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAqIHByb3BlcnRpZXMgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdG8gVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgaWYgKCFpc09iamVjdChwcm90bykpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgaWYgKG9iamVjdENyZWF0ZSkge1xuICAgICAgcmV0dXJuIG9iamVjdENyZWF0ZShwcm90byk7XG4gICAgfVxuICAgIG9iamVjdC5wcm90b3R5cGUgPSBwcm90bztcbiAgICB2YXIgcmVzdWx0ID0gbmV3IG9iamVjdDtcbiAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDcmVhdGU7XG4iLCJ2YXIgYXJyYXlQdXNoID0gcmVxdWlyZSgnLi9fYXJyYXlQdXNoJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlc1xuICogYGtleXNGdW5jYCBhbmQgYHN5bWJvbHNGdW5jYCB0byBnZXQgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3ltYm9sc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5c0Z1bmMsIHN5bWJvbHNGdW5jKSB7XG4gIHZhciByZXN1bHQgPSBrZXlzRnVuYyhvYmplY3QpO1xuICByZXR1cm4gaXNBcnJheShvYmplY3QpID8gcmVzdWx0IDogYXJyYXlQdXNoKHJlc3VsdCwgc3ltYm9sc0Z1bmMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldEFsbEtleXM7XG4iLCJ2YXIgU3ltYm9sID0gcmVxdWlyZSgnLi9fU3ltYm9sJyksXG4gICAgZ2V0UmF3VGFnID0gcmVxdWlyZSgnLi9fZ2V0UmF3VGFnJyksXG4gICAgb2JqZWN0VG9TdHJpbmcgPSByZXF1aXJlKCcuL19vYmplY3RUb1N0cmluZycpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJyxcbiAgICB1bmRlZmluZWRUYWcgPSAnW29iamVjdCBVbmRlZmluZWRdJztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBgdG9TdHJpbmdUYWdgLlxuICovXG5mdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWRUYWcgOiBudWxsVGFnO1xuICB9XG4gIHJldHVybiAoc3ltVG9TdHJpbmdUYWcgJiYgc3ltVG9TdHJpbmdUYWcgaW4gT2JqZWN0KHZhbHVlKSlcbiAgICA/IGdldFJhd1RhZyh2YWx1ZSlcbiAgICA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0VGFnO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LFxuICovXG5mdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNBcmd1bWVudHM7XG4iLCJ2YXIgYmFzZUlzRXF1YWxEZWVwID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gKiBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAqICAxIC0gVW5vcmRlcmVkIGNvbXBhcmlzb25cbiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gIH1cbiAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzRXF1YWw7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9fZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9fZXF1YWxCeVRhZycpLFxuICAgIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vX2VxdWFsT2JqZWN0cycpLFxuICAgIGdldFRhZyA9IHJlcXVpcmUoJy4vX2dldFRhZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyA9IDE7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZztcbiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihvdGhlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgb2JqSXNBcnIgPSB0cnVlO1xuICAgIG9iaklzT2JqID0gZmFsc2U7XG4gIH1cbiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHtcbiAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICA/IGVxdWFsQXJyYXlzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spXG4gICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgfVxuICBpZiAoIShiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcpKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgZ2V0VGFnID0gcmVxdWlyZSgnLi9fZ2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWFwYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXAodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBtYXBUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzTWFwO1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc01hc2tlZCA9IHJlcXVpcmUoJy4vX2lzTWFza2VkJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgdG9Tb3VyY2UgPSByZXF1aXJlKCcuL190b1NvdXJjZScpO1xuXG4vKipcbiAqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGBcbiAqIFtzeW50YXggY2hhcmFjdGVyc10oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcGF0dGVybnMpLlxuICovXG52YXIgcmVSZWdFeHBDaGFyID0gL1tcXFxcXiQuKis/KClbXFxde318XS9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaG9zdCBjb25zdHJ1Y3RvcnMgKFNhZmFyaSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZSxcbiAgICBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmdW5jVG9TdHJpbmcuY2FsbChoYXNPd25Qcm9wZXJ0eSkucmVwbGFjZShyZVJlZ0V4cENoYXIsICdcXFxcJCYnKVxuICAucmVwbGFjZSgvaGFzT3duUHJvcGVydHl8KGZ1bmN0aW9uKS4qPyg/PVxcXFxcXCgpfCBmb3IgLis/KD89XFxcXFxcXSkvZywgJyQxLio/JykgKyAnJCdcbik7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNOYXRpdmVgIHdpdGhvdXQgYmFkIHNoaW0gY2hlY2tzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICghaXNPYmplY3QodmFsdWUpIHx8IGlzTWFza2VkKHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgcGF0dGVybiA9IGlzRnVuY3Rpb24odmFsdWUpID8gcmVJc05hdGl2ZSA6IHJlSXNIb3N0Q3RvcjtcbiAgcmV0dXJuIHBhdHRlcm4udGVzdCh0b1NvdXJjZSh2YWx1ZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc05hdGl2ZTtcbiIsInZhciBnZXRUYWcgPSByZXF1aXJlKCcuL19nZXRUYWcnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNTZXRgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc2V0LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc1NldCh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBnZXRUYWcodmFsdWUpID09IHNldFRhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNTZXQ7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxudHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxudHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzVHlwZWRBcnJheTtcbiIsInZhciBpc1Byb3RvdHlwZSA9IHJlcXVpcmUoJy4vX2lzUHJvdG90eXBlJyksXG4gICAgbmF0aXZlS2V5cyA9IHJlcXVpcmUoJy4vX25hdGl2ZUtleXMnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VLZXlzKG9iamVjdCkge1xuICBpZiAoIWlzUHJvdG90eXBlKG9iamVjdCkpIHtcbiAgICByZXR1cm4gbmF0aXZlS2V5cyhvYmplY3QpO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGtleSAhPSAnY29uc3RydWN0b3InKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VLZXlzO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBuYXRpdmVLZXlzSW4gPSByZXF1aXJlKCcuL19uYXRpdmVLZXlzSW4nKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5rZXlzSW5gIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gYmFzZUtleXNJbihvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIG5hdGl2ZUtleXNJbihvYmplY3QpO1xuICB9XG4gIHZhciBpc1Byb3RvID0gaXNQcm90b3R5cGUob2JqZWN0KSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShrZXkgPT0gJ2NvbnN0cnVjdG9yJyAmJiAoaXNQcm90byB8fCAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlS2V5c0luO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50aW1lc2Agd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzXG4gKiBvciBtYXggYXJyYXkgbGVuZ3RoIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byBpbnZva2UgYGl0ZXJhdGVlYC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHJlc3VsdHMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUaW1lcyhuLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KG4pO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbikge1xuICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShpbmRleCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVGltZXM7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuYXJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIHN0b3JpbmcgbWV0YWRhdGEuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNhcCBhcmd1bWVudHMgZm9yLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlVW5hcnkoZnVuYykge1xuICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVVuYXJ5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gY2FjaGVIYXMoY2FjaGUsIGtleSkge1xuICByZXR1cm4gY2FjaGUuaGFzKGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FjaGVIYXM7XG4iLCJ2YXIgVWludDhBcnJheSA9IHJlcXVpcmUoJy4vX1VpbnQ4QXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYGFycmF5QnVmZmVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheUJ1ZmZlcn0gYXJyYXlCdWZmZXIgVGhlIGFycmF5IGJ1ZmZlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAqL1xuZnVuY3Rpb24gY2xvbmVBcnJheUJ1ZmZlcihhcnJheUJ1ZmZlcikge1xuICB2YXIgcmVzdWx0ID0gbmV3IGFycmF5QnVmZmVyLmNvbnN0cnVjdG9yKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpO1xuICBuZXcgVWludDhBcnJheShyZXN1bHQpLnNldChuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lQXJyYXlCdWZmZXI7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbnZhciBmcmVlRXhwb3J0cyA9IHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgLiAqL1xudmFyIGZyZWVNb2R1bGUgPSBmcmVlRXhwb3J0cyAmJiB0eXBlb2YgbW9kdWxlID09ICdvYmplY3QnICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZTtcblxuLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbnZhciBtb2R1bGVFeHBvcnRzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBCdWZmZXIgPSBtb2R1bGVFeHBvcnRzID8gcm9vdC5CdWZmZXIgOiB1bmRlZmluZWQsXG4gICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mICBgYnVmZmVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBUaGUgYnVmZmVyIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEByZXR1cm5zIHtCdWZmZXJ9IFJldHVybnMgdGhlIGNsb25lZCBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIGNsb25lQnVmZmVyKGJ1ZmZlciwgaXNEZWVwKSB7XG4gIGlmIChpc0RlZXApIHtcbiAgICByZXR1cm4gYnVmZmVyLnNsaWNlKCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IGJ1ZmZlci5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBhbGxvY1Vuc2FmZSA/IGFsbG9jVW5zYWZlKGxlbmd0aCkgOiBuZXcgYnVmZmVyLmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgYnVmZmVyLmNvcHkocmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZUJ1ZmZlcjtcbiIsInZhciBjbG9uZUFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fY2xvbmVBcnJheUJ1ZmZlcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgZGF0YVZpZXdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVZpZXcgVGhlIGRhdGEgdmlldyB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgZGF0YSB2aWV3LlxuICovXG5mdW5jdGlvbiBjbG9uZURhdGFWaWV3KGRhdGFWaWV3LCBpc0RlZXApIHtcbiAgdmFyIGJ1ZmZlciA9IGlzRGVlcCA/IGNsb25lQXJyYXlCdWZmZXIoZGF0YVZpZXcuYnVmZmVyKSA6IGRhdGFWaWV3LmJ1ZmZlcjtcbiAgcmV0dXJuIG5ldyBkYXRhVmlldy5jb25zdHJ1Y3RvcihidWZmZXIsIGRhdGFWaWV3LmJ5dGVPZmZzZXQsIGRhdGFWaWV3LmJ5dGVMZW5ndGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lRGF0YVZpZXc7XG4iLCIvKiogVXNlZCB0byBtYXRjaCBgUmVnRXhwYCBmbGFncyBmcm9tIHRoZWlyIGNvZXJjZWQgc3RyaW5nIHZhbHVlcy4gKi9cbnZhciByZUZsYWdzID0gL1xcdyokLztcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHJlZ2V4cGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSByZWdleHAgVGhlIHJlZ2V4cCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCByZWdleHAuXG4gKi9cbmZ1bmN0aW9uIGNsb25lUmVnRXhwKHJlZ2V4cCkge1xuICB2YXIgcmVzdWx0ID0gbmV3IHJlZ2V4cC5jb25zdHJ1Y3RvcihyZWdleHAuc291cmNlLCByZUZsYWdzLmV4ZWMocmVnZXhwKSk7XG4gIHJlc3VsdC5sYXN0SW5kZXggPSByZWdleHAubGFzdEluZGV4O1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNsb25lUmVnRXhwO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVmFsdWVPZiA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udmFsdWVPZiA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCBzeW1ib2wgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgcmV0dXJuIHN5bWJvbFZhbHVlT2YgPyBPYmplY3Qoc3ltYm9sVmFsdWVPZi5jYWxsKHN5bWJvbCkpIDoge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVTeW1ib2w7XG4iLCJ2YXIgY2xvbmVBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2Nsb25lQXJyYXlCdWZmZXInKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHR5cGVkQXJyYXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gdHlwZWRBcnJheSBUaGUgdHlwZWQgYXJyYXkgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHR5cGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKHR5cGVkQXJyYXkuYnVmZmVyKSA6IHR5cGVkQXJyYXkuYnVmZmVyO1xuICByZXR1cm4gbmV3IHR5cGVkQXJyYXkuY29uc3RydWN0b3IoYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkubGVuZ3RoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZVR5cGVkQXJyYXk7XG4iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5QXJyYXk7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGJhc2VBc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ25WYWx1ZScpO1xuXG4vKipcbiAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICA/IGN1c3RvbWl6ZXIob2JqZWN0W2tleV0sIHNvdXJjZVtrZXldLCBrZXksIG9iamVjdCwgc291cmNlKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbmV3VmFsdWUgPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gICAgaWYgKGlzTmV3KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5T2JqZWN0O1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKTtcblxuLyoqXG4gKiBDb3BpZXMgb3duIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlTeW1ib2xzKHNvdXJjZSwgb2JqZWN0KSB7XG4gIHJldHVybiBjb3B5T2JqZWN0KHNvdXJjZSwgZ2V0U3ltYm9scyhzb3VyY2UpLCBvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvcHlTeW1ib2xzO1xuIiwidmFyIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgZ2V0U3ltYm9sc0luID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9sc0luJyk7XG5cbi8qKlxuICogQ29waWVzIG93biBhbmQgaW5oZXJpdGVkIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgc3ltYm9scyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlTeW1ib2xzSW4oc291cmNlLCBvYmplY3QpIHtcbiAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzSW4oc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5U3ltYm9sc0luO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbnZhciBjb3JlSnNEYXRhID0gcm9vdFsnX19jb3JlLWpzX3NoYXJlZF9fJ107XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZUpzRGF0YTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgZnVuYyh7fSwgJycsIHt9KTtcbiAgICByZXR1cm4gZnVuYztcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydHk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vX2FycmF5U29tZScpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYGFycmF5YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcsXG4gICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLlxuICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gIH1cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgc2VlbiA9IChiaXRtYXNrICYgQ09NUEFSRV9VTk9SREVSRURfRkxBRykgPyBuZXcgU2V0Q2FjaGUgOiB1bmRlZmluZWQ7XG5cbiAgc3RhY2suc2V0KGFycmF5LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdO1xuXG4gICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIGFyclZhbHVlLCBpbmRleCwgb3RoZXIsIGFycmF5LCBzdGFjaylcbiAgICAgICAgOiBjdXN0b21pemVyKGFyclZhbHVlLCBvdGhWYWx1ZSwgaW5kZXgsIGFycmF5LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNvbXBhcmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoc2Vlbikge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlLCBvdGhJbmRleCkge1xuICAgICAgICAgICAgaWYgKCFjYWNoZUhhcyhzZWVuLCBvdGhJbmRleCkgJiZcbiAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShcbiAgICAgICAgICBhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHxcbiAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICApKSB7XG4gICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpLFxuICAgIFVpbnQ4QXJyYXkgPSByZXF1aXJlKCcuL19VaW50OEFycmF5JyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyksXG4gICAgZXF1YWxBcnJheXMgPSByZXF1aXJlKCcuL19lcXVhbEFycmF5cycpLFxuICAgIG1hcFRvQXJyYXkgPSByZXF1aXJlKCcuL19tYXBUb0FycmF5JyksXG4gICAgc2V0VG9BcnJheSA9IHJlcXVpcmUoJy4vX3NldFRvQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqL1xudmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgKG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IG9iamVjdC5idWZmZXI7XG4gICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjtcblxuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgIWVxdWFsRnVuYyhuZXcgVWludDhBcnJheShvYmplY3QpLCBuZXcgVWludDhBcnJheShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLlxuICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncywgcHJpbWl0aXZlcyBhbmQgb2JqZWN0cyxcbiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmdcbiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcblxuICAgIGNhc2UgbWFwVGFnOlxuICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHO1xuICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIGlmIChzeW1ib2xWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpO1xuICAgICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGdldEFsbEtleXMgPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xudmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgIG9ialByb3BzID0gZ2V0QWxsS2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzUGFydGlhbCA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIHZhciBvYmpTdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBvYmpTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gb2JqZWN0O1xuICB9XG4gIHZhciByZXN1bHQgPSB0cnVlO1xuICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTtcblxuICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICkpIHtcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAocmVzdWx0ICYmICFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsIi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZUdsb2JhbDtcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0QWxsS2V5cztcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9sc0luID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9sc0luJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi9rZXlzSW4nKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgYW5kXG4gKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIGFuZCBzeW1ib2xzLlxuICovXG5mdW5jdGlvbiBnZXRBbGxLZXlzSW4ob2JqZWN0KSB7XG4gIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNJbiwgZ2V0U3ltYm9sc0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRBbGxLZXlzSW47XG4iLCJ2YXIgaXNLZXlhYmxlID0gcmVxdWlyZSgnLi9faXNLZXlhYmxlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187XG4gIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgOiBkYXRhLm1hcDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXBEYXRhO1xuIiwidmFyIGJhc2VJc05hdGl2ZSA9IHJlcXVpcmUoJy4vX2Jhc2VJc05hdGl2ZScpLFxuICAgIGdldFZhbHVlID0gcmVxdWlyZSgnLi9fZ2V0VmFsdWUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG4iLCJ2YXIgb3ZlckFyZyA9IHJlcXVpcmUoJy4vX292ZXJBcmcnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgZ2V0UHJvdG90eXBlID0gb3ZlckFyZyhPYmplY3QuZ2V0UHJvdG90eXBlT2YsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UHJvdG90eXBlO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC5cbiAqL1xuZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gIHZhciBpc093biA9IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHN5bVRvU3RyaW5nVGFnKSxcbiAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICB0cnkge1xuICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHVuZGVmaW5lZDtcbiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIHZhciByZXN1bHQgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgaWYgKHVubWFza2VkKSB7XG4gICAgaWYgKGlzT3duKSB7XG4gICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB0YWc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UmF3VGFnO1xuIiwidmFyIGFycmF5RmlsdGVyID0gcmVxdWlyZSgnLi9fYXJyYXlGaWx0ZXInKSxcbiAgICBzdHViQXJyYXkgPSByZXF1aXJlKCcuL3N0dWJBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLlxuICovXG52YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9scztcbiIsInZhciBhcnJheVB1c2ggPSByZXF1aXJlKCcuL19hcnJheVB1c2gnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBnZXRTeW1ib2xzID0gcmVxdWlyZSgnLi9fZ2V0U3ltYm9scycpLFxuICAgIHN0dWJBcnJheSA9IHJlcXVpcmUoJy4vc3R1YkFycmF5Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVHZXRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAqL1xudmFyIGdldFN5bWJvbHNJbiA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgd2hpbGUgKG9iamVjdCkge1xuICAgIGFycmF5UHVzaChyZXN1bHQsIGdldFN5bWJvbHMob2JqZWN0KSk7XG4gICAgb2JqZWN0ID0gZ2V0UHJvdG90eXBlKG9iamVjdCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9sc0luO1xuIiwidmFyIERhdGFWaWV3ID0gcmVxdWlyZSgnLi9fRGF0YVZpZXcnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBQcm9taXNlID0gcmVxdWlyZSgnLi9fUHJvbWlzZScpLFxuICAgIFNldCA9IHJlcXVpcmUoJy4vX1NldCcpLFxuICAgIFdlYWtNYXAgPSByZXF1aXJlKCcuL19XZWFrTWFwJyksXG4gICAgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICB0b1NvdXJjZSA9IHJlcXVpcmUoJy4vX3RvU291cmNlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICBwcm9taXNlVGFnID0gJ1tvYmplY3QgUHJvbWlzZV0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBtYXBzLCBzZXRzLCBhbmQgd2Vha21hcHMuICovXG52YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXcpLFxuICAgIG1hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShNYXApLFxuICAgIHByb21pc2VDdG9yU3RyaW5nID0gdG9Tb3VyY2UoUHJvbWlzZSksXG4gICAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCksXG4gICAgd2Vha01hcEN0b3JTdHJpbmcgPSB0b1NvdXJjZShXZWFrTWFwKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC5cbiAqL1xudmFyIGdldFRhZyA9IGJhc2VHZXRUYWc7XG5cbi8vIEZhbGxiYWNrIGZvciBkYXRhIHZpZXdzLCBtYXBzLCBzZXRzLCBhbmQgd2VhayBtYXBzIGluIElFIDExIGFuZCBwcm9taXNlcyBpbiBOb2RlLmpzIDwgNi5cbmlmICgoRGF0YVZpZXcgJiYgZ2V0VGFnKG5ldyBEYXRhVmlldyhuZXcgQXJyYXlCdWZmZXIoMSkpKSAhPSBkYXRhVmlld1RhZykgfHxcbiAgICAoTWFwICYmIGdldFRhZyhuZXcgTWFwKSAhPSBtYXBUYWcpIHx8XG4gICAgKFByb21pc2UgJiYgZ2V0VGFnKFByb21pc2UucmVzb2x2ZSgpKSAhPSBwcm9taXNlVGFnKSB8fFxuICAgIChTZXQgJiYgZ2V0VGFnKG5ldyBTZXQpICE9IHNldFRhZykgfHxcbiAgICAoV2Vha01hcCAmJiBnZXRUYWcobmV3IFdlYWtNYXApICE9IHdlYWtNYXBUYWcpKSB7XG4gIGdldFRhZyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIHJlc3VsdCA9IGJhc2VHZXRUYWcodmFsdWUpLFxuICAgICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICBjdG9yU3RyaW5nID0gQ3RvciA/IHRvU291cmNlKEN0b3IpIDogJyc7XG5cbiAgICBpZiAoY3RvclN0cmluZykge1xuICAgICAgc3dpdGNoIChjdG9yU3RyaW5nKSB7XG4gICAgICAgIGNhc2UgZGF0YVZpZXdDdG9yU3RyaW5nOiByZXR1cm4gZGF0YVZpZXdUYWc7XG4gICAgICAgIGNhc2UgbWFwQ3RvclN0cmluZzogcmV0dXJuIG1hcFRhZztcbiAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzogcmV0dXJuIHByb21pc2VUYWc7XG4gICAgICAgIGNhc2Ugc2V0Q3RvclN0cmluZzogcmV0dXJuIHNldFRhZztcbiAgICAgICAgY2FzZSB3ZWFrTWFwQ3RvclN0cmluZzogcmV0dXJuIHdlYWtNYXBUYWc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0VGFnO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0VmFsdWUob2JqZWN0LCBrZXkpIHtcbiAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0VmFsdWU7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgaGFzaC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKi9cbmZ1bmN0aW9uIGhhc2hDbGVhcigpIHtcbiAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9O1xuICB0aGlzLnNpemUgPSAwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hDbGVhcjtcbiIsIi8qKlxuICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIGhhc2guXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoIFRoZSBoYXNoIHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBoYXNoRGVsZXRlKGtleSkge1xuICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICB0aGlzLnNpemUgLT0gcmVzdWx0ID8gMSA6IDA7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaERlbGV0ZTtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqL1xudmFyIEhBU0hfVU5ERUZJTkVEID0gJ19fbG9kYXNoX2hhc2hfdW5kZWZpbmVkX18nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEdldHMgdGhlIGhhc2ggdmFsdWUgZm9yIGBrZXlgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBnZXRcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gaGFzaEdldChrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAobmF0aXZlQ3JlYXRlKSB7XG4gICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSBIQVNIX1VOREVGSU5FRCA/IHVuZGVmaW5lZCA6IHJlc3VsdDtcbiAgfVxuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpID8gZGF0YVtrZXldIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hHZXQ7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgaGFzaCB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICByZXR1cm4gbmF0aXZlQ3JlYXRlID8gKGRhdGFba2V5XSAhPT0gdW5kZWZpbmVkKSA6IGhhc093blByb3BlcnR5LmNhbGwoZGF0YSwga2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoSGFzO1xuIiwidmFyIG5hdGl2ZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX25hdGl2ZUNyZWF0ZScpO1xuXG4vKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKlxuICogU2V0cyB0aGUgaGFzaCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBIYXNoXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGhhc2ggaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIGhhc2hTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7XG4gIGRhdGFba2V5XSA9IChuYXRpdmVDcmVhdGUgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkgPyBIQVNIX1VOREVGSU5FRCA6IHZhbHVlO1xuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoU2V0O1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBJbml0aWFsaXplcyBhbiBhcnJheSBjbG9uZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQXJyYXkoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IG5ldyBhcnJheS5jb25zdHJ1Y3RvcihsZW5ndGgpO1xuXG4gIC8vIEFkZCBwcm9wZXJ0aWVzIGFzc2lnbmVkIGJ5IGBSZWdFeHAjZXhlY2AuXG4gIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgcmVzdWx0LmluZGV4ID0gYXJyYXkuaW5kZXg7XG4gICAgcmVzdWx0LmlucHV0ID0gYXJyYXkuaW5wdXQ7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVBcnJheTtcbiIsInZhciBjbG9uZUFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fY2xvbmVBcnJheUJ1ZmZlcicpLFxuICAgIGNsb25lRGF0YVZpZXcgPSByZXF1aXJlKCcuL19jbG9uZURhdGFWaWV3JyksXG4gICAgY2xvbmVSZWdFeHAgPSByZXF1aXJlKCcuL19jbG9uZVJlZ0V4cCcpLFxuICAgIGNsb25lU3ltYm9sID0gcmVxdWlyZSgnLi9fY2xvbmVTeW1ib2wnKSxcbiAgICBjbG9uZVR5cGVkQXJyYXkgPSByZXF1aXJlKCcuL19jbG9uZVR5cGVkQXJyYXknKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lIGJhc2VkIG9uIGl0cyBgdG9TdHJpbmdUYWdgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY2xvbmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gKiBgQm9vbGVhbmAsIGBEYXRlYCwgYEVycm9yYCwgYE1hcGAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgYFNldGAsIG9yIGBTdHJpbmdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUJ5VGFnKG9iamVjdCwgdGFnLCBpc0RlZXApIHtcbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3I7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBhcnJheUJ1ZmZlclRhZzpcbiAgICAgIHJldHVybiBjbG9uZUFycmF5QnVmZmVyKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgIHJldHVybiBjbG9uZURhdGFWaWV3KG9iamVjdCwgaXNEZWVwKTtcblxuICAgIGNhc2UgZmxvYXQzMlRhZzogY2FzZSBmbG9hdDY0VGFnOlxuICAgIGNhc2UgaW50OFRhZzogY2FzZSBpbnQxNlRhZzogY2FzZSBpbnQzMlRhZzpcbiAgICBjYXNlIHVpbnQ4VGFnOiBjYXNlIHVpbnQ4Q2xhbXBlZFRhZzogY2FzZSB1aW50MTZUYWc6IGNhc2UgdWludDMyVGFnOlxuICAgICAgcmV0dXJuIGNsb25lVHlwZWRBcnJheShvYmplY3QsIGlzRGVlcCk7XG5cbiAgICBjYXNlIG1hcFRhZzpcbiAgICAgIHJldHVybiBuZXcgQ3RvcjtcblxuICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKG9iamVjdCk7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVJlZ0V4cChvYmplY3QpO1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIHJldHVybiBjbG9uZVN5bWJvbChvYmplY3QpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX2Jhc2VDcmVhdGUnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBpc1Byb3RvdHlwZSA9IHJlcXVpcmUoJy4vX2lzUHJvdG90eXBlJyk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNQcm90b3R5cGUob2JqZWN0KSlcbiAgICA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpXG4gICAgOiB7fTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCIvKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAodHlwZSA9PSAnbnVtYmVyJyB8fFxuICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAodHlwZSA9PSAnc3RyaW5nJyB8fCB0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicpXG4gICAgPyAodmFsdWUgIT09ICdfX3Byb3RvX18nKVxuICAgIDogKHZhbHVlID09PSBudWxsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleWFibGU7XG4iLCJ2YXIgY29yZUpzRGF0YSA9IHJlcXVpcmUoJy4vX2NvcmVKc0RhdGEnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbnZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhICYmIGNvcmVKc0RhdGEua2V5cyAmJiBjb3JlSnNEYXRhLmtleXMuSUVfUFJPVE8gfHwgJycpO1xuICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG59KCkpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc01hc2tlZDtcbiIsIi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgcHJvdG8gPSAodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG5cbiAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1Byb3RvdHlwZTtcbiIsIi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gIHRoaXMuX19kYXRhX18gPSBbXTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVDbGVhcjtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBkZWxldGVcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgZGF0YS5wb3AoKTtcbiAgfSBlbHNlIHtcbiAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gIH1cbiAgLS10aGlzLnNpemU7XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZURlbGV0ZTtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZ2V0XG4gKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVHZXQ7XG4iLCJ2YXIgYXNzb2NJbmRleE9mID0gcmVxdWlyZSgnLi9fYXNzb2NJbmRleE9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZUhhcztcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIExpc3RDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICArK3RoaXMuc2l6ZTtcbiAgICBkYXRhLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSBlbHNlIHtcbiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZVNldDtcbiIsInZhciBIYXNoID0gcmVxdWlyZSgnLi9fSGFzaCcpLFxuICAgIExpc3RDYWNoZSA9IHJlcXVpcmUoJy4vX0xpc3RDYWNoZScpLFxuICAgIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpO1xuXG4vKipcbiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICB0aGlzLnNpemUgPSAwO1xuICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgJ21hcCc6IG5ldyAoTWFwIHx8IExpc3RDYWNoZSksXG4gICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVDbGVhcjtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZURlbGV0ZTtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7XG4gIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVHZXQ7XG4iLCJ2YXIgZ2V0TWFwRGF0YSA9IHJlcXVpcmUoJy4vX2dldE1hcERhdGEnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgaGFzXG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZUhhcztcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFNldHMgdGhlIG1hcCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIG1hcENhY2hlU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVTZXQ7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gKi9cbmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcFRvQXJyYXk7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBuYXRpdmVDcmVhdGUgPSBnZXROYXRpdmUoT2JqZWN0LCAnY3JlYXRlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlQ3JlYXRlO1xuIiwidmFyIG92ZXJBcmcgPSByZXF1aXJlKCcuL19vdmVyQXJnJyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVLZXlzID0gb3ZlckFyZyhPYmplY3Qua2V5cywgT2JqZWN0KTtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXRpdmVLZXlzO1xuIiwiLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2VcbiAqIFtgT2JqZWN0LmtleXNgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGV4Y2VwdCB0aGF0IGl0IGluY2x1ZGVzIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIG5hdGl2ZUtleXNJbihvYmplY3QpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBpZiAob2JqZWN0ICE9IG51bGwpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlS2V5c0luO1xuIiwidmFyIGZyZWVHbG9iYWwgPSByZXF1aXJlKCcuL19mcmVlR2xvYmFsJyk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG52YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovXG52YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBwcm9jZXNzYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZVByb2Nlc3MgPSBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwucHJvY2VzcztcblxuLyoqIFVzZWQgdG8gYWNjZXNzIGZhc3RlciBOb2RlLmpzIGhlbHBlcnMuICovXG52YXIgbm9kZVV0aWwgPSAoZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgLy8gVXNlIGB1dGlsLnR5cGVzYCBmb3IgTm9kZS5qcyAxMCsuXG4gICAgdmFyIHR5cGVzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlKCd1dGlsJykudHlwZXM7XG5cbiAgICBpZiAodHlwZXMpIHtcbiAgICAgIHJldHVybiB0eXBlcztcbiAgICB9XG5cbiAgICAvLyBMZWdhY3kgYHByb2Nlc3MuYmluZGluZygndXRpbCcpYCBmb3IgTm9kZS5qcyA8IDEwLlxuICAgIHJldHVybiBmcmVlUHJvY2VzcyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nICYmIGZyZWVQcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKTtcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gbm9kZVV0aWw7XG4iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvYmplY3RUb1N0cmluZztcbiIsIi8qKlxuICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIGFyZ3VtZW50IHRyYW5zZm9ybS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBvdmVyQXJnKGZ1bmMsIHRyYW5zZm9ybSkge1xuICByZXR1cm4gZnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIGZ1bmModHJhbnNmb3JtKGFyZykpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG92ZXJBcmc7XG4iLCJ2YXIgZnJlZUdsb2JhbCA9IHJlcXVpcmUoJy4vX2ZyZWVHbG9iYWwnKTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbnZhciBmcmVlU2VsZiA9IHR5cGVvZiBzZWxmID09ICdvYmplY3QnICYmIHNlbGYgJiYgc2VsZi5PYmplY3QgPT09IE9iamVjdCAmJiBzZWxmO1xuXG4vKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbnZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJvb3Q7XG4iLCIvKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKlxuICogQWRkcyBgdmFsdWVgIHRvIHRoZSBhcnJheSBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgYWRkXG4gKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAqIEBhbGlhcyBwdXNoXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjYWNoZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBzZXRDYWNoZUFkZCh2YWx1ZSkge1xuICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpO1xuICByZXR1cm4gdGhpcztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRDYWNoZUFkZDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTZXRDYWNoZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc2V0Q2FjaGVIYXModmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRDYWNoZUhhcztcbiIsIi8qKlxuICogQ29udmVydHMgYHNldGAgdG8gYW4gYXJyYXkgb2YgaXRzIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHNldCBUaGUgc2V0IHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gc2V0VG9BcnJheShzZXQpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2V0VG9BcnJheTtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBTdGFja1xuICovXG5mdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0NsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrRGVsZXRlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrR2V0O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTdGFja1xuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0hhcztcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xudmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbi8qKlxuICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187XG4gICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpO1xuICB9XG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrU2V0O1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZ1bmNUb1N0cmluZyA9IGZ1bmNQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc291cmNlIGNvZGUuXG4gKi9cbmZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHtcbiAgaWYgKGZ1bmMgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZnVuY1RvU3RyaW5nLmNhbGwoZnVuYyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIChmdW5jICsgJycpO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvU291cmNlO1xuIiwidmFyIGJhc2VDbG9uZSA9IHJlcXVpcmUoJy4vX2Jhc2VDbG9uZScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBjbG9uaW5nLiAqL1xudmFyIENMT05FX0RFRVBfRkxBRyA9IDEsXG4gICAgQ0xPTkVfU1lNQk9MU19GTEFHID0gNDtcblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBjbG9uZXMgYHZhbHVlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDEuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcmVjdXJzaXZlbHkgY2xvbmUuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gKiBAc2VlIF8uY2xvbmVcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbeyAnYSc6IDEgfSwgeyAnYic6IDIgfV07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAqIGNvbnNvbGUubG9nKGRlZXBbMF0gPT09IG9iamVjdHNbMF0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gY2xvbmVEZWVwKHZhbHVlKSB7XG4gIHJldHVybiBiYXNlQ2xvbmUodmFsdWUsIENMT05FX0RFRVBfRkxBRyB8IENMT05FX1NZTUJPTFNfRkxBRyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2xvbmVEZWVwO1xuIiwiLyoqXG4gKiBQZXJmb3JtcyBhXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGVxdWl2YWxlbnQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9O1xuICpcbiAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoJ2EnLCAnYScpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoTmFOLCBOYU4pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBvdGhlciB8fCAodmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXE7XG4iLCJ2YXIgYmFzZUlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9fYmFzZUlzQXJndW1lbnRzJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGBhcmd1bWVudHNgIG9iamVjdCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQXJndW1lbnRzID0gYmFzZUlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID8gYmFzZUlzQXJndW1lbnRzIDogZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwodmFsdWUsICdjYWxsZWUnKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcmd1bWVudHM7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5KGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5O1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLiBBIHZhbHVlIGlzIGNvbnNpZGVyZWQgYXJyYXktbGlrZSBpZiBpdCdzXG4gKiBub3QgYSBmdW5jdGlvbiBhbmQgaGFzIGEgYHZhbHVlLmxlbmd0aGAgdGhhdCdzIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIG9yXG4gKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZSgnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhaXNGdW5jdGlvbih2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKSxcbiAgICBzdHViRmFsc2UgPSByZXF1aXJlKCcuL3N0dWJGYWxzZScpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG52YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4vKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xudmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIEJ1ZmZlciA9IG1vZHVsZUV4cG9ydHMgPyByb290LkJ1ZmZlciA6IHVuZGVmaW5lZDtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUlzQnVmZmVyID0gQnVmZmVyID8gQnVmZmVyLmlzQnVmZmVyIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4zLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNCdWZmZXIobmV3IEJ1ZmZlcigyKSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0J1ZmZlcihuZXcgVWludDhBcnJheSgyKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNCdWZmZXIgPSBuYXRpdmVJc0J1ZmZlciB8fCBzdHViRmFsc2U7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNCdWZmZXI7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL19iYXNlSXNFcXVhbCcpO1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgZGVlcCBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmVcbiAqIGVxdWl2YWxlbnQuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHN1cHBvcnRzIGNvbXBhcmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLFxuICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICogc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkIGFycmF5cy4gYE9iamVjdGAgb2JqZWN0cyBhcmUgY29tcGFyZWRcbiAqIGJ5IHRoZWlyIG93biwgbm90IGluaGVyaXRlZCwgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLiBGdW5jdGlvbnMgYW5kIERPTVxuICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEgfTtcbiAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gKlxuICogXy5pc0VxdWFsKG9iamVjdCwgb3RoZXIpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIG9iamVjdCA9PT0gb3RoZXI7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VxdWFsKHZhbHVlLCBvdGhlcikge1xuICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VxdWFsO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nLFxuICAgIHByb3h5VGFnID0gJ1tvYmplY3QgUHJveHldJztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYEZ1bmN0aW9uYCBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oXyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0Z1bmN0aW9uKC9hYmMvKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIFNhZmFyaSA5IHdoaWNoIHJldHVybnMgJ29iamVjdCcgZm9yIHR5cGVkIGFycmF5cyBhbmQgb3RoZXIgY29uc3RydWN0b3JzLlxuICB2YXIgdGFnID0gYmFzZUdldFRhZyh2YWx1ZSk7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsIi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0xlbmd0aCgzKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzTGVuZ3RoKEluZmluaXR5KTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aCgnMycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsInZhciBiYXNlSXNNYXAgPSByZXF1aXJlKCcuL19iYXNlSXNNYXAnKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzTWFwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNNYXA7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBNYXBgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMy4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTWFwKG5ldyBNYXApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNNYXAobmV3IFdlYWtNYXApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzTWFwID0gbm9kZUlzTWFwID8gYmFzZVVuYXJ5KG5vZGVJc01hcCkgOiBiYXNlSXNNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNNYXA7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0TGlrZTtcbiIsInZhciBiYXNlSXNTZXQgPSByZXF1aXJlKCcuL19iYXNlSXNTZXQnKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzU2V0ID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNTZXQ7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMy4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNldCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU2V0KG5ldyBTZXQpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTZXQobmV3IFdlYWtTZXQpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzU2V0ID0gbm9kZUlzU2V0ID8gYmFzZVVuYXJ5KG5vZGVJc1NldCkgOiBiYXNlSXNTZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTZXQ7XG4iLCJ2YXIgYmFzZUlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vX2Jhc2VJc1R5cGVkQXJyYXknKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVHlwZWRBcnJheTtcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzID0gcmVxdWlyZSgnLi9fYmFzZUtleXMnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy5rZXlzKCdoaScpO1xuICogLy8gPT4gWycwJywgJzEnXVxuICovXG5mdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5cztcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzSW4gPSByZXF1aXJlKCcuL19iYXNlS2V5c0luJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDMuMC4wXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXNJbihuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJywgJ2MnXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBrZXlzSW4ob2JqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5TGlrZShvYmplY3QpID8gYXJyYXlMaWtlS2V5cyhvYmplY3QsIHRydWUpIDogYmFzZUtleXNJbihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBlbXB0eSBhcnJheS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMTMuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgYXJyYXlzID0gXy50aW1lcygyLCBfLnN0dWJBcnJheSk7XG4gKlxuICogY29uc29sZS5sb2coYXJyYXlzKTtcbiAqIC8vID0+IFtbXSwgW11dXG4gKlxuICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gc3R1YkFycmF5KCkge1xuICByZXR1cm4gW107XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3R1YkFycmF5O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEzLjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRpbWVzKDIsIF8uc3R1YkZhbHNlKTtcbiAqIC8vID0+IFtmYWxzZSwgZmFsc2VdXG4gKi9cbmZ1bmN0aW9uIHN0dWJGYWxzZSgpIHtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0dWJGYWxzZTtcbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0aWQ6IG1vZHVsZUlkLFxuXHRcdGxvYWRlZDogZmFsc2UsXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0obW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuXHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIl9fd2VicGFja19yZXF1aXJlX18uZyA9IChmdW5jdGlvbigpIHtcblx0aWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSAnb2JqZWN0JykgcmV0dXJuIGdsb2JhbFRoaXM7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIHRoaXMgfHwgbmV3IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHJldHVybiB3aW5kb3c7XG5cdH1cbn0pKCk7IiwiLy8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5yID0gKGV4cG9ydHMpID0+IHtcblx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG5cdH1cblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5ubWQgPSAobW9kdWxlKSA9PiB7XG5cdG1vZHVsZS5wYXRocyA9IFtdO1xuXHRpZiAoIW1vZHVsZS5jaGlsZHJlbikgbW9kdWxlLmNoaWxkcmVuID0gW107XG5cdHJldHVybiBtb2R1bGU7XG59OyIsImltcG9ydCB0eXBlIE9wZW5GaW4gZnJvbSBcIkBvcGVuZmluL2NvcmVcIjtcbmltcG9ydCB7IGZpbiB9IGZyb20gXCJAb3BlbmZpbi9jb3JlXCI7XG5cbmxldCBmaWxlTmFtZTogc3RyaW5nO1xubGV0IGRlYnVnTG9nU3RyOiBzdHJpbmc7XG5sZXQgZGVidWdMb2dGaWxlOiBGaWxlO1xubGV0IG9wZnNMb2dGaWxlOiBGaWxlO1xuY29uc3QgY2hhbm5lbE5hbWUgPSBgJHtmaW4ubWUuaWRlbnRpdHkudXVpZH0tbG9nZ2VyYDtcbmxldCBjaGFubmVsQ2xpZW50OiBPcGVuRmluLkNoYW5uZWxDbGllbnQ7XG5sZXQgY2hhbm5lbFByb3ZpZGVyOiBPcGVuRmluLkNoYW5uZWxQcm92aWRlcjtcbmxldCBmaWxlSGFuZGxlOiBGaWxlU3lzdGVtRmlsZUhhbmRsZTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGFzeW5jICgpID0+IHtcblx0Y29uc3QgcGxhdGZvcm06IE9wZW5GaW4uUGxhdGZvcm0gPSBmaW4uUGxhdGZvcm0uZ2V0Q3VycmVudFN5bmMoKTtcblx0YXdhaXQgcGxhdGZvcm0ub25jZShcInBsYXRmb3JtLWFwaS1yZWFkeVwiLCBhc3luYyAoKSA9PiBpbml0KCkpO1xuXHRmaW4uUGxhdGZvcm0uaW5pdCh7XG5cdFx0b3ZlcnJpZGVDYWxsYmFjazogYXN5bmMgKFByb3ZpZGVyKSA9PiB7XG5cdFx0XHQvKipcblx0XHRcdCAqIE92ZXJyaWRlIHRoZSBwcm92aWRlciBjbGFzcy5cblx0XHRcdCAqL1xuXHRcdFx0Y2xhc3MgT3ZlcnJpZGUgZXh0ZW5kcyBQcm92aWRlciB7fVxuXHRcdFx0cmV0dXJuIG5ldyBPdmVycmlkZSgpO1xuXHRcdH1cblx0fSkuY2F0Y2goKCkgPT4ge30pO1xufSk7XG5cbi8qKlxuICogUG9wdWxhdGVzIERPTSB3aXRoIHRoZSBVSSBlbGVtZW50cyBhbmQgYWRkcyBsaXN0ZW5lcnMgb2J0YWluaW5nIHNlbGVjdGVkL3N1Ym1pdHRlZCBvcHRpb25zLlxuICovXG5hc3luYyBmdW5jdGlvbiBpbml0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRjb25zdCBsb2dMaXN0RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTFNlbGVjdEVsZW1lbnQ+KFwiI2xvZy1saXN0XCIpO1xuXHRpZiAobG9nTGlzdEVsZW1lbnQpIHtcblx0XHRhd2FpdCBjcmVhdGVMb2dEcm9wRG93bihsb2dMaXN0RWxlbWVudCk7XG5cdFx0bG9nTGlzdEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCBhc3luYyAoc2VsZWN0aW9uQ2hhbmdlRXZlbnQpID0+IHtcblx0XHRcdGZpbGVOYW1lID0gKHNlbGVjdGlvbkNoYW5nZUV2ZW50LnRhcmdldCBhcyBIVE1MT3B0aW9uRWxlbWVudCkudmFsdWU7XG5cdFx0fSk7XG5cdH1cblxuXHRjb25zdCB1cGxvYWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxGb3JtRWxlbWVudD4oXCIjdXBsb2FkLWZvcm1cIik7XG5cdGlmICh1cGxvYWQpIHtcblx0XHR1cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcihcInN1Ym1pdFwiLCB1cGxvYWRIYW5kbGVyKTtcblx0fVxuXG5cdGNvbnN0IHNlbmRBcHBMb2dCdG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxCdXR0b25FbGVtZW50PihcIiNzZW5kLWFwcC1sb2dcIik7XG5cdGlmIChzZW5kQXBwTG9nQnRuKSB7XG5cdFx0c2VuZEFwcExvZ0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgc2VuZEFwcGxpY2F0aW9uTG9ncyk7XG5cdH1cblxuXHRjb25zdCBzZW5kT1BGU0xvZ0J0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEJ1dHRvbkVsZW1lbnQ+KFwiI3NlbmQtb3Bmcy1sb2dcIik7XG5cdGlmIChzZW5kT1BGU0xvZ0J0bikge1xuXHRcdHNlbmRPUEZTTG9nQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBzZW5kT1BGU0xvZ3MpO1xuXHR9XG5cblx0Y29uc3QgY29uc29sZUxvZ0J0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEJ1dHRvbkVsZW1lbnQ+KFwiI2NvbnNvbGUtYXBwLWxvZ1wiKTtcblx0aWYgKGNvbnNvbGVMb2dCdG4pIHtcblx0XHRjb25zb2xlTG9nQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBjb25zb2xlTG9nTWVzc2FnZSk7XG5cdH1cblxuXHRjb25zdCBjaGFubmVsTG9nQnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcjxIVE1MQnV0dG9uRWxlbWVudD4oXCIjY2hhbm5lbC1hcHAtbG9nXCIpO1xuXHRpZiAoY2hhbm5lbExvZ0J0bikge1xuXHRcdGNoYW5uZWxMb2dCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGNoYW5uZWxMb2dNZXNzYWdlKTtcblx0fVxuXG5cdGNvbnN0IGNsZWFyUHJldmlld0J0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEJ1dHRvbkVsZW1lbnQ+KFwiI2NsZWFyLXByZXZpZXdcIik7XG5cdGlmIChjbGVhclByZXZpZXdCdG4pIHtcblx0XHRjbGVhclByZXZpZXdCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGNsZWFyUHJldmlldyk7XG5cdH1cblxuXHRhd2FpdCBzZXR1cENoYW5uZWxDbGllbnRBbmRTZXJ2aWNlKCk7XG59XG5cbi8qKlxuICogU2V0cyB1cCB0aGUgQ2hhbm5lbCBDbGllbnQgYW5kIFNlcnZpY2UuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNldHVwQ2hhbm5lbENsaWVudEFuZFNlcnZpY2UoKTogUHJvbWlzZTx2b2lkPiB7XG5cdC8vIGlmIHlvdXIgY29udGVudCBpcyBjb21pbmcgZnJvbSB0aGUgc2FtZSBkb21haW4gdGhlbiB5b3Ugd291bGQgbm90IG5lZWQgdG8gdXNlIHRoZSBDaGFubmVsIEFQSSBhbmQgY2FuIGNvbnNpZGVyIGFsdGVybmF0aXZlc1xuXHQvLyBzdWNoIGFzIEJyb2FkY2FzdENoYW5uZWwgQVBJIG9yIFNoYXJlZFdvcmtlclxuXHRpZiAoY2hhbm5lbENsaWVudCA9PT0gdW5kZWZpbmVkICYmIGNoYW5uZWxQcm92aWRlciA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0Ly8gc2V0IHVwIHRoZSBmaWxlIGhhbmRsZXIgZm9yIGxvZ2dpbmcgZm9yIHRoZSBzZXJ2aWNlXG5cdFx0aWYgKGZpbGVIYW5kbGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Y29uc3Qgcm9vdCA9IGF3YWl0IG5hdmlnYXRvci5zdG9yYWdlLmdldERpcmVjdG9yeSgpO1xuXHRcdFx0Ly8gQ3JlYXRlIGEgbmV3IGZpbGUgaGFuZGxlLlxuXHRcdFx0Ly8gVGhlIG5hbWUgY291bGQgYmUgZGF0ZSBiYXNlZCBpZiB5b3Ugd2VyZSBnb2luZyB0byBjcmVhdGUgYSBuZXcgZmlsZSBlYWNoIGRheS5cblx0XHRcdGZpbGVIYW5kbGUgPSBhd2FpdCByb290LmdldEZpbGVIYW5kbGUoXCJsb2cubG9nXCIsIHsgY3JlYXRlOiB0cnVlIH0pO1xuXHRcdH1cblx0XHRjaGFubmVsUHJvdmlkZXIgPSBhd2FpdCBmaW4uSW50ZXJBcHBsaWNhdGlvbkJ1cy5DaGFubmVsLmNyZWF0ZShjaGFubmVsTmFtZSk7XG5cdFx0Y2hhbm5lbFByb3ZpZGVyLm9uQ29ubmVjdGlvbigoaWRlbnRpdHksIHBheWxvYWQpID0+IHtcblx0XHRcdGlmIChpZGVudGl0eS51dWlkICE9PSBmaW4ubWUuaWRlbnRpdHkudXVpZCkge1xuXHRcdFx0XHQvLyByZWplY3QgY29ubmVjdGlvblxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJDb25uZWN0aW9uIHJlamVjdGVkLiBPbmx5IHRoZSBjdXJyZW50IGFwcGxpY2F0aW9uIGNhbiBjb25uZWN0IHRvIHRoZSBjaGFubmVsLlwiKTtcblx0XHRcdH1cblx0XHRcdC8vIHlvdSBjYW4gYWRkIGFkZGl0aW9uYWwgbG9naWMgdG8gdmFsaWRhdGUgdGhlIHZpZXcvd2luZG93IGNvbm5lY3RpbmcgKGUuZy4gdG8gZW5zdXJlIGl0IGlzIG9ubHkgdHJ1c3RlZCB1cmxzIHRoYXQgYXJlIGFsbG93ZWQgdG8gbG9nIGV0Yylcblx0XHR9KTtcblx0XHRjaGFubmVsUHJvdmlkZXIucmVnaXN0ZXIoXCJsb2dcIiwgYXN5bmMgKHBheWxvYWQ6IHVua25vd24sIGlkZW50aXR5KSA9PiB7XG5cdFx0XHRpZiAoaWRlbnRpdHkudXVpZCAhPT0gZmluLm1lLmlkZW50aXR5LnV1aWQpIHtcblx0XHRcdFx0Ly8gcmVqZWN0IHJlcXVlc3QgdG8gbG9nICh0aGlzIGlzIG9wdGlvbmFsIGJ1dCB5b3UgbWlnaHQgaGF2ZSBtdWx0aXBsZSBhY3Rpb25zIHJlZ2lzdGVyZWQgYW5kIHlvdSBtaWdodCBhbGxvdyBhIGNvbm5lY3Rpb24gdG8gdGhlIHNlcnZpY2UgYnV0IG5vdCBhbGwgYWN0aW9ucylcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiTG9nIHJlcXVlc3QgcmVqZWN0ZWQuIE9ubHkgdGhlIGN1cnJlbnQgYXBwbGljYXRpb24gY2FuIGxvZy5cIik7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Ly8geW91IGNvdWxkIG1ha2UgdGhpcyBtb3JlIGNvbXBsZXggdG8gc3VwcG9ydCBsb2cgbGV2ZWxzIGV0Yy4gRm9yIG5vdyB3ZSBqdXN0IHBhc3MgYSBzdHJpbmcgdG8gdGhlIGxvZyBmdW5jdGlvblxuXHRcdFx0XHQvLyB1dGMgdGltZXN0YW1wXG5cdFx0XHRcdGNvbnN0IHV0Y1RpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcblx0XHRcdFx0Y29uc3QgbWVzc2FnZSA9IGAke3V0Y1RpbWVzdGFtcH18JHtpZGVudGl0eS5uYW1lfXwke3BheWxvYWR9YDtcblx0XHRcdFx0YXdhaXQgd3JpdGVMb2dUb0ZpbGUobWVzc2FnZSk7XG5cdFx0XHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBgXG5Db25zb2xlIExvZ2dlZCB0aGUgZm9sbG93aW5nIG1lc3NhZ2UgdGhyb3VnaCBDaGFubmVsIEFQSTogXG5cIiR7bWVzc2FnZX1cImA7XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuXHRcdFx0XHRpZiAobG9nUHJldmlldykge1xuXHRcdFx0XHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgKz0gYFxuRXJyb3IgY29uc29sZSBsb2dnaW5nIG1lc3NhZ2UgdGhyb3VnaCBDaGFubmVsIEFQSTogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0XHRjaGFubmVsQ2xpZW50ID0gYXdhaXQgZmluLkludGVyQXBwbGljYXRpb25CdXMuQ2hhbm5lbC5jb25uZWN0KGNoYW5uZWxOYW1lKTtcblx0fVxufVxuXG4vKipcbiAqIFdyaXRlIGxvZ3MgdG8gZmlsZS4gVGhpcyBsb2dpYyBjb3VsZCBiZSBkb25lIGluIGEgd29ya2VyIHRvIGF2b2lkIGJsb2NraW5nIHRoZSBtYWluIHRocmVhZC5cbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9GaWxlX1N5c3RlbV9BUEkvT3JpZ2luX3ByaXZhdGVfZmlsZV9zeXN0ZW0uXG4gKiBAcGFyYW0gbG9nTWVzc2FnZSBUaGUgbG9nIG1lc3NhZ2UgdG8gd3JpdGUgdG8gZmlsZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gd3JpdGVMb2dUb0ZpbGUobG9nTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdHRyeSB7XG5cdFx0aWYgKGZpbGVIYW5kbGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Y29uc3Qgcm9vdCA9IGF3YWl0IG5hdmlnYXRvci5zdG9yYWdlLmdldERpcmVjdG9yeSgpO1xuXHRcdFx0Ly8gQ3JlYXRlIGEgbmV3IGZpbGUgaGFuZGxlIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG5cdFx0XHQvLyBUaGUgbmFtZSBjb3VsZCBiZSBkYXRlIGJhc2VkIGlmIHlvdSB3ZXJlIGdvaW5nIHRvIGNyZWF0ZSBhIG5ldyBmaWxlIGVhY2ggZGF5LlxuXHRcdFx0ZmlsZUhhbmRsZSA9IGF3YWl0IHJvb3QuZ2V0RmlsZUhhbmRsZShcImxvZy5sb2dcIiwgeyBjcmVhdGU6IHRydWUgfSk7XG5cdFx0fVxuXHRcdC8vIENyZWF0ZSBhIHdyaXRhYmxlIHN0cmVhbVxuXHRcdGNvbnN0IHdyaXRhYmxlU3RyZWFtID0gYXdhaXQgZmlsZUhhbmRsZS5jcmVhdGVXcml0YWJsZSh7IGtlZXBFeGlzdGluZ0RhdGE6IHRydWUgfSk7XG5cblx0XHQvLyBNb3ZlIHRoZSB3cml0ZSBwb3NpdGlvbiB0byB0aGUgZW5kIG9mIHRoZSBmaWxlXG5cdFx0Y29uc3QgZmlsZUZvclNpemUgPSBhd2FpdCBmaWxlSGFuZGxlLmdldEZpbGUoKTtcblx0XHRjb25zdCBzaXplID0gZmlsZUZvclNpemUuc2l6ZTtcblx0XHRhd2FpdCB3cml0YWJsZVN0cmVhbS5zZWVrKHNpemUpO1xuXG5cdFx0Ly8gV3JpdGUgdGhlIGxvZyBtZXNzYWdlIHRvIHRoZSBmaWxlXG5cdFx0aWYgKHNpemUgPT09IDApIHtcblx0XHRcdGF3YWl0IHdyaXRhYmxlU3RyZWFtLndyaXRlKGxvZ01lc3NhZ2UpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhd2FpdCB3cml0YWJsZVN0cmVhbS53cml0ZShgXFxuJHtsb2dNZXNzYWdlfWApO1xuXHRcdH1cblxuXHRcdC8vIENsb3NlIHRoZSBmaWxlXG5cdFx0YXdhaXQgd3JpdGFibGVTdHJlYW0uY2xvc2UoKTtcblxuXHRcdGNvbnNvbGUubG9nKFwiTG9nIHdyaXR0ZW4gdG8gZmlsZSBzdWNjZXNzZnVsbHkuXCIpO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHRjb25zb2xlLmVycm9yKFwiRXJyb3Igd3JpdGluZyBsb2cgdG8gZmlsZTpcIiwgZXJyKTtcblx0fVxufVxuXG4vKipcbiAqIEhhbmRsZSB1cGxvYWRzLlxuICogMS4gQ3JlYXRlcyBhIEZvcm1EYXRhIG9iamVjdC5cbiAqIDIuIENyZWF0ZXMgYSBGaWxlIG9iamVjdCBmcm9tIHRoZSBzdHJpbmcgb2YgdGhlIFJ1bnRpbWUgZGVidWcgbG9nIGZpbGUgY29udGVudHMuXG4gKiAzLiBQb3B1bGF0ZXMgdGhlIEZvcm1EYXRhIG9iamVjdCB3aXRoIG5lY2Vzc2FyeSBwYXJhbWV0ZXJzIHRvIGJlIHJlYWQgYnkgdGhlIHNlcnZlci5cbiAqIDQuIFVwbG9hZHMgdGhlIGNyZWF0ZWQgcnVudGltZSBkZWJ1ZyBsb2cgZmlsZSB0byBhIHNlcnZlciBlbmRwb2ludC5cbiAqIEBwYXJhbSBzdWJtaXRFdmVudCBUaGUgZXZlbnQgdG8gaGFuZGxlLlxuICovXG5hc3luYyBmdW5jdGlvbiB1cGxvYWRIYW5kbGVyKHN1Ym1pdEV2ZW50OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuXHRzdWJtaXRFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRpZiAoIWZpbGVOYW1lKSB7XG5cdFx0ZmlsZU5hbWUgPSBcImRlYnVnLmxvZ1wiO1xuXHR9XG5cdGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG5cdGRlYnVnTG9nU3RyID0gYXdhaXQgZ2V0TG9nRnJvbU5hbWUoZmlsZU5hbWUpO1xuXHRkZWJ1Z0xvZ0ZpbGUgPSBuZXcgRmlsZShbZGVidWdMb2dTdHJdLCBmaWxlTmFtZSwgeyB0eXBlOiBcInRleHQvcGxhaW5cIiB9KTtcblx0Zm9ybURhdGEuYXBwZW5kKFwiZmlsZVwiLCBkZWJ1Z0xvZ0ZpbGUpO1xuXHRmb3JtRGF0YS5hcHBlbmQoXCJmaWxlbmFtZVwiLCBmaWxlTmFtZSk7XG5cdGZvcm1EYXRhLmFwcGVuZChcInV1aWRcIiwgZmluLm1lLnV1aWQpO1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXG5cdHRyeSB7XG5cdFx0Y29uc3QgdXBsb2FkU3RhdGUgPSBhd2FpdCBmZXRjaChcImh0dHA6Ly9sb2NhbGhvc3Q6NTA1MC91cGxvYWRzXCIsIHtcblx0XHRcdG1ldGhvZDogXCJQT1NUXCIsXG5cdFx0XHRib2R5OiBmb3JtRGF0YVxuXHRcdH0pO1xuXHRcdGNvbnN0IHVwbG9hZFN0YXRlSnNvbiA9IGF3YWl0IHVwbG9hZFN0YXRlLmpzb24oKTtcblx0XHRjb25zdCB1cGxvYWRTdGF0ZUpzb25TdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh1cGxvYWRTdGF0ZUpzb24sIG51bGwsIDUpO1xuXHRcdGNvbnN0IGxvZ3MgPSBgJHtuZXcgRGF0ZSgpLnRvTG9jYWxlVGltZVN0cmluZygpfTogJHt1cGxvYWRTdGF0ZUpzb25TdHJpbmd9XFxuYDtcblx0XHRpZiAobG9nUHJldmlldykge1xuXHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBsb2dzO1xuXHRcdH1cblx0fSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG5cdFx0aWYgKGxvZ1ByZXZpZXcpIHtcblx0XHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgKz0gYFxuRXJyb3IgdXBsb2FkaW5nIFJ1bnRpbWUgTG9nczogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogVXBsb2FkcyB0aGUgT1BGUyBsb2cgZmlsZSB0byB0aGUgc2VydmVyLlxuICogQHJldHVybnMgdHJ1ZSBpZiB0aGUgbG9nIGZpbGUgd2FzIHVwbG9hZGVkIHN1Y2Nlc3NmdWxseSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5hc3luYyBmdW5jdGlvbiB1cGxvYWRPUEZTTG9nSGFuZGxlcigpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0Ly8gcmVhZCB0aGUgbG9nIGZpbGUgZnJvbSBvcmlnaW4gcHJpdmF0ZSBmaWxlIHN5c3RlbVxuXHRpZiAoZmlsZUhhbmRsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0dHJ5IHtcblx0XHRcdC8vIHJlYWQgdGhlIGZpbGUgZnJvbSBmaWxlSGFubGRlXG5cdFx0XHRjb25zdCBmaWxlID0gYXdhaXQgZmlsZUhhbmRsZS5nZXRGaWxlKCk7XG5cdFx0XHRjb25zdCBsb2dGaWxlTmFtZSA9IGZpbGUubmFtZTtcblx0XHRcdGNvbnN0IGZpbGVDb250ZW50cyA9IGF3YWl0IGZpbGUudGV4dCgpO1xuXHRcdFx0b3Bmc0xvZ0ZpbGUgPSBuZXcgRmlsZShbZmlsZUNvbnRlbnRzXSwgbG9nRmlsZU5hbWUsIHsgdHlwZTogXCJ0ZXh0L3BsYWluXCIgfSk7XG5cdFx0XHRjb25zdCBvcGZzRm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcblx0XHRcdG9wZnNGb3JtRGF0YS5hcHBlbmQoXCJvcGZzRmlsZVwiLCBvcGZzTG9nRmlsZSk7XG5cdFx0XHRvcGZzRm9ybURhdGEuYXBwZW5kKFwiZmlsZW5hbWVcIiwgbG9nRmlsZU5hbWUpO1xuXHRcdFx0b3Bmc0Zvcm1EYXRhLmFwcGVuZChcInV1aWRcIiwgZmluLm1lLnV1aWQpO1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgZmV0Y2goXCJodHRwOi8vbG9jYWxob3N0OjUwNTAvb3Bmc3VwbG9hZHNcIiwge1xuXHRcdFx0XHRtZXRob2Q6IFwiUE9TVFwiLFxuXHRcdFx0XHRib2R5OiBvcGZzRm9ybURhdGFcblx0XHRcdH0pO1xuXHRcdFx0aWYgKHJlc3VsdC5vaykge1xuXHRcdFx0XHQvLyBDbGVhciB0aGUgbG9nIGZpbGUgYWZ0ZXIgdXBsb2FkaW5nXG5cdFx0XHRcdGNvbnN0IHdyaXRhYmxlU3RyZWFtID0gYXdhaXQgZmlsZUhhbmRsZS5jcmVhdGVXcml0YWJsZSgpO1xuXHRcdFx0XHRhd2FpdCB3cml0YWJsZVN0cmVhbS50cnVuY2F0ZSgwKTtcblx0XHRcdFx0YXdhaXQgd3JpdGFibGVTdHJlYW0uY2xvc2UoKTtcblxuXHRcdFx0XHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHRcdFx0XHRjb25zdCB1cGxvYWRTdGF0ZUpzb24gPSBhd2FpdCByZXN1bHQuanNvbigpO1xuXHRcdFx0XHRjb25zdCB1cGxvYWRTdGF0ZUpzb25TdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh1cGxvYWRTdGF0ZUpzb24sIG51bGwsIDUpO1xuXHRcdFx0XHRjb25zdCBsb2dzID0gYCR7bmV3IERhdGUoKS50b0xvY2FsZVRpbWVTdHJpbmcoKX06ICR7dXBsb2FkU3RhdGVKc29uU3RyaW5nfVxcbmA7XG5cdFx0XHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBsb2dzO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKFwiRXJyb3IgcmVhZGluZyBsb2cgZmlsZTpcIiwgZXJyb3IpO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2xlYXJzIHRoZSBwcmV2aWV3IGxvZy5cbiAqL1xuZnVuY3Rpb24gY2xlYXJQcmV2aWV3KCk6IHZvaWQge1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHRpZiAobG9nUHJldmlldykge1xuXHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgPSBcIlwiO1xuXHR9XG59XG5cbi8qKlxuICogU2VuZHMgYSBtZXNzYWdlIHRvIHRoZSBPcGVuRmluIFJWTSB0byBzZW5kIHRoZSBhcHBsaWNhdGlvbiBsb2dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBzZW5kQXBwbGljYXRpb25Mb2dzKCk6IFByb21pc2U8dm9pZD4ge1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHR0cnkge1xuXHRcdGNvbnN0IGFwcExvZ1Jlc3BvbnNlID0gYXdhaXQgZmluLkFwcGxpY2F0aW9uLmdldEN1cnJlbnRTeW5jKCkuc2VuZEFwcGxpY2F0aW9uTG9nKCk7XG5cdFx0aWYgKGxvZ1ByZXZpZXcpIHtcblx0XHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgKz0gYFxuVXBsb2FkZWQgQXBwIExvZ3MuIExvZyBJRDogJHthcHBMb2dSZXNwb25zZS5sb2dJZH1gO1xuXHRcdH1cblx0fSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG5cdFx0aWYgKGxvZ1ByZXZpZXcpIHtcblx0XHRcdGxvZ1ByZXZpZXcudGV4dENvbnRlbnQgKz0gYFxuRXJyb3IgdXBsb2FkaW5nIEFwcCBMb2dzOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YDtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBTZW5kcyBvcGZzIGxvZ3MgdG8gdGhlIHNlcnZlci5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2VuZE9QRlNMb2dzKCk6IFByb21pc2U8dm9pZD4ge1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHR0cnkge1xuXHRcdGNvbnN0IHN1Y2Nlc3MgPSBhd2FpdCB1cGxvYWRPUEZTTG9nSGFuZGxlcigpO1xuXHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRsb2dQcmV2aWV3LnRleHRDb250ZW50ICs9IGBcblVwbG9hZGVkIE9QRlMgTG9ncy4gU3VjY2VzczogJHtzdWNjZXNzfWA7XG5cdFx0fVxuXHR9IGNhdGNoIChlcnI6IHVua25vd24pIHtcblx0XHRpZiAobG9nUHJldmlldykge1xuXHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBgXG5FcnJvciB1cGxvYWRpbmcgT1BGUyBMb2dzOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YDtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UgdG8gY29uc29sZSBsb2cuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvbnNvbGVMb2dNZXNzYWdlKCk6IFByb21pc2U8dm9pZD4ge1xuXHRjb25zdCBsb2dQcmV2aWV3ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNwcmV2aWV3XCIpO1xuXHR0cnkge1xuXHRcdGNvbnN0IG1lc3NhZ2UgPSBgXG5TZW5kaW5nIGNvbnNvbGUgbG9nIG1lc3NhZ2U6ICR7RGF0ZS5ub3coKX1gO1xuXHRcdGNvbnNvbGUubG9nKG1lc3NhZ2UpO1xuXHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRsb2dQcmV2aWV3LnRleHRDb250ZW50ICs9IGBcbkNvbnNvbGUgTG9nZ2VkIHRoZSBmb2xsb3dpbmcgbWVzc2FnZTogXG5cIiR7bWVzc2FnZX1cImA7XG5cdFx0fVxuXHR9IGNhdGNoIChlcnI6IHVua25vd24pIHtcblx0XHRpZiAobG9nUHJldmlldykge1xuXHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBgXG5FcnJvciBjb25zb2xlIGxvZ2dpbmcgbWVzc2FnZTogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWA7XG5cdFx0fVxuXHR9XG59XG5cbi8qKlxuICogU2VuZHMgYSBtZXNzYWdlIHRvIGNvbnNvbGUgbG9nIHRocm91Z2ggdGhlIENoYW5uZWwgQVBJLlxuICovXG5hc3luYyBmdW5jdGlvbiBjaGFubmVsTG9nTWVzc2FnZSgpOiBQcm9taXNlPHZvaWQ+IHtcblx0Y29uc3QgbG9nUHJldmlldyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjcHJldmlld1wiKTtcblx0dHJ5IHtcblx0XHRjb25zdCBtZXNzYWdlID0gYFxuU2VuZGluZyBjaGFubmVsIGxvZyBtZXNzYWdlOiAke0RhdGUubm93KCl9YDtcblx0XHRpZiAobG9nUHJldmlldykge1xuXHRcdFx0bG9nUHJldmlldy50ZXh0Q29udGVudCArPSBgXG5TZW5kaW5nIHRoZSBmb2xsb3dpbmcgbWVzc2FnZSB0aHJvdWdoIHRoZSBDaGFubmVsIEFQSTogXG5cIiR7bWVzc2FnZX1cImA7XG5cdFx0fVxuXHRcdGF3YWl0IGNoYW5uZWxDbGllbnQuZGlzcGF0Y2goXCJsb2dcIiwgbWVzc2FnZSk7XG5cdH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuXHRcdGlmIChsb2dQcmV2aWV3KSB7XG5cdFx0XHRsb2dQcmV2aWV3LnRleHRDb250ZW50ICs9IGBcbkVycm9yIHNlbmRpbmcgbWVzc2FnZSB0aHJvdWdoIENoYW5uZWwgQVBJOiAkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9YDtcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIHJ1bnRpbWUgZGVidWcgbG9nIGZyb20gYSBmaWxlbmFtZS5cbiAqIEBwYXJhbSBuYW1lIGZpbGUgbmFtZSBvZiB0aGUgcnVudGltZSBkZWJ1ZyBsb2cgdG8gcmV0cmlldmUuXG4gKiBAcmV0dXJucyB0aGUgbG9nIGNvbnRlbnQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldExvZ0Zyb21OYW1lKG5hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG5cdGNvbnN0IGxvZyA9IGF3YWl0IGZpbi5TeXN0ZW0uZ2V0TG9nKHsgbmFtZSB9KTtcblx0cmV0dXJuIGxvZztcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIEhUTUxPcHRpb25FbGVtZW50IGZvciBlYWNoIG9mIHRoZSBSdW50aW1lIGRlYnVnIGxvZ3MuXG4gKiBAcGFyYW0gcGFyZW50RWxlbWVudCBIVE1MIEVsZW1lbnQgdG8gYXBwZW5kIHRoZSBsb2cgZmlsZW5hbWUgSFRNTE9wdGlvbkVsZW1lbnQgdG8uXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZUxvZ0Ryb3BEb3duKHBhcmVudEVsZW1lbnQ6IEhUTUxTZWxlY3RFbGVtZW50KTogUHJvbWlzZTx2b2lkPiB7XG5cdGNvbnN0IGxvZ0xpc3Q6IE9wZW5GaW4uTG9nSW5mb1tdID0gYXdhaXQgZmluLlN5c3RlbS5nZXRMb2dMaXN0KCk7XG5cblx0Zm9yIChjb25zdCBsb2cgb2YgbG9nTGlzdCkge1xuXHRcdGNvbnN0IGxvZ0VsZW1lbnQ6IEhUTUxPcHRpb25FbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIm9wdGlvblwiKTtcblx0XHRsb2dFbGVtZW50LmlkID0gbG9nLmRhdGU7XG5cdFx0bG9nRWxlbWVudC50ZXh0Q29udGVudCA9IGxvZy5uYW1lO1xuXHRcdGxvZ0VsZW1lbnQudmFsdWUgPSBsb2cubmFtZTtcblx0XHRwYXJlbnRFbGVtZW50LmFwcGVuZChsb2dFbGVtZW50KTtcblx0fVxufVxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file diff --git a/dev/john/update-logging-example/use-logging-apis/manifest.fin.json b/dev/john/update-logging-example/use-logging-apis/manifest.fin.json index b4c82b3c..5577a918 100644 --- a/dev/john/update-logging-example/use-logging-apis/manifest.fin.json +++ b/dev/john/update-logging-example/use-logging-apis/manifest.fin.json @@ -1,14 +1,14 @@ { "runtime": { - "arguments": "--v=1 --inspect", + "arguments": "--enable-mesh --security-realm=workspace-platform-starter", "version": "38.126.83.79" }, - "licenseKey": "64605fac-add3-48a0-8710-64b38e96a2dd", - "startup_app": { + "licenseKey": "openfin-demo-license-key", + "platform": { "name": "use-application-logging", "uuid": "use-application-logging", "description": "An example of using application logging", - "url": "https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/html/app.html", + "providerUrl": "https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/html/provider.html", "icon": "https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/favicon.ico", "autoShow": true, "defaultWidth": 1200, @@ -16,10 +16,49 @@ "defaultCentered": true, "minWidth": 800, "minHeight": 400, + "appLogsTimezone": "utc", "enableAppLogging": true, "logManagement": { "enabled": true, "url": "https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis" } + }, + "snapshot": { + "windows": [ + { + "defaultHeight": 900, + "defaultWidth": 1200, + "defaultCentered": true, + "layout": { + "content": [ + { + "type": "row", + "content": [ + { + "type": "component", + "componentName": "view", + "componentState": { + "url": "https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/html/app.html" + } + }, + { + "type": "component", + "componentName": "view", + "componentState": { + "url": "https://built-on-openfin.github.io/container-starter/dev/john/update-logging-example/use-logging-apis/html/app.html" + } + } + ] + } + ] + } + } + ] + }, + "supportInformation": { + "company": "OpenFin", + "product": "Container Logging APIs Example", + "email": "support@openfin.co", + "forwardErrorReports": false } } diff --git a/dev/john/update-logging-example/use-logging-apis/uploads/applogs/AppLogs.md b/dev/john/update-logging-example/use-logging-apis/uploads/applogs/AppLogs.md new file mode 100644 index 00000000..bb829f14 --- /dev/null +++ b/dev/john/update-logging-example/use-logging-apis/uploads/applogs/AppLogs.md @@ -0,0 +1,4 @@ +# App Logs + +This directory will be written to by our example node server. It will receive the app log files that are sent to the server by the RVM. +The file will be a zip and it will contain the app.log file which has the combined data from all web pages writing to the console. diff --git a/dev/john/update-logging-example/use-logging-apis/uploads/opfslogs/OPFSLogs.md b/dev/john/update-logging-example/use-logging-apis/uploads/opfslogs/OPFSLogs.md new file mode 100644 index 00000000..5541146f --- /dev/null +++ b/dev/john/update-logging-example/use-logging-apis/uploads/opfslogs/OPFSLogs.md @@ -0,0 +1,3 @@ +# OPFS Logs + +This directory will be written to by our example node server. It will receive the log file that was written to by the provider. The provider gets messages from multiple views and itself and writes them to a log file in the origin private filesystem. The sample app then lets you get the contents of that log file to send to the server, write to this directory and clear. diff --git a/dev/john/update-logging-example/use-logging-apis/uploads/runtimelogs/SystemLogs.md b/dev/john/update-logging-example/use-logging-apis/uploads/runtimelogs/SystemLogs.md new file mode 100644 index 00000000..eca9f13c --- /dev/null +++ b/dev/john/update-logging-example/use-logging-apis/uploads/runtimelogs/SystemLogs.md @@ -0,0 +1,3 @@ +# System Logs + +This directory will be written to by our example node server. It will receive the debug log file that contains runtime messages as well as other data and it will write it to this directory.