/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/main.ts var main_exports = {}; __export(main_exports, { default: () => AttachFlowPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian7 = require("obsidian"); // src/options/deleleAllAttachsInTheNote.ts var import_obsidian4 = require("obsidian"); // src/util.ts var import_obsidian = require("obsidian"); var import_child_process = require("child_process"); var import_fs = require("fs"); var import_obsidian2 = require("obsidian"); var DEBUG = false; var SUCCESS_NOTICE_TIMEOUT = 1800; var print = (message, ...optionalParams) => { if (DEBUG) { console.log(message, ...optionalParams); } }; function setDebug(value) { DEBUG = value; } var checkReferenceInfo = (target_file, currentMd) => { const resolvedLinks = app.metadataCache.resolvedLinks; let CurMDPath; let result = { state: 0, mdPath: [] }; let refNum = 0; for (const [mdFile, links] of Object.entries(resolvedLinks)) { if (currentMd.path === mdFile) { CurMDPath = currentMd.path; result.mdPath.unshift(CurMDPath); } for (const [filePath, nr] of Object.entries(links)) { if ((target_file == null ? void 0 : target_file.path) === filePath) { refNum++; if (nr > 1) { result.state = 2 /* MORE */; result.mdPath.push(mdFile); return result; } result.mdPath.push(mdFile); } } } if (refNum > 1) { result.state = 1 /* MUTIPLE */; } else { result.state = 0 /* ONCE */; } return result; }; var getFileByBaseName = (currentMd, FileBaseName) => { const resolvedLinks = app.metadataCache.resolvedLinks; for (const [mdFile, links] of Object.entries(resolvedLinks)) { if (currentMd.path === mdFile) { for (const [filePath, nr] of Object.entries(links)) { if (filePath.includes(FileBaseName)) { try { const AttachFile = app.vault.getAbstractFileByPath(filePath); if (AttachFile instanceof import_obsidian.TFile) { return AttachFile; } } catch (error) { new import_obsidian.Notice(` cannot get the image file`); console.error(error); } } } } } }; var PureClearAttachment = (file, target_type, plugin) => __async(void 0, null, function* () { const deleteOption = plugin.settings.deleteOption; const delFileFolder = onlyOneFileExists(file); const fileFolder = getFileParentFolder(file); let name = target_type == "img" ? "Image" : "File"; try { if (deleteOption === ".trash") { yield app.vault.trash(file, false); new import_obsidian.Notice(name + " moved to Obsidian Trash !", SUCCESS_NOTICE_TIMEOUT); if (delFileFolder) { yield app.vault.trash(fileFolder, false); new import_obsidian.Notice("Attachment folder have been deleted!", 3e3); } } else if (deleteOption === "system-trash") { yield app.vault.trash(file, true); new import_obsidian.Notice(name + " moved to System Trash !", SUCCESS_NOTICE_TIMEOUT); if (delFileFolder) { yield app.vault.trash(fileFolder, true); new import_obsidian.Notice("Attachment folder have been deleted!", 3e3); } } else if (deleteOption === "permanent") { yield app.vault.delete(file); new import_obsidian.Notice(name + " deleted Permanently !", SUCCESS_NOTICE_TIMEOUT); if (delFileFolder) { yield app.vault.delete(fileFolder, true); new import_obsidian.Notice("Attachment folder have been deleted!", 3e3); } } } catch (error) { console.error(error); new import_obsidian.Notice("Faild to delelte the " + name + "!", SUCCESS_NOTICE_TIMEOUT); } }); var handlerDelFileNew = (FileBaseName, currentMd, plugin, target_type, target_pos, in_table, in_callout) => { let logs; let modal; const target_file = getFileByBaseName(currentMd, FileBaseName); const refInfo = checkReferenceInfo(target_file, currentMd); let state = refInfo.state; switch (state) { case 0: deleteCurTargetLink(FileBaseName, plugin, target_type, target_pos, in_table, in_callout); PureClearAttachment(target_file, target_type, plugin); break; case 1: case 2: deleteCurTargetLink(FileBaseName, plugin, target_type, target_pos, in_table, in_callout); logs = refInfo.mdPath; new import_obsidian.Notice("As other references of current file exist, just deleted the current reference link without deleting the actual file.", 3500); default: break; } }; var deleteCurTargetLink = (file_base_name, plugin, target_type, target_pos, in_table, in_callout) => { file_base_name = file_base_name.startsWith("/") ? file_base_name.substring(1) : file_base_name; const activeView = plugin.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); const editor = activeView.editor; const editorView = editor.cm; let target_line = editorView.state.doc.lineAt(target_pos); let line_text = target_line.text; if (!in_table && !in_callout) { let finds = findLinkInLine(file_base_name, line_text); if (finds.length == 0) { new import_obsidian.Notice("Fail to find the link-text, please delete it manually!", 0); return; } else if (finds.length != 1) { new import_obsidian.Notice("Find multiple same Link in current line, please delete it manually!", 0); return; } else { editor.replaceRange("", { line: target_line.number - 1, ch: finds[0][0] }, { line: target_line.number - 1, ch: finds[0][1] }); return; } } let startReg = { "table": /^\s*\|/, "callout": /^>/ }; let mode = in_table ? "table" : "callout"; let finds_lines = []; let finds_all = []; for (let i = target_line.number; i <= editor.lineCount(); i++) { let line_text2 = editor.getLine(i - 1); if (!startReg[mode].test(line_text2)) break; print(`line_${i}_text:`, line_text2); let finds = findLinkInLine(file_base_name, line_text2); if (finds.length > 0) { finds_lines.push(...new Array(finds.length).fill(i)); finds_all.push(...finds); } } for (let i = target_line.number - 1; i >= 1; i--) { let line_text2 = editor.getLine(i - 1); if (!startReg[mode].test(line_text2)) break; print(`line_${i}_text:`, line_text2); let finds = findLinkInLine(file_base_name, line_text2); if (finds.length > 0) { finds_lines.push(...new Array(finds.length).fill(i)); finds_all.push(...finds); } } if (finds_all.length == 0) { new import_obsidian.Notice(`Fail to find the link-text (for links in ${mode}), please delete it manually!`, 0); return; } else if (finds_all.length != 1) { new import_obsidian.Notice(`Find multiple same Link in current ${mode}, please delete it manually!`, 0); return; } else { editor.replaceRange("", { line: finds_lines[0] - 1, ch: finds_all[0][0] }, { line: finds_lines[0] - 1, ch: finds_all[0][1] }); } editor.focus(); }; var handlerCopyFile = (FileBaseName, currentMd, plugin) => __async(void 0, null, function* () { const file = getFileByBaseName(currentMd, FileBaseName); const basePath = file.vault.adapter.basePath; const file_ab_path = basePath + "/" + file.path; try { copyFileToClipboardCMD(file_ab_path); new import_obsidian.Notice("Copied to clipboard !", SUCCESS_NOTICE_TIMEOUT); } catch (error) { console.error(error); new import_obsidian.Notice("Faild to copy the file !", SUCCESS_NOTICE_TIMEOUT); } }); var handlerMoveFile = (FileBaseName, currentMd, plugin) => __async(void 0, null, function* () { const target_file = getFileByBaseName(currentMd, FileBaseName); new moveFileToFolderSuggester(plugin.app, target_file).open(); }); var getFileParentFolder = (file) => { if (file instanceof import_obsidian.TFile) { if (file.parent instanceof import_obsidian.TFolder) { return file.parent; } } return; }; var onlyOneFileExists = (file) => { const fileFolder = getFileParentFolder(file); return fileFolder.children.length === 1; }; function copyFileToClipboardCMD(filePath) { if (!(0, import_fs.existsSync)(filePath)) { console.error(`File ${filePath} does not exist`); return; } const callback = (error, stdout, stderr) => { if (error) { new import_obsidian.Notice(`Error executing command: ${error.message}`, SUCCESS_NOTICE_TIMEOUT); console.error(`Error executing command: ${error.message}`); return; } }; if (process.platform === "darwin") { (0, import_child_process.execSync)(`open -R "${filePath}"`); (0, import_child_process.execSync)(`osascript -e 'tell application "System Events" to keystroke "c" using command down'`); (0, import_child_process.execSync)(`osascript -e 'tell application "System Events" to keystroke "w" using command down'`); (0, import_child_process.execSync)(`open -a "Obsidian.app"`); } else if (process.platform === "linux") { } else if (process.platform === "win32") { let safeFilePath = filePath.replace(/'/g, "''"); (0, import_child_process.exec)(`powershell -command "Set-Clipboard -Path '${safeFilePath}'"`, callback); } } var findLinkInLine = (file_name, line_text) => { const file_name_mdlink = file_name.replace(/ /g, "%20"); let regWikiLink = /\!\[\[[^\[\]]*?\]\]/g; let regMdLink = /\!\[[^\[\]]*?\]\([^\s\)\(\[\]\{\}']*\)/g; print("target_name (WIKI/MD):", file_name, file_name_mdlink); let search_result = []; if (line_text.includes(file_name)) { while (true) { let match = regWikiLink.exec(line_text); if (!match) break; let matched_link = match[0]; print("matched_link:", matched_link); print("matched_link.includes(file_name)", matched_link.includes(file_name)); if (matched_link.includes(file_name)) { search_result.push([match.index, match.index + matched_link.length]); } } } if (line_text.includes(file_name_mdlink)) { while (true) { let match = regMdLink.exec(line_text); if (!match) break; let matched_link = match[0]; print("matched_link:", matched_link); print("matched_link.includes(file_name_mdlink)", matched_link.includes(file_name_mdlink)); if (matched_link.includes(file_name_mdlink)) { search_result.push([match.index, match.index + matched_link.length]); } } } return search_result; }; var handlerRenameFile = (FileBaseName, currentMd, plugin) => { const target_file = getFileByBaseName(currentMd, FileBaseName); let path = target_file.path; let name = target_file.name; let target_folder = path.substring(0, path.length - name.length); let file_type = name.split(".").pop(); new RenameModal(plugin.app, target_folder, name.substring(0, name.length - file_type.length - 1), file_type, (result) => { if (!result) return; if (result == path) return; app.vault.adapter.exists(result).then((exists) => { if (exists) { new import_obsidian.Notice(`Fail to rename for there alreay exist file ${result}`); } else { plugin.app.fileManager.renameFile(target_file, `${result}`); } }); }).open(); }; var RenameModal = class extends import_obsidian2.Modal { constructor(app2, folder, name, filetype, onSubmit) { super(app2); this.onSubmit = onSubmit; this.folder = folder; this.name = name; this.filetype = filetype; } onOpen() { const { contentEl } = this; let setting = new import_obsidian2.Setting(contentEl).setName("Rename:").addText((text) => text.setValue(this.name).onChange((value) => { this.result = `${this.folder}${value}.${this.filetype}`; })); setTimeout(() => { let inputBox = setting.settingEl.querySelector('input[type="text"]'); if (inputBox && inputBox.parentElement) { let folder_indicator = document.createElement("label"); folder_indicator.innerText = `${this.folder}`; folder_indicator.style.marginRight = "4px"; inputBox.parentElement.insertBefore(folder_indicator, inputBox); let file_type_indicator = document.createElement("label"); file_type_indicator.innerText = `.${this.filetype}`; file_type_indicator.style.marginLeft = "4px"; inputBox.after(file_type_indicator); let parentEl = setting.settingEl.parentElement; if (parentEl) { parentEl.style.display = "flex"; parentEl.style.justifyContent = "center"; } let inputElem = inputBox; inputElem.select(); } else { console.error("\u65E0\u6CD5\u627E\u5230\u6587\u672C\u8F93\u5165\u6846"); } }, 0); this.scope.register([], "Enter", (evt) => { if (evt.isComposing) { return; } this.close(); this.onSubmit(this.result); }); } onClose() { let { contentEl } = this; contentEl.empty(); } }; var moveFileToFolderSuggester = class extends import_obsidian2.FuzzySuggestModal { constructor(app2, file) { super(app2); this.folderList = this.getAllFolders(this.app.vault); this.target_file = file; } getAllFolders(vault) { const folders = /* @__PURE__ */ new Set(); vault.getAllLoadedFiles().forEach((file) => { if (file instanceof import_obsidian.TFolder) { folders.add(file.path); } }); return folders; } getItems() { return Array.from(this.folderList).sort(); } getItemText(item) { return item; } onChooseItem(item) { return __async(this, null, function* () { var _a; if (((_a = this.target_file.parent) == null ? void 0 : _a.path) === item) { new import_obsidian.Notice("The file is already in the folder!", 3e3); return; } let choosed_folder = item.endsWith("/") ? item : item + "/"; let new_path = choosed_folder + this.target_file.name; print(new_path); app.vault.adapter.exists(new_path).then((exists) => { if (exists) { new import_obsidian.Notice(`Fail to move for there alreay exist file ${new_path}`); } else { this.app.fileManager.renameFile(this.target_file, `${new_path}`); } }); }); } renderSuggestion(item, el) { el.innerText = item.item; } }; // src/utils/deleteFile.ts var import_obsidian3 = require("obsidian"); var SUCCESS_NOTICE_TIMEOUT2 = 1800; var deleteFile = (file, plugin) => __async(void 0, null, function* () { const deleteOption = plugin.settings.deleteOption; try { if (deleteOption === ".trash") { yield app.vault.trash(file, false); } else if (deleteOption === "system-trash") { yield app.vault.trash(file, true); } else if (deleteOption === "permanent") { yield app.vault.delete(file); } } catch (error) { console.error(error); new import_obsidian3.Notice("Faild to delete the file/folder !", SUCCESS_NOTICE_TIMEOUT2); } }); // src/options/deleleAllAttachsInTheNote.ts var deleteAllAttachs = (plugin) => __async(void 0, null, function* () { const activeMd = app.workspace.getActiveFile(); const resolvedLinks = app.metadataCache.resolvedLinks; const attachsPaths = []; for (const [mdFile, links] of Object.entries(resolvedLinks)) { if ((activeMd == null ? void 0 : activeMd.path) === mdFile) { let fileCount = 0; let flag = false; for (const [filePath, nr] of Object.entries(links)) { if (filePath.match(/.*\.md$/m)) continue; if (isReferencedByOtherNotes(filePath, activeMd)) continue; attachsPaths.push(filePath); try { const AttachFile = app.vault.getAbstractFileByPath(filePath); if (AttachFile instanceof import_obsidian4.TFile) { deleteFile(AttachFile, plugin); } const parentFolder = getFileParentFolder(AttachFile); if (!flag) { fileCount = parentFolder.children.length; flag = !flag; } fileCount = fileCount - 1; if (!fileCount) { yield deleteFile(parentFolder, plugin); new import_obsidian4.Notice("All attachments and its parent folder deleted!", 3e3); } } catch (error) { console.warn(error); } } } } }); var isReferencedByOtherNotes = (attachPath, currentMd) => { const resolvedLinks = app.metadataCache.resolvedLinks; let flag = false; for (const [mdFile, links] of Object.entries(resolvedLinks)) { if (mdFile !== currentMd.path) { for (const [filePath, nr] of Object.entries(links)) { if (filePath === attachPath) { flag = true; } } } } return flag; }; var getRefencedLinkCount = () => { const activeMd = app.workspace.getActiveFile(); const resolvedLinks = app.metadataCache.resolvedLinks; const attachsPaths = []; for (const [mdFile, links] of Object.entries(resolvedLinks)) { if ((activeMd == null ? void 0 : activeMd.path) === mdFile) { for (const [filePath, nr] of Object.entries(links)) { if (filePath.match(/.*\.md$/m)) continue; if (isReferencedByOtherNotes(filePath, activeMd)) continue; attachsPaths.push(filePath); } } } return attachsPaths.length; }; // src/config/addCommand-config.ts var addCommand = (myPlugin) => { myPlugin.addCommand({ id: "clear-all-attachments-in-current-file", name: "clear all attachments in current file", callback: () => __async(void 0, null, function* () { deleteAllAttachs(myPlugin); }) }); }; // src/settings.ts var import_obsidian5 = require("obsidian"); var DEFAULT_SETTINGS = { deleteOption: ".trash", logsModal: true, dragResize: true, resizeInterval: 0, clickView: false, adaptiveRatio: 0.9, moveFileMenu: false, debug: false }; var AttachFlowSettingsTab = class extends import_obsidian5.PluginSettingTab { constructor(app2, plugin) { super(app2, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); new import_obsidian5.Setting(containerEl).setName("Right-click menu for attachments").setHeading(); new import_obsidian5.Setting(containerEl).setName("Deleted attachment destination").setDesc("Select where you want Attachments to be moved once they are deleted").addDropdown((dropdown) => { dropdown.addOption("permanent", "Delete Permanently"); dropdown.addOption(".trash", "Move to Obsidian Trash"); dropdown.addOption("system-trash", "Move to System Trash"); dropdown.setValue(this.plugin.settings.deleteOption); dropdown.onChange((option) => { this.plugin.settings.deleteOption = option; this.plugin.saveSettings(); }); }); new import_obsidian5.Setting(containerEl).setName("Move file to...").setDesc('Add a "Move to..." option to the right-click menu for attachments').addToggle((toggle) => { toggle.setValue(this.plugin.settings.moveFileMenu).onChange((value) => __async(this, null, function* () { this.plugin.settings.moveFileMenu = value; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Click to view images").setHeading(); new import_obsidian5.Setting(containerEl).setName("Click to view images").setDesc("Click the right half of the image to view the image in detail.").addToggle((toggle) => { toggle.setValue(this.plugin.settings.clickView).onChange((value) => __async(this, null, function* () { this.plugin.settings.clickView = value; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Adaptive image display ratio based on window size").setDesc("When the image exceeds the window size, the image is displayed adaptively according to the window size.").addSlider((slider) => { slider.setLimits(0.1, 1, 0.05); slider.setValue(this.plugin.settings.adaptiveRatio); slider.onChange((value) => __async(this, null, function* () { this.plugin.settings.adaptiveRatio = value; new import_obsidian5.Notice(`Adaptive ratio: ${value}`); yield this.plugin.saveSettings(); })); slider.setDynamicTooltip(); }); new import_obsidian5.Setting(containerEl).setName("Drag to resize images").setHeading(); new import_obsidian5.Setting(containerEl).setName("Drag to resize images").setDesc("Turn on to enable drag to resize images.").addToggle((toggle) => { toggle.setValue(this.plugin.settings.dragResize).onChange((value) => __async(this, null, function* () { this.plugin.settings.dragResize = value; yield this.plugin.saveSettings(); })); }); new import_obsidian5.Setting(containerEl).setName("Resize interval").setDesc("\u62D6\u62FD\u8C03\u8282\u6700\u5C0F\u523B\u5EA6\uFF08\u9ED8\u8BA4\u503C\u4E3A 0 \u5373\u4E0D\u5BF9\u9F50\u523B\u5EA6\uFF09").addText((text) => { text.setValue(this.plugin.settings.resizeInterval.toString()).onChange((value) => __async(this, null, function* () { if (value === "") { this.plugin.settings.resizeInterval = 0; yield this.plugin.saveSettings(); } else if (/^\d+$/.test(value) && Number(value) >= 0) { this.plugin.settings.resizeInterval = parseInt(value); yield this.plugin.saveSettings(); } else { new import_obsidian5.Notice("\u8BF7\u8F93\u5165\u6B63\u6574\u6570"); text.setValue(this.plugin.settings.resizeInterval.toString()); } })); }); new import_obsidian5.Setting(containerEl).setName("Debug").setHeading(); new import_obsidian5.Setting(containerEl).setName("Debug mode").setDesc("Print debug information in console").addToggle((toggle) => { toggle.setValue(this.plugin.settings.debug).onChange((value) => __async(this, null, function* () { this.plugin.settings.debug = value; setDebug(value); yield this.plugin.saveSettings(); })); }); } }; // src/utils/handlerEvent.ts var getMouseEventTarget = (event) => { event.preventDefault(); const target = event.target; return target; }; // src/modals/deletionPrompt.ts var import_obsidian6 = require("obsidian"); var DeleteAllLogsModal = class extends import_obsidian6.Modal { constructor(note, myPlugin) { super(app); this.note = note; this.myPlugin = myPlugin; } getLog() { const referenceMessage = `Are you sure you want to delete "${this.note.basename}.md"? It will be moved to your ${this.myPlugin.settings.deleteOption}.`; return referenceMessage; } showLogs() { const logs = this.contentEl.createEl("div"); logs.addClass("attachment-flow-log"); logs.setText(this.getLog()); } onOpen() { const { contentEl } = this; const myModal = this; const headerWrapper = contentEl.createEl("div"); headerWrapper.addClass("attachment-flow-center-wrapper"); this.showLogs(); const referencedMessageWrapper = contentEl.createEl("span"); referencedMessageWrapper.style.color = "red"; const referencedMessage = `There are(is) currently [${getRefencedLinkCount()}] non-multi-referenced link(s) pointing to this note.`; referencedMessageWrapper.append(referencedMessage); const buttonWrapper = this.contentEl.createEl("div"); buttonWrapper.addClass("attachment-flow-center-wrapper"); const headerEl = headerWrapper.createEl("h1", { text: "Delete the file and its all attachments - logs " }); headerEl.addClass("modal-title"); this.showConfirmButton(buttonWrapper, myModal); this.showCancelBtn(buttonWrapper, myModal); } showCancelBtn(buttonWrapper, myModal) { const closeButton = buttonWrapper.createEl("button", { text: "Cancel" }); closeButton.setAttribute("aria-label", "Cancel the operation"); closeButton.addEventListener("click", () => { myModal.close(); }); } showConfirmButton(buttonWrapper, myModal) { const removeLinkButton = buttonWrapper.createEl("button", { text: "Confirm" }); removeLinkButton.setAttribute("aria-label", "Continue to delete current file and its all non-multi-referenced attachments"); removeLinkButton.addClass("mod-warning"); removeLinkButton.addEventListener("click", () => __async(this, null, function* () { deleteFile(this.note, this.myPlugin); deleteAllAttachs(this.myPlugin); myModal.close(); })); } }; // src/helpers.ts var loadImageBlobTimeout = 3e3; function withTimeout(ms, promise) { const timeout = new Promise((resolve, reject) => { const id = setTimeout(() => { clearTimeout(id); reject(`timed out after ${ms} ms`); }, ms); }); return Promise.race([ promise, timeout ]); } function loadImageBlob(imgSrc, retryCount = 0) { return __async(this, null, function* () { const loadImageBlobCore = () => { return new Promise((resolve, reject) => { const image = new Image(); image.crossOrigin = "anonymous"; image.onload = () => { const canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height; const ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0); canvas.toBlob((blob) => { resolve(blob); }); }; image.onerror = () => __async(this, null, function* () { if (retryCount < 3) { try { yield fetch(image.src, { "mode": "no-cors" }); const blob = yield loadImageBlob(`https://api.allorigins.win/raw?url=${encodeURIComponent(imgSrc)}`, retryCount + 1); resolve(blob); } catch (e) { reject(); } } else { reject(new Error("Unable to retrieve the image data after 3 retries.")); } }); image.src = imgSrc; }); }; return withTimeout(loadImageBlobTimeout, loadImageBlobCore()); }); } function onElement(el, event, selector, listener, options) { el.on(event, selector, listener, options); return () => el.off(event, selector, listener, options); } // src/main.ts var AttachFlowPlugin = class extends import_obsidian7.Plugin { constructor() { super(...arguments); this.updateImageLinkWithNewSize = (img, target_pos, newWidth, newHeight) => { var _a; const activeView = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView); const inTable = img.closest("table") != null; const inCallout = img.closest(".callout") != null; const isExcalidraw = img.classList.contains("excalidraw-embedded-img"); if (activeView) { print("update new Width", newWidth); let imageName = img.getAttribute("src"); if (imageName == null ? void 0 : imageName.startsWith("http")) { updateExternalLink(activeView, img, target_pos, newWidth, newHeight, inTable, inCallout); } else if (isExcalidraw) { let target_name = img.getAttribute("filesource"); let draw_base_name = getExcalidrawBaseName(img); img.style.maxWidth = "none"; updateInternalLink(activeView, img, target_pos, draw_base_name, newWidth, newHeight, inTable, inCallout); } else { imageName = (_a = img.closest(".internal-embed")) == null ? void 0 : _a.getAttribute("src"); updateInternalLink(activeView, img, target_pos, imageName, newWidth, newHeight, inTable, inCallout); } } }; this.addMenuExtendedSourceMode = (menu, FileBaseName, currentMd, target_type, target_pos, inTable, inCallout) => { this.addMenuExtendedPreviewMode(menu, FileBaseName, currentMd); menu.addItem((item) => item.setIcon("pencil").setTitle("Rename").onClick(() => __async(this, null, function* () { try { print("test rename"); handlerRenameFile(FileBaseName, currentMd, this); } catch (e) { new import_obsidian7.Notice("Error, could not rename the file!"); } }))); if (this.settings.moveFileMenu) { menu.addItem((item) => item.setIcon("folder-tree").setTitle("Move file to...").onClick(() => __async(this, null, function* () { try { handlerMoveFile(FileBaseName, currentMd, this); } catch (e) { new import_obsidian7.Notice("Error, could not Move the file!"); } }))); } menu.addItem((item) => item.setIcon("trash-2").setTitle("Clear file and associated link").onClick(() => __async(this, null, function* () { try { handlerDelFileNew(FileBaseName, currentMd, this, target_type, target_pos, inTable, inCallout); } catch (e) { new import_obsidian7.Notice("Error, could not clear the file!"); } }))); }; this.addMenuExtendedPreviewMode = (menu, FileBaseName, currentMd) => { const file = getFileByBaseName(currentMd, FileBaseName); if (process.platform != "linux") { menu.addItem((item) => item.setIcon("copy").setTitle("Copy file to clipboard").onClick(() => __async(this, null, function* () { try { handlerCopyFile(FileBaseName, currentMd, this); } catch (e) { new import_obsidian7.Notice("Error, could not copy the file!"); } }))); } menu.addItem((item) => item.setIcon("arrow-up-right").setTitle("Open in default app").onClick(() => this.app.openWithDefaultApp(file.path))); menu.addItem((item) => item.setIcon("arrow-up-right").setTitle(import_obsidian7.Platform.isMacOS ? "Reveal in finder" : "Show in system explorer").onClick(() => { this.app.showInFolder(file.path); })); menu.addItem((item) => item.setIcon("folder").setTitle("Reveal file in navigation").onClick(() => { const abstractFilePath = this.app.vault.getAbstractFileByPath(file.path); this.app.internalPlugins.getEnabledPluginById("file-explorer").revealInFolder(abstractFilePath); })); }; this.addExternalImageMenuPreviewMode = (menu, img) => { menu.addItem((item) => item.setIcon("copy").setTitle("Copy image to clipboard").onClick(() => __async(this, null, function* () { try { const blob = yield loadImageBlob(img.src); yield navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]); new import_obsidian7.Notice("Image copied to clipboard"); } catch (error) { new import_obsidian7.Notice("Failed to copy image!"); } }))); menu.addItem((item) => item.setIcon("link").setTitle("Copy image link").onClick(() => __async(this, null, function* () { navigator.clipboard.writeText(img.src); }))); menu.addItem((item) => item.setIcon("link").setTitle("Copy markdown link").onClick(() => __async(this, null, function* () { navigator.clipboard.writeText(`![](${img.src})`); }))); menu.addItem((item) => item.setIcon("external-link").setTitle("Open in external browser").onClick(() => __async(this, null, function* () { window.open(img.src, "_blank"); }))); }; this.addExternalImageMenuSourceMode = (menu, img, inTable, inCallout) => { this.addExternalImageMenuPreviewMode(menu, img); menu.addItem((item) => item.setIcon("trash-2").setTitle("Clear image link").onClick(() => { var _a; const editor = (_a = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _a.editor; const editorView = editor.cm; const target_pos = editorView.posAtDOM(img); deleteCurTargetLink(img.src, this, "img", target_pos, inTable, inCallout); })); }; } onload() { return __async(this, null, function* () { console.log("AttachFlow plugin loaded..."); this.edgeSize = 20; this.addSettingTab(new AttachFlowSettingsTab(this.app, this)); yield this.loadSettings(); this.registerDocument(document); app.workspace.on("window-open", (workspaceWindow, window2) => { this.registerDocument(window2.document); }); this.registerEvent(this.app.workspace.on("file-menu", (menu, file) => { if (file instanceof import_obsidian7.TFile) { if (!file.path.endsWith(".md")) return; const addMenuItem = (item) => { item.setTitle("Delete file and its attachments").setIcon("trash-2").setSection("danger"); item.onClick(() => __async(this, null, function* () { const modal = new DeleteAllLogsModal(file, this); modal.open(); })); }; menu.addItem(addMenuItem); } })); addCommand(this); this.registerDomEvent(document, "click", (evt) => __async(this, null, function* () { if (!this.settings.clickView) return; const target = evt.target; if (target.tagName !== "IMG") { this.removeZoomedImage(); return; } const rect = target.getBoundingClientRect(); const imageCenter = rect.left + rect.width / 2; if (evt.clientX <= imageCenter || document.getElementById("af-zoomed-image")) return; evt.preventDefault(); const mask = createZoomMask(); const { zoomedImage, originalWidth, originalHeight } = yield createZoomedImage(target.src, this.settings.adaptiveRatio); const scaleDiv = createZoomScaleDiv(zoomedImage, originalWidth, originalHeight); zoomedImage.addEventListener("wheel", (e) => handleZoomMouseWheel(e, zoomedImage, originalWidth, originalHeight, scaleDiv)); zoomedImage.addEventListener("contextmenu", (e) => handleZoomContextMenu(e, zoomedImage, originalWidth, originalHeight, scaleDiv)); zoomedImage.addEventListener("mousedown", (e) => handleZoomDragStart(e, zoomedImage)); zoomedImage.addEventListener("dblclick", (e) => { adaptivelyDisplayImage(zoomedImage, originalWidth, originalHeight, this.settings.adaptiveRatio); updateZoomScaleDiv(scaleDiv, zoomedImage, originalWidth, originalHeight); }); })); this.registerDomEvent(document, "keydown", (evt) => { if (evt.key === "Escape") { this.removeZoomedImage(); } }); setDebug(this.settings.debug); }); } onunload() { console.log("AttachFlow plugin unloaded..."); } removeZoomedImage() { if (document.getElementById("af-zoomed-image")) { const zoomedImage = document.getElementById("af-zoomed-image"); if (zoomedImage) document.body.removeChild(zoomedImage); const scaleDiv = document.getElementById("af-scale-div"); if (scaleDiv) document.body.removeChild(scaleDiv); const mask = document.getElementById("af-mask"); if (mask) document.body.removeChild(mask); } } registerDocument(document2) { this.register(onElement(document2, "contextmenu", "img, iframe, video, div.file-embed-title, audio", this.onRightClickMenu.bind(this))); this.register(onElement(document2, "mousedown", "img", (event) => { var _a, _b; if (!this.settings.dragResize) return; const currentMd = app.workspace.getActiveFile(); if (currentMd.name.endsWith(".canvas")) return; const inPreview = ((_a = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _a.getMode()) == "preview"; if (inPreview) return; if (event.button === 0) { event.preventDefault(); } const img = event.target; if (img.id == "af-zoomed-image") return; const editor = (_b = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _b.editor; const editorView = editor.cm; const target_pos = editorView.posAtDOM(img); let target_line = editorView.state.doc.lineAt(target_pos); const inTable = img.closest("table") != null; const inCallout = img.closest(".callout") != null; const isExcalidraw = img.classList.contains("excalidraw-embedded-img"); print("InTable", inTable); print("Target Element", img); let preventEvent = function(event2) { event2.preventDefault(); event2.stopPropagation(); }; const rect = img.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; const edgeSize = this.edgeSize; if (x < edgeSize || y < edgeSize || x > rect.width - edgeSize || y > rect.height - edgeSize) { const startX = event.clientX; const startY = event.clientY; const startWidth = img.clientWidth; const startHeight = img.clientHeight; let lastUpdateX = startX; let lastUpdateY = startY; let lastUpdate = 1; let updatedWidth = startWidth; let lastMoveTime = Date.now(); const onMouseMove = (event2) => { img.addEventListener("click", preventEvent); const currentX = event2.clientX; lastUpdate = currentX - lastUpdateX == 0 ? lastUpdate : currentX - lastUpdateX; let newWidth = startWidth + (currentX - startX); const aspectRatio = startWidth / startHeight; newWidth = Math.max(newWidth, 100); let newHeight = newWidth / aspectRatio; newWidth = Math.round(newWidth); newHeight = Math.round(newHeight); updatedWidth = newWidth; if (img instanceof HTMLImageElement) { img.classList.add("image-in-drag-resize"); img.style.width = `${newWidth}px`; } const now = Date.now(); if (now - lastMoveTime < 100) return; lastMoveTime = now; this.updateImageLinkWithNewSize(img, target_pos, newWidth, newHeight); lastUpdateX = event2.clientX; lastUpdateY = event2.clientY; }; const allowOtherEvent = () => { img.removeEventListener("click", preventEvent); }; const onMouseUp = (event2) => { setTimeout(allowOtherEvent, 100); event2.preventDefault(); img.classList.remove("image-in-drag-resize", "image-ready-click-view"); document2.removeEventListener("mousemove", onMouseMove); document2.removeEventListener("mouseup", onMouseUp); if (this.settings.resizeInterval > 1) { let resize_interval = this.settings.resizeInterval; let width_offset = lastUpdate > 0 ? resize_interval : 0; if (updatedWidth % resize_interval != 0) { updatedWidth = Math.floor(updatedWidth / resize_interval) * resize_interval + width_offset; } img.style.width = `${updatedWidth}px`; this.updateImageLinkWithNewSize(img, target_pos, updatedWidth, 0); } }; document2.addEventListener("mousemove", onMouseMove); document2.addEventListener("mouseup", onMouseUp); } })); this.register(onElement(document2, "mouseover", "img", (event) => { var _a; const currentMd = app.workspace.getActiveFile(); if (currentMd.name.endsWith(".canvas")) return; const inPreview = ((_a = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _a.getMode()) == "preview"; const img = event.target; const edgeSize = this.edgeSize; if (img.id == "af-zoomed-image") return; const isExcalidraw = img.classList.contains("excalidraw-embedded-img"); let lastMove = 0; const mouseOverHandler = (event2) => { if (event2.buttons != 0) return; if (!this.settings.dragResize) return; const now = Date.now(); if (now - lastMove < 100) return; lastMove = now; const rect = img.getBoundingClientRect(); const x = event2.clientX - rect.left; const y = event2.clientY - rect.top; if (x >= rect.width - edgeSize || x <= edgeSize || (y >= rect.height - edgeSize || y <= edgeSize)) { if (this.settings.dragResize && !inPreview) { img.classList.remove("image-ready-click-view"); img.classList.add("image-ready-resize"); } else if (inPreview && this.settings.clickView && x > rect.width / 2) { img.classList.add("image-ready-click-view"); img.classList.remove("image-ready-resize"); } } else if (x > rect.width / 2 && this.settings.clickView) { img.classList.add("image-ready-click-view"); img.classList.remove("image-ready-resize"); } else { img.classList.remove("image-ready-click-view", "image-ready-resize"); } }; this.registerDomEvent(img, "mousemove", mouseOverHandler); })); this.register(onElement(document2, "mouseout", "img", (event) => { var _a; if (!this.settings.dragResize) return; const currentMd = app.workspace.getActiveFile(); if (currentMd.name.endsWith(".canvas")) return; const inPreview = ((_a = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _a.getMode()) == "preview"; if (event.buttons != 0) return; const img = event.target; if (this.settings.clickView || this.settings.dragResize) { img.classList.remove("image-ready-click-view", "image-ready-resize"); } })); this.register(onElement(document2, "mousedown", "img", this.externalImageContextMenuCall.bind(this))); } loadSettings() { return __async(this, null, function* () { this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); }); } saveSettings() { return __async(this, null, function* () { yield this.saveData(this.settings); }); } registerEscapeButton(menu, document2 = activeDocument) { menu.register(onElement(document2, "keydown", "*", (e) => { if (e.key === "Escape") { e.preventDefault(); e.stopPropagation(); menu.hide(); } })); } externalImageContextMenuCall(event) { var _a, _b, _c; const img = event.target; const inTable = img.closest("table") != null; const inCallout = img.closest(".callout") != null; if (img.id == "af-zoomed-image") return; if (!img.src.startsWith("http")) return; if (event.button != 2) return; event.preventDefault(); (_b = (_a = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _a.editor) == null ? void 0 : _b.blur(); img.classList.remove("image-ready-click-view", "image-ready-resize"); const menu = new import_obsidian7.Menu(); const inPreview = ((_c = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _c.getMode()) == "preview"; if (inPreview) { this.addExternalImageMenuPreviewMode(menu, img); } else { this.addExternalImageMenuSourceMode(menu, img, inTable, inCallout); } this.registerEscapeButton(menu); let offset = 0; if (!inPreview && (inTable || inCallout)) offset = -138; menu.showAtPosition({ x: event.pageX, y: event.pageY + offset }); this.app.workspace.trigger("AttachFlow:contextmenu", menu); } onRightClickMenu(event) { var _a, _b, _c, _d, _e; const target = getMouseEventTarget(event); const curTargetType = target.localName; if (target.id == "af-zoomed-image") return; const currentMd = app.workspace.getActiveFile(); const inCanvas = currentMd.name.endsWith(".canvas"); const SupportedTargetType = ["img", "iframe", "video", "div", "audio"]; const menu = new import_obsidian7.Menu(); if (!SupportedTargetType.includes(curTargetType)) return; const inTable = target.closest("table") != null; const inCallout = target.closest(".callout") != null; const inPreview = ((_a = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _a.getMode()) == "preview"; const isExcalidraw = target.classList.contains("excalidraw-embedded-img"); let target_name = target.getAttribute("src"); if (target_name && target_name.startsWith("http")) return; if (inCanvas) { if ((_b = target.parentElement) == null ? void 0 : _b.classList.contains("canvas-node-content")) return; let file_name = (_c = target.parentElement) == null ? void 0 : _c.getAttribute("src"); return; } target.classList.remove("image-ready-click-view", "image-ready-resize"); if (isExcalidraw) { target_name = getExcalidrawBaseName(target); target_name = target_name.replace(/^(\.\.\/)+/g, ""); } else { target_name = (_d = target.closest(".internal-embed")) == null ? void 0 : _d.getAttribute("src"); target_name = target_name.replace(/^(\.\.\/)+/g, ""); let pdf_match = target_name.match(/.*\.pdf/); target_name = pdf_match ? pdf_match[0] : target_name; if (curTargetType == "img" && pdf_match) return; } if (inPreview) { if (SupportedTargetType.includes(curTargetType)) { this.addMenuExtendedPreviewMode(menu, target_name, currentMd); } } else { const editor = (_e = this.app.workspace.getActiveViewOfType(import_obsidian7.MarkdownView)) == null ? void 0 : _e.editor; const editorView = editor.cm; const target_pos = editorView.posAtDOM(target); let target_line = editorView.state.doc.lineAt(target_pos); print("target line information: line-content, line-number(1-based), target.ch"); print(target_line.text, target_line.number, target_pos - target_line.from); if (SupportedTargetType.includes(curTargetType)) { this.addMenuExtendedSourceMode(menu, target_name, currentMd, curTargetType, target_pos, inTable, inCallout); } } this.registerEscapeButton(menu); let offset = -163; let linux_offset = -138; offset = process.platform == "linux" ? linux_offset : offset; if (this.settings.moveFileMenu) offset -= 25; if (inTable && !inPreview) { menu.showAtPosition({ x: event.pageX, y: event.pageY + offset }); } else { menu.showAtPosition({ x: event.pageX, y: event.pageY }); } this.app.workspace.trigger("AttachFlow:contextmenu", menu); } }; function updateInternalLink(activeView, target, target_pos, imageName, newWidth, newHeight, inTable, inCallout) { const editor = activeView.editor; const editorView = editor.cm; let target_line = editorView.state.doc.lineAt(target_pos); if (!inCallout && !inTable) { let matched = matchLineWithInternalLink(target_line.text, imageName, newWidth, inTable); if (matched.length == 1) { editorView.dispatch({ changes: { from: target_line.from + matched[0].from_ch, to: target_line.from + matched[0].to_ch, insert: matched[0].new_link } }); } else if (matched.length == 0) { } else { new import_obsidian7.Notice("Find multiple same image-link in line, please zoom manually!"); } return; } let startReg = { "table": /^\s*\|/, "callout": /^>/ }; let mode = inTable ? "table" : "callout"; print("mode", mode); const start_reg = startReg[mode]; let start_line_number = target_line.number; let matched_results = []; let matched_lines = []; for (let i = start_line_number; i <= editor.lineCount(); i++) { let line = editorView.state.doc.line(i); if (!start_reg.test(line.text)) break; let matched = matchLineWithInternalLink(line.text, imageName, newWidth, inTable); matched_results.push(...matched); matched_lines.push(...new Array(matched.length).fill(i)); } for (let i = start_line_number - 1; i >= 1; i--) { let line = editorView.state.doc.line(i); if (!start_reg.test(line.text)) break; let matched = matchLineWithInternalLink(line.text, imageName, newWidth, inTable); matched_results.push(...matched); matched_lines.push(...new Array(matched.length).fill(i)); } if (matched_results.length == 1) { let target_line2 = editorView.state.doc.line(matched_lines[0]); if (mode == "table") { let old_text = target_line2.text; let new_line_text = old_text.substring(0, matched_results[0].from_ch) + matched_results[0].new_link + old_text.substring(matched_results[0].to_ch); editorView.dispatch({ changes: { from: target_line2.from, to: target_line2.from + old_text.length, insert: new_line_text } }); } else { editorView.dispatch({ changes: { from: target_line2.from + matched_results[0].from_ch, to: target_line2.from + matched_results[0].to_ch, insert: matched_results[0].new_link } }); } } else if (matched_results.length == 0) { new import_obsidian7.Notice(`Fail to find current image-link in ${mode}, please zoom manually!`); } else { new import_obsidian7.Notice(`Find multiple same image-link in ${mode}, please zoom manually!`); } return; } function updateExternalLink(activeView, target, target_pos, newWidth, newHeight, inTable, inCallout) { const editor = activeView.editor; const editorView = editor.cm; let target_line = editorView.state.doc.lineAt(target_pos); const link = target.getAttribute("src"); const altText = target.getAttribute("alt"); if (!inCallout && !inTable) { let matched = matchLineWithExternalLink(target_line.text, link, altText, newWidth, inTable); if (matched.length == 1) { editorView.dispatch({ changes: { from: target_line.from + matched[0].from_ch, to: target_line.from + matched[0].to_ch, insert: matched[0].new_link } }); } else if (matched.length == 0) { } else { new import_obsidian7.Notice("Find multiple same image-link in line, please zoom manually!"); } return; } let startReg = { "table": /^\s*\|/, "callout": /^>/ }; let mode = inTable ? "table" : "callout"; print("mode", mode); const start_reg = startReg[mode]; let start_line_number = target_line.number; let matched_results = []; let matched_lines = []; for (let i = start_line_number; i <= editor.lineCount(); i++) { let line = editorView.state.doc.line(i); if (!start_reg.test(line.text)) break; let matched = matchLineWithExternalLink(line.text, link, altText, newWidth, inTable); matched_results.push(...matched); matched_lines.push(...new Array(matched.length).fill(i)); } for (let i = start_line_number - 1; i >= 1; i--) { let line = editorView.state.doc.line(i); if (!start_reg.test(line.text)) break; let matched = matchLineWithExternalLink(line.text, link, altText, newWidth, inTable); matched_results.push(...matched); matched_lines.push(...new Array(matched.length).fill(i)); } print(matched_results); print(matched_lines); if (matched_results.length == 1) { let target_line2 = editorView.state.doc.line(matched_lines[0]); if (mode == "table") { let old_text = target_line2.text; let new_line_text = old_text.substring(0, matched_results[0].from_ch) + matched_results[0].new_link + old_text.substring(matched_results[0].to_ch); editorView.dispatch({ changes: { from: target_line2.from, to: target_line2.from + old_text.length, insert: new_line_text } }); } else { editorView.dispatch({ changes: { from: target_line2.from + matched_results[0].from_ch, to: target_line2.from + matched_results[0].to_ch, insert: matched_results[0].new_link } }); } } else if (matched_results.length == 0) { new import_obsidian7.Notice(`Fail to find current image-link in ${mode}, please zoom manually!`); } else { new import_obsidian7.Notice(`Find multiple same image-link in ${mode}, please zoom manually!`); } return; } function matchLineWithInternalLink(line_text, target_name, new_width, intable) { let regWikiLink = /\!\[\[[^\[\]]*?\]\]/g; let regMdLink = /\!\[[^\[\]]*?\]\([^\s\)\(\[\]\{\}']*\)/g; const target_name_mdlink = target_name.replace(/ /g, "%20"); if (!line_text.includes(target_name) && !line_text.includes(target_name_mdlink)) return []; let result = []; while (true) { let wiki_match = regWikiLink.exec(line_text); if (!wiki_match) break; const matched_link = wiki_match[0]; if (matched_link.includes(target_name)) { let normal_link = intable ? matched_link.replace(/\\\|/g, "|") : matched_link; let link_match = normal_link.match(/!\[\[(.*?)(\||\]\])/); let link_text = link_match ? link_match[1] : ""; let alt_match = matched_link.match(/!\[\[.*?(\|(.*?))\]\]/); let alt_text = alt_match ? alt_match[1] : ""; let alt_text_list = alt_text.split("|"); let alt_text_wo_size = ""; let new_alt_text = ""; for (let alt of alt_text_list) { if (!/^\d+$/.test(alt) && !/^\s*$/.test(alt)) { alt_text_wo_size = alt_text_wo_size + "|" + alt; } } new_alt_text = new_width != 0 ? `${alt_text_wo_size}|${new_width}` : alt_text_wo_size; new_alt_text = intable ? new_alt_text.replace(/\|/g, "\\|") : new_alt_text; let newWikiLink = link_match ? `![[${link_text}${new_alt_text}]]` : `![[${target_name}${new_alt_text}]]`; result.push({ old_link: matched_link, new_link: newWikiLink, from_ch: wiki_match.index, to_ch: wiki_match.index + matched_link.length }); } } while (true) { let match = regMdLink.exec(line_text); if (!match) break; const matched_link = match[0]; if (matched_link.includes(target_name_mdlink)) { let alt_text_match = matched_link.match(/\[.*?\]/g); let alt_text = alt_text_match[0].substring(1, alt_text_match[0].length - 1); let pure_alt = alt_text.replace(/\|\d+(\|\d+)?$/g, ""); if (intable) { pure_alt = alt_text.replace(/\\\|\d+(\|\d+)?$/g, ""); } let link_text = matched_link.substring(alt_text_match[0].length + 2, matched_link.length - 1); let newMDLink = intable ? `![${pure_alt}\\|${new_width}](${link_text})` : `![${pure_alt}|${new_width}](${link_text})`; if (/^\d*$/.test(alt_text)) { newMDLink = `![${new_width}](${link_text})`; } result.push({ old_link: matched_link, new_link: newMDLink, from_ch: match.index, to_ch: match.index + matched_link.length }); } } print("Line Text: ", line_text); print("MatchedInfo:", result); return result; } function matchLineWithExternalLink(line_text, link, alt_text, new_width, intable) { let result = []; let regMdLink = /\!\[[^\[\]]*?\]\([^\s\)\(\[\]\{\}']*\)/g; if (!line_text.includes(link)) return []; while (true) { let match = regMdLink.exec(line_text); if (!match) break; let matched_link = match[0]; if (matched_link.includes(link)) { let alt_text_match = matched_link.match(/\[.*?\]/g); let alt_text2 = alt_text_match[0].substring(1, alt_text_match[0].length - 1); let pure_alt = alt_text2.replace(/\|\d+(\|\d+)?$/g, ""); if (intable) { pure_alt = alt_text2.replace(/\\\|\d+(\|\d+)?$/g, ""); } if (/^\d*$/.test(alt_text2)) { pure_alt = ""; } let link_text = matched_link.substring(alt_text_match[0].length + 2, matched_link.length - 1); let newExternalLink = intable ? `![${pure_alt}\\|${new_width}](${link_text})` : `![${pure_alt}|${new_width}](${link_text})`; result.push({ old_link: matched_link, new_link: newExternalLink, from_ch: match.index, to_ch: match.index + matched_link.length }); } } print("Line Text: ", line_text); print("MatchedInfo:", result); return result; } function createZoomMask() { const mask = document.createElement("div"); mask.id = "af-mask"; mask.style.position = "fixed"; mask.style.top = "0"; mask.style.left = "0"; mask.style.width = "100%"; mask.style.height = "100%"; mask.style.background = "rgba(0, 0, 0, 0.5)"; mask.style.zIndex = "9998"; document.body.appendChild(mask); return mask; } function createZoomedImage(src, adaptive_ratio) { return __async(this, null, function* () { const zoomedImage = document.createElement("img"); zoomedImage.id = "af-zoomed-image"; zoomedImage.src = src; zoomedImage.style.position = "fixed"; zoomedImage.style.zIndex = "9999"; zoomedImage.style.top = "50%"; zoomedImage.style.left = "50%"; zoomedImage.style.transform = "translate(-50%, -50%)"; document.body.appendChild(zoomedImage); let originalWidth = zoomedImage.naturalWidth; let originalHeight = zoomedImage.naturalHeight; adaptivelyDisplayImage(zoomedImage, originalWidth, originalHeight, adaptive_ratio); return { zoomedImage, originalWidth, originalHeight }; }); } function createZoomScaleDiv(zoomedImage, originalWidth, originalHeight) { const scaleDiv = document.createElement("div"); scaleDiv.id = "af-scale-div"; scaleDiv.classList.add("af-scale-div"); scaleDiv.style.zIndex = "10000"; updateZoomScaleDiv(scaleDiv, zoomedImage, originalWidth, originalHeight); document.body.appendChild(scaleDiv); return scaleDiv; } function updateZoomScaleDiv(scaleDiv, zoomedImage, originalWidth, originalHeight) { const width = zoomedImage.offsetWidth; const height = zoomedImage.offsetHeight; let scalePercent = width / originalWidth * 100; scaleDiv.innerText = `${width}\xD7${height} (${scalePercent.toFixed(1)}%)`; } function handleZoomMouseWheel(e, zoomedImage, originalWidth, originalHeight, scaleDiv) { e.preventDefault(); const mouseX = e.clientX; const mouseY = e.clientY; const scale = e.deltaY > 0 ? 0.95 : 1.05; const newWidth = scale * zoomedImage.offsetWidth; const newHeight = scale * zoomedImage.offsetHeight; const newLeft = mouseX - (mouseX - zoomedImage.offsetLeft) * scale; const newTop = mouseY - (mouseY - zoomedImage.offsetTop) * scale; zoomedImage.style.width = `${newWidth}px`; zoomedImage.style.height = `${newHeight}px`; zoomedImage.style.left = `${newLeft}px`; zoomedImage.style.top = `${newTop}px`; updateZoomScaleDiv(scaleDiv, zoomedImage, originalWidth, originalHeight); } function handleZoomContextMenu(e, zoomedImage, originalWidth, originalHeight, scaleDiv) { e.preventDefault(); zoomedImage.style.width = `${originalWidth}px`; zoomedImage.style.height = `${originalHeight}px`; zoomedImage.style.left = `50%`; zoomedImage.style.top = `50%`; updateZoomScaleDiv(scaleDiv, zoomedImage, originalWidth, originalHeight); } function adaptivelyDisplayImage(zoomedImage, originalWidth, originalHeight, adaptive_ratio) { zoomedImage.style.left = `50%`; zoomedImage.style.top = `50%`; let screenRatio = adaptive_ratio; let screenWidth = window.innerWidth; let screenHeight = window.innerHeight; if (originalWidth > screenWidth || originalHeight > screenHeight) { if (originalWidth / screenWidth > originalHeight / screenHeight) { zoomedImage.style.width = `${screenWidth * screenRatio}px`; zoomedImage.style.height = "auto"; } else { zoomedImage.style.height = `${screenHeight * screenRatio}px`; zoomedImage.style.width = "auto"; } } else { zoomedImage.style.width = `${originalWidth}px`; zoomedImage.style.height = `${originalHeight}px`; } } function handleZoomDragStart(e, zoomedImage) { e.preventDefault(); let clickX = e.clientX; let clickY = e.clientY; const updatePosition = (moveEvt) => { let moveX = moveEvt.clientX - clickX; let moveY = moveEvt.clientY - clickY; zoomedImage.style.left = `${zoomedImage.offsetLeft + moveX}px`; zoomedImage.style.top = `${zoomedImage.offsetTop + moveY}px`; clickX = moveEvt.clientX; clickY = moveEvt.clientY; }; document.addEventListener("mousemove", updatePosition); document.addEventListener("mouseup", function listener() { document.removeEventListener("mousemove", updatePosition); document.removeEventListener("mouseup", listener); }, { once: true }); } function getExcalidrawBaseName(target) { let target_name = target.getAttribute("filesource"); let file_base_name = target_name; if (file_base_name.includes("/")) { let temp_arr = file_base_name.split("/"); file_base_name = temp_arr[temp_arr.length - 1]; } else if (file_base_name.includes("\\")) { let temp_arr = file_base_name.split("\\"); file_base_name = temp_arr[temp_arr.length - 1]; } file_base_name = file_base_name.endsWith(".md") ? file_base_name.substring(0, file_base_name.length - 3) : file_base_name; return file_base_name; } //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL29wdGlvbnMvZGVsZWxlQWxsQXR0YWNoc0luVGhlTm90ZS50cyIsICJzcmMvdXRpbC50cyIsICJzcmMvdXRpbHMvZGVsZXRlRmlsZS50cyIsICJzcmMvY29uZmlnL2FkZENvbW1hbmQtY29uZmlnLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvdXRpbHMvaGFuZGxlckV2ZW50LnRzIiwgInNyYy9tb2RhbHMvZGVsZXRpb25Qcm9tcHQudHMiLCAic3JjL2hlbHBlcnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7IE1lbnUsIE1lbnVJdGVtLCBOb3RpY2UsIFBsdWdpbiwgVEZpbGUsIE1hcmtkb3duVmlldywgUGxhdGZvcm0sIEVkaXRvciB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgYWRkQ29tbWFuZCB9IGZyb20gXCIuL2NvbmZpZy9hZGRDb21tYW5kLWNvbmZpZ1wiO1xuaW1wb3J0IHsgQXR0YWNoRmxvd1NldHRpbmdzVGFiIH0gZnJvbSBcIi4vc2V0dGluZ3NcIjtcbmltcG9ydCB7IEF0dGFjaEZsb3dTZXR0aW5ncywgREVGQVVMVF9TRVRUSU5HUyB9IGZyb20gXCIuL3NldHRpbmdzXCI7XG5pbXBvcnQgKiBhcyBVdGlsIGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCB7IHByaW50LCBzZXREZWJ1ZywgZGVsZXRlQ3VyVGFyZ2V0TGluayB9IGZyb20gJy4vdXRpbCdcbmltcG9ydCB7IGdldE1vdXNlRXZlbnRUYXJnZXQgfSBmcm9tIFwiLi91dGlscy9oYW5kbGVyRXZlbnRcIjtcbmltcG9ydCB7IERlbGV0ZUFsbExvZ3NNb2RhbCB9IGZyb20gXCIuL21vZGFscy9kZWxldGlvblByb21wdFwiO1xuaW1wb3J0IHsgRWRpdG9yVmlldywga2V5bWFwLCBWaWV3VXBkYXRlIH0gZnJvbSAnQGNvZGVtaXJyb3Ivdmlldyc7XG5pbXBvcnQge1xuXHRFbGVjdHJvbldpbmRvdywgRmlsZVN5c3RlbUFkYXB0ZXJXaXRoSW50ZXJuYWxBcGksXG5cdGxvYWRJbWFnZUJsb2IsIEFwcFdpdGhEZXNrdG9wSW50ZXJuYWxBcGksIEVkaXRvckludGVybmFsQXBpLCBvbkVsZW1lbnRcbn0gZnJvbSBcIi4vaGVscGVyc1wiXG5cbmludGVyZmFjZSBNYXRjaGVkTGlua0luTGluZSB7XG5cdG9sZF9saW5rOiBzdHJpbmcsXG5cdG5ld19saW5rOiBzdHJpbmcsXG5cdGZyb21fY2g6IG51bWJlcixcblx0dG9fY2g6IG51bWJlclxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBdHRhY2hGbG93UGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IEF0dGFjaEZsb3dTZXR0aW5ncztcblx0ZWRnZVNpemU6IG51bWJlcjtcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coXCJBdHRhY2hGbG93IHBsdWdpbiBsb2FkZWQuLi5cIik7XG5cdFx0dGhpcy5lZGdlU2l6ZSA9IDIwO1xuXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBBdHRhY2hGbG93U2V0dGluZ3NUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XG5cdFx0dGhpcy5yZWdpc3RlckRvY3VtZW50KGRvY3VtZW50KTtcblx0XHRhcHAud29ya3NwYWNlLm9uKFwid2luZG93LW9wZW5cIiwgKHdvcmtzcGFjZVdpbmRvdywgd2luZG93KSA9PiB7XG5cdFx0XHR0aGlzLnJlZ2lzdGVyRG9jdW1lbnQod2luZG93LmRvY3VtZW50KTtcblx0XHR9KTtcblx0XHQvLyBhZGQgY29udGV4dG1lbnUgb24gZmlsZSBjb250ZXh0XG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKFwiZmlsZS1tZW51XCIsIChtZW51LCBmaWxlKSA9PiB7XG5cdFx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcblx0XHRcdFx0XHRpZiAoIWZpbGUucGF0aC5lbmRzV2l0aChcIi5tZFwiKSkgcmV0dXJuO1xuXHRcdFx0XHRcdGNvbnN0IGFkZE1lbnVJdGVtID0gKGl0ZW06IE1lbnVJdGVtKSA9PiB7XG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKFwiRGVsZXRlIGZpbGUgYW5kIGl0cyBhdHRhY2htZW50c1wiKVxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbihcInRyYXNoLTJcIilcblx0XHRcdFx0XHRcdFx0LnNldFNlY3Rpb24oXCJkYW5nZXJcIik7XG5cdFx0XHRcdFx0XHRpdGVtLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRjb25zdCBtb2RhbCA9IG5ldyBEZWxldGVBbGxMb2dzTW9kYWwoZmlsZSwgdGhpcyk7XG5cdFx0XHRcdFx0XHRcdG1vZGFsLm9wZW4oKTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0bWVudS5hZGRJdGVtKGFkZE1lbnVJdGVtKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHQpO1xuXHRcdC8vIHJlZ2lzdGVyIGFsbCBjb21tYW5kcyBpbiBhZGRDb21tYW5kIGZ1bmN0aW9uXG5cdFx0YWRkQ29tbWFuZCh0aGlzKTtcblxuXHRcdC8vIFx1NEUzQlx1NTkwNFx1NzQwNlx1NTFGRFx1NjU3MFxuXHRcdHRoaXMucmVnaXN0ZXJEb21FdmVudChkb2N1bWVudCwgJ2NsaWNrJywgYXN5bmMgKGV2dDogTW91c2VFdmVudCkgPT4ge1xuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmNsaWNrVmlldykgcmV0dXJuO1xuXHRcdFx0Y29uc3QgdGFyZ2V0ID0gZXZ0LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcblx0XHRcdGlmICh0YXJnZXQudGFnTmFtZSAhPT0gJ0lNRycpIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVab29tZWRJbWFnZSgpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjb25zdCByZWN0ID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdFx0Y29uc3QgaW1hZ2VDZW50ZXIgPSByZWN0LmxlZnQgKyByZWN0LndpZHRoIC8gMjtcblx0XHRcdGlmIChldnQuY2xpZW50WCA8PSBpbWFnZUNlbnRlciB8fCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWYtem9vbWVkLWltYWdlJykpIHJldHVybjtcblx0XHRcdGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0Y29uc3QgbWFzayA9IGNyZWF0ZVpvb21NYXNrKCk7XG5cdFx0XHRjb25zdCB7IHpvb21lZEltYWdlLCBvcmlnaW5hbFdpZHRoLCBvcmlnaW5hbEhlaWdodCB9ID0gYXdhaXQgY3JlYXRlWm9vbWVkSW1hZ2UoKHRhcmdldCBhcyBIVE1MSW1hZ2VFbGVtZW50KS5zcmMsIHRoaXMuc2V0dGluZ3MuYWRhcHRpdmVSYXRpbyk7XG5cdFx0XHRjb25zdCBzY2FsZURpdiA9IGNyZWF0ZVpvb21TY2FsZURpdih6b29tZWRJbWFnZSwgb3JpZ2luYWxXaWR0aCwgb3JpZ2luYWxIZWlnaHQpO1xuXHRcdFx0em9vbWVkSW1hZ2UuYWRkRXZlbnRMaXN0ZW5lcignd2hlZWwnLCAoZSkgPT4gaGFuZGxlWm9vbU1vdXNlV2hlZWwoZSwgem9vbWVkSW1hZ2UsIG9yaWdpbmFsV2lkdGgsIG9yaWdpbmFsSGVpZ2h0LCBzY2FsZURpdikpO1xuXHRcdFx0em9vbWVkSW1hZ2UuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCAoZSkgPT4gaGFuZGxlWm9vbUNvbnRleHRNZW51KGUsIHpvb21lZEltYWdlLCBvcmlnaW5hbFdpZHRoLCBvcmlnaW5hbEhlaWdodCwgc2NhbGVEaXYpKTtcblx0XHRcdHpvb21lZEltYWdlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlKSA9PiBoYW5kbGVab29tRHJhZ1N0YXJ0KGUsIHpvb21lZEltYWdlKSk7XG5cdFx0XHR6b29tZWRJbWFnZS5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIChlKSA9PiB7XG5cdFx0XHRcdGFkYXB0aXZlbHlEaXNwbGF5SW1hZ2Uoem9vbWVkSW1hZ2UsIG9yaWdpbmFsV2lkdGgsIG9yaWdpbmFsSGVpZ2h0LCB0aGlzLnNldHRpbmdzLmFkYXB0aXZlUmF0aW8pO1xuXHRcdFx0XHR1cGRhdGVab29tU2NhbGVEaXYoc2NhbGVEaXYsIHpvb21lZEltYWdlLCBvcmlnaW5hbFdpZHRoLCBvcmlnaW5hbEhlaWdodCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblxuXHRcdHRoaXMucmVnaXN0ZXJEb21FdmVudChkb2N1bWVudCwgJ2tleWRvd24nLCAoZXZ0OiBLZXlib2FyZEV2ZW50KSA9PiB7XG5cdFx0XHRpZiAoZXZ0LmtleSA9PT0gJ0VzY2FwZScpIHtcblx0XHRcdFx0dGhpcy5yZW1vdmVab29tZWRJbWFnZSgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0c2V0RGVidWcodGhpcy5zZXR0aW5ncy5kZWJ1Zyk7XG5cdH1cblxuXHRvbnVubG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZyhcIkF0dGFjaEZsb3cgcGx1Z2luIHVubG9hZGVkLi4uXCIpO1xuXHR9XG5cblx0cmVtb3ZlWm9vbWVkSW1hZ2UoKSB7XG5cdFx0aWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhZi16b29tZWQtaW1hZ2UnKSkge1xuXHRcdFx0Y29uc3Qgem9vbWVkSW1hZ2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWYtem9vbWVkLWltYWdlJyk7XG5cdFx0XHRpZiAoem9vbWVkSW1hZ2UpIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoem9vbWVkSW1hZ2UpO1xuXHRcdFx0Y29uc3Qgc2NhbGVEaXYgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWYtc2NhbGUtZGl2Jyk7XG5cdFx0XHRpZiAoc2NhbGVEaXYpIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoc2NhbGVEaXYpO1xuXHRcdFx0Y29uc3QgbWFzayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhZi1tYXNrJyk7XG5cdFx0XHRpZiAobWFzaykgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChtYXNrKTtcblx0XHR9XG5cdH1cblxuXHRyZWdpc3RlckRvY3VtZW50KGRvY3VtZW50OiBEb2N1bWVudCkge1xuXHRcdHRoaXMucmVnaXN0ZXIoXG5cdFx0XHRvbkVsZW1lbnQoXG5cdFx0XHRcdGRvY3VtZW50LFxuXHRcdFx0XHRcImNvbnRleHRtZW51XCIgYXMga2V5b2YgSFRNTEVsZW1lbnRFdmVudE1hcCxcblx0XHRcdFx0XCJpbWcsIGlmcmFtZSwgdmlkZW8sIGRpdi5maWxlLWVtYmVkLXRpdGxlLCBhdWRpb1wiLFxuXHRcdFx0XHR0aGlzLm9uUmlnaHRDbGlja01lbnUuYmluZCh0aGlzKVxuXHRcdFx0KVxuXHRcdCk7XG5cblx0XHQvLyBcdTRFRTVcdTRFMEJcdTRFMDlcdTRFMkFcdTRFOEJcdTRFRjZcdTY2MkZcdTRFM0FcdTRFODZcdTVCOUVcdTczQjBcdTYyRDZcdTYyRkRcdTY1MzlcdTUzRDhcdTU2RkVcdTcyNDdcdTU5MjdcdTVDMEZcdTc2ODRcdTUyOUZcdTgwRkRcdUZGMENcdTRGRUVcdTY1MzlcdTgxRUEgaHR0cHM6Ly9naXRodWIuY29tL3hSeXVsL29ic2lkaWFuLWltYWdlLWNvbnZlcnRlclxuXHRcdC8vIFx1OTY0NFx1NEUwQVx1NTE3NiBNSVQgTGljZW5zZVxuXHRcdC8vIE1JVCBMaWNlbnNlXG5cdFx0Ly8gQ29weXJpZ2h0IChjKSAyMDIzIHhSeXVsXG5cdFx0Ly8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuXHRcdC8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcblx0XHQvLyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG5cdFx0Ly8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuXHRcdC8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuXHRcdC8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblx0XHQvLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcblx0XHQvLyBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXG5cdFx0Ly8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuXHRcdC8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuXHRcdC8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuXHRcdC8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcblx0XHQvLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuXHRcdC8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG5cdFx0Ly8gU09GVFdBUkUuXG5cblx0XHR0aGlzLnJlZ2lzdGVyKFxuXHRcdFx0b25FbGVtZW50KFxuXHRcdFx0XHRkb2N1bWVudCxcblx0XHRcdFx0XCJtb3VzZWRvd25cIixcblx0XHRcdFx0XCJpbWdcIixcblx0XHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmRyYWdSZXNpemUpIHJldHVybjtcblx0XHRcdFx0XHRjb25zdCBjdXJyZW50TWQgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKSBhcyBURmlsZTtcblx0XHRcdFx0XHRpZiAoY3VycmVudE1kLm5hbWUuZW5kc1dpdGgoJy5jYW52YXMnKSkgcmV0dXJuO1xuXHRcdFx0XHRcdGNvbnN0IGluUHJldmlldzogYm9vbGVhbiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmdldE1vZGUoKSA9PSBcInByZXZpZXdcIjtcblx0XHRcdFx0XHRpZiAoaW5QcmV2aWV3KSByZXR1cm47XG5cblx0XHRcdFx0XHRpZiAoZXZlbnQuYnV0dG9uID09PSAwKSB7XG5cdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCBpbWcgPSBldmVudC50YXJnZXQgYXMgSFRNTEltYWdlRWxlbWVudDtcblx0XHRcdFx0XHRpZiAoaW1nLmlkID09ICdhZi16b29tZWQtaW1hZ2UnKSByZXR1cm47XG5cblx0XHRcdFx0XHRjb25zdCBlZGl0b3IgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3I7XG5cdFx0XHRcdFx0Ly8gIEB0cy1leHBlY3QtZXJyb3IsIG5vdCB0eXBlZFxuXHRcdFx0XHRcdGNvbnN0IGVkaXRvclZpZXcgPSBlZGl0b3IuY20gYXMgRWRpdG9yVmlldztcblx0XHRcdFx0XHRjb25zdCB0YXJnZXRfcG9zID0gZWRpdG9yVmlldy5wb3NBdERPTShpbWcpO1xuXHRcdFx0XHRcdGxldCB0YXJnZXRfbGluZSA9IGVkaXRvclZpZXcuc3RhdGUuZG9jLmxpbmVBdCh0YXJnZXRfcG9zKTtcblxuXHRcdFx0XHRcdGNvbnN0IGluVGFibGU6IGJvb2xlYW4gPSBpbWcuY2xvc2VzdCgndGFibGUnKSAhPSBudWxsO1xuXHRcdFx0XHRcdGNvbnN0IGluQ2FsbG91dDogYm9vbGVhbiA9IGltZy5jbG9zZXN0KCcuY2FsbG91dCcpICE9IG51bGw7XG5cdFx0XHRcdFx0Y29uc3QgaXNFeGNhbGlkcmF3ID0gaW1nLmNsYXNzTGlzdC5jb250YWlucygnZXhjYWxpZHJhdy1lbWJlZGRlZC1pbWcnKTtcblx0XHRcdFx0XHRwcmludCgnSW5UYWJsZScsIGluVGFibGUpXG5cdFx0XHRcdFx0cHJpbnQoJ1RhcmdldCBFbGVtZW50JywgaW1nKVxuXG5cdFx0XHRcdFx0Ly8gcHJpbnQoXCJpbWcucGFyZW50XCIsIGltZy5wYXJlbnRFbGVtZW50P2ltZy5wYXJlbnRFbGVtZW50OidOVUxMJylcblxuXHRcdFx0XHRcdC8vIFx1NUI5QVx1NEU0OVx1NEU4Qlx1NEVGNlx1NTkwNFx1NzQwNlx1NTFGRFx1NjU3MFxuXHRcdFx0XHRcdGxldCBwcmV2ZW50RXZlbnQgPSBmdW5jdGlvbihldmVudDogTW91c2VFdmVudCkge1xuXHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRjb25zdCByZWN0ID0gaW1nLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdFx0XHRcdGNvbnN0IHggPSBldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0O1xuXHRcdFx0XHRcdGNvbnN0IHkgPSBldmVudC5jbGllbnRZIC0gcmVjdC50b3A7XG5cdFx0XHRcdFx0Y29uc3QgZWRnZVNpemUgPSB0aGlzLmVkZ2VTaXplOyAvLyBzaXplIG9mIHRoZSBlZGdlIGluIHBpeGVsc1xuXHRcdFx0XHRcdGlmICh4IDwgZWRnZVNpemUgfHwgeSA8IGVkZ2VTaXplIHx8IHggPiByZWN0LndpZHRoIC0gZWRnZVNpemUgfHwgeSA+IHJlY3QuaGVpZ2h0IC0gZWRnZVNpemUpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHN0YXJ0WCA9IGV2ZW50LmNsaWVudFg7XG5cdFx0XHRcdFx0XHRjb25zdCBzdGFydFkgPSBldmVudC5jbGllbnRZO1xuXHRcdFx0XHRcdFx0Y29uc3Qgc3RhcnRXaWR0aCA9IGltZy5jbGllbnRXaWR0aDtcblx0XHRcdFx0XHRcdGNvbnN0IHN0YXJ0SGVpZ2h0ID0gaW1nLmNsaWVudEhlaWdodDtcblx0XHRcdFx0XHRcdGxldCBsYXN0VXBkYXRlWCA9IHN0YXJ0WDtcblx0XHRcdFx0XHRcdGxldCBsYXN0VXBkYXRlWSA9IHN0YXJ0WTtcblxuXHRcdFx0XHRcdFx0bGV0IGxhc3RVcGRhdGUgPSAxO1xuXHRcdFx0XHRcdFx0bGV0IHVwZGF0ZWRXaWR0aCA9IHN0YXJ0V2lkdGg7XG5cdFx0XHRcdFx0XHRsZXQgbGFzdE1vdmVUaW1lID0gRGF0ZS5ub3coKTtcblx0XHRcdFx0XHRcdGNvbnN0IG9uTW91c2VNb3ZlID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0XHRcdC8vIHRoaXMuQWxsb3dab29tID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdGltZy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHByZXZlbnRFdmVudCk7XG5cdFx0XHRcdFx0XHRcdC8vIGltZy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCBwcmV2ZW50RXZlbnQpO1xuXHRcdFx0XHRcdFx0XHQvLyBpbWcuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCBwcmV2ZW50RXZlbnQpO1xuXHRcdFx0XHRcdFx0XHRjb25zdCBjdXJyZW50WCA9IGV2ZW50LmNsaWVudFg7XG5cdFx0XHRcdFx0XHRcdGxhc3RVcGRhdGUgPSBjdXJyZW50WCAtIGxhc3RVcGRhdGVYID09IDA/bGFzdFVwZGF0ZTpjdXJyZW50WCAtIGxhc3RVcGRhdGVYO1xuXHRcdFx0XHRcdFx0XHQvLyBwcmludCgnbGFzdFVwZGF0ZScsIGxhc3RVcGRhdGUpXG5cdFx0XHRcdFx0XHRcdGxldCBuZXdXaWR0aCA9IHN0YXJ0V2lkdGggKyAoY3VycmVudFggLSBzdGFydFgpO1xuXHRcdFx0XHRcdFx0XHRjb25zdCBhc3BlY3RSYXRpbyA9IHN0YXJ0V2lkdGggLyBzdGFydEhlaWdodDtcblxuXHRcdFx0XHRcdFx0XHQvLyBFbnN1cmUgdGhlIGltYWdlIGRvZXNuJ3QgZ2V0IHRvbyBzbWFsbFxuXHRcdFx0XHRcdFx0XHRuZXdXaWR0aCA9IE1hdGgubWF4KG5ld1dpZHRoLCAxMDApO1xuXG5cdFx0XHRcdFx0XHRcdGxldCBuZXdIZWlnaHQgPSBuZXdXaWR0aCAvIGFzcGVjdFJhdGlvO1xuXHRcdFx0XHRcdFx0XHQvLyBSb3VuZCB0aGUgdmFsdWVzIHRvIHRoZSBuZWFyZXN0IHdob2xlIG51bWJlclxuXHRcdFx0XHRcdFx0XHRuZXdXaWR0aCA9IE1hdGgucm91bmQobmV3V2lkdGgpO1xuXHRcdFx0XHRcdFx0XHRuZXdIZWlnaHQgPSBNYXRoLnJvdW5kKG5ld0hlaWdodCk7XG5cdFx0XHRcdFx0XHRcdHVwZGF0ZWRXaWR0aCA9IG5ld1dpZHRoO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFwcGx5IHRoZSBuZXcgZGltZW5zaW9ucyB0byB0aGUgaW1hZ2Ugb3IgdmlkZW9cblx0XHRcdFx0XHRcdFx0aWYgKGltZyBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQpIHtcblx0XHRcdFx0XHRcdFx0XHRpbWcuY2xhc3NMaXN0LmFkZCgnaW1hZ2UtaW4tZHJhZy1yZXNpemUnKVxuXHRcdFx0XHRcdFx0XHRcdGltZy5zdHlsZS53aWR0aCA9IGAke25ld1dpZHRofXB4YDtcblx0XHRcdFx0XHRcdFx0XHQvLyBpbWcuc3R5bGUuaGVpZ2h0ID0gYCR7bmV3SGVpZ2h0fXB4YDtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cdFx0XHRcdFx0XHRcdGlmIChub3cgLSBsYXN0TW92ZVRpbWUgPCAxMDApIHJldHVybjsgLy8gT25seSBleGVjdXRlIG9uY2UgZXZlcnkgMTAwbXNcblx0XHRcdFx0XHRcdFx0bGFzdE1vdmVUaW1lID0gbm93O1xuXHRcdFx0XHRcdFx0XHQvLyB1cGRhdGUgaW1hZ2UgbGlua1xuXHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUltYWdlTGlua1dpdGhOZXdTaXplKGltZywgdGFyZ2V0X3BvcywgbmV3V2lkdGgsIG5ld0hlaWdodCk7XG5cdFx0XHRcdFx0XHRcdC8vIFVwZGF0ZSB0aGUgbGFzdCB1cGRhdGUgY29vcmRpbmF0ZXNcblx0XHRcdFx0XHRcdFx0bGFzdFVwZGF0ZVggPSBldmVudC5jbGllbnRYO1xuXHRcdFx0XHRcdFx0XHRsYXN0VXBkYXRlWSA9IGV2ZW50LmNsaWVudFk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGNvbnN0IGFsbG93T3RoZXJFdmVudCA9ICgpID0+IHtcblx0XHRcdFx0XHRcdFx0aW1nLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgcHJldmVudEV2ZW50KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Y29uc3Qgb25Nb3VzZVVwID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0XHRcdHNldFRpbWVvdXQoYWxsb3dPdGhlckV2ZW50LCAxMDApO1xuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpXG5cdFx0XHRcdFx0XHRcdGltZy5jbGFzc0xpc3QucmVtb3ZlKCdpbWFnZS1pbi1kcmFnLXJlc2l6ZScsICdpbWFnZS1yZWFkeS1jbGljay12aWV3Jylcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCBvbk1vdXNlTW92ZSk7XG5cdFx0XHRcdFx0XHRcdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIG9uTW91c2VVcCk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gXHU5MDc1XHU1RkFBXHU2NzAwXHU1QzBGXHU1MjNCXHU1RUE2XG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLnJlc2l6ZUludGVydmFsID4gMSkge1xuXHRcdFx0XHRcdFx0XHRcdGxldCByZXNpemVfaW50ZXJ2YWwgPSB0aGlzLnNldHRpbmdzLnJlc2l6ZUludGVydmFsO1xuXHRcdFx0XHRcdFx0XHRcdGxldCB3aWR0aF9vZmZzZXQgPSBsYXN0VXBkYXRlPjA/cmVzaXplX2ludGVydmFsOjA7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKHVwZGF0ZWRXaWR0aCVyZXNpemVfaW50ZXJ2YWwhPTApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHVwZGF0ZWRXaWR0aCA9IE1hdGguZmxvb3IodXBkYXRlZFdpZHRoL3Jlc2l6ZV9pbnRlcnZhbCkqcmVzaXplX2ludGVydmFsK3dpZHRoX29mZnNldDtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0aW1nLnN0eWxlLndpZHRoID0gYCR7dXBkYXRlZFdpZHRofXB4YDtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUltYWdlTGlua1dpdGhOZXdTaXplKGltZywgdGFyZ2V0X3BvcywgdXBkYXRlZFdpZHRoLCAwKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIG9uTW91c2VNb3ZlKTtcblx0XHRcdFx0XHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIG9uTW91c2VVcCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHQpXG5cdFx0KVxuXHRcdHRoaXMucmVnaXN0ZXIoXG5cdFx0XHRvbkVsZW1lbnQoXG5cdFx0XHRcdGRvY3VtZW50LFxuXHRcdFx0XHRcIm1vdXNlb3ZlclwiLFxuXHRcdFx0XHRcImltZ1wiLFxuXHRcdFx0XHQoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcblx0XHRcdFx0XHRjb25zdCBjdXJyZW50TWQgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKSBhcyBURmlsZTtcblx0XHRcdFx0XHRpZiAoY3VycmVudE1kLm5hbWUuZW5kc1dpdGgoJy5jYW52YXMnKSkgcmV0dXJuO1xuXHRcdFx0XHRcdGNvbnN0IGluUHJldmlldzogYm9vbGVhbiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmdldE1vZGUoKSA9PSBcInByZXZpZXdcIjtcblx0XHRcdFx0XHQvLyBpZiAoaW5QcmV2aWV3KSByZXR1cm47XG5cblx0XHRcdFx0XHRjb25zdCBpbWcgPSBldmVudC50YXJnZXQgYXMgSFRNTEltYWdlRWxlbWVudCB8IEhUTUxWaWRlb0VsZW1lbnQ7XG5cdFx0XHRcdFx0XG5cdFx0XHRcdFx0Y29uc3QgZWRnZVNpemUgPSB0aGlzLmVkZ2VTaXplOyAvLyBzaXplIG9mIHRoZSBlZGdlIGluIHBpeGVsc1xuXG5cdFx0XHRcdFx0aWYgKGltZy5pZCA9PSAnYWYtem9vbWVkLWltYWdlJykgcmV0dXJuO1xuXG5cdFx0XHRcdFx0Y29uc3QgaXNFeGNhbGlkcmF3ID0gaW1nLmNsYXNzTGlzdC5jb250YWlucygnZXhjYWxpZHJhdy1lbWJlZGRlZC1pbWcnKTtcblxuXHRcdFx0XHRcdC8vIFRocm90dGxlIG1vdXNlbW92ZSBldmVudHNcblx0XHRcdFx0XHRsZXQgbGFzdE1vdmUgPSAwO1xuXHRcdFx0XHRcdGNvbnN0IG1vdXNlT3ZlckhhbmRsZXIgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcblx0XHRcdFx0XHRcdGlmIChldmVudC5idXR0b25zICE9IDApIHJldHVybjtcblx0XHRcdFx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5kcmFnUmVzaXplKSByZXR1cm47XG5cdFx0XHRcdFx0XHRjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXHRcdFx0XHRcdFx0aWYgKG5vdyAtIGxhc3RNb3ZlIDwgMTAwKSByZXR1cm47IC8vIE9ubHkgZXhlY3V0ZSBvbmNlIGV2ZXJ5IDEwMG1zXG5cdFx0XHRcdFx0XHRsYXN0TW92ZSA9IG5vdztcblx0XHRcdFx0XHRcdGNvbnN0IHJlY3QgPSBpbWcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0XHRcdFx0XHRjb25zdCB4ID0gZXZlbnQuY2xpZW50WCAtIHJlY3QubGVmdDtcblx0XHRcdFx0XHRcdGNvbnN0IHkgPSBldmVudC5jbGllbnRZIC0gcmVjdC50b3A7XG5cblx0XHRcdFx0XHRcdGlmICgoeCA+PSByZWN0LndpZHRoIC0gZWRnZVNpemUgfHwgeCA8PSBlZGdlU2l6ZSkgfHwgKHkgPj0gcmVjdC5oZWlnaHQgLSBlZGdlU2l6ZSB8fCB5IDw9IGVkZ2VTaXplKSkge1xuXHRcdFx0XHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5kcmFnUmVzaXplICYmICFpblByZXZpZXcpe1xuXHRcdFx0XHRcdFx0XHRcdGltZy5jbGFzc0xpc3QucmVtb3ZlKCdpbWFnZS1yZWFkeS1jbGljay12aWV3Jylcblx0XHRcdFx0XHRcdFx0XHRpbWcuY2xhc3NMaXN0LmFkZCgnaW1hZ2UtcmVhZHktcmVzaXplJyk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZWxzZSBpZiAoaW5QcmV2aWV3ICYmIHRoaXMuc2V0dGluZ3MuY2xpY2tWaWV3ICYmIHggPiByZWN0LndpZHRoIC8gMikge1xuXHRcdFx0XHRcdFx0XHRcdGltZy5jbGFzc0xpc3QuYWRkKCdpbWFnZS1yZWFkeS1jbGljay12aWV3Jylcblx0XHRcdFx0XHRcdFx0XHRpbWcuY2xhc3NMaXN0LnJlbW92ZSgnaW1hZ2UtcmVhZHktcmVzaXplJyk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2UgaWYgKHggPiByZWN0LndpZHRoIC8gMiAmJiB0aGlzLnNldHRpbmdzLmNsaWNrVmlldykge1xuXHRcdFx0XHRcdFx0XHRpbWcuY2xhc3NMaXN0LmFkZCgnaW1hZ2UtcmVhZHktY2xpY2stdmlldycpXG5cdFx0XHRcdFx0XHRcdGltZy5jbGFzc0xpc3QucmVtb3ZlKCdpbWFnZS1yZWFkeS1yZXNpemUnKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGVsc2V7XG5cdFx0XHRcdFx0XHRcdGltZy5jbGFzc0xpc3QucmVtb3ZlKCdpbWFnZS1yZWFkeS1jbGljay12aWV3JywgJ2ltYWdlLXJlYWR5LXJlc2l6ZScpXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR0aGlzLnJlZ2lzdGVyRG9tRXZlbnQoaW1nLCAnbW91c2Vtb3ZlJywgbW91c2VPdmVySGFuZGxlcik7XG5cdFx0XHRcdH1cblx0XHRcdClcblx0XHQpO1xuXG5cdFx0dGhpcy5yZWdpc3Rlcihcblx0XHRcdG9uRWxlbWVudChcblx0XHRcdFx0ZG9jdW1lbnQsXG5cdFx0XHRcdFwibW91c2VvdXRcIixcblx0XHRcdFx0XCJpbWdcIixcblx0XHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmRyYWdSZXNpemUpIHJldHVybjtcblx0XHRcdFx0XHRjb25zdCBjdXJyZW50TWQgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKSBhcyBURmlsZTtcblx0XHRcdFx0XHRpZiAoY3VycmVudE1kLm5hbWUuZW5kc1dpdGgoJy5jYW52YXMnKSkgcmV0dXJuO1xuXHRcdFx0XHRcdGNvbnN0IGluUHJldmlldzogYm9vbGVhbiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmdldE1vZGUoKSA9PSBcInByZXZpZXdcIjtcblx0XHRcdFx0XHRpZiAoZXZlbnQuYnV0dG9ucyAhPSAwKSByZXR1cm47XG5cdFx0XHRcdFx0Y29uc3QgaW1nID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbWFnZUVsZW1lbnQgfCBIVE1MVmlkZW9FbGVtZW50O1xuXG5cdFx0XHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuY2xpY2tWaWV3IHx8IHRoaXMuc2V0dGluZ3MuZHJhZ1Jlc2l6ZSl7XG5cdFx0XHRcdFx0XHRpbWcuY2xhc3NMaXN0LnJlbW92ZSgnaW1hZ2UtcmVhZHktY2xpY2stdmlldycsICdpbWFnZS1yZWFkeS1yZXNpemUnKVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0KVxuXHRcdCk7XG5cblx0XHQvLyBcdTYyMTFcdTVCOUVcdTczQjBcdTc2ODRcdTU5MTZcdTkwRThcdTk0RkVcdTYzQTVcdTUzRjNcdTk1MkVcdTgzRENcdTUzNTVcblx0XHQvLyBcdTUxNzNcdTk1MkVcdTU3MjhcdTRFOEUgZWRpdG9yLmJsdXIoKVx1RkYwQ1x1OEZEOVx1NjgzN1x1NTNFRlx1NEVFNVx1OEJBOSBPYnNpZGlhbiBcdTU5MzFcdTUzQkJcdTcxMjZcdTcwQjlcdUZGMENcdTRFQ0VcdTgwMENcdTRFMERcdTRGMUFcdTg5RTZcdTUzRDEgT2JzaWRpYW4gXHU3Njg0XHU1M0YzXHU5NTJFXHU4M0RDXHU1MzU1XG5cdFx0dGhpcy5yZWdpc3Rlcihcblx0XHRcdG9uRWxlbWVudChcblx0XHRcdFx0ZG9jdW1lbnQsXG5cdFx0XHRcdFwibW91c2Vkb3duXCIsXG5cdFx0XHRcdFwiaW1nXCIsXG5cdFx0XHRcdHRoaXMuZXh0ZXJuYWxJbWFnZUNvbnRleHRNZW51Q2FsbC5iaW5kKHRoaXMpXG5cdFx0XHQpXG5cdFx0KTtcblx0XHRcblx0fVxuXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbihcblx0XHRcdHt9LFxuXHRcdFx0REVGQVVMVF9TRVRUSU5HUyxcblx0XHRcdGF3YWl0IHRoaXMubG9hZERhdGEoKVxuXHRcdCk7XG5cdH1cblxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxuXHRyZWdpc3RlckVzY2FwZUJ1dHRvbihtZW51OiBNZW51LCBkb2N1bWVudDogRG9jdW1lbnQgPSBhY3RpdmVEb2N1bWVudCkge1xuXHRcdG1lbnUucmVnaXN0ZXIoXG5cdFx0XHRvbkVsZW1lbnQoXG5cdFx0XHRcdGRvY3VtZW50LFxuXHRcdFx0XHRcImtleWRvd25cIiBhcyBrZXlvZiBIVE1MRWxlbWVudEV2ZW50TWFwLFxuXHRcdFx0XHRcIipcIixcblx0XHRcdFx0KGU6IEtleWJvYXJkRXZlbnQpID0+IHtcblx0XHRcdFx0XHRpZiAoZS5rZXkgPT09IFwiRXNjYXBlXCIpIHtcblx0XHRcdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHRtZW51LmhpZGUoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdClcblx0XHQpO1xuXHR9XG5cblx0dXBkYXRlSW1hZ2VMaW5rV2l0aE5ld1NpemUgPSAoaW1nOiBIVE1MSW1hZ2VFbGVtZW50LCB0YXJnZXRfcG9zOiBudW1iZXIsIG5ld1dpZHRoOiBudW1iZXIsIG5ld0hlaWdodDogbnVtYmVyKSA9PiB7XG5cdFx0Y29uc3QgYWN0aXZlVmlldyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk7XG5cdFx0Y29uc3QgaW5UYWJsZTogYm9vbGVhbiA9IGltZy5jbG9zZXN0KCd0YWJsZScpICE9IG51bGw7XG5cdFx0Y29uc3QgaW5DYWxsb3V0OiBib29sZWFuID0gaW1nLmNsb3Nlc3QoJy5jYWxsb3V0JykgIT0gbnVsbDtcblx0XHRjb25zdCBpc0V4Y2FsaWRyYXcgPSBpbWcuY2xhc3NMaXN0LmNvbnRhaW5zKCdleGNhbGlkcmF3LWVtYmVkZGVkLWltZycpO1xuXHRcdGlmIChhY3RpdmVWaWV3KSB7XG5cdFx0XHRwcmludChcInVwZGF0ZSBuZXcgV2lkdGhcIiwgbmV3V2lkdGgpO1xuXHRcdFx0bGV0IGltYWdlTmFtZSA9IGltZy5nZXRBdHRyaWJ1dGUoJ3NyYycpO1xuXHRcdFx0aWYgKGltYWdlTmFtZT8uc3RhcnRzV2l0aCgnaHR0cCcpKSB7XG5cdFx0XHRcdHVwZGF0ZUV4dGVybmFsTGluayhhY3RpdmVWaWV3LCBpbWcsIHRhcmdldF9wb3MsIG5ld1dpZHRoLCBuZXdIZWlnaHQsIGluVGFibGUsIGluQ2FsbG91dCk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIGlmIChpc0V4Y2FsaWRyYXcpIHtcblx0XHRcdFx0bGV0IHRhcmdldF9uYW1lID0gaW1nLmdldEF0dHJpYnV0ZSgnZmlsZXNvdXJjZScpIGFzIHN0cmluZztcblx0XHRcdFx0bGV0IGRyYXdfYmFzZV9uYW1lID0gZ2V0RXhjYWxpZHJhd0Jhc2VOYW1lKGltZyBhcyBIVE1MSW1hZ2VFbGVtZW50KTtcblx0XHRcdFx0aW1nLnN0eWxlLm1heFdpZHRoID0gJ25vbmUnO1xuXHRcdFx0XHR1cGRhdGVJbnRlcm5hbExpbmsoYWN0aXZlVmlldywgaW1nLCB0YXJnZXRfcG9zLCBkcmF3X2Jhc2VfbmFtZSwgbmV3V2lkdGgsIG5ld0hlaWdodCwgaW5UYWJsZSwgaW5DYWxsb3V0KTtcblx0XHRcdH1cblx0XHRcdGVsc2Uge1xuXHRcdFx0XHRpbWFnZU5hbWUgPSBpbWcuY2xvc2VzdCgnLmludGVybmFsLWVtYmVkJyk/LmdldEF0dHJpYnV0ZSgnc3JjJykgYXMgc3RyaW5nO1xuXHRcdFx0XHR1cGRhdGVJbnRlcm5hbExpbmsoYWN0aXZlVmlldywgaW1nLCB0YXJnZXRfcG9zLCBpbWFnZU5hbWUsIG5ld1dpZHRoLCBuZXdIZWlnaHQsIGluVGFibGUsIGluQ2FsbG91dCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0ZXh0ZXJuYWxJbWFnZUNvbnRleHRNZW51Q2FsbChldmVudDogTW91c2VFdmVudCkge1xuXHRcdGNvbnN0IGltZyA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW1hZ2VFbGVtZW50O1xuXHRcdGNvbnN0IGluVGFibGU6IGJvb2xlYW4gPSBpbWcuY2xvc2VzdCgndGFibGUnKSAhPSBudWxsO1xuXHRcdGNvbnN0IGluQ2FsbG91dDogYm9vbGVhbiA9IGltZy5jbG9zZXN0KCcuY2FsbG91dCcpICE9IG51bGw7XG5cdFx0aWYgKGltZy5pZCA9PSAnYWYtem9vbWVkLWltYWdlJykgcmV0dXJuO1xuXHRcdGlmICghaW1nLnNyYy5zdGFydHNXaXRoKCdodHRwJykpIHJldHVybjtcblx0XHRpZiAoZXZlbnQuYnV0dG9uICE9IDIpIHJldHVybjtcblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmVkaXRvcj8uYmx1cigpO1xuXHRcdGltZy5jbGFzc0xpc3QucmVtb3ZlKCdpbWFnZS1yZWFkeS1jbGljay12aWV3JywgJ2ltYWdlLXJlYWR5LXJlc2l6ZScpO1xuXHRcdGNvbnN0IG1lbnUgPSBuZXcgTWVudSgpO1xuXHRcdGNvbnN0IGluUHJldmlldyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmdldE1vZGUoKSA9PSBcInByZXZpZXdcIjtcblx0XHRpZiAoaW5QcmV2aWV3KSB7XG5cdFx0XHR0aGlzLmFkZEV4dGVybmFsSW1hZ2VNZW51UHJldmlld01vZGUobWVudSwgaW1nKTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLmFkZEV4dGVybmFsSW1hZ2VNZW51U291cmNlTW9kZShtZW51LCBpbWcsIGluVGFibGUsIGluQ2FsbG91dCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5yZWdpc3RlckVzY2FwZUJ1dHRvbihtZW51KTtcblxuXHRcdGxldCBvZmZzZXQgPSAwO1xuXHRcdGlmICghaW5QcmV2aWV3ICYmIChpblRhYmxlIHx8IGluQ2FsbG91dCkpIG9mZnNldCA9IC0xMzg7XG5cdFx0bWVudS5zaG93QXRQb3NpdGlvbih7IHg6IGV2ZW50LnBhZ2VYLCB5OiBldmVudC5wYWdlWSArIG9mZnNldCB9KTtcblxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS50cmlnZ2VyKFwiQXR0YWNoRmxvdzpjb250ZXh0bWVudVwiLCBtZW51KTtcblx0fVxuXG5cblx0LyoqXG5cdCAqIFx1OEJCRVx1N0Y2RVx1ODNEQ1x1NTM1NVx1NjMwOVx1OTRBRVx1RkYwQ1x1NUU3Nlx1OEJCRVx1N0Y2RVx1NzBCOVx1NTFGQlx1NEU4Qlx1NEVGNlxuXHQgKlxuXHQgKiBAcGFyYW0gbWVudVxuXHQgKiBAcGFyYW0gRmlsZUJhc2VOYW1lXG5cdCAqIEBwYXJhbSBjdXJyZW50TWRcblx0ICovXG5cdGFkZE1lbnVFeHRlbmRlZFNvdXJjZU1vZGUgPSAobWVudTogTWVudSwgRmlsZUJhc2VOYW1lOiBzdHJpbmcsIGN1cnJlbnRNZDogVEZpbGUsIHRhcmdldF90eXBlOiBzdHJpbmcsIHRhcmdldF9wb3M6IG51bWJlciwgaW5UYWJsZTogYm9vbGVhbiwgaW5DYWxsb3V0OiBib29sZWFuKSA9PiB7XG5cdFx0dGhpcy5hZGRNZW51RXh0ZW5kZWRQcmV2aWV3TW9kZShtZW51LCBGaWxlQmFzZU5hbWUsIGN1cnJlbnRNZCk7XG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cblx0XHRcdGl0ZW1cblx0XHRcdFx0LnNldEljb24oXCJwZW5jaWxcIilcblx0XHRcdFx0LnNldFRpdGxlKFwiUmVuYW1lXCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0cHJpbnQoXCJ0ZXN0IHJlbmFtZVwiKVxuXHRcdFx0XHRcdFx0VXRpbC5oYW5kbGVyUmVuYW1lRmlsZShGaWxlQmFzZU5hbWUsIGN1cnJlbnRNZCwgdGhpcyk7XG5cdFx0XHRcdFx0fSBjYXRjaCB7XG5cdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwiRXJyb3IsIGNvdWxkIG5vdCByZW5hbWUgdGhlIGZpbGUhXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHQpXG5cblx0XHRpZiAodGhpcy5zZXR0aW5ncy5tb3ZlRmlsZU1lbnUpe1xuXHRcdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cblx0XHRcdFx0aXRlbVxuXHRcdFx0XHRcdC5zZXRJY29uKFwiZm9sZGVyLXRyZWVcIilcblx0XHRcdFx0XHQuc2V0VGl0bGUoXCJNb3ZlIGZpbGUgdG8uLi5cIilcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRVdGlsLmhhbmRsZXJNb3ZlRmlsZShGaWxlQmFzZU5hbWUsIGN1cnJlbnRNZCwgdGhpcyk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0bmV3IE5vdGljZShcIkVycm9yLCBjb3VsZCBub3QgTW92ZSB0aGUgZmlsZSFcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cblx0XHRcdGl0ZW1cblx0XHRcdFx0LnNldEljb24oXCJ0cmFzaC0yXCIpXG5cdFx0XHRcdC5zZXRUaXRsZShcIkNsZWFyIGZpbGUgYW5kIGFzc29jaWF0ZWQgbGlua1wiKVxuXHRcdFx0XHQvLyAuc2V0U2VjdGlvbihcImF0dGFjaC1mbG93XCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0Ly8gVXRpbC5oYW5kbGVyRGVsRmlsZShGaWxlQmFzZU5hbWUsIGN1cnJlbnRNZCwgdGhpcyk7XG5cdFx0XHRcdFx0XHRVdGlsLmhhbmRsZXJEZWxGaWxlTmV3KEZpbGVCYXNlTmFtZSwgY3VycmVudE1kLCB0aGlzLCB0YXJnZXRfdHlwZSwgdGFyZ2V0X3BvcywgaW5UYWJsZSwgaW5DYWxsb3V0KTtcblx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJFcnJvciwgY291bGQgbm90IGNsZWFyIHRoZSBmaWxlIVwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0KTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBcdThCQkVcdTdGNkVcdTgzRENcdTUzNTVcdTYzMDlcdTk0QUVcdUZGMENcdTVFNzZcdThCQkVcdTdGNkVcdTcwQjlcdTUxRkJcdTRFOEJcdTRFRjZcblx0ICpcblx0ICogQHBhcmFtIG1lbnVcblx0ICogQHBhcmFtIEZpbGVCYXNlTmFtZVxuXHQgKiBAcGFyYW0gY3VycmVudE1kXG5cdCAqL1xuXHRhZGRNZW51RXh0ZW5kZWRQcmV2aWV3TW9kZSA9IChtZW51OiBNZW51LCBGaWxlQmFzZU5hbWU6IHN0cmluZywgY3VycmVudE1kOiBURmlsZSkgPT4ge1xuXHRcdGNvbnN0IGZpbGUgPSBVdGlsLmdldEZpbGVCeUJhc2VOYW1lKGN1cnJlbnRNZCwgRmlsZUJhc2VOYW1lKSBhcyBURmlsZTtcblx0XHQvLyBjb25zdCBiYXNlUGF0aCA9IChmaWxlLnZhdWx0LmFkYXB0ZXIgYXMgYW55KS5iYXNlUGF0aDtcblx0XHQvLyBjb25zdCByZWxhdGl2ZUZpbGVQYXRoID0gZmlsZS5wYXRoO1xuXHRcdGlmIChwcm9jZXNzLnBsYXRmb3JtICE9ICdsaW51eCcpIHtcblx0XHRcdG1lbnUuYWRkSXRlbSgoaXRlbTogTWVudUl0ZW0pID0+XG5cdFx0XHRcdGl0ZW1cblx0XHRcdFx0XHQuc2V0SWNvbihcImNvcHlcIilcblx0XHRcdFx0XHQuc2V0VGl0bGUoXCJDb3B5IGZpbGUgdG8gY2xpcGJvYXJkXCIpXG5cdFx0XHRcdFx0Ly8gLnNldENoZWNrZWQodHJ1ZSlcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRVdGlsLmhhbmRsZXJDb3B5RmlsZShGaWxlQmFzZU5hbWUsIGN1cnJlbnRNZCwgdGhpcyk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoIHtcblx0XHRcdFx0XHRcdFx0bmV3IE5vdGljZShcIkVycm9yLCBjb3VsZCBub3QgY29weSB0aGUgZmlsZSFcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT4gaXRlbVxuXHRcdFx0LnNldEljb24oXCJhcnJvdy11cC1yaWdodFwiKVxuXHRcdFx0LnNldFRpdGxlKFwiT3BlbiBpbiBkZWZhdWx0IGFwcFwiKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4gKHRoaXMuYXBwIGFzIEFwcFdpdGhEZXNrdG9wSW50ZXJuYWxBcGkpLm9wZW5XaXRoRGVmYXVsdEFwcChmaWxlLnBhdGgpKVxuXHRcdCk7XG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT4gaXRlbVxuXHRcdFx0LnNldEljb24oXCJhcnJvdy11cC1yaWdodFwiKVxuXHRcdFx0LnNldFRpdGxlKFBsYXRmb3JtLmlzTWFjT1MgPyBcIlJldmVhbCBpbiBmaW5kZXJcIiA6IFwiU2hvdyBpbiBzeXN0ZW0gZXhwbG9yZXJcIilcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0KHRoaXMuYXBwIGFzIEFwcFdpdGhEZXNrdG9wSW50ZXJuYWxBcGkpLnNob3dJbkZvbGRlcihmaWxlLnBhdGgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXHRcdG1lbnUuYWRkSXRlbSgoaXRlbTogTWVudUl0ZW0pID0+IGl0ZW1cblx0XHRcdC5zZXRJY29uKFwiZm9sZGVyXCIpXG5cdFx0XHQuc2V0VGl0bGUoXCJSZXZlYWwgZmlsZSBpbiBuYXZpZ2F0aW9uXCIpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdGNvbnN0IGFic3RyYWN0RmlsZVBhdGggPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZS5wYXRoKTtcblx0XHRcdFx0KHRoaXMuYXBwIGFzIGFueSkuaW50ZXJuYWxQbHVnaW5zLmdldEVuYWJsZWRQbHVnaW5CeUlkKFwiZmlsZS1leHBsb3JlclwiKS5yZXZlYWxJbkZvbGRlcihhYnN0cmFjdEZpbGVQYXRoKTtcblx0XHRcdH0pXG5cdFx0KTtcblx0fTtcblxuXG5cdGFkZEV4dGVybmFsSW1hZ2VNZW51UHJldmlld01vZGUgPSAobWVudTogTWVudSwgaW1nOiBIVE1MSW1hZ2VFbGVtZW50KSA9PiB7XG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cblx0XHRcdGl0ZW1cblx0XHRcdFx0LnNldEljb24oXCJjb3B5XCIpXG5cdFx0XHRcdC5zZXRUaXRsZShcIkNvcHkgaW1hZ2UgdG8gY2xpcGJvYXJkXCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0Y29uc3QgYmxvYiA9IGF3YWl0IGxvYWRJbWFnZUJsb2IoaW1nLnNyYyk7XG5cdFx0XHRcdFx0XHRhd2FpdCBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlKFtuZXcgQ2xpcGJvYXJkSXRlbSh7IFwiaW1hZ2UvcG5nXCI6IGJsb2IgfSldKTtcblx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoJ0ltYWdlIGNvcGllZCB0byBjbGlwYm9hcmQnKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGYWlsZWQgdG8gY29weSBpbWFnZSEnKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdG1lbnUuYWRkSXRlbSgoaXRlbTogTWVudUl0ZW0pID0+XG5cdFx0XHRpdGVtXG5cdFx0XHRcdC5zZXRJY29uKFwibGlua1wiKVxuXHRcdFx0XHQuc2V0VGl0bGUoXCJDb3B5IGltYWdlIGxpbmtcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KGltZy5zcmMpO1xuXHRcdFx0XHR9KVxuXHRcdCk7XG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cblx0XHRcdGl0ZW1cblx0XHRcdFx0LnNldEljb24oXCJsaW5rXCIpXG5cdFx0XHRcdC5zZXRUaXRsZShcIkNvcHkgbWFya2Rvd24gbGlua1wiKVxuXHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0bmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQoYCFbXSgke2ltZy5zcmN9KWApO1xuXHRcdFx0XHR9KVxuXHRcdCk7XG5cdFx0bWVudS5hZGRJdGVtKChpdGVtOiBNZW51SXRlbSkgPT5cblx0XHRcdGl0ZW1cblx0XHRcdFx0LnNldEljb24oXCJleHRlcm5hbC1saW5rXCIpXG5cdFx0XHRcdC5zZXRUaXRsZShcIk9wZW4gaW4gZXh0ZXJuYWwgYnJvd3NlclwiKVxuXHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0d2luZG93Lm9wZW4oaW1nLnNyYywgJ19ibGFuaycpO1xuXHRcdFx0XHR9KVxuXHRcdCk7XG5cdH1cblxuXHRhZGRFeHRlcm5hbEltYWdlTWVudVNvdXJjZU1vZGUgPSAobWVudTogTWVudSwgaW1nOiBIVE1MSW1hZ2VFbGVtZW50LCBpblRhYmxlOiBib29sZWFuLCBpbkNhbGxvdXQ6IGJvb2xlYW4pID0+IHtcblx0XHR0aGlzLmFkZEV4dGVybmFsSW1hZ2VNZW51UHJldmlld01vZGUobWVudSwgaW1nKTtcblx0XHRtZW51LmFkZEl0ZW0oKGl0ZW06IE1lbnVJdGVtKSA9PlxuXHRcdFx0aXRlbVxuXHRcdFx0XHQuc2V0SWNvbihcInRyYXNoLTJcIilcblx0XHRcdFx0LnNldFRpdGxlKFwiQ2xlYXIgaW1hZ2UgbGlua1wiKVxuXHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xuXHRcdFx0XHRcdC8vICBAdHMtZXhwZWN0LWVycm9yLCBub3QgdHlwZWRcblx0XHRcdFx0XHRjb25zdCBlZGl0b3JWaWV3ID0gZWRpdG9yLmNtIGFzIEVkaXRvclZpZXc7XG5cdFx0XHRcdFx0Y29uc3QgdGFyZ2V0X3BvcyA9IGVkaXRvclZpZXcucG9zQXRET00oaW1nKTtcblx0XHRcdFx0XHRkZWxldGVDdXJUYXJnZXRMaW5rKGltZy5zcmMsIHRoaXMsICdpbWcnLCB0YXJnZXRfcG9zLCBpblRhYmxlLCBpbkNhbGxvdXQpO1xuXHRcdFx0XHR9KVxuXHRcdCk7XG5cdH1cblxuXHQvKipcblx0ICogXHU5RjIwXHU2ODA3XHU1M0YzXHU5NTJFXHU4M0RDXHU1MzU1XHU0RThCXHU0RUY2XG5cdCAqL1xuXHRvblJpZ2h0Q2xpY2tNZW51KGV2ZW50OiBNb3VzZUV2ZW50KSB7XG5cdFx0Y29uc3QgdGFyZ2V0ID0gZ2V0TW91c2VFdmVudFRhcmdldChldmVudCk7XG5cdFx0Y29uc3QgY3VyVGFyZ2V0VHlwZSA9IHRhcmdldC5sb2NhbE5hbWU7XG5cdFx0aWYgKHRhcmdldC5pZCA9PSAnYWYtem9vbWVkLWltYWdlJykgcmV0dXJuO1xuXG5cdFx0Y29uc3QgY3VycmVudE1kID0gYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCkgYXMgVEZpbGU7XG5cdFx0Y29uc3QgaW5DYW52YXMgPSBjdXJyZW50TWQubmFtZS5lbmRzV2l0aCgnLmNhbnZhcycpO1xuXHRcdGNvbnN0IFN1cHBvcnRlZFRhcmdldFR5cGUgPSBbXCJpbWdcIiwgXCJpZnJhbWVcIiwgXCJ2aWRlb1wiLCBcImRpdlwiLCBcImF1ZGlvXCJdO1xuXG5cdFx0Y29uc3QgbWVudSA9IG5ldyBNZW51KCk7XG5cblx0XHRpZiAoIVN1cHBvcnRlZFRhcmdldFR5cGUuaW5jbHVkZXMoY3VyVGFyZ2V0VHlwZSkpIHJldHVybjtcblxuXHRcdC8vIFx1NTIyNFx1NjVBRFx1NUY1M1x1NTI0RFx1NzBCOVx1NTFGQlx1NzY4NFx1NTczMFx1NjVCOVx1NjYyRlx1NTQyNlx1NEUzQVx1ODg2OFx1NjgzQ1xuXHRcdC8vIGNvbnN0IGluVGFibGU6Ym9vbGVhbiA9IHRhcmdldC5wYXJlbnRFbGVtZW50Py5wYXJlbnRFbGVtZW50Py5nZXRBdHRyaWJ1dGUoJ2NsYXNzJyk9PSd0YWJsZS1jZWxsLXdyYXBwZXInO1xuXHRcdGNvbnN0IGluVGFibGU6IGJvb2xlYW4gPSB0YXJnZXQuY2xvc2VzdCgndGFibGUnKSAhPSBudWxsO1xuXHRcdGNvbnN0IGluQ2FsbG91dDogYm9vbGVhbiA9IHRhcmdldC5jbG9zZXN0KCcuY2FsbG91dCcpICE9IG51bGw7XG5cdFx0Y29uc3QgaW5QcmV2aWV3OiBib29sZWFuID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZ2V0TW9kZSgpID09IFwicHJldmlld1wiO1xuXHRcdGNvbnN0IGlzRXhjYWxpZHJhdzogYm9vbGVhbiA9IHRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoJ2V4Y2FsaWRyYXctZW1iZWRkZWQtaW1nJyk7XG5cblx0XHRsZXQgdGFyZ2V0X25hbWUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKFwic3JjXCIpIGFzIHN0cmluZztcblx0XHQvLyBcdTVCRjlcdTRFOEUgQ2FsbG91dCBcdTU0OEMgVGFibGUgXHU0RTJEXHU3Njg0XHU3RjUxXHU3RURDXHU1NkZFXHU3MjQ3XHVGRjBDXHU2Q0ExXHU2NzA5XHU1M0YzXHU5NTJFXHU4M0RDXHU1MzU1XG5cdFx0aWYgKHRhcmdldF9uYW1lICYmIHRhcmdldF9uYW1lLnN0YXJ0c1dpdGgoJ2h0dHAnKSkgcmV0dXJuO1xuXG5cdFx0aWYgKGluQ2FudmFzKSB7XG5cdFx0XHQvLyBcdTU5ODJcdTY3OUNcdTY2MkZcdTU2RkVcdTUwQ0ZcdTgyODJcdTcwQjlcdUZGMENcdThGRDRcdTU2REVcblx0XHRcdGlmICh0YXJnZXQucGFyZW50RWxlbWVudD8uY2xhc3NMaXN0LmNvbnRhaW5zKCdjYW52YXMtbm9kZS1jb250ZW50JykpIHJldHVybjtcblx0XHRcdGxldCBmaWxlX25hbWUgPSB0YXJnZXQucGFyZW50RWxlbWVudD8uZ2V0QXR0cmlidXRlKCdzcmMnKTtcblx0XHRcdC8vIHByaW50KFwiVGFyZ2V0IE5hbWU6XCIsIGZpbGVfbmFtZSk7XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0YXJnZXQuY2xhc3NMaXN0LnJlbW92ZSgnaW1hZ2UtcmVhZHktY2xpY2stdmlldycsICdpbWFnZS1yZWFkeS1yZXNpemUnKTtcblxuXHRcdGlmIChpc0V4Y2FsaWRyYXcpIHtcblx0XHRcdHRhcmdldF9uYW1lID0gZ2V0RXhjYWxpZHJhd0Jhc2VOYW1lKHRhcmdldCBhcyBIVE1MSW1hZ2VFbGVtZW50KTtcblx0XHRcdHRhcmdldF9uYW1lID0gdGFyZ2V0X25hbWUucmVwbGFjZSgvXihcXC5cXC5cXC8pKy9nLCAnJyk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0dGFyZ2V0X25hbWUgPSB0YXJnZXQuY2xvc2VzdCgnLmludGVybmFsLWVtYmVkJyk/LmdldEF0dHJpYnV0ZShcInNyY1wiKSBhcyBzdHJpbmc7XG5cdFx0XHQvLyBcdTUyMjBcdTk2NjQgdGFyZ2V0X25hbWUgXHU1M0VGXHU4MEZEXHU1MjREXHU3RjAwXHU3Njg0XHU1OTFBXHU0RTJBICcuLi8nXHVGRjBDXHU2NTJGXHU2MzAxXHU5NEZFXHU2M0E1XHU4REVGXHU1Rjg0XHU0RTNBXHU1RjUzXHU1MjREXHU3QjE0XHU4QkIwXHU3Njg0XHU3NkY4XHU1QkY5XHU4REVGXHU1Rjg0XG5cdFx0XHR0YXJnZXRfbmFtZSA9IHRhcmdldF9uYW1lLnJlcGxhY2UoL14oXFwuXFwuXFwvKSsvZywgJycpO1xuXHRcdFx0bGV0IHBkZl9tYXRjaCA9IHRhcmdldF9uYW1lLm1hdGNoKC8uKlxcLnBkZi8pO1xuXHRcdFx0dGFyZ2V0X25hbWUgPSBwZGZfbWF0Y2ggPyBwZGZfbWF0Y2hbMF0gOiB0YXJnZXRfbmFtZTtcblx0XHRcdGlmIChjdXJUYXJnZXRUeXBlID09ICdpbWcnICYmIHBkZl9tYXRjaCkgcmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChpblByZXZpZXcpIHtcblx0XHRcdGlmIChTdXBwb3J0ZWRUYXJnZXRUeXBlLmluY2x1ZGVzKGN1clRhcmdldFR5cGUpKSB7XG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKFwiRmlsZUJhc2VOYW1lXCIsIEZpbGVCYXNlTmFtZSk7XG5cdFx0XHRcdHRoaXMuYWRkTWVudUV4dGVuZGVkUHJldmlld01vZGUobWVudSwgdGFyZ2V0X25hbWUsIGN1cnJlbnRNZCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0Y29uc3QgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xuXHRcdFx0Ly8gIEB0cy1leHBlY3QtZXJyb3IsIG5vdCB0eXBlZFxuXHRcdFx0Y29uc3QgZWRpdG9yVmlldyA9IGVkaXRvci5jbSBhcyBFZGl0b3JWaWV3O1xuXHRcdFx0Y29uc3QgdGFyZ2V0X3BvcyA9IGVkaXRvclZpZXcucG9zQXRET00odGFyZ2V0KTtcblx0XHRcdC8vIGNvbnNvbGUubG9nKCd0YXJnZXQnLCB0YXJnZXQpXG5cdFx0XHQvLyBjb25zb2xlLmxvZygndGFyZ2V0LnBhcmVudEVsZW1lbnQnLCB0YXJnZXQucGFyZW50RWxlbWVudClcblx0XHRcdC8vIGNvbnN0IHByZXZfcG9zID0gZWRpdG9yVmlldy5wb3NBdERPTSh0YXJnZXQucGFyZW50RWxlbWVudD8ucHJldmlvdXNFbGVtZW50U2libGluZyBhcyBIVE1MRWxlbWVudCk7XG5cdFx0XHQvLyBjb25zdCBuZXh0X3BvcyA9IGVkaXRvclZpZXcucG9zQXRET00odGFyZ2V0LnBhcmVudEVsZW1lbnQ/Lm5leHRFbGVtZW50U2libGluZyBhcyBIVE1MRWxlbWVudCk7XG5cdFx0XHQvLyBsZXQgcHJldl90YXJnZXRfbGluZSA9IGVkaXRvclZpZXcuc3RhdGUuZG9jLmxpbmVBdChwcmV2X3Bvcyk7XG5cdFx0XHQvLyBsZXQgbmV4dF90YXJnZXRfbGluZSA9IGVkaXRvclZpZXcuc3RhdGUuZG9jLmxpbmVBdChuZXh0X3Bvcyk7XG5cdFx0XHQvLyBjb25zb2xlLmxvZygncHJldiB0YXJnZXQgbGluZSBpbmZvcm1hdGlvbjogbGluZS1jb250ZW50LCBsaW5lLW51bWJlcigxLWJhc2VkKSwgdGFyZ2V0LmNoJyk7XG5cdFx0XHQvLyBjb25zb2xlLmxvZyhwcmV2X3RhcmdldF9saW5lLnRleHQsIHByZXZfdGFyZ2V0X2xpbmUubnVtYmVyLCBwcmV2X3Bvcy1wcmV2X3RhcmdldF9saW5lLmZyb20pXG5cblx0XHRcdGxldCB0YXJnZXRfbGluZSA9IGVkaXRvclZpZXcuc3RhdGUuZG9jLmxpbmVBdCh0YXJnZXRfcG9zKTtcblx0XHRcdHByaW50KCd0YXJnZXQgbGluZSBpbmZvcm1hdGlvbjogbGluZS1jb250ZW50LCBsaW5lLW51bWJlcigxLWJhc2VkKSwgdGFyZ2V0LmNoJyk7XG5cdFx0XHRwcmludCh0YXJnZXRfbGluZS50ZXh0LCB0YXJnZXRfbGluZS5udW1iZXIsIHRhcmdldF9wb3MgLSB0YXJnZXRfbGluZS5mcm9tKTtcblxuXHRcdFx0Ly8gLS0tLS0tLS0tLSBFZGl0b3JJbnRlcm5hbEFwaS5wb3NBdE1vdXNlIFx1NEUwRFx1NjYyRlx1NUY4OFx1NTFDNlx1Nzg2RVx1RkYwQ1x1NEUwRFx1NzdFNVx1OTA1M1x1NEUzQVx1NEVDMFx1NEU0OFx1RkYwQ1x1ODg0Q1x1NTNGN1x1NTQ4Q2NoXHU5MEZEXHU0RTBEXHU1MUM2XHU3ODZFIC0tLS0tLS0tLS1cblx0XHRcdC8vIGNvbnN0IGVkaXRvcjIgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3IgYXMgRWRpdG9ySW50ZXJuYWxBcGk7XG5cdFx0XHQvLyBjb25zdCBwb3NpdGlvbiA9IGVkaXRvcjIucG9zQXRNb3VzZShldmVudCk7XG5cdFx0XHQvLyBjb25zb2xlLmxvZygnSW50ZXJBUElQb3MgbGluZSBpbmZvcm1hdGlvbjogbGluZS1jb250ZW50LCBsaW5lLW51bWJlcigxLWJhc2VkKSwgdGFyZ2V0LmNoJylcblx0XHRcdC8vIGNvbnNvbGUubG9nKGVkaXRvcj8uZ2V0TGluZShwb3NpdGlvbi5saW5lKSwgcG9zaXRpb24ubGluZSsxLCBwb3NpdGlvbi5jaClcblx0XHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdFx0XHQvLyBjb25zb2xlLmxvZygnbmV4dCB0YXJnZXQgbGluZSBpbmZvcm1hdGlvbjogbGluZS1jb250ZW50LCBsaW5lLW51bWJlcigxLWJhc2VkKSwgdGFyZ2V0LmNoJyk7XG5cdFx0XHQvLyBjb25zb2xlLmxvZyhuZXh0X3RhcmdldF9saW5lLnRleHQsIG5leHRfdGFyZ2V0X2xpbmUubnVtYmVyLCBuZXh0X3Bvcy1uZXh0X3RhcmdldF9saW5lLmZyb20pXG5cblx0XHRcdGlmIChTdXBwb3J0ZWRUYXJnZXRUeXBlLmluY2x1ZGVzKGN1clRhcmdldFR5cGUpKSB7XG5cdFx0XHRcdHRoaXMuYWRkTWVudUV4dGVuZGVkU291cmNlTW9kZShtZW51LCB0YXJnZXRfbmFtZSwgY3VycmVudE1kLCBjdXJUYXJnZXRUeXBlLCB0YXJnZXRfcG9zLCBpblRhYmxlLCBpbkNhbGxvdXQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMucmVnaXN0ZXJFc2NhcGVCdXR0b24obWVudSk7XG5cblx0XHRsZXQgb2Zmc2V0ID0gLTE2Mztcblx0XHRsZXQgbGludXhfb2Zmc2V0ID0gLTEzODtcblx0XHRvZmZzZXQgPSBwcm9jZXNzLnBsYXRmb3JtID09ICdsaW51eCcgPyBsaW51eF9vZmZzZXQgOiBvZmZzZXQ7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MubW92ZUZpbGVNZW51KSBvZmZzZXQgLT0gMjU7XG5cblx0XHRpZiAoaW5UYWJsZSAmJiAhaW5QcmV2aWV3KSB7XG5cdFx0XHRtZW51LnNob3dBdFBvc2l0aW9uKHsgeDogZXZlbnQucGFnZVgsIHk6IGV2ZW50LnBhZ2VZICsgb2Zmc2V0IH0pO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdG1lbnUuc2hvd0F0UG9zaXRpb24oeyB4OiBldmVudC5wYWdlWCwgeTogZXZlbnQucGFnZVkgfSk7XG5cdFx0fVxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS50cmlnZ2VyKFwiQXR0YWNoRmxvdzpjb250ZXh0bWVudVwiLCBtZW51KTtcblx0fVxuXG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUludGVybmFsTGluayhhY3RpdmVWaWV3OiBNYXJrZG93blZpZXcsIHRhcmdldDogSFRNTEltYWdlRWxlbWVudCB8IEhUTUxWaWRlb0VsZW1lbnQsIHRhcmdldF9wb3M6IG51bWJlciwgaW1hZ2VOYW1lOiBzdHJpbmcsIG5ld1dpZHRoOiBudW1iZXIsIG5ld0hlaWdodDogbnVtYmVyLCBpblRhYmxlOiBib29sZWFuLCBpbkNhbGxvdXQ6IGJvb2xlYW4pOiB2b2lkIHtcblx0Y29uc3QgZWRpdG9yID0gYWN0aXZlVmlldy5lZGl0b3I7XG5cdC8vICBAdHMtZXhwZWN0LWVycm9yLCBub3QgdHlwZWRcblx0Y29uc3QgZWRpdG9yVmlldyA9IGVkaXRvci5jbSBhcyBFZGl0b3JWaWV3O1xuXHRsZXQgdGFyZ2V0X2xpbmUgPSBlZGl0b3JWaWV3LnN0YXRlLmRvYy5saW5lQXQodGFyZ2V0X3Bvcyk7XG5cdC8vIHByaW50KCd0YXJnZXQgbGluZSBpbmZvcm1hdGlvbjogbGluZS1jb250ZW50LCBsaW5lLW51bWJlcigxLWJhc2VkKSwgdGFyZ2V0LmNoJyk7XG5cdC8vIHByaW50KHRhcmdldF9saW5lLnRleHQsIHRhcmdldF9saW5lLm51bWJlciwgdGFyZ2V0X3BvcyAtIHRhcmdldF9saW5lLmZyb20pO1xuXG5cblx0aWYgKCFpbkNhbGxvdXQgJiYgIWluVGFibGUpIHtcblx0XHRsZXQgbWF0Y2hlZCA9IG1hdGNoTGluZVdpdGhJbnRlcm5hbExpbmsodGFyZ2V0X2xpbmUudGV4dCwgaW1hZ2VOYW1lLCBuZXdXaWR0aCwgaW5UYWJsZSk7XG5cdFx0aWYgKG1hdGNoZWQubGVuZ3RoID09IDEpIHtcblx0XHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogdGFyZ2V0X2xpbmUuZnJvbSArIG1hdGNoZWRbMF0uZnJvbV9jaCxcblx0XHRcdFx0XHR0bzogdGFyZ2V0X2xpbmUuZnJvbSArIG1hdGNoZWRbMF0udG9fY2gsXG5cdFx0XHRcdFx0aW5zZXJ0OiBtYXRjaGVkWzBdLm5ld19saW5rXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0Ly8gZWRpdG9yLnJlcGxhY2VSYW5nZShtYXRjaGVkWzBdLm5ld19saW5rLCBcblx0XHRcdC8vIFx0e2xpbmU6dGFyZ2V0X2xpbmUubnVtYmVyLTEsIGNoOm1hdGNoZWRbMF0uZnJvbV9jaH0sIFxuXHRcdFx0Ly8gXHR7bGluZTp0YXJnZXRfbGluZS5udW1iZXItMSwgY2g6bWF0Y2hlZFswXS50b19jaH1cblx0XHRcdC8vIFx0KTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAobWF0Y2hlZC5sZW5ndGggPT0gMCkge1xuXHRcdFx0Ly8gbmV3IE5vdGljZSgnRmFpbCB0byBmaW5kIGN1cnJlbnQgaW1hZ2UtbGluaywgcGxlYXNlIHpvb20gbWFudWFsbHkhJylcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRuZXcgTm90aWNlKCdGaW5kIG11bHRpcGxlIHNhbWUgaW1hZ2UtbGluayBpbiBsaW5lLCBwbGVhc2Ugem9vbSBtYW51YWxseSEnKVxuXHRcdH1cblx0XHRyZXR1cm47XG5cdH1cblxuXHR0eXBlIFJlZ0RpY3Rpb25hcnkgPSB7XG5cdFx0W2tleTogc3RyaW5nXTogUmVnRXhwO1xuXHR9O1xuXG5cdGxldCBzdGFydFJlZzogUmVnRGljdGlvbmFyeSA9IHtcblx0XHQndGFibGUnOiAvXlxccypcXHwvLFxuXHRcdCdjYWxsb3V0JzogL14+Lyxcblx0fTtcblxuXHRsZXQgbW9kZSA9IGluVGFibGUgPyAndGFibGUnIDogJ2NhbGxvdXQnO1xuXHRwcmludCgnbW9kZScsIG1vZGUpXG5cblx0Y29uc3Qgc3RhcnRfcmVnID0gc3RhcnRSZWdbbW9kZV07XG5cdGxldCBzdGFydF9saW5lX251bWJlciA9IHRhcmdldF9saW5lLm51bWJlcjtcblx0bGV0IG1hdGNoZWRfcmVzdWx0czogTWF0Y2hlZExpbmtJbkxpbmVbXSA9IFtdO1xuXHRsZXQgbWF0Y2hlZF9saW5lczogbnVtYmVyW10gPSBbXTsgIC8vMS1iYXNlZFxuXHRmb3IgKGxldCBpID0gc3RhcnRfbGluZV9udW1iZXI7IGkgPD0gZWRpdG9yLmxpbmVDb3VudCgpOyBpKyspIHtcblx0XHRsZXQgbGluZSA9IGVkaXRvclZpZXcuc3RhdGUuZG9jLmxpbmUoaSk7XG5cdFx0aWYgKCFzdGFydF9yZWcudGVzdChsaW5lLnRleHQpKSBicmVhaztcblx0XHRsZXQgbWF0Y2hlZCA9IG1hdGNoTGluZVdpdGhJbnRlcm5hbExpbmsobGluZS50ZXh0LCBpbWFnZU5hbWUsIG5ld1dpZHRoLCBpblRhYmxlKTtcblx0XHRtYXRjaGVkX3Jlc3VsdHMucHVzaCguLi5tYXRjaGVkKTtcblx0XHRtYXRjaGVkX2xpbmVzLnB1c2goLi4ubmV3IEFycmF5KG1hdGNoZWQubGVuZ3RoKS5maWxsKGkpKTtcblx0fVxuXG5cdGZvciAobGV0IGkgPSBzdGFydF9saW5lX251bWJlciAtIDE7IGkgPj0gMTsgaS0tKSB7XG5cdFx0bGV0IGxpbmUgPSBlZGl0b3JWaWV3LnN0YXRlLmRvYy5saW5lKGkpO1xuXHRcdGlmICghc3RhcnRfcmVnLnRlc3QobGluZS50ZXh0KSkgYnJlYWs7XG5cdFx0bGV0IG1hdGNoZWQgPSBtYXRjaExpbmVXaXRoSW50ZXJuYWxMaW5rKGxpbmUudGV4dCwgaW1hZ2VOYW1lLCBuZXdXaWR0aCwgaW5UYWJsZSk7XG5cdFx0bWF0Y2hlZF9yZXN1bHRzLnB1c2goLi4ubWF0Y2hlZCk7XG5cdFx0bWF0Y2hlZF9saW5lcy5wdXNoKC4uLm5ldyBBcnJheShtYXRjaGVkLmxlbmd0aCkuZmlsbChpKSk7XG5cdH1cblxuXHQvLyBwcmludChcIk1hdGNoZWQgSW5mb3JtYXRpb25cIilcblx0Ly8gcHJpbnQobWF0Y2hlZF9yZXN1bHRzKVxuXHQvLyBwcmludChtYXRjaGVkX2xpbmVzKVxuXG5cdGlmIChtYXRjaGVkX3Jlc3VsdHMubGVuZ3RoID09IDEpIHtcblx0XHRsZXQgdGFyZ2V0X2xpbmUgPSBlZGl0b3JWaWV3LnN0YXRlLmRvYy5saW5lKG1hdGNoZWRfbGluZXNbMF0pO1xuXHRcdGlmIChtb2RlID09ICd0YWJsZScpIHtcblx0XHRcdGxldCBvbGRfdGV4dCA9IHRhcmdldF9saW5lLnRleHQ7XG5cdFx0XHRsZXQgbmV3X2xpbmVfdGV4dCA9IG9sZF90ZXh0LnN1YnN0cmluZygwLCBtYXRjaGVkX3Jlc3VsdHNbMF0uZnJvbV9jaCkgK1xuXHRcdFx0XHRtYXRjaGVkX3Jlc3VsdHNbMF0ubmV3X2xpbmsgK1xuXHRcdFx0XHRvbGRfdGV4dC5zdWJzdHJpbmcobWF0Y2hlZF9yZXN1bHRzWzBdLnRvX2NoKTtcblx0XHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogdGFyZ2V0X2xpbmUuZnJvbSxcblx0XHRcdFx0XHR0bzogdGFyZ2V0X2xpbmUuZnJvbSArIG9sZF90ZXh0Lmxlbmd0aCxcblx0XHRcdFx0XHRpbnNlcnQ6IG5ld19saW5lX3RleHRcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogdGFyZ2V0X2xpbmUuZnJvbSArIG1hdGNoZWRfcmVzdWx0c1swXS5mcm9tX2NoLFxuXHRcdFx0XHRcdHRvOiB0YXJnZXRfbGluZS5mcm9tICsgbWF0Y2hlZF9yZXN1bHRzWzBdLnRvX2NoLFxuXHRcdFx0XHRcdGluc2VydDogbWF0Y2hlZF9yZXN1bHRzWzBdLm5ld19saW5rXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHRlbHNlIGlmIChtYXRjaGVkX3Jlc3VsdHMubGVuZ3RoID09IDApIHtcblx0XHRuZXcgTm90aWNlKGBGYWlsIHRvIGZpbmQgY3VycmVudCBpbWFnZS1saW5rIGluICR7bW9kZX0sIHBsZWFzZSB6b29tIG1hbnVhbGx5IWApXG5cdH1cblx0ZWxzZSB7XG5cdFx0bmV3IE5vdGljZShgRmluZCBtdWx0aXBsZSBzYW1lIGltYWdlLWxpbmsgaW4gJHttb2RlfSwgcGxlYXNlIHpvb20gbWFudWFsbHkhYClcblx0fVxuXHRyZXR1cm47XG59XG5cblxuZnVuY3Rpb24gdXBkYXRlRXh0ZXJuYWxMaW5rKGFjdGl2ZVZpZXc6IE1hcmtkb3duVmlldywgdGFyZ2V0OiBIVE1MSW1hZ2VFbGVtZW50IHwgSFRNTFZpZGVvRWxlbWVudCwgdGFyZ2V0X3BvczogbnVtYmVyLCBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciwgaW5UYWJsZTogYm9vbGVhbiwgaW5DYWxsb3V0OiBib29sZWFuKTogdm9pZCB7XG5cdGNvbnN0IGVkaXRvciA9IGFjdGl2ZVZpZXcuZWRpdG9yO1xuXHQvLyAgQHRzLWV4cGVjdC1lcnJvciwgbm90IHR5cGVkXG5cdGNvbnN0IGVkaXRvclZpZXcgPSBlZGl0b3IuY20gYXMgRWRpdG9yVmlldztcblx0bGV0IHRhcmdldF9saW5lID0gZWRpdG9yVmlldy5zdGF0ZS5kb2MubGluZUF0KHRhcmdldF9wb3MpO1xuXG5cdGNvbnN0IGxpbmsgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKCdzcmMnKSBhcyBzdHJpbmc7XG5cdGNvbnN0IGFsdFRleHQgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKFwiYWx0XCIpIGFzIHN0cmluZztcblxuXHRpZiAoIWluQ2FsbG91dCAmJiAhaW5UYWJsZSkge1xuXHRcdGxldCBtYXRjaGVkID0gbWF0Y2hMaW5lV2l0aEV4dGVybmFsTGluayh0YXJnZXRfbGluZS50ZXh0LCBsaW5rLCBhbHRUZXh0LCBuZXdXaWR0aCwgaW5UYWJsZSk7XG5cdFx0aWYgKG1hdGNoZWQubGVuZ3RoID09IDEpIHtcblx0XHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogdGFyZ2V0X2xpbmUuZnJvbSArIG1hdGNoZWRbMF0uZnJvbV9jaCxcblx0XHRcdFx0XHR0bzogdGFyZ2V0X2xpbmUuZnJvbSArIG1hdGNoZWRbMF0udG9fY2gsXG5cdFx0XHRcdFx0aW5zZXJ0OiBtYXRjaGVkWzBdLm5ld19saW5rXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRlbHNlIGlmIChtYXRjaGVkLmxlbmd0aCA9PSAwKSB7XG5cdFx0XHQvLyBuZXcgTm90aWNlKCdGYWlsIHRvIGZpbmQgY3VycmVudCBpbWFnZS1saW5rLCBwbGVhc2Ugem9vbSBtYW51YWxseSEnKVxuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdG5ldyBOb3RpY2UoJ0ZpbmQgbXVsdGlwbGUgc2FtZSBpbWFnZS1saW5rIGluIGxpbmUsIHBsZWFzZSB6b29tIG1hbnVhbGx5IScpXG5cdFx0fVxuXHRcdHJldHVybjtcblx0fVxuXG5cdHR5cGUgUmVnRGljdGlvbmFyeSA9IHtcblx0XHRba2V5OiBzdHJpbmddOiBSZWdFeHA7XG5cdH07XG5cblx0bGV0IHN0YXJ0UmVnOiBSZWdEaWN0aW9uYXJ5ID0ge1xuXHRcdCd0YWJsZSc6IC9eXFxzKlxcfC8sXG5cdFx0J2NhbGxvdXQnOiAvXj4vLFxuXHR9O1xuXG5cdGxldCBtb2RlID0gaW5UYWJsZSA/ICd0YWJsZScgOiAnY2FsbG91dCc7XG5cdHByaW50KCdtb2RlJywgbW9kZSlcblxuXHRjb25zdCBzdGFydF9yZWcgPSBzdGFydFJlZ1ttb2RlXTtcblx0bGV0IHN0YXJ0X2xpbmVfbnVtYmVyID0gdGFyZ2V0X2xpbmUubnVtYmVyO1xuXHRsZXQgbWF0Y2hlZF9yZXN1bHRzOiBNYXRjaGVkTGlua0luTGluZVtdID0gW107XG5cdGxldCBtYXRjaGVkX2xpbmVzOiBudW1iZXJbXSA9IFtdOyAgLy8xLWJhc2VkXG5cdGZvciAobGV0IGkgPSBzdGFydF9saW5lX251bWJlcjsgaSA8PSBlZGl0b3IubGluZUNvdW50KCk7IGkrKykge1xuXHRcdGxldCBsaW5lID0gZWRpdG9yVmlldy5zdGF0ZS5kb2MubGluZShpKTtcblx0XHRpZiAoIXN0YXJ0X3JlZy50ZXN0KGxpbmUudGV4dCkpIGJyZWFrO1xuXHRcdGxldCBtYXRjaGVkID0gbWF0Y2hMaW5lV2l0aEV4dGVybmFsTGluayhsaW5lLnRleHQsIGxpbmssIGFsdFRleHQsIG5ld1dpZHRoLCBpblRhYmxlKTtcblx0XHRtYXRjaGVkX3Jlc3VsdHMucHVzaCguLi5tYXRjaGVkKTtcblx0XHRtYXRjaGVkX2xpbmVzLnB1c2goLi4ubmV3IEFycmF5KG1hdGNoZWQubGVuZ3RoKS5maWxsKGkpKTtcblx0fVxuXG5cdGZvciAobGV0IGkgPSBzdGFydF9saW5lX251bWJlciAtIDE7IGkgPj0gMTsgaS0tKSB7XG5cdFx0bGV0IGxpbmUgPSBlZGl0b3JWaWV3LnN0YXRlLmRvYy5saW5lKGkpO1xuXHRcdGlmICghc3RhcnRfcmVnLnRlc3QobGluZS50ZXh0KSkgYnJlYWs7XG5cdFx0bGV0IG1hdGNoZWQgPSBtYXRjaExpbmVXaXRoRXh0ZXJuYWxMaW5rKGxpbmUudGV4dCwgbGluaywgYWx0VGV4dCwgbmV3V2lkdGgsIGluVGFibGUpO1xuXHRcdG1hdGNoZWRfcmVzdWx0cy5wdXNoKC4uLm1hdGNoZWQpO1xuXHRcdG1hdGNoZWRfbGluZXMucHVzaCguLi5uZXcgQXJyYXkobWF0Y2hlZC5sZW5ndGgpLmZpbGwoaSkpO1xuXHR9XG5cblx0cHJpbnQobWF0Y2hlZF9yZXN1bHRzKVxuXHRwcmludChtYXRjaGVkX2xpbmVzKVxuXG5cdGlmIChtYXRjaGVkX3Jlc3VsdHMubGVuZ3RoID09IDEpIHtcblx0XHRsZXQgdGFyZ2V0X2xpbmUgPSBlZGl0b3JWaWV3LnN0YXRlLmRvYy5saW5lKG1hdGNoZWRfbGluZXNbMF0pO1xuXHRcdGlmIChtb2RlID09ICd0YWJsZScpIHtcblx0XHRcdGxldCBvbGRfdGV4dCA9IHRhcmdldF9saW5lLnRleHQ7XG5cdFx0XHRsZXQgbmV3X2xpbmVfdGV4dCA9IG9sZF90ZXh0LnN1YnN0cmluZygwLCBtYXRjaGVkX3Jlc3VsdHNbMF0uZnJvbV9jaCkgK1xuXHRcdFx0XHRtYXRjaGVkX3Jlc3VsdHNbMF0ubmV3X2xpbmsgK1xuXHRcdFx0XHRvbGRfdGV4dC5zdWJzdHJpbmcobWF0Y2hlZF9yZXN1bHRzWzBdLnRvX2NoKTtcblx0XHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogdGFyZ2V0X2xpbmUuZnJvbSxcblx0XHRcdFx0XHR0bzogdGFyZ2V0X2xpbmUuZnJvbSArIG9sZF90ZXh0Lmxlbmd0aCxcblx0XHRcdFx0XHRpbnNlcnQ6IG5ld19saW5lX3RleHRcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVkaXRvclZpZXcuZGlzcGF0Y2goe1xuXHRcdFx0XHRjaGFuZ2VzOiB7XG5cdFx0XHRcdFx0ZnJvbTogdGFyZ2V0X2xpbmUuZnJvbSArIG1hdGNoZWRfcmVzdWx0c1swXS5mcm9tX2NoLFxuXHRcdFx0XHRcdHRvOiB0YXJnZXRfbGluZS5mcm9tICsgbWF0Y2hlZF9yZXN1bHRzWzBdLnRvX2NoLFxuXHRcdFx0XHRcdGluc2VydDogbWF0Y2hlZF9yZXN1bHRzWzBdLm5ld19saW5rXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHRlbHNlIGlmIChtYXRjaGVkX3Jlc3VsdHMubGVuZ3RoID09IDApIHtcblx0XHRuZXcgTm90aWNlKGBGYWlsIHRvIGZpbmQgY3VycmVudCBpbWFnZS1saW5rIGluICR7bW9kZX0sIHBsZWFzZSB6b29tIG1hbnVhbGx5IWApXG5cdH1cblx0ZWxzZSB7XG5cdFx0bmV3IE5vdGljZShgRmluZCBtdWx0aXBsZSBzYW1lIGltYWdlLWxpbmsgaW4gJHttb2RlfSwgcGxlYXNlIHpvb20gbWFudWFsbHkhYClcblx0fVxuXHRyZXR1cm47XG5cbn1cblxuXG5mdW5jdGlvbiBtYXRjaExpbmVXaXRoSW50ZXJuYWxMaW5rKGxpbmVfdGV4dDogc3RyaW5nLCB0YXJnZXRfbmFtZTogc3RyaW5nLCBuZXdfd2lkdGg6IG51bWJlciwgaW50YWJsZTogYm9vbGVhbik6IE1hdGNoZWRMaW5rSW5MaW5lW10ge1xuXHRsZXQgcmVnV2lraUxpbmsgPSAvXFwhXFxbXFxbW15cXFtcXF1dKj9cXF1cXF0vZztcblx0bGV0IHJlZ01kTGluayA9IC9cXCFcXFtbXlxcW1xcXV0qP1xcXVxcKFteXFxzXFwpXFwoXFxbXFxdXFx7XFx9J10qXFwpL2c7XG5cdGNvbnN0IHRhcmdldF9uYW1lX21kbGluayA9IHRhcmdldF9uYW1lLnJlcGxhY2UoLyAvZywgJyUyMCcpO1xuXHRpZiAoIWxpbmVfdGV4dC5pbmNsdWRlcyh0YXJnZXRfbmFtZSkgJiYgIWxpbmVfdGV4dC5pbmNsdWRlcyh0YXJnZXRfbmFtZV9tZGxpbmspKSByZXR1cm4gW107XG5cblx0Ly8gcHJpbnQobGluZV90ZXh0KVxuXHRsZXQgcmVzdWx0OiBNYXRjaGVkTGlua0luTGluZVtdID0gW107XG5cdC8vIGNvbnN0IG5ld1dpa2lMaW5rID0gaW50YWJsZSA/IGAhW1ske3RhcmdldF9uYW1lfVxcXFx8JHtuZXdfd2lkdGh9XV1gOmAhW1ske3RhcmdldF9uYW1lfXwke25ld193aWR0aH1dXWA7XG5cdHdoaWxlICh0cnVlKSB7XG5cdFx0bGV0IHdpa2lfbWF0Y2ggPSByZWdXaWtpTGluay5leGVjKGxpbmVfdGV4dCk7XG5cdFx0aWYgKCF3aWtpX21hdGNoKSBicmVhaztcblx0XHRjb25zdCBtYXRjaGVkX2xpbmsgPSB3aWtpX21hdGNoWzBdO1xuXHRcdC8vIHByaW50KCdtYXRjaGVkX2xpbms6JywgbWF0Y2hlZF9saW5rKVxuXHRcdGlmIChtYXRjaGVkX2xpbmsuaW5jbHVkZXModGFyZ2V0X25hbWUpKSB7XG5cdFx0XHRsZXQgbm9ybWFsX2xpbmsgPSBpbnRhYmxlID8gbWF0Y2hlZF9saW5rLnJlcGxhY2UoL1xcXFxcXHwvZywgJ3wnKSA6IG1hdGNoZWRfbGluaztcblx0XHRcdGxldCBsaW5rX21hdGNoID0gbm9ybWFsX2xpbmsubWF0Y2goLyFcXFtcXFsoLio/KShcXHx8XFxdXFxdKS8pO1xuXHRcdFx0bGV0IGxpbmtfdGV4dCA9IGxpbmtfbWF0Y2ggPyBsaW5rX21hdGNoWzFdIDogJyc7XG5cblx0XHRcdGxldCBhbHRfbWF0Y2ggPSBtYXRjaGVkX2xpbmsubWF0Y2goLyFcXFtcXFsuKj8oXFx8KC4qPykpXFxdXFxdLyk7XG5cdFx0XHRsZXQgYWx0X3RleHQgPSBhbHRfbWF0Y2ggPyBhbHRfbWF0Y2hbMV0gOiAnJztcblx0XHRcdGxldCBhbHRfdGV4dF9saXN0ID0gYWx0X3RleHQuc3BsaXQoJ3wnKTtcblx0XHRcdGxldCBhbHRfdGV4dF93b19zaXplID0gJyc7XG5cdFx0XHRsZXQgbmV3X2FsdF90ZXh0ID0gJydcblx0XHRcdGZvciAobGV0IGFsdCBvZiBhbHRfdGV4dF9saXN0KSB7XG5cdFx0XHRcdGlmICghL15cXGQrJC8udGVzdChhbHQpICYmICEvXlxccyokLy50ZXN0KGFsdCkpIHtcblx0XHRcdFx0XHRhbHRfdGV4dF93b19zaXplID0gYWx0X3RleHRfd29fc2l6ZSArICd8JyArIGFsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0bmV3X2FsdF90ZXh0ID0gbmV3X3dpZHRoICE9IDAgPyBgJHthbHRfdGV4dF93b19zaXplfXwke25ld193aWR0aH1gIDogYWx0X3RleHRfd29fc2l6ZTtcblx0XHRcdG5ld19hbHRfdGV4dCA9IGludGFibGUgPyBuZXdfYWx0X3RleHQucmVwbGFjZSgvXFx8L2csICdcXFxcfCcpIDogbmV3X2FsdF90ZXh0O1xuXHRcdFx0bGV0IG5ld1dpa2lMaW5rID0gbGlua19tYXRjaCA/IGAhW1ske2xpbmtfdGV4dH0ke25ld19hbHRfdGV4dH1dXWAgOiBgIVtbJHt0YXJnZXRfbmFtZX0ke25ld19hbHRfdGV4dH1dXWA7XG5cblx0XHRcdHJlc3VsdC5wdXNoKHtcblx0XHRcdFx0b2xkX2xpbms6IG1hdGNoZWRfbGluayxcblx0XHRcdFx0bmV3X2xpbms6IG5ld1dpa2lMaW5rLFxuXHRcdFx0XHRmcm9tX2NoOiB3aWtpX21hdGNoLmluZGV4LFxuXHRcdFx0XHR0b19jaDogd2lraV9tYXRjaC5pbmRleCArIG1hdGNoZWRfbGluay5sZW5ndGhcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdHdoaWxlICh0cnVlKSB7XG5cdFx0bGV0IG1hdGNoID0gcmVnTWRMaW5rLmV4ZWMobGluZV90ZXh0KTtcblx0XHRpZiAoIW1hdGNoKSBicmVhaztcblx0XHRjb25zdCBtYXRjaGVkX2xpbmsgPSBtYXRjaFswXTtcblx0XHRpZiAobWF0Y2hlZF9saW5rLmluY2x1ZGVzKHRhcmdldF9uYW1lX21kbGluaykpIHtcblx0XHRcdC8vIFx1NjI3RVx1NTIzMCBtYXRjaGVkX2xpbmsgXHU0RTJEXHU3Njg0IGFsdFRleHRcblx0XHRcdGxldCBhbHRfdGV4dF9tYXRjaCA9IG1hdGNoZWRfbGluay5tYXRjaCgvXFxbLio/XFxdL2cpIGFzIHN0cmluZ1tdO1xuXHRcdFx0bGV0IGFsdF90ZXh0ID0gYWx0X3RleHRfbWF0Y2hbMF0uc3Vic3RyaW5nKDEsIGFsdF90ZXh0X21hdGNoWzBdLmxlbmd0aCAtIDEpO1xuXHRcdFx0bGV0IHB1cmVfYWx0ID0gYWx0X3RleHQucmVwbGFjZSgvXFx8XFxkKyhcXHxcXGQrKT8kL2csICcnKTtcblx0XHRcdGlmIChpbnRhYmxlKSB7XG5cdFx0XHRcdHB1cmVfYWx0ID0gYWx0X3RleHQucmVwbGFjZSgvXFxcXFxcfFxcZCsoXFx8XFxkKyk/JC9nLCAnJylcblx0XHRcdH1cblx0XHRcdGxldCBsaW5rX3RleHQgPSBtYXRjaGVkX2xpbmsuc3Vic3RyaW5nKGFsdF90ZXh0X21hdGNoWzBdLmxlbmd0aCArIDIsIG1hdGNoZWRfbGluay5sZW5ndGggLSAxKVxuXHRcdFx0bGV0IG5ld01ETGluayA9IGludGFibGUgPyBgIVske3B1cmVfYWx0fVxcXFx8JHtuZXdfd2lkdGh9XSgke2xpbmtfdGV4dH0pYCA6IGAhWyR7cHVyZV9hbHR9fCR7bmV3X3dpZHRofV0oJHtsaW5rX3RleHR9KWA7XG5cdFx0XHRpZiAoL15cXGQqJC8udGVzdChhbHRfdGV4dCkpIHtcblx0XHRcdFx0bmV3TURMaW5rID0gYCFbJHtuZXdfd2lkdGh9XSgke2xpbmtfdGV4dH0pYDtcblx0XHRcdH1cblx0XHRcdC8vIGxldCBuZXdMaW5lVGV4dCA9IGxpbmVfdGV4dC5zdWJzdHJpbmcoMCwgbWF0Y2guaW5kZXgpICsgXG5cdFx0XHQvLyBcdFx0XHRcdFx0bmV3TURMaW5rICsgXG5cdFx0XHQvLyBcdFx0XHRcdFx0bGluZV90ZXh0LnN1YnN0cmluZyhtYXRjaC5pbmRleCttYXRjaGVkX2xpbmsubGVuZ3RoKTtcblx0XHRcdHJlc3VsdC5wdXNoKHtcblx0XHRcdFx0b2xkX2xpbms6IG1hdGNoZWRfbGluayxcblx0XHRcdFx0bmV3X2xpbms6IG5ld01ETGluayxcblx0XHRcdFx0ZnJvbV9jaDogbWF0Y2guaW5kZXgsXG5cdFx0XHRcdHRvX2NoOiBtYXRjaC5pbmRleCArIG1hdGNoZWRfbGluay5sZW5ndGhcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHRwcmludChcIkxpbmUgVGV4dDogXCIsIGxpbmVfdGV4dClcblx0cHJpbnQoXCJNYXRjaGVkSW5mbzpcIiwgcmVzdWx0KTtcblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBtYXRjaExpbmVXaXRoRXh0ZXJuYWxMaW5rKGxpbmVfdGV4dDogc3RyaW5nLCBsaW5rOiBzdHJpbmcsIGFsdF90ZXh0OiBzdHJpbmcsIG5ld193aWR0aDogbnVtYmVyLCBpbnRhYmxlOiBib29sZWFuKTogTWF0Y2hlZExpbmtJbkxpbmVbXSB7XG5cdGxldCByZXN1bHQ6IE1hdGNoZWRMaW5rSW5MaW5lW10gPSBbXVxuXHRsZXQgcmVnTWRMaW5rID0gL1xcIVxcW1teXFxbXFxdXSo/XFxdXFwoW15cXHNcXClcXChcXFtcXF1cXHtcXH0nXSpcXCkvZztcblx0aWYgKCFsaW5lX3RleHQuaW5jbHVkZXMobGluaykpIHJldHVybiBbXTtcblx0d2hpbGUgKHRydWUpIHtcblx0XHRsZXQgbWF0Y2ggPSByZWdNZExpbmsuZXhlYyhsaW5lX3RleHQpO1xuXHRcdGlmICghbWF0Y2gpIGJyZWFrO1xuXHRcdGxldCBtYXRjaGVkX2xpbmsgPSBtYXRjaFswXTtcblx0XHRpZiAobWF0Y2hlZF9saW5rLmluY2x1ZGVzKGxpbmspKSB7XG5cdFx0XHRsZXQgYWx0X3RleHRfbWF0Y2ggPSBtYXRjaGVkX2xpbmsubWF0Y2goL1xcWy4qP1xcXS9nKSBhcyBzdHJpbmdbXTtcblx0XHRcdGxldCBhbHRfdGV4dCA9IGFsdF90ZXh0X21hdGNoWzBdLnN1YnN0cmluZygxLCBhbHRfdGV4dF9tYXRjaFswXS5sZW5ndGggLSAxKTtcblx0XHRcdGxldCBwdXJlX2FsdCA9IGFsdF90ZXh0LnJlcGxhY2UoL1xcfFxcZCsoXFx8XFxkKyk/JC9nLCAnJyk7XG5cdFx0XHRpZiAoaW50YWJsZSkge1xuXHRcdFx0XHRwdXJlX2FsdCA9IGFsdF90ZXh0LnJlcGxhY2UoL1xcXFxcXHxcXGQrKFxcfFxcZCspPyQvZywgJycpXG5cdFx0XHR9XG5cdFx0XHRpZiAoL15cXGQqJC8udGVzdChhbHRfdGV4dCkpIHtcblx0XHRcdFx0cHVyZV9hbHQgPSAnJztcblx0XHRcdH1cblx0XHRcdGxldCBsaW5rX3RleHQgPSBtYXRjaGVkX2xpbmsuc3Vic3RyaW5nKGFsdF90ZXh0X21hdGNoWzBdLmxlbmd0aCArIDIsIG1hdGNoZWRfbGluay5sZW5ndGggLSAxKVxuXHRcdFx0bGV0IG5ld0V4dGVybmFsTGluayA9IGludGFibGUgPyBgIVske3B1cmVfYWx0fVxcXFx8JHtuZXdfd2lkdGh9XSgke2xpbmtfdGV4dH0pYCA6IGAhWyR7cHVyZV9hbHR9fCR7bmV3X3dpZHRofV0oJHtsaW5rX3RleHR9KWA7XG5cdFx0XHRcblx0XHRcdHJlc3VsdC5wdXNoKHtcblx0XHRcdFx0b2xkX2xpbms6IG1hdGNoZWRfbGluayxcblx0XHRcdFx0bmV3X2xpbms6IG5ld0V4dGVybmFsTGluayxcblx0XHRcdFx0ZnJvbV9jaDogbWF0Y2guaW5kZXgsXG5cdFx0XHRcdHRvX2NoOiBtYXRjaC5pbmRleCArIG1hdGNoZWRfbGluay5sZW5ndGhcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXHRwcmludChcIkxpbmUgVGV4dDogXCIsIGxpbmVfdGV4dClcblx0cHJpbnQoXCJNYXRjaGVkSW5mbzpcIiwgcmVzdWx0KTtcblx0cmV0dXJuIHJlc3VsdDtcbn1cblxuXG5cbi8vIFx1NTIxQlx1NUVGQVx1OTA2RVx1N0Y2OVx1NTE0M1x1N0QyMFxuZnVuY3Rpb24gY3JlYXRlWm9vbU1hc2soKTogSFRNTERpdkVsZW1lbnQge1xuICAgIGNvbnN0IG1hc2sgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBtYXNrLmlkID0gJ2FmLW1hc2snO1xuICAgIG1hc2suc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xuICAgIG1hc2suc3R5bGUudG9wID0gJzAnO1xuICAgIG1hc2suc3R5bGUubGVmdCA9ICcwJztcbiAgICBtYXNrLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIG1hc2suc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIG1hc2suc3R5bGUuYmFja2dyb3VuZCA9ICdyZ2JhKDAsIDAsIDAsIDAuNSknO1xuICAgIG1hc2suc3R5bGUuekluZGV4ID0gJzk5OTgnO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobWFzayk7XG4gICAgcmV0dXJuIG1hc2s7XG59XG5cbi8vIFx1NTIxQlx1NUVGQVx1NjUzRVx1NTkyN1x1NzY4NFx1NTZGRVx1NTBDRlx1NTE0M1x1N0QyMFxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlWm9vbWVkSW1hZ2Uoc3JjOiBzdHJpbmcsIGFkYXB0aXZlX3JhdGlvOiBudW1iZXIpOiBQcm9taXNlPHt6b29tZWRJbWFnZTogSFRNTEltYWdlRWxlbWVudCwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBvcmlnaW5hbEhlaWdodDogbnVtYmVyfT4ge1xuICAgIGNvbnN0IHpvb21lZEltYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW1nJyk7XG4gICAgem9vbWVkSW1hZ2UuaWQgPSAnYWYtem9vbWVkLWltYWdlJztcbiAgICB6b29tZWRJbWFnZS5zcmMgPSBzcmM7XG4gICAgem9vbWVkSW1hZ2Uuc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xuICAgIHpvb21lZEltYWdlLnN0eWxlLnpJbmRleCA9ICc5OTk5JztcbiAgICB6b29tZWRJbWFnZS5zdHlsZS50b3AgPSAnNTAlJztcbiAgICB6b29tZWRJbWFnZS5zdHlsZS5sZWZ0ID0gJzUwJSc7XG4gICAgem9vbWVkSW1hZ2Uuc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZSgtNTAlLCAtNTAlKSc7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh6b29tZWRJbWFnZSk7XG5cbiAgICBsZXQgb3JpZ2luYWxXaWR0aCA9IHpvb21lZEltYWdlLm5hdHVyYWxXaWR0aDtcblx0bGV0IG9yaWdpbmFsSGVpZ2h0ID0gem9vbWVkSW1hZ2UubmF0dXJhbEhlaWdodDtcblxuXHRhZGFwdGl2ZWx5RGlzcGxheUltYWdlKHpvb21lZEltYWdlLCBvcmlnaW5hbFdpZHRoLCBvcmlnaW5hbEhlaWdodCwgYWRhcHRpdmVfcmF0aW8pO1xuXG4gICAgcmV0dXJuIHtcblx0XHR6b29tZWRJbWFnZSxcblx0XHRvcmlnaW5hbFdpZHRoLFxuXHRcdG9yaWdpbmFsSGVpZ2h0XG5cdH07XG59XG5cbi8vIFx1NTIxQlx1NUVGQVx1NzY3RVx1NTIwNlx1NkJENFx1NjMwN1x1NzkzQVx1NTE0M1x1N0QyMFxuZnVuY3Rpb24gY3JlYXRlWm9vbVNjYWxlRGl2KHpvb21lZEltYWdlOiBIVE1MSW1hZ2VFbGVtZW50LCBvcmlnaW5hbFdpZHRoOiBudW1iZXIsIG9yaWdpbmFsSGVpZ2h0Om51bWJlcik6IEhUTUxEaXZFbGVtZW50IHtcblx0Y29uc3Qgc2NhbGVEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0c2NhbGVEaXYuaWQgPSAnYWYtc2NhbGUtZGl2Jztcblx0c2NhbGVEaXYuY2xhc3NMaXN0LmFkZCgnYWYtc2NhbGUtZGl2Jyk7XG5cdHNjYWxlRGl2LnN0eWxlLnpJbmRleCA9ICcxMDAwMCc7XG5cdHVwZGF0ZVpvb21TY2FsZURpdihzY2FsZURpdiwgem9vbWVkSW1hZ2UsIG9yaWdpbmFsV2lkdGgsIG9yaWdpbmFsSGVpZ2h0KTtcblx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzY2FsZURpdik7XG5cdHJldHVybiBzY2FsZURpdjtcbn1cblxuZnVuY3Rpb24gdXBkYXRlWm9vbVNjYWxlRGl2KHNjYWxlRGl2OiBIVE1MRGl2RWxlbWVudCwgem9vbWVkSW1hZ2U6IEhUTUxJbWFnZUVsZW1lbnQsIG9yaWdpbmFsV2lkdGg6IG51bWJlciwgb3JpZ2luYWxIZWlnaHQ6bnVtYmVyKXtcblx0Ly8gXHU4M0I3XHU1M0Q2XHU1RjUzXHU1MjREXHU3Njg0XHU1QkJEXHU1RUE2XHU1NDhDXHU5QUQ4XHU1RUE2XG5cdGNvbnN0IHdpZHRoID0gem9vbWVkSW1hZ2Uub2Zmc2V0V2lkdGg7XG5cdGNvbnN0IGhlaWdodCA9IHpvb21lZEltYWdlLm9mZnNldEhlaWdodDtcblx0bGV0IHNjYWxlUGVyY2VudCA9IHdpZHRoIC8gb3JpZ2luYWxXaWR0aCAqIDEwMDtcblx0c2NhbGVEaXYuaW5uZXJUZXh0ID0gYCR7d2lkdGh9XHUwMEQ3JHtoZWlnaHR9ICgke3NjYWxlUGVyY2VudC50b0ZpeGVkKDEpfSUpYDtcbn1cblxuLy8gXHU2RURBXHU4RjZFXHU0RThCXHU0RUY2XHU1OTA0XHU3NDA2XHU1NjY4XG5mdW5jdGlvbiBoYW5kbGVab29tTW91c2VXaGVlbChlOiBXaGVlbEV2ZW50LCB6b29tZWRJbWFnZTogSFRNTEltYWdlRWxlbWVudCwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBvcmlnaW5hbEhlaWdodDogbnVtYmVyLCBzY2FsZURpdjogSFRNTERpdkVsZW1lbnQpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgbW91c2VYID0gZS5jbGllbnRYO1xuICAgIGNvbnN0IG1vdXNlWSA9IGUuY2xpZW50WTtcbiAgICBjb25zdCBzY2FsZSA9IGUuZGVsdGFZID4gMCA/IDAuOTUgOiAxLjA1O1xuICAgIGNvbnN0IG5ld1dpZHRoID0gc2NhbGUgKiB6b29tZWRJbWFnZS5vZmZzZXRXaWR0aDtcbiAgICBjb25zdCBuZXdIZWlnaHQgPSBzY2FsZSAqIHpvb21lZEltYWdlLm9mZnNldEhlaWdodDtcbiAgICBjb25zdCBuZXdMZWZ0ID0gbW91c2VYIC0gKG1vdXNlWCAtIHpvb21lZEltYWdlLm9mZnNldExlZnQpICogc2NhbGU7XG4gICAgY29uc3QgbmV3VG9wID0gbW91c2VZIC0gKG1vdXNlWSAtIHpvb21lZEltYWdlLm9mZnNldFRvcCkgKiBzY2FsZTtcbiAgICB6b29tZWRJbWFnZS5zdHlsZS53aWR0aCA9IGAke25ld1dpZHRofXB4YDtcbiAgICB6b29tZWRJbWFnZS5zdHlsZS5oZWlnaHQgPSBgJHtuZXdIZWlnaHR9cHhgO1xuICAgIHpvb21lZEltYWdlLnN0eWxlLmxlZnQgPSBgJHtuZXdMZWZ0fXB4YDtcbiAgICB6b29tZWRJbWFnZS5zdHlsZS50b3AgPSBgJHtuZXdUb3B9cHhgO1xuICAgIHVwZGF0ZVpvb21TY2FsZURpdihzY2FsZURpdiwgem9vbWVkSW1hZ2UsIG9yaWdpbmFsV2lkdGgsIG9yaWdpbmFsSGVpZ2h0KTtcbn1cblxuLy8gXHU5RjIwXHU2ODA3XHU1M0YzXHU5NTJFXHU3MEI5XHU1MUZCXHU0RThCXHU0RUY2XHU1OTA0XHU3NDA2XHU1NjY4XG5mdW5jdGlvbiBoYW5kbGVab29tQ29udGV4dE1lbnUoZTogTW91c2VFdmVudCx6b29tZWRJbWFnZTogSFRNTEltYWdlRWxlbWVudCwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBvcmlnaW5hbEhlaWdodDogbnVtYmVyLCBzY2FsZURpdjogSFRNTERpdkVsZW1lbnQpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgem9vbWVkSW1hZ2Uuc3R5bGUud2lkdGggPSBgJHtvcmlnaW5hbFdpZHRofXB4YDtcbiAgICB6b29tZWRJbWFnZS5zdHlsZS5oZWlnaHQgPSBgJHtvcmlnaW5hbEhlaWdodH1weGA7XG4gICAgem9vbWVkSW1hZ2Uuc3R5bGUubGVmdCA9IGA1MCVgO1xuICAgIHpvb21lZEltYWdlLnN0eWxlLnRvcCA9IGA1MCVgO1xuXHR1cGRhdGVab29tU2NhbGVEaXYoc2NhbGVEaXYsIHpvb21lZEltYWdlLCBvcmlnaW5hbFdpZHRoLCBvcmlnaW5hbEhlaWdodCk7XG59XG5cblxuZnVuY3Rpb24gYWRhcHRpdmVseURpc3BsYXlJbWFnZSh6b29tZWRJbWFnZTogSFRNTEltYWdlRWxlbWVudCwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBvcmlnaW5hbEhlaWdodDogbnVtYmVyLCBhZGFwdGl2ZV9yYXRpbzpudW1iZXIpIHtcblx0em9vbWVkSW1hZ2Uuc3R5bGUubGVmdCA9IGA1MCVgO1xuXHR6b29tZWRJbWFnZS5zdHlsZS50b3AgPSBgNTAlYDtcblx0Ly8gXHU1OTgyXHU2NzlDXHU1NkZFXHU3MjQ3XHU3Njg0XHU1QzNBXHU1QkY4XHU1OTI3XHU0RThFXHU1QzRGXHU1RTU1XHU1QzNBXHU1QkY4XHVGRjBDXHU0RjdGXHU1MTc2XHU1OTI3XHU1QzBGXHU0RTNBXHU1QzRGXHU1RTU1XHU1QzNBXHU1QkY4XHU3Njg0IGFkYXB0aXZlX3JhdGlvXG5cdGxldCBzY3JlZW5SYXRpbyA9IGFkYXB0aXZlX3JhdGlvOyAgIC8vIFx1NUM0Rlx1NUU1NVx1NUMzQVx1NUJGOFx1NkJENFx1NEY4QlxuXHRsZXQgc2NyZWVuV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcblx0bGV0IHNjcmVlbkhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblxuXHQvLyBBZGp1c3QgaW5pdGlhbCBzaXplIG9mIHRoZSBpbWFnZSBpZiBpdCBleGNlZWRzIHNjcmVlbiBzaXplXG5cdGlmIChvcmlnaW5hbFdpZHRoID4gc2NyZWVuV2lkdGggfHwgb3JpZ2luYWxIZWlnaHQgPiBzY3JlZW5IZWlnaHQpIHtcblx0XHRpZiAob3JpZ2luYWxXaWR0aCAvIHNjcmVlbldpZHRoID4gb3JpZ2luYWxIZWlnaHQgLyBzY3JlZW5IZWlnaHQpIHtcblx0XHRcdHpvb21lZEltYWdlLnN0eWxlLndpZHRoID0gYCR7c2NyZWVuV2lkdGggKiBzY3JlZW5SYXRpb31weGA7XG5cdFx0XHR6b29tZWRJbWFnZS5zdHlsZS5oZWlnaHQgPSAnYXV0byc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHpvb21lZEltYWdlLnN0eWxlLmhlaWdodCA9IGAke3NjcmVlbkhlaWdodCAqIHNjcmVlblJhdGlvfXB4YDtcblx0XHRcdHpvb21lZEltYWdlLnN0eWxlLndpZHRoID0gJ2F1dG8nO1xuXHRcdH1cblx0fWVsc2V7XG5cdFx0em9vbWVkSW1hZ2Uuc3R5bGUud2lkdGggPSBgJHtvcmlnaW5hbFdpZHRofXB4YDtcblx0XHR6b29tZWRJbWFnZS5zdHlsZS5oZWlnaHQgPSBgJHtvcmlnaW5hbEhlaWdodH1weGA7XG5cdH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlWm9vbURyYWdTdGFydChlOiBNb3VzZUV2ZW50LHpvb21lZEltYWdlOiBIVE1MSW1hZ2VFbGVtZW50KSB7XG4gICAgLy8gXHU0RThCXHU0RUY2XHU1OTA0XHU3NDA2XHU3Njg0XHU0RUUzXHU3ODAxIC4uLlxuXHQvLyBcdTk2M0JcdTZCNjJcdTZENEZcdTg5QzhcdTU2NjhcdTlFRDhcdThCQTRcdTc2ODRcdTYyRDZcdTUyQThcdTRFOEJcdTRFRjZcblx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdC8vIFx1OEJCMFx1NUY1NVx1NzBCOVx1NTFGQlx1NEY0RFx1N0Y2RVxuXHRsZXQgY2xpY2tYID0gZS5jbGllbnRYO1xuXHRsZXQgY2xpY2tZID0gZS5jbGllbnRZO1xuXG5cdC8vIFx1NjZGNFx1NjVCMFx1NTE0M1x1N0QyMFx1NEY0RFx1N0Y2RVx1NzY4NFx1NTZERVx1OEMwM1x1NTFGRFx1NjU3MFxuXHRjb25zdCB1cGRhdGVQb3NpdGlvbiA9IChtb3ZlRXZ0OiBNb3VzZUV2ZW50KSA9PiB7XG5cdFx0Ly8gXHU4QkExXHU3Qjk3XHU5RjIwXHU2ODA3XHU3OUZCXHU1MkE4XHU4REREXHU3OUJCXG5cdFx0bGV0IG1vdmVYID0gbW92ZUV2dC5jbGllbnRYIC0gY2xpY2tYO1xuXHRcdGxldCBtb3ZlWSA9IG1vdmVFdnQuY2xpZW50WSAtIGNsaWNrWTtcblxuXHRcdC8vIFx1NUI5QVx1NEY0RFx1NTZGRVx1NzI0N1x1NEY0RFx1N0Y2RVxuXHRcdHpvb21lZEltYWdlLnN0eWxlLmxlZnQgPSBgJHt6b29tZWRJbWFnZS5vZmZzZXRMZWZ0ICsgbW92ZVh9cHhgO1xuXHRcdHpvb21lZEltYWdlLnN0eWxlLnRvcCA9IGAke3pvb21lZEltYWdlLm9mZnNldFRvcCArIG1vdmVZfXB4YDtcblxuXHRcdC8vIFx1NjZGNFx1NjVCMFx1NzBCOVx1NTFGQlx1NEY0RFx1N0Y2RVxuXHRcdGNsaWNrWCA9IG1vdmVFdnQuY2xpZW50WDtcblx0XHRjbGlja1kgPSBtb3ZlRXZ0LmNsaWVudFk7XG5cdH1cblxuXHQvLyBcdTlGMjBcdTY4MDdcdTc5RkJcdTUyQThcdTRFOEJcdTRFRjZcblx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdXBkYXRlUG9zaXRpb24pO1xuXG5cdC8vIFx1OUYyMFx1NjgwN1x1Njc3RVx1NUYwMFx1NEU4Qlx1NEVGNlxuXHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgZnVuY3Rpb24gbGlzdGVuZXIoKSB7XG5cdFx0Ly8gXHU3OUZCXHU5NjY0XHU5RjIwXHU2ODA3XHU3OUZCXHU1MkE4XHU1NDhDXHU5RjIwXHU2ODA3XHU2NzdFXHU1RjAwXHU3Njg0XHU3NkQxXHU1NDJDXHU1NjY4XG5cdFx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdXBkYXRlUG9zaXRpb24pO1xuXHRcdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBsaXN0ZW5lcik7XG5cdH0sIHsgb25jZTogdHJ1ZSB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0RXhjYWxpZHJhd0Jhc2VOYW1lKHRhcmdldDogSFRNTEltYWdlRWxlbWVudCk6IHN0cmluZyB7XG5cdGxldCB0YXJnZXRfbmFtZSA9IHRhcmdldC5nZXRBdHRyaWJ1dGUoJ2ZpbGVzb3VyY2UnKSBhcyBzdHJpbmc7XG5cdGxldCBmaWxlX2Jhc2VfbmFtZSA9IHRhcmdldF9uYW1lXG5cdGlmIChmaWxlX2Jhc2VfbmFtZS5pbmNsdWRlcygnLycpKSB7XG5cdFx0bGV0IHRlbXBfYXJyID0gZmlsZV9iYXNlX25hbWUuc3BsaXQoJy8nKTtcblx0XHRmaWxlX2Jhc2VfbmFtZSA9IHRlbXBfYXJyW3RlbXBfYXJyLmxlbmd0aCAtIDFdXG5cdH0gZWxzZSBpZiAoZmlsZV9iYXNlX25hbWUuaW5jbHVkZXMoJ1xcXFwnKSkge1xuXHRcdGxldCB0ZW1wX2FyciA9IGZpbGVfYmFzZV9uYW1lLnNwbGl0KCdcXFxcJyk7XG5cdFx0ZmlsZV9iYXNlX25hbWUgPSB0ZW1wX2Fyclt0ZW1wX2Fyci5sZW5ndGggLSAxXVxuXHR9XG5cdGZpbGVfYmFzZV9uYW1lID0gZmlsZV9iYXNlX25hbWUuZW5kc1dpdGgoJy5tZCcpID9cblx0XHRmaWxlX2Jhc2VfbmFtZS5zdWJzdHJpbmcoMCwgZmlsZV9iYXNlX25hbWUubGVuZ3RoIC0gMykgOlxuXHRcdGZpbGVfYmFzZV9uYW1lO1xuXHRyZXR1cm4gZmlsZV9iYXNlX25hbWU7XG59IiwgImltcG9ydCB7IE5vdGljZSwgVEZpbGUsIFRGb2xkZXIgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7IGdldEZpbGVQYXJlbnRGb2xkZXIgfSBmcm9tIFwic3JjL3V0aWxcIjtcbmltcG9ydCB7IGRlbGV0ZUZpbGUgfSBmcm9tIFwic3JjL3V0aWxzL2RlbGV0ZUZpbGVcIjtcbmltcG9ydCBBdHRhY2hGbG93UGx1Z2luIGZyb20gXCIuLi8uLi9zcmMvbWFpblwiO1xuLyoqXG4gKiBkZWxBbGxBdHRhY2hzQnlDb21tYW5kXG4gKlxuICogMS4gZ2V0IGN1cnJlbnQgZmlsZVxuICogMi4gZ2V0IFRGaWxlIG9mIHRoZSBhdHRhY2htZW50IHJlZmVyZW5jZWQgYnkgZmlsZVxuICovXG5leHBvcnQgY29uc3QgZGVsZXRlQWxsQXR0YWNocyA9IGFzeW5jIChwbHVnaW46IEF0dGFjaEZsb3dQbHVnaW4pID0+IHtcblx0Ly8gMS4gZ2V0IGN1cnJlbnQgZmlsZVxuXHRjb25zdCBhY3RpdmVNZDogVEZpbGUgPSBhcHAud29ya3NwYWNlLmdldEFjdGl2ZUZpbGUoKSBhcyBURmlsZTtcblx0Y29uc3QgcmVzb2x2ZWRMaW5rcyA9IGFwcC5tZXRhZGF0YUNhY2hlLnJlc29sdmVkTGlua3M7XG5cdGNvbnN0IGF0dGFjaHNQYXRoczogc3RyaW5nW10gPSBbXTtcblx0Zm9yIChjb25zdCBbbWRGaWxlLCBsaW5rc10gb2YgT2JqZWN0LmVudHJpZXMocmVzb2x2ZWRMaW5rcykpIHtcblx0XHRpZiAoYWN0aXZlTWQ/LnBhdGggPT09IG1kRmlsZSkge1xuXHRcdFx0bGV0IGZpbGVDb3VudCA9IDA7XG5cdFx0XHRsZXQgZmxhZyA9IGZhbHNlO1xuXHRcdFx0Zm9yIChjb25zdCBbZmlsZVBhdGgsIG5yXSBvZiBPYmplY3QuZW50cmllcyhsaW5rcykpIHtcblx0XHRcdFx0Ly8gSWYgdGhlIGZpbGVQYXRoIGVuZHMgd2l0aCAnLm1kJyAsd2hpY2ggaW5kaWNhdGVzIHRoZSBmaWxlIGlzIG1hcmtkb3duIGZpbGUsIGFuZCBkbyBub3QgZGVsZXRlIGl0XG5cdFx0XHRcdGlmIChmaWxlUGF0aC5tYXRjaCgvLipcXC5tZCQvbSkpIGNvbnRpbnVlO1xuXHRcdFx0XHQvLyBpZiB0aGUgYXR0YWNobWVudCBpbiB0aGUgbm90ZSBoYXMgYmVlbiByZWZlcmVuY2VkIGJ5IG90aGVyIG5vdGVzICBzaW11bHRhbmVvdXNseSBza2lwIGl0LlxuXHRcdFx0XHRpZiAoaXNSZWZlcmVuY2VkQnlPdGhlck5vdGVzKGZpbGVQYXRoLCBhY3RpdmVNZCkpIGNvbnRpbnVlO1xuXHRcdFx0XHRhdHRhY2hzUGF0aHMucHVzaChmaWxlUGF0aCk7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0Ly8gMi4gZ2V0IFRGaWxlIG9mIHRoZSBhdHRhY2htZW50IHJlZmVyZW5jZWQgYnkgZmlsZVxuXHRcdFx0XHRcdGNvbnN0IEF0dGFjaEZpbGU6IFRGaWxlID0gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChcblx0XHRcdFx0XHRcdGZpbGVQYXRoXG5cdFx0XHRcdFx0KSBhcyBURmlsZTtcblx0XHRcdFx0XHRpZiAoQXR0YWNoRmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XG5cdFx0XHRcdFx0XHRkZWxldGVGaWxlKEF0dGFjaEZpbGUsIHBsdWdpbik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvbnN0IHBhcmVudEZvbGRlciA9IGdldEZpbGVQYXJlbnRGb2xkZXIoXG5cdFx0XHRcdFx0XHRBdHRhY2hGaWxlXG5cdFx0XHRcdFx0KSBhcyBURm9sZGVyO1xuXHRcdFx0XHRcdGlmICghZmxhZykge1xuXHRcdFx0XHRcdFx0ZmlsZUNvdW50ID0gcGFyZW50Rm9sZGVyLmNoaWxkcmVuLmxlbmd0aDtcblx0XHRcdFx0XHRcdGZsYWcgPSAhZmxhZztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZmlsZUNvdW50ID0gZmlsZUNvdW50IC0gMTtcblx0XHRcdFx0XHRpZiAoIWZpbGVDb3VudCkge1xuXHRcdFx0XHRcdFx0YXdhaXQgZGVsZXRlRmlsZShwYXJlbnRGb2xkZXIsIHBsdWdpbik7XG5cdFx0XHRcdFx0XHQvLyBhd2FpdCBhcHAudmF1bHQuZGVsZXRlKHBhcmVudEZvbGRlciwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRuZXcgTm90aWNlKFxuXHRcdFx0XHRcdFx0XHRcIkFsbCBhdHRhY2htZW50cyBhbmQgaXRzIHBhcmVudCBmb2xkZXIgZGVsZXRlZCFcIixcblx0XHRcdFx0XHRcdFx0MzAwMFxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdFx0Y29uc29sZS53YXJuKGVycm9yKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHQvLyByZW1vdmVBbGxVbnVzZWRSZWZlcmVuY2VMaW5rcyhhY3RpdmVNZCwgYXR0YWNoc1BhdGhzKTtcbn07XG4vKipcbiAqXG4gKiBAcGFyYW0gYXR0YWNoUGF0aFxuICogQHBhcmFtIGN1cnJlbnRNZFxuICogQHJldHVybnNcbiAqL1xuY29uc3QgaXNSZWZlcmVuY2VkQnlPdGhlck5vdGVzID0gKFxuXHRhdHRhY2hQYXRoOiBzdHJpbmcsXG5cdGN1cnJlbnRNZDogVEZpbGVcbik6IGJvb2xlYW4gPT4ge1xuXHRjb25zdCByZXNvbHZlZExpbmtzID0gYXBwLm1ldGFkYXRhQ2FjaGUucmVzb2x2ZWRMaW5rcztcblx0bGV0IGZsYWc6IGJvb2xlYW4gPSBmYWxzZTtcblxuXHRmb3IgKGNvbnN0IFttZEZpbGUsIGxpbmtzXSBvZiBPYmplY3QuZW50cmllcyhyZXNvbHZlZExpbmtzKSkge1xuXHRcdGlmIChtZEZpbGUgIT09IGN1cnJlbnRNZC5wYXRoKSB7XG5cdFx0XHRmb3IgKGNvbnN0IFtmaWxlUGF0aCwgbnJdIG9mIE9iamVjdC5lbnRyaWVzKGxpbmtzKSkge1xuXHRcdFx0XHRpZiAoZmlsZVBhdGggPT09IGF0dGFjaFBhdGgpIHtcblx0XHRcdFx0XHRmbGFnID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gZmxhZztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCByZWZlcmVuY2UgbGlua3NcbiAqXG4gKiBAcGFyYW0gaW1hZ2VQYXRocyAgcGF0aCAgbGlzdCAgb2YgdGhlIGN1cnJlbnQgZGVsZXRlZCBpbWFnZSB3aXRob3V0IHN1YnBhdGgsZm9ybWF0IGFzICBuYW1lLmV4dGVuc2lvblxuICogQHBhcmFtIG1kRmlsZSAgdGhlIG1hcmtkb3duIGZpbGUgY29udGFpbmluZyB0aGUgZGVsZXRlZCBpbWFnZVxuICovXG5leHBvcnQgY29uc3QgcmVtb3ZlQWxsVW51c2VkUmVmZXJlbmNlTGlua3MgPSBhc3luYyAoXG5cdGFjdGl2ZU1kOiBURmlsZSxcblx0YXR0YWNoc1BhdGhzOiBzdHJpbmdbXVxuKSA9PiB7XG5cdC8vIDEuZ2V0IHBhdGggbGlzdCBvZiBhbGwgdW51c2VkIGF0dGFjaG1lbnRzXG5cdGNvbnN0IG9yaWdpbkNvbnRlbnRzID0gYXdhaXQgYXBwLnZhdWx0LnJlYWQoYWN0aXZlTWQpO1xuXHRjb25zdCBsaW5lcyA9IG9yaWdpbkNvbnRlbnRzLnNwbGl0KFwiXFxuXCIpO1xuXHRjb25zdCBuZXdDb250ZW50czogc3RyaW5nW10gPSBbXTtcblx0bGV0IGlzTm90VGFyZ2V0TGluZTogYm9vbGVhbiA9IHRydWU7XG5cblx0Ly8gMi4gY2xlYXIgYWxsIHVudXNlZCBhdHRhY2htZW50cyBsaW5rcyBpbiB0aGUgbm90ZVxuXHQvLyBFc2NhcGUgLiB0byBcXC4gZm9yIHJlZ3VsYXIgZXhwcmVzaW9uXG5cdGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuXHRcdGZvciAoY29uc3QgaW5kZXggaW4gYXR0YWNoc1BhdGhzKSB7XG5cdFx0XHRjb25zdCByZWdNZFJlZkxpbmsgPSBuZXcgUmVnRXhwKFxuXHRcdFx0XHRcIiFcXFxcWyguKik/XFxcXF1cXFxcKCgoLipcXFxcLykrKT9cIiArIGF0dGFjaHNQYXRoc1tpbmRleF0gKyBcIlxcXFwpXCIsXG5cdFx0XHRcdFwiZ21cIlxuXHRcdFx0KTtcblx0XHRcdGNvbnN0IHJlZ1dpa2lSZWZMaW5rMiA9IG5ldyBSZWdFeHAoXG5cdFx0XHRcdFwiIVxcXFxbXFxcXFsuKj9cIiArIGF0dGFjaHNQYXRoc1tpbmRleF0gKyBcIihcXFxcfFxcXFxkKik/XFxcXF1cXFxcXVwiLFxuXHRcdFx0XHRcImdtXCJcblx0XHRcdCk7XG5cdFx0XHRjb25zdCBkZWNvZGVMaW5lID0gZGVjb2RlVVJJKGxpbmUpO1xuXHRcdFx0Y29uc3QgaXNJbmNsdWRlSW1hZ2UgPSBkZWNvZGVMaW5lLmluY2x1ZGVzKGF0dGFjaHNQYXRoc1tpbmRleF0pO1xuXHRcdFx0Y29uc3QgaXNNYXJrZG93blN0eWxlID0gZGVjb2RlTGluZS5tYXRjaChyZWdNZFJlZkxpbmspICE9IG51bGw7XG5cdFx0XHRjb25zdCBpc1dpa2lTdHlsZSA9IGRlY29kZUxpbmUubWF0Y2gocmVnV2lraVJlZkxpbmsyKSAhPSBudWxsO1xuXHRcdFx0aWYgKGlzSW5jbHVkZUltYWdlICYmIGlzTWFya2Rvd25TdHlsZSkge1xuXHRcdFx0XHRpc05vdFRhcmdldExpbmUgPSBmYWxzZTtcblx0XHRcdFx0bmV3Q29udGVudHMucHVzaChkZWNvZGVMaW5lLnJlcGxhY2UocmVnTWRSZWZMaW5rLCBcIlwiKSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fSBlbHNlIGlmIChpc0luY2x1ZGVJbWFnZSAmJiBpc1dpa2lTdHlsZSkge1xuXHRcdFx0XHRpc05vdFRhcmdldExpbmUgPSBmYWxzZTtcblx0XHRcdFx0bmV3Q29udGVudHMucHVzaChkZWNvZGVMaW5lLnJlcGxhY2UocmVnV2lraVJlZkxpbmsyLCBcIlwiKSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChpc05vdFRhcmdldExpbmUpIG5ld0NvbnRlbnRzLnB1c2gobGluZSk7XG5cdH1cblx0YXBwLnZhdWx0LmFkYXB0ZXIud3JpdGUoYWN0aXZlTWQucGF0aCwgbmV3Q29udGVudHMuam9pbihcIlxcblwiKSk7XG59O1xuZXhwb3J0IGNvbnN0IGdldFJlZmVuY2VkTGlua0NvdW50ID0gKCk6IG51bWJlciA9PiB7XG5cdGNvbnN0IGFjdGl2ZU1kOiBURmlsZSA9IGFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpIGFzIFRGaWxlO1xuXHRjb25zdCByZXNvbHZlZExpbmtzID0gYXBwLm1ldGFkYXRhQ2FjaGUucmVzb2x2ZWRMaW5rcztcblx0Y29uc3QgYXR0YWNoc1BhdGhzOiBzdHJpbmdbXSA9IFtdO1xuXHRmb3IgKGNvbnN0IFttZEZpbGUsIGxpbmtzXSBvZiBPYmplY3QuZW50cmllcyhyZXNvbHZlZExpbmtzKSkge1xuXHRcdGlmIChhY3RpdmVNZD8ucGF0aCA9PT0gbWRGaWxlKSB7XG5cdFx0XHRmb3IgKGNvbnN0IFtmaWxlUGF0aCwgbnJdIG9mIE9iamVjdC5lbnRyaWVzKGxpbmtzKSkge1xuXHRcdFx0XHRpZiAoZmlsZVBhdGgubWF0Y2goLy4qXFwubWQkL20pKSBjb250aW51ZTtcblx0XHRcdFx0aWYgKGlzUmVmZXJlbmNlZEJ5T3RoZXJOb3RlcyhmaWxlUGF0aCwgYWN0aXZlTWQpKSBjb250aW51ZTtcblx0XHRcdFx0YXR0YWNoc1BhdGhzLnB1c2goZmlsZVBhdGgpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gYXR0YWNoc1BhdGhzLmxlbmd0aDtcbn07XG4iLCAiaW1wb3J0IEF0dGFjaEZsb3dQbHVnaW4gZnJvbSBcInNyYy9tYWluXCI7XG5pbXBvcnQgeyBURmlsZSwgTm90aWNlLCBURm9sZGVyLCBNYXJrZG93blZpZXcsIEVkaXRvcn0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBpbWFnZVJlZmVyZW5jZWRTdGF0ZSB9IGZyb20gXCIuL2VudW0vaW1hZ2VSZWZlcmVuY2VkU3RhdGVcIjtcbmltcG9ydCB7IHJlc3VsdERldGVybWluZUltYWdlRGVsZXRpb24gYXMgZGVsZXRpb25SZXN1bHQgfSBmcm9tIFwiLi9pbnRlcmZhY2UvcmVzdWx0RGV0ZXJtaW5lSW1hZ2VEZWxldGlvblwiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgZXhlYywgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQge1xuXHRFbGVjdHJvbldpbmRvdywgRmlsZVN5c3RlbUFkYXB0ZXJXaXRoSW50ZXJuYWxBcGksXG5cdGxvYWRJbWFnZUJsb2IsIEFwcFdpdGhEZXNrdG9wSW50ZXJuYWxBcGksIEVkaXRvckludGVybmFsQXBpXG4gIH0gZnJvbSBcIi4vaGVscGVyc1wiXG5pbXBvcnQgeyBBcHAsIE1vZGFsLCBTZXR0aW5nLCBGdXp6eVN1Z2dlc3RNb2RhbCwgVmF1bHQsIEZ1enp5TWF0Y2ggfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuZXhwb3J0IGxldCBERUJVRzpib29sZWFuID0gZmFsc2U7XG5jb25zdCBTVUNDRVNTX05PVElDRV9USU1FT1VUID0gMTgwMDtcblxuZXhwb3J0IGNvbnN0IHByaW50PShtZXNzYWdlPzogYW55LCAuLi5vcHRpb25hbFBhcmFtczogYW55W10pID0+e1xuICAgIGlmIChERUJVRykge1xuICAgICAgICBjb25zb2xlLmxvZyhtZXNzYWdlLCAuLi5vcHRpb25hbFBhcmFtcyk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0RGVidWcodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBERUJVRyA9IHZhbHVlO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0gdGFyZ2V0X2ZpbGUgXHU4OTgxXHU1MjIwXHU5NjY0XHU3Njg0XHU3NkVFXHU2ODA3XHU2NTg3XHU0RUY2XG4gKiBAcGFyYW0gY3VycmVudE1kXHRcdTVGNTNcdTUyNERcdTYyNDBcdTU3MjhcdTc2ODQgbWFya2Rvd24gXHU2NTg3XHU0RUY2XG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgY29uc3QgY2hlY2tSZWZlcmVuY2VJbmZvID0gKFxuXHR0YXJnZXRfZmlsZTogVEZpbGUsXG5cdGN1cnJlbnRNZDogVEZpbGVcbik6IHsgc3RhdGU6IG51bWJlcjsgbWRQYXRoOiBzdHJpbmdbXSB9ID0+IHtcblxuXHRjb25zdCByZXNvbHZlZExpbmtzID0gYXBwLm1ldGFkYXRhQ2FjaGUucmVzb2x2ZWRMaW5rcztcblx0bGV0IEN1ck1EUGF0aDogc3RyaW5nO1xuXHQvLyAvLyByZWNvcmQgdGhlIHN0YXRlIG9mIGltYWdlIHJlZmVyZW5jZWQgYW5kIGFsbCBwYXRocyBvZiBtYXJrZG93biByZWZlcmVuY2luZyB0byB0aGUgaW1hZ2Vcblx0bGV0IHJlc3VsdDogZGVsZXRpb25SZXN1bHQgPSB7XG5cdFx0c3RhdGU6IDAsXG5cdFx0bWRQYXRoOiBbXSxcblx0fTtcblx0bGV0IHJlZk51bSA9IDA7IC8vIHJlY29yZCB0aGUgbnVtYmVyIG9mIG5vdGUgcmVmZXJlbmNpbmcgdG8gdGhlIGltYWdlLlxuXHRmb3IgKGNvbnN0IFttZEZpbGUsIGxpbmtzXSBvZiBPYmplY3QuZW50cmllcyhyZXNvbHZlZExpbmtzKSkge1xuXHRcdGlmIChjdXJyZW50TWQucGF0aCA9PT0gbWRGaWxlKSB7XG5cdFx0XHRDdXJNRFBhdGggPSBjdXJyZW50TWQucGF0aDtcblx0XHRcdHJlc3VsdC5tZFBhdGgudW5zaGlmdChDdXJNRFBhdGgpO1xuXHRcdH1cblx0XHRmb3IgKGNvbnN0IFtmaWxlUGF0aCwgbnJdIG9mIE9iamVjdC5lbnRyaWVzKGxpbmtzKSkge1xuXHRcdFx0aWYgKHRhcmdldF9maWxlPy5wYXRoID09PSBmaWxlUGF0aCkge1xuXHRcdFx0XHRyZWZOdW0rKztcblx0XHRcdFx0Ly8gaWYgdGhlIGRlbGV0ZWQgdGFyZ2V0IGltYWdlIHJlZmVyZW5jZWQgYnkgY3VycmVudCBub3RlIG1vcmUgdGhhbiBvbmNlXG5cdFx0XHRcdGlmIChuciA+IDEpIHtcblx0XHRcdFx0XHRyZXN1bHQuc3RhdGUgPSBpbWFnZVJlZmVyZW5jZWRTdGF0ZS5NT1JFO1xuXHRcdFx0XHRcdHJlc3VsdC5tZFBhdGgucHVzaChtZEZpbGUpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzdWx0Lm1kUGF0aC5wdXNoKG1kRmlsZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdGlmIChyZWZOdW0gPiAxKSB7XG5cdFx0cmVzdWx0LnN0YXRlID0gaW1hZ2VSZWZlcmVuY2VkU3RhdGUuTVVUSVBMRTtcblx0fSBlbHNlIHtcblx0XHRyZXN1bHQuc3RhdGUgPSBpbWFnZVJlZmVyZW5jZWRTdGF0ZS5PTkNFO1xuXHR9XG5cdHJldHVybiByZXN1bHQ7XG59O1xuXG5cbi8qKlxuICogXHRcdTkwMUFcdThGQzdcdTVGNTNcdTUyNERtZFx1NjU4N1x1NEVGNlx1NTQ4Q1x1NTZGRVx1NzI0N1x1NTQwRCBcdTgzQjdcdTUzRDYgXHU1NkZFXHU3MjQ3XHU2NTg3XHU0RUY2XHU1QkY5XHU4QzYxICAgXHVGRjBDXHU3QzdCXHU1NzhCXHU0RTNBVEZpbGVcbiAqIFxuXHRAcGFyYW0gY3VycmVudE1kICBcdTVGNTNcdTUyNERcdTk3MDBcdTg5ODFcdTg4QUJcdTUyMjBcdTk2NjRcdTc2ODRjdXJNZFx1NjI0MFx1NTcyOFx1NzY4NG1hcmtkb3duXHU2NTg3XHU0RUY2XG5cdEBwYXJhbSBGaWxlQmFzZU5hbWUgIFx1NUY1M1x1NTI0RFx1OTcwMFx1ODk4MVx1ODhBQlx1NTIyMFx1OTY2NFx1NzY4NGN1ck1kXHU1NDBEIG5hbWUuZXh0ZW5zaW9uXG4gKiAgQHJldHVybnMgIEF0dGFjaEZpbGVcbiAqL1xuZXhwb3J0IGNvbnN0IGdldEZpbGVCeUJhc2VOYW1lID0gKFxuXHRjdXJyZW50TWQ6IFRGaWxlLFxuXHRGaWxlQmFzZU5hbWU6IHN0cmluZ1xuKTogVEZpbGUgfCB1bmRlZmluZWQgPT4ge1xuXHRjb25zdCByZXNvbHZlZExpbmtzID0gYXBwLm1ldGFkYXRhQ2FjaGUucmVzb2x2ZWRMaW5rcztcblx0Zm9yIChjb25zdCBbbWRGaWxlLCBsaW5rc10gb2YgT2JqZWN0LmVudHJpZXMocmVzb2x2ZWRMaW5rcykpIHtcblx0XHRpZiAoY3VycmVudE1kLnBhdGggPT09IG1kRmlsZSkge1xuXHRcdFx0Zm9yIChjb25zdCBbZmlsZVBhdGgsIG5yXSBvZiBPYmplY3QuZW50cmllcyhsaW5rcykpIHtcblx0XHRcdFx0Ly8gcHJpbnQoJ2ZpbGVQYXRoJywgZmlsZVBhdGgpXG5cdFx0XHRcdC8vIHByaW50KEZpbGVCYXNlTmFtZSlcblx0XHRcdFx0aWYgKGZpbGVQYXRoLmluY2x1ZGVzKEZpbGVCYXNlTmFtZSkpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0Y29uc3QgQXR0YWNoRmlsZTogVEZpbGUgPVxuXHRcdFx0XHRcdFx0XHRhcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGZpbGVQYXRoKSBhcyBURmlsZTtcblx0XHRcdFx0XHRcdGlmIChBdHRhY2hGaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIEF0dGFjaEZpbGU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoYCBjYW5ub3QgZ2V0IHRoZSBpbWFnZSBmaWxlYCk7XG5cdFx0XHRcdFx0XHRjb25zb2xlLmVycm9yKGVycm9yKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8qKlxuICogXHU1MjIwXHU5NjY0XHU2MzA3XHU1QjlBXHU5NjQ0XHU0RUY2XHU2NTg3XHU0RUY2XG4gKlxuICogQHBhcmFtIGZpbGUgIFx1NjMwN1x1NUI5QVx1NzY4NFx1OTY0NFx1NEVGNlx1NjU4N1x1NEVGNlxuICogQHBhcmFtIHBsdWdpbiBcdTVGNTNcdTUyNERcdTYzRDJcdTRFRjZcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBjb25zdCBQdXJlQ2xlYXJBdHRhY2htZW50ID0gYXN5bmMgKFxuXHRmaWxlOiBURmlsZSxcblx0dGFyZ2V0X3R5cGU6IHN0cmluZyxcblx0cGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luXG4pID0+IHtcblx0Y29uc3QgZGVsZXRlT3B0aW9uID0gcGx1Z2luLnNldHRpbmdzLmRlbGV0ZU9wdGlvbjtcblx0Y29uc3QgZGVsRmlsZUZvbGRlciA9IG9ubHlPbmVGaWxlRXhpc3RzKGZpbGUpO1xuXHRjb25zdCBmaWxlRm9sZGVyID0gZ2V0RmlsZVBhcmVudEZvbGRlcihmaWxlKSBhcyBURm9sZGVyO1xuXHRsZXQgbmFtZSA9IHRhcmdldF90eXBlPT0naW1nJyA/ICdJbWFnZScgOiAnRmlsZSc7XG5cdHRyeSB7XG5cdFx0aWYgKGRlbGV0ZU9wdGlvbiA9PT0gXCIudHJhc2hcIikge1xuXHRcdFx0YXdhaXQgYXBwLnZhdWx0LnRyYXNoKGZpbGUsIGZhbHNlKTtcblx0XHRcdG5ldyBOb3RpY2UoXG5cdFx0XHRcdG5hbWUgKyBcIiBtb3ZlZCB0byBPYnNpZGlhbiBUcmFzaCAhXCIsXG5cdFx0XHRcdFNVQ0NFU1NfTk9USUNFX1RJTUVPVVRcblx0XHRcdCk7XG5cdFx0XHRpZiAoZGVsRmlsZUZvbGRlcikge1xuXHRcdFx0XHRhd2FpdCBhcHAudmF1bHQudHJhc2goZmlsZUZvbGRlciwgZmFsc2UpO1xuXHRcdFx0XHRuZXcgTm90aWNlKFwiQXR0YWNobWVudCBmb2xkZXIgaGF2ZSBiZWVuIGRlbGV0ZWQhXCIsIDMwMDApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoZGVsZXRlT3B0aW9uID09PSBcInN5c3RlbS10cmFzaFwiKSB7XG5cdFx0XHRhd2FpdCBhcHAudmF1bHQudHJhc2goZmlsZSwgdHJ1ZSk7XG5cdFx0XHRuZXcgTm90aWNlKG5hbWUgKyBcIiBtb3ZlZCB0byBTeXN0ZW0gVHJhc2ggIVwiLCBTVUNDRVNTX05PVElDRV9USU1FT1VUKTtcblx0XHRcdGlmIChkZWxGaWxlRm9sZGVyKSB7XG5cdFx0XHRcdGF3YWl0IGFwcC52YXVsdC50cmFzaChmaWxlRm9sZGVyLCB0cnVlKTtcblx0XHRcdFx0bmV3IE5vdGljZShcIkF0dGFjaG1lbnQgZm9sZGVyIGhhdmUgYmVlbiBkZWxldGVkIVwiLCAzMDAwKTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKGRlbGV0ZU9wdGlvbiA9PT0gXCJwZXJtYW5lbnRcIikge1xuXHRcdFx0YXdhaXQgYXBwLnZhdWx0LmRlbGV0ZShmaWxlKTtcblx0XHRcdG5ldyBOb3RpY2UobmFtZSArIFwiIGRlbGV0ZWQgUGVybWFuZW50bHkgIVwiLCBTVUNDRVNTX05PVElDRV9USU1FT1VUKTtcblx0XHRcdGlmIChkZWxGaWxlRm9sZGVyKSB7XG5cdFx0XHRcdGF3YWl0IGFwcC52YXVsdC5kZWxldGUoZmlsZUZvbGRlciwgdHJ1ZSk7XG5cdFx0XHRcdG5ldyBOb3RpY2UoXCJBdHRhY2htZW50IGZvbGRlciBoYXZlIGJlZW4gZGVsZXRlZCFcIiwgMzAwMCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGNhdGNoIChlcnJvcikge1xuXHRcdGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuXHRcdG5ldyBOb3RpY2UoXCJGYWlsZCB0byBkZWxlbHRlIHRoZSBcIiArIG5hbWUgKyBcIiFcIiwgU1VDQ0VTU19OT1RJQ0VfVElNRU9VVCk7XG5cdH1cbn07XG5cblxuZXhwb3J0IGNvbnN0IGhhbmRsZXJEZWxGaWxlTmV3ID0gKFxuXHRGaWxlQmFzZU5hbWU6IHN0cmluZyxcblx0Y3VycmVudE1kOiBURmlsZSxcblx0cGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luLFxuXHR0YXJnZXRfdHlwZTogc3RyaW5nLFxuXHR0YXJnZXRfcG9zOiBudW1iZXIsXG5cdGluX3RhYmxlOiBib29sZWFuLFxuXHRpbl9jYWxsb3V0OiBib29sZWFuXG4pID0+IHtcblx0bGV0IGxvZ3M6IHN0cmluZ1tdO1xuXHRsZXQgbW9kYWw7XG5cdGNvbnN0IHRhcmdldF9maWxlID0gZ2V0RmlsZUJ5QmFzZU5hbWUoY3VycmVudE1kLCBGaWxlQmFzZU5hbWUpIGFzIFRGaWxlO1xuXHRjb25zdCByZWZJbmZvID0gY2hlY2tSZWZlcmVuY2VJbmZvKHRhcmdldF9maWxlLCBjdXJyZW50TWQpO1xuXHRsZXQgc3RhdGUgPSByZWZJbmZvLnN0YXRlO1xuXHRzd2l0Y2ggKHN0YXRlKSB7XG5cdFx0Y2FzZSAwOlxuXHRcdFx0Ly8gY2xlYXIgYXR0YWNobWVudCBkaXJlY3RseVxuXHRcdFx0ZGVsZXRlQ3VyVGFyZ2V0TGluayhGaWxlQmFzZU5hbWUsIHBsdWdpbiwgdGFyZ2V0X3R5cGUsIHRhcmdldF9wb3MsIGluX3RhYmxlLCBpbl9jYWxsb3V0KTtcblx0XHRcdFB1cmVDbGVhckF0dGFjaG1lbnQodGFyZ2V0X2ZpbGUsIHRhcmdldF90eXBlLCBwbHVnaW4pO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAxOlxuXHRcdGNhc2UgMjpcblx0XHRcdGRlbGV0ZUN1clRhcmdldExpbmsoRmlsZUJhc2VOYW1lLCBwbHVnaW4sIHRhcmdldF90eXBlLCB0YXJnZXRfcG9zLCBpbl90YWJsZSwgaW5fY2FsbG91dCk7XG5cdFx0XHQvLyByZWZlcmVuY2VkIGJ5IGVpdGhvciBvbmx5IG5vdGUgb3Igb3RoZXIgbXV0aXBsZSBub3RlcyBtb3JlIHRoYW4gb25jZVxuXHRcdFx0bG9ncyA9IHJlZkluZm8ubWRQYXRoIGFzIHN0cmluZ1tdO1xuXHRcdFx0Ly8gXHU3NTMxXHU0RThFXHU2NzA5XHU1MjJCXHU3Njg0XHU1RjE1XHU3NTI4XHVGRjBDXHU2MjQwXHU0RUU1XHU1M0VBXHU1MjIwXHU5NjY0XHU1RjUzXHU1MjREXHU3Njg0XHU1RjE1XHU3NTI4XHU5NEZFXHU2M0E1XHU4MDBDXHU0RTBEXHU1MjIwXHU5NjY0XHU2NTg3XHU0RUY2XG5cdFx0XHRuZXcgTm90aWNlKFwiQXMgb3RoZXIgcmVmZXJlbmNlcyBvZiBjdXJyZW50IGZpbGUgZXhpc3QsIFwiICsgXG5cdFx0XHRcdFwianVzdCBkZWxldGVkIHRoZSBjdXJyZW50IHJlZmVyZW5jZSBsaW5rIHdpdGhvdXQgZGVsZXRpbmcgdGhlIGFjdHVhbCBmaWxlLlwiLCBcblx0XHRcdFx0MzUwMCk7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdGJyZWFrO1xuXHR9XG59XG5cbi8vIFx1NTk4Mlx1Njc5Q1x1NjYyRiB0eXBlIFx1NjYyRiBcImltZ1wiXHVGRjBDXHU1QzMxXHU1MUM2XHU3ODZFXHU1MjIwXHU5NjY0XHU1NkZFXHU3MjQ3XHU1RjE1XHU3NTI4XHU5NEZFXHU2M0E1XHU3Njg0XHU5MEU4XHU1MjA2XHVGRjBDXHU1OTgyXHU2NzlDXHU2NjJGXHU1MTc2XHU0RUQ2XHU3QzdCXHU1NzhCXHVGRjBDXHU3NkY0XHU2M0E1XHU1MjIwXHU5NjY0XHU2NTc0XHU4ODRDXG4vLyB0YXJnZXRfbGluZSBcdUZGMDgxLWJhc2VkXHVGRjA5IFx1NTQ4QyB0YXJnZXRfY2ggXHU2NjJGXHU2MzA3XHU3OTNBXHU5NjQ0XHU0RUY2XHU2MjQwXHU1NzI4XHU3Njg0XHU0RjREXHU3RjZFXG5leHBvcnQgY29uc3QgZGVsZXRlQ3VyVGFyZ2V0TGluayA9IChcblx0ZmlsZV9iYXNlX25hbWU6IHN0cmluZyxcblx0cGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luLFxuXHR0YXJnZXRfdHlwZTogc3RyaW5nLFxuXHR0YXJnZXRfcG9zOiBudW1iZXIsXG5cdGluX3RhYmxlOiBib29sZWFuLFxuXHRpbl9jYWxsb3V0OiBib29sZWFuXG4pID0+IHtcblx0ZmlsZV9iYXNlX25hbWUgPSBmaWxlX2Jhc2VfbmFtZS5zdGFydHNXaXRoKCcvJykgPyBmaWxlX2Jhc2VfbmFtZS5zdWJzdHJpbmcoMSk6ZmlsZV9iYXNlX25hbWU7XG5cdGNvbnN0IGFjdGl2ZVZpZXcgPSBwbHVnaW4uYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldykgYXMgTWFya2Rvd25WaWV3O1xuXHRjb25zdCBlZGl0b3IgPSBhY3RpdmVWaWV3LmVkaXRvcjtcblx0Ly8gIEB0cy1leHBlY3QtZXJyb3IsIG5vdCB0eXBlZFxuXHRjb25zdCBlZGl0b3JWaWV3ID0gZWRpdG9yLmNtIGFzIEVkaXRvclZpZXc7XG5cblx0bGV0IHRhcmdldF9saW5lID0gZWRpdG9yVmlldy5zdGF0ZS5kb2MubGluZUF0KHRhcmdldF9wb3MpO1xuXHRsZXQgbGluZV90ZXh0ID0gdGFyZ2V0X2xpbmUudGV4dDtcblxuXHRpZiAoIWluX3RhYmxlICYmICFpbl9jYWxsb3V0KXtcblx0XHRsZXQgZmluZHMgPSBmaW5kTGlua0luTGluZShmaWxlX2Jhc2VfbmFtZSwgbGluZV90ZXh0KTtcblx0XHRpZiAoZmluZHMubGVuZ3RoID09IDApe1xuXHRcdFx0bmV3IE5vdGljZShcIkZhaWwgdG8gZmluZCB0aGUgbGluay10ZXh0LCBwbGVhc2UgZGVsZXRlIGl0IG1hbnVhbGx5IVwiLCAwKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZWxzZSBpZihmaW5kcy5sZW5ndGggIT0gMSl7XG5cdFx0XHRuZXcgTm90aWNlKFwiRmluZCBtdWx0aXBsZSBzYW1lIExpbmsgaW4gY3VycmVudCBsaW5lLCBwbGVhc2UgZGVsZXRlIGl0IG1hbnVhbGx5IVwiLCAwKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0ZWxzZXtcblx0XHRcdC8vIGVkaXRvclZpZXcuZGlzcGF0Y2goe2NoYW5nZXM6IHtmcm9tOiB0YXJnZXRfbGluZS5mcm9tICsgZmluZHNbMF1bMF0sIHRvOiB0YXJnZXRfbGluZS5mcm9tICsgZmluZHNbMF1bMV0sIGluc2VydDogJyd9fSk7XG5cdFx0XHRlZGl0b3IucmVwbGFjZVJhbmdlKCcnLCB7bGluZTogdGFyZ2V0X2xpbmUubnVtYmVyLTEsIGNoOiBmaW5kc1swXVswXX0sIHtsaW5lOiB0YXJnZXRfbGluZS5udW1iZXItMSwgY2g6IGZpbmRzWzBdWzFdfSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHR9XG5cblx0dHlwZSBSZWdEaWN0aW9uYXJ5ID0ge1xuXHRcdFtrZXk6IHN0cmluZ106IFJlZ0V4cDtcblx0fTtcblx0XG5cdGxldCBzdGFydFJlZzogUmVnRGljdGlvbmFyeSA9IHtcblx0XHQndGFibGUnOiAvXlxccypcXHwvLFxuXHRcdCdjYWxsb3V0JzogL14+Lyxcblx0fTtcblxuXHRsZXQgbW9kZSA9IGluX3RhYmxlID8gJ3RhYmxlJyA6ICdjYWxsb3V0Jztcblx0bGV0IGZpbmRzX2xpbmVzOiBudW1iZXJbXSA9IFtdO1xuXHRsZXQgZmluZHNfYWxsOiBbZnJvbTpudW1iZXIsIHRvOm51bWJlcl1bXSA9IFtdO1xuXHRmb3IgKGxldCBpPXRhcmdldF9saW5lLm51bWJlcjsgaTw9ZWRpdG9yLmxpbmVDb3VudCgpOyBpKyspe1xuXHRcdGxldCBsaW5lX3RleHQgPSBlZGl0b3IuZ2V0TGluZShpLTEpO1xuXHRcdGlmICghc3RhcnRSZWdbbW9kZV0udGVzdChsaW5lX3RleHQpKSBicmVhaztcblx0XHRwcmludChgbGluZV8ke2l9X3RleHQ6YCwgbGluZV90ZXh0KVxuXHRcdGxldCBmaW5kcyA9IGZpbmRMaW5rSW5MaW5lKGZpbGVfYmFzZV9uYW1lLCBsaW5lX3RleHQpO1xuXHRcdGlmIChmaW5kcy5sZW5ndGggPiAwKXtcblx0XHRcdGZpbmRzX2xpbmVzLnB1c2goLi4ubmV3IEFycmF5KGZpbmRzLmxlbmd0aCkuZmlsbChpKSk7XG5cdFx0XHRmaW5kc19hbGwucHVzaCguLi5maW5kcyk7XG5cdFx0fVxuXHR9XG5cblx0Zm9yIChsZXQgaT10YXJnZXRfbGluZS5udW1iZXItMTsgaT49MTsgaS0tKXtcblx0XHRsZXQgbGluZV90ZXh0ID0gZWRpdG9yLmdldExpbmUoaS0xKTtcblx0XHRpZiAoIXN0YXJ0UmVnW21vZGVdLnRlc3QobGluZV90ZXh0KSkgYnJlYWs7XG5cdFx0cHJpbnQoYGxpbmVfJHtpfV90ZXh0OmAsIGxpbmVfdGV4dClcblx0XHRsZXQgZmluZHMgPSBmaW5kTGlua0luTGluZShmaWxlX2Jhc2VfbmFtZSwgbGluZV90ZXh0KTtcblx0XHRpZiAoZmluZHMubGVuZ3RoID4gMCl7XG5cdFx0XHRmaW5kc19saW5lcy5wdXNoKC4uLm5ldyBBcnJheShmaW5kcy5sZW5ndGgpLmZpbGwoaSkpO1xuXHRcdFx0ZmluZHNfYWxsLnB1c2goLi4uZmluZHMpO1xuXHRcdH1cblx0fVxuXG5cdGlmIChmaW5kc19hbGwubGVuZ3RoID09IDApe1xuXHRcdG5ldyBOb3RpY2UoYEZhaWwgdG8gZmluZCB0aGUgbGluay10ZXh0IChmb3IgbGlua3MgaW4gJHttb2RlfSksIHBsZWFzZSBkZWxldGUgaXQgbWFudWFsbHkhYCwgMCk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGVsc2UgaWYoZmluZHNfYWxsLmxlbmd0aCAhPSAxKXtcblx0XHRuZXcgTm90aWNlKGBGaW5kIG11bHRpcGxlIHNhbWUgTGluayBpbiBjdXJyZW50ICR7bW9kZX0sIHBsZWFzZSBkZWxldGUgaXQgbWFudWFsbHkhYCwgMCk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGVsc2V7XG5cdFx0ZWRpdG9yLnJlcGxhY2VSYW5nZSgnJywge2xpbmU6IGZpbmRzX2xpbmVzWzBdLTEsIGNoOiBmaW5kc19hbGxbMF1bMF19LCB7bGluZTogZmluZHNfbGluZXNbMF0tMSwgY2g6IGZpbmRzX2FsbFswXVsxXX0pO1xuXHR9XG5cblx0ZWRpdG9yLmZvY3VzKCk7XG59XG5cbi8vIGNvcHkgaW1nIGZpbGUgdG8gY2xpcGJvYXJkXG5leHBvcnQgY29uc3QgaGFuZGxlckNvcHlGaWxlID0gYXN5bmMgKFxuXHRGaWxlQmFzZU5hbWU6IHN0cmluZyxcblx0Y3VycmVudE1kOiBURmlsZSxcblx0cGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luXG4pID0+IHtcblx0Y29uc3QgZmlsZSA9IGdldEZpbGVCeUJhc2VOYW1lKGN1cnJlbnRNZCwgRmlsZUJhc2VOYW1lKSBhcyBURmlsZTtcblx0Y29uc3QgYmFzZVBhdGggPSAoZmlsZS52YXVsdC5hZGFwdGVyIGFzIGFueSkuYmFzZVBhdGhcblx0Y29uc3QgZmlsZV9hYl9wYXRoID0gYmFzZVBhdGggKyAnLycgKyBmaWxlLnBhdGhcblxuXHR0cnl7XG5cdFx0Y29weUZpbGVUb0NsaXBib2FyZENNRChmaWxlX2FiX3BhdGgpO1xuXHRcdG5ldyBOb3RpY2UoXCJDb3BpZWQgdG8gY2xpcGJvYXJkICFcIiwgU1VDQ0VTU19OT1RJQ0VfVElNRU9VVCk7XG5cdH1cblx0Y2F0Y2ggKGVycm9yKSB7XG5cdFx0Y29uc29sZS5lcnJvcihlcnJvcik7XG5cdFx0bmV3IE5vdGljZShcIkZhaWxkIHRvIGNvcHkgdGhlIGZpbGUgIVwiLCBTVUNDRVNTX05PVElDRV9USU1FT1VUKTtcblx0fVxufVxuXG5leHBvcnQgY29uc3QgaGFuZGxlck1vdmVGaWxlID0gYXN5bmMgKFxuXHRGaWxlQmFzZU5hbWU6IHN0cmluZyxcblx0Y3VycmVudE1kOiBURmlsZSxcblx0cGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luXG4pID0+IHtcblx0Y29uc3QgdGFyZ2V0X2ZpbGUgPSBnZXRGaWxlQnlCYXNlTmFtZShjdXJyZW50TWQsIEZpbGVCYXNlTmFtZSkgYXMgVEZpbGU7XG5cdG5ldyBtb3ZlRmlsZVRvRm9sZGVyU3VnZ2VzdGVyKHBsdWdpbi5hcHAsIHRhcmdldF9maWxlKS5vcGVuKCk7XG59XG5cbi8qKlxuICpcbiAqIEBwYXJhbSBmaWxlIHRhcmdldCBkZWxldGVkIGZpbGVcbiAqIEByZXR1cm5zIHBhcmVudCBmb2xkZXIgb3IgdW5kZWZpZW5kXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRGaWxlUGFyZW50Rm9sZGVyID0gKGZpbGU6IFRGaWxlKTogVEZvbGRlciB8IHVuZGVmaW5lZCA9PiB7XG5cdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcblx0XHRpZiAoZmlsZS5wYXJlbnQgaW5zdGFuY2VvZiBURm9sZGVyKSB7XG5cdFx0XHRyZXR1cm4gZmlsZS5wYXJlbnQ7XG5cdFx0fVxuXHR9XG5cdHJldHVybjtcbn07XG4vKipcbiAqXG4gKiBAcGFyYW0gZmlsZVxuICogQHJldHVybnNcbiAqL1xuY29uc3Qgb25seU9uZUZpbGVFeGlzdHMgPSAoZmlsZTogVEZpbGUpOiBib29sZWFuID0+IHtcblx0Y29uc3QgZmlsZUZvbGRlciA9IGdldEZpbGVQYXJlbnRGb2xkZXIoZmlsZSkgYXMgVEZvbGRlcjtcblx0cmV0dXJuIGZpbGVGb2xkZXIuY2hpbGRyZW4ubGVuZ3RoID09PSAxO1xufTtcblxuXG4vLyBcdThDMDNcdTc1MjhcdTdDRkJcdTdFREZcdTU0N0RcdTRFRTRcdTU5MERcdTUyMzZcdTY1ODdcdTRFRjZcdTUyMzBcdTdDRkJcdTdFREZcdTUyNkFcdThEMzRcdTY3N0ZcbmZ1bmN0aW9uIGNvcHlGaWxlVG9DbGlwYm9hcmRDTUQoZmlsZVBhdGg6IHN0cmluZykge1xuXG5cdGlmICghZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmlsZSAke2ZpbGVQYXRofSBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2FsbGJhY2sgPSAoZXJyb3I6IEVycm9yIHwgbnVsbCwgc3Rkb3V0OiBzdHJpbmcsIHN0ZGVycjogc3RyaW5nKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuXHRcdFx0bmV3IE5vdGljZShgRXJyb3IgZXhlY3V0aW5nIGNvbW1hbmQ6ICR7ZXJyb3IubWVzc2FnZX1gLCBTVUNDRVNTX05PVElDRV9USU1FT1VUKTtcblx0XHRcdGNvbnNvbGUuZXJyb3IoYEVycm9yIGV4ZWN1dGluZyBjb21tYW5kOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG5cdFx0XHRyZXR1cm47XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHByb2Nlc3MucGxhdGZvcm0gPT09ICdkYXJ3aW4nKSB7XG5cdFx0Ly8gXHU4OUUzXHU1MUIzXHU2NUI5XHU2ODQ4MTogXHU0RjFBXHU4QzAzXHU1MUZBRmluZGVyXHVGRjBDXHU0RUE3XHU3NTFGXHU3N0FDXHU5NUY0XHU3Njg0XHU3QTk3XHU1M0UzXHVGRjBDXHU0RjQ2XHU2NjJGXHU4QkU1XHU1OTBEXHU1MjM2XHU2NENEXHU0RjVDXHU1QjhDXHU1MTY4XHU2NjJGXHU3Q0ZCXHU3RURGXHU3RUE3XHU1MjJCXHU3Njg0XHVGRjBDXHU2Q0ExXHU2NzA5XHU0RUZCXHU0RjU1XHU5NjUwXHU1MjM2XG5cdFx0ZXhlY1N5bmMoYG9wZW4gLVIgXCIke2ZpbGVQYXRofVwiYCk7XG4gICAgICAgIGV4ZWNTeW5jKGBvc2FzY3JpcHQgLWUgJ3RlbGwgYXBwbGljYXRpb24gXCJTeXN0ZW0gRXZlbnRzXCIgdG8ga2V5c3Ryb2tlIFwiY1wiIHVzaW5nIGNvbW1hbmQgZG93bidgKTtcbiAgICAgICAgZXhlY1N5bmMoYG9zYXNjcmlwdCAtZSAndGVsbCBhcHBsaWNhdGlvbiBcIlN5c3RlbSBFdmVudHNcIiB0byBrZXlzdHJva2UgXCJ3XCIgdXNpbmcgY29tbWFuZCBkb3duJ2ApO1xuXHRcdGV4ZWNTeW5jKGBvcGVuIC1hIFwiT2JzaWRpYW4uYXBwXCJgKTtcblxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHQvLyBcdTZENEJcdThCRDVcdTUyMDdcdTYzNjJcdThGOTNcdTUxNjVcdTZDRDVcdTY1QjlcdTY4NDg6IFx1NkEyMVx1NjJERlNoaWZ0XHU5NTJFXHU2MzA5XHU0RTBCXHVGRjBDXHU0RjQ2XHU2NjJGXHU1OTMxXHU4RDI1XHU0RTg2XG5cdFx0Ly8gZXhlY1N5bmMoYG9zYXNjcmlwdCAtZSAndGVsbCBhcHBsaWNhdGlvbiBcIlN5c3RlbSBFdmVudHNcIiB0byBrZXkgZG93biBzaGlmdCdgKTtcblx0XHQvLyBleGVjU3luYyhgb3Nhc2NyaXB0IC1lICdkZWxheSAwLjA1J2ApO1xuXHRcdC8vIGV4ZWNTeW5jKGBvc2FzY3JpcHQgLWUgJ3RlbGwgYXBwbGljYXRpb24gXCJTeXN0ZW0gRXZlbnRzXCIgdG8ga2V5IHVwIHNoaWZ0J2ApO1xuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHQvLyBcdTUzRTZcdTRFMDBcdTc5Q0RcdTg5RTNcdTUxQjNcdTY1QjlcdTY4NDhcdUZGMENcdTRFMERcdTRGMUFcdThDMDNcdTUxRkFGaW5kZXJcdUZGMENcdTRGNDZcdTY2MkZcdTU5MERcdTUyMzZcdTc2ODRcdTY1ODdcdTRFRjZcdTY1RTBcdTZDRDVcdTdDOThcdThEMzRcdTUyMzB3b3JkXHU2MjE2XHU4MDA1XHU1RkFFXHU0RkUxXHU0RTJEXG5cdFx0Ly8gY29uc3QgYXBwbGVTY3JpcHQgPSBgXG5cdFx0Ly8gXHRvbiBydW4gYXJnc1xuXHRcdC8vIFx0XHRzZXQgdGhlIGNsaXBib2FyZCB0byBQT1NJWCBmaWxlIChmaXJzdCBpdGVtIG9mIGFyZ3MpXG5cdFx0Ly8gXHRlbmRcblx0XHQvLyBcdGA7XG5cdFx0Ly8gZXhlYyhgb3Nhc2NyaXB0IC1lICcke2FwcGxlU2NyaXB0fScgXCIke2ZpbGVQYXRofVwiYCwgY2FsbGJhY2spO1xuXHRcdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ2xpbnV4Jykge1xuXHRcdC8vIFx1NzZFRVx1NTI0RFx1NjVCOVx1Njg0OFxuXHRcdC8vIHhjbGlwIC1zZWxlY3Rpb24gY2xpcGJvYXJkIC10ICQoZmlsZSAtLW1pbWUtdHlwZSAtYiAvcGF0aC90by95b3VyL2ZpbGUpIC1pIC9wYXRoL3RvL3lvdXIvZmlsZVxuICAgICAgICAvLyBleGVjKGB4Y2xpcCAtc2VsZWN0aW9uIGMgPCAke2ZpbGVQYXRofWAsIGNhbGxiYWNrKTtcblx0XHQvLyBleGVjKGB4Y2xpcCAtc2VsZWN0aW9uIGNsaXBib2FyZCAtdCAkKGZpbGUgLS1taW1lLXR5cGUgLWIgXCIke2ZpbGVQYXRofVwiKSAtaSBcIiR7ZmlsZVBhdGh9XCJgLCBjYWxsYmFjayk7XG4gICAgfSBlbHNlIGlmIChwcm9jZXNzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG5cdFx0Ly8gXHU1RjUzXHU2NTg3XHU0RUY2XHU4REVGXHU1Rjg0XHU1MzA1XHU1NDJCICdcblx0XHQvLyBcdTU3MjhQb3dlclNoZWxsXHU0RTJEXHVGRjBDXHU1MzU1XHU1RjE1XHU1M0Y3XHU1QjU3XHU3QjI2XHU0RTMyXHU2NjJGXHU3NkY0XHU2M0E1XHU3Njg0XHU1QjU3XHU3QjI2XHU0RTMyXHVGRjBDXHU1MTg1XHU5MEU4XHU3Njg0XHU1MzU1XHU1RjE1XHU1M0Y3XHU2NUUwXHU2Q0Q1XHU5MDFBXHU4RkM3XHU1M0NEXHU2NTlDXHU3RUJGXHU2NzY1XHU4RjZDXHU0RTQ5XHVGRjBDXHU0RjQ2XHU2NjJGXHU1M0VGXHU0RUU1XHU5MDFBXHU4RkM3XHU1NzI4XHU1MzU1XHU1RjE1XHU1M0Y3XHU1MjREXHU1MThEXHU1MkEwXHU0RTAwXHU0RTJBXHU1MzU1XHU1RjE1XHU1M0Y3XHU2NzY1XHU4RkRCXHU4ODRDXHU4RjZDXHU0RTQ5XHUzMDAyXG5cdFx0bGV0IHNhZmVGaWxlUGF0aCA9IGZpbGVQYXRoLnJlcGxhY2UoLycvZywgXCInJ1wiKTtcbiAgICAgICAgZXhlYyhgcG93ZXJzaGVsbCAtY29tbWFuZCBcIlNldC1DbGlwYm9hcmQgLVBhdGggJyR7c2FmZUZpbGVQYXRofSdcImAsIGNhbGxiYWNrKTtcbiAgICB9XG59XG5cbmNvbnN0IGZpbmRMaW5rSW5MaW5lID0gKGZpbGVfbmFtZTogc3RyaW5nLCBsaW5lX3RleHQ6IHN0cmluZykgPT57XG5cdGNvbnN0IGZpbGVfbmFtZV9tZGxpbmsgPSBmaWxlX25hbWUucmVwbGFjZSgvIC9nLCAnJTIwJyk7XG5cdGxldCByZWdXaWtpTGluayA9IC9cXCFcXFtcXFtbXlxcW1xcXV0qP1xcXVxcXS9nO1xuICAgIGxldCByZWdNZExpbmsgPSAvXFwhXFxbW15cXFtcXF1dKj9cXF1cXChbXlxcc1xcKVxcKFxcW1xcXVxce1xcfSddKlxcKS9nO1xuXHRwcmludCgndGFyZ2V0X25hbWUgKFdJS0kvTUQpOicsIGZpbGVfbmFtZSwgZmlsZV9uYW1lX21kbGluaylcblxuXHQvLyBjb25zb2xlLmxvZygnc2VhcmNoIGluIGxpbmVfdGV4dDonLCBsaW5lX3RleHQpXG5cdGxldCBzZWFyY2hfcmVzdWx0OiBbZnJvbTpudW1iZXIsIHRvOm51bWJlcl1bXSA9IFtdXG5cdGlmIChsaW5lX3RleHQuaW5jbHVkZXMoZmlsZV9uYW1lKSl7XG5cdFx0d2hpbGUodHJ1ZSl7XG5cdFx0XHRsZXQgbWF0Y2ggPSByZWdXaWtpTGluay5leGVjKGxpbmVfdGV4dCk7XG5cdFx0XHRpZighbWF0Y2gpIGJyZWFrO1xuXHRcdFx0bGV0IG1hdGNoZWRfbGluayA9IG1hdGNoWzBdO1xuXHRcdFx0cHJpbnQoJ21hdGNoZWRfbGluazonLCBtYXRjaGVkX2xpbmspXG5cdFx0XHRwcmludCgnbWF0Y2hlZF9saW5rLmluY2x1ZGVzKGZpbGVfbmFtZSknLCBtYXRjaGVkX2xpbmsuaW5jbHVkZXMoZmlsZV9uYW1lKSlcblx0XHRcdGlmIChtYXRjaGVkX2xpbmsuaW5jbHVkZXMoZmlsZV9uYW1lKSl7XG5cdFx0XHRcdHNlYXJjaF9yZXN1bHQucHVzaChbbWF0Y2guaW5kZXgsIG1hdGNoLmluZGV4K21hdGNoZWRfbGluay5sZW5ndGhdKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAobGluZV90ZXh0LmluY2x1ZGVzKGZpbGVfbmFtZV9tZGxpbmspKXtcblx0XHR3aGlsZSh0cnVlKXtcblx0XHRcdGxldCBtYXRjaCA9IHJlZ01kTGluay5leGVjKGxpbmVfdGV4dCk7XG5cdFx0XHRpZighbWF0Y2gpIGJyZWFrO1xuXHRcdFx0bGV0IG1hdGNoZWRfbGluayA9IG1hdGNoWzBdO1xuXHRcdFx0cHJpbnQoJ21hdGNoZWRfbGluazonLCBtYXRjaGVkX2xpbmspXG5cdFx0XHRwcmludCgnbWF0Y2hlZF9saW5rLmluY2x1ZGVzKGZpbGVfbmFtZV9tZGxpbmspJywgbWF0Y2hlZF9saW5rLmluY2x1ZGVzKGZpbGVfbmFtZV9tZGxpbmspKVxuXHRcdFx0aWYgKG1hdGNoZWRfbGluay5pbmNsdWRlcyhmaWxlX25hbWVfbWRsaW5rKSl7XG5cdFx0XHRcdHNlYXJjaF9yZXN1bHQucHVzaChbbWF0Y2guaW5kZXgsIG1hdGNoLmluZGV4K21hdGNoZWRfbGluay5sZW5ndGhdKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIHNlYXJjaF9yZXN1bHQ7XG59XG5cblxuZXhwb3J0IGNvbnN0IGhhbmRsZXJSZW5hbWVGaWxlID0gKFxuXHRGaWxlQmFzZU5hbWU6IHN0cmluZyxcblx0Y3VycmVudE1kOiBURmlsZSxcblx0cGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luXG4pID0+IHtcblx0Y29uc3QgdGFyZ2V0X2ZpbGUgPSBnZXRGaWxlQnlCYXNlTmFtZShjdXJyZW50TWQsIEZpbGVCYXNlTmFtZSkgYXMgVEZpbGU7XG5cdGxldCBwYXRoID0gdGFyZ2V0X2ZpbGUucGF0aDtcblx0bGV0IG5hbWUgPSB0YXJnZXRfZmlsZS5uYW1lO1xuXHRsZXQgdGFyZ2V0X2ZvbGRlciA9IHBhdGguc3Vic3RyaW5nKDAsIHBhdGgubGVuZ3RoLW5hbWUubGVuZ3RoKTtcblx0bGV0IGZpbGVfdHlwZSA9IG5hbWUuc3BsaXQoJy4nKS5wb3AoKSBhcyBzdHJpbmc7XG5cdG5ldyBSZW5hbWVNb2RhbChwbHVnaW4uYXBwLCBcblx0XHR0YXJnZXRfZm9sZGVyLCBcblx0XHRuYW1lLnN1YnN0cmluZygwLCBuYW1lLmxlbmd0aC1maWxlX3R5cGUubGVuZ3RoLTEpLCBcblx0XHRmaWxlX3R5cGUsIFxuXHRcdChyZXN1bHQpID0+IHtcblx0XHRpZiAoIXJlc3VsdCkgcmV0dXJuO1xuXHRcdGlmKHJlc3VsdD09cGF0aCkgcmV0dXJuO1xuXHRcdGFwcC52YXVsdC5hZGFwdGVyLmV4aXN0cyhyZXN1bHQpXG5cdFx0LnRoZW4oKGV4aXN0cykgPT4ge1xuXHRcdFx0aWYoZXhpc3RzKSB7XG5cdFx0XHRcdG5ldyBOb3RpY2UoYEZhaWwgdG8gcmVuYW1lIGZvciB0aGVyZSBhbHJlYXkgZXhpc3QgZmlsZSAke3Jlc3VsdH1gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBsdWdpbi5hcHAuZmlsZU1hbmFnZXIucmVuYW1lRmlsZSh0YXJnZXRfZmlsZSwgYCR7cmVzdWx0fWApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KS5vcGVuKCk7XG59XG5cblxuXG5leHBvcnQgY2xhc3MgUmVuYW1lTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdHJlc3VsdDogc3RyaW5nO1xuXHRmb2xkZXI6IHN0cmluZztcblx0bmFtZTogc3RyaW5nO1xuXHRmaWxldHlwZTogc3RyaW5nO1xuXHRvblN1Ym1pdDogKHJlc3VsdDogc3RyaW5nKSA9PiB2b2lkO1xuICBcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIGZvbGRlcjpzdHJpbmcsIG5hbWU6c3RyaW5nLCBmaWxldHlwZTpzdHJpbmcsIG9uU3VibWl0OiAocmVzdWx0OiBzdHJpbmcpID0+IHZvaWQpIHtcblx0ICBzdXBlcihhcHApO1xuXHQgIHRoaXMub25TdWJtaXQgPSBvblN1Ym1pdDtcblx0ICB0aGlzLmZvbGRlciA9IGZvbGRlcjtcblx0ICB0aGlzLm5hbWUgPSBuYW1lO1xuXHQgIHRoaXMuZmlsZXR5cGUgPSBmaWxldHlwZTtcblx0fVxuICBcblx0b25PcGVuKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuXHRcdGxldCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGVudEVsKVxuXHRcdFx0LnNldE5hbWUoXCJSZW5hbWU6XCIpXG5cdFx0XHQuYWRkVGV4dCh0ZXh0ID0+IHRleHRcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMubmFtZSlcblx0XHRcdFx0Lm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucmVzdWx0ID0gYCR7dGhpcy5mb2xkZXJ9JHt2YWx1ZX0uJHt0aGlzLmZpbGV0eXBlfWA7XG5cdFx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdC8vIFx1NEY3RiBET00gXHU2NzA5XHU4REIzXHU1OTFGXHU3Njg0XHU2NUY2XHU5NUY0XHU2RTMyXHU2N0QzXHU4ODY4XHU1MzU1XHU1MTQzXHU3RDIwXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRsZXQgaW5wdXRCb3ggPSBzZXR0aW5nLnNldHRpbmdFbC5xdWVyeVNlbGVjdG9yKCdpbnB1dFt0eXBlPVwidGV4dFwiXScpO1xuXHRcdFx0aWYgKGlucHV0Qm94ICYmIGlucHV0Qm94LnBhcmVudEVsZW1lbnQpIHtcblx0XHRcdFx0bGV0IGZvbGRlcl9pbmRpY2F0b3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuXHRcdFx0XHRmb2xkZXJfaW5kaWNhdG9yLmlubmVyVGV4dCA9IGAke3RoaXMuZm9sZGVyfWA7XG5cdFx0XHRcdGZvbGRlcl9pbmRpY2F0b3Iuc3R5bGUubWFyZ2luUmlnaHQgPSAnNHB4JzsgIC8vIFx1NTNFRlx1NEVFNVx1NjgzOVx1NjM2RVx1OTcwMFx1ODk4MVx1OEMwM1x1NjU3NFx1OTVGNFx1OERERFxuXHRcdFx0XHRpbnB1dEJveC5wYXJlbnRFbGVtZW50Lmluc2VydEJlZm9yZShmb2xkZXJfaW5kaWNhdG9yLCBpbnB1dEJveCk7XG5cblx0XHRcdFx0bGV0IGZpbGVfdHlwZV9pbmRpY2F0b3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuXHRcdFx0XHRmaWxlX3R5cGVfaW5kaWNhdG9yLmlubmVyVGV4dCA9IGAuJHt0aGlzLmZpbGV0eXBlfWA7XG5cdFx0XHRcdGZpbGVfdHlwZV9pbmRpY2F0b3Iuc3R5bGUubWFyZ2luTGVmdCA9ICc0cHgnOyAgLy8gXHU1M0VGXHU0RUU1XHU2ODM5XHU2MzZFXHU5NzAwXHU4OTgxXHU4QzAzXHU2NTc0XHU5NUY0XHU4REREXG5cdFx0XHRcdGlucHV0Qm94LmFmdGVyKGZpbGVfdHlwZV9pbmRpY2F0b3IpO1xuXG5cdFx0XHRcdC8vIFx1ODNCN1x1NTNENlx1OEJCRVx1N0Y2RVx1NzU0Q1x1OTc2Mlx1NzY4NFx1NEUwQVx1N0VBN1x1NTE0M1x1N0QyMCBcblx0XHRcdFx0bGV0IHBhcmVudEVsID0gc2V0dGluZy5zZXR0aW5nRWwucGFyZW50RWxlbWVudDtcblx0XHRcdFx0aWYgKHBhcmVudEVsKSB7XG5cdFx0XHRcdFx0Ly8gXHU0RjdGXHU1MTc2XHU1QjUwXHU1MTQzXHU3RDIwXHU1QzQ1XHU0RTJEXHU2NjNFXHU3OTNBXG5cdFx0XHRcdFx0cGFyZW50RWwuc3R5bGUuZGlzcGxheSA9ICdmbGV4Jztcblx0XHRcdFx0XHRwYXJlbnRFbC5zdHlsZS5qdXN0aWZ5Q29udGVudCA9ICdjZW50ZXInO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIFx1OEY2Q1x1NjM2MmlucHV0Qm94XHU3QzdCXHU1NzhCXHU1RTc2XHU5MDA5XHU2MkU5XHU4RjkzXHU1MTY1XHU2ODQ2XHU3Njg0XHU2NTg3XHU2NzJDXG5cdFx0XHRcdGxldCBpbnB1dEVsZW0gPSBpbnB1dEJveCBhcyBIVE1MSW5wdXRFbGVtZW50O1xuXHRcdFx0XHRpbnB1dEVsZW0uc2VsZWN0KCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zb2xlLmVycm9yKFwiXHU2NUUwXHU2Q0Q1XHU2MjdFXHU1MjMwXHU2NTg3XHU2NzJDXHU4RjkzXHU1MTY1XHU2ODQ2XCIpO1xuXHRcdFx0fVxuXHRcdH0sIDApO1xuXG5cdFx0Ly8gRW50ZXIgdG8gc3VibWl0XG5cdFx0dGhpcy5zY29wZS5yZWdpc3RlcihbXSwgXCJFbnRlclwiLCAoZXZ0OiBLZXlib2FyZEV2ZW50KSA9PiB7XG5cdFx0XHRpZiAoZXZ0LmlzQ29tcG9zaW5nKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdHRoaXMuY2xvc2UoKTtcblx0XHRcdHRoaXMub25TdWJtaXQodGhpcy5yZXN1bHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0b25DbG9zZSgpIHtcblx0XHRsZXQgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XG5cdH1cbn1cblxuXG5cbmNsYXNzIG1vdmVGaWxlVG9Gb2xkZXJTdWdnZXN0ZXIgZXh0ZW5kcyBGdXp6eVN1Z2dlc3RNb2RhbDxzdHJpbmc+IHtcblx0cHJpdmF0ZSBmb2xkZXJMaXN0OiBTZXQ8c3RyaW5nPjtcblx0dGFyZ2V0X2ZpbGU6IFRGaWxlO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBmaWxlOiBURmlsZSkge1xuXHRcdHN1cGVyKGFwcCk7XG5cdFx0dGhpcy5mb2xkZXJMaXN0ID0gdGhpcy5nZXRBbGxGb2xkZXJzKHRoaXMuYXBwLnZhdWx0KTtcblx0XHR0aGlzLnRhcmdldF9maWxlID0gZmlsZTtcblx0fVxuXG5cdGdldEFsbEZvbGRlcnModmF1bHQ6IFZhdWx0KTogU2V0PHN0cmluZz4ge1xuXHRcdGNvbnN0IGZvbGRlcnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblx0XHR2YXVsdC5nZXRBbGxMb2FkZWRGaWxlcygpLmZvckVhY2goZmlsZSA9PiB7XG5cdFx0XHQvLyBcdTUyMjRcdTY1QURcdTY2MkZcdTU0MjZcdTY2MkYgVEZvbGRlciBcdTdDN0JcdTU3OEJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xuXHRcdFx0XHRmb2xkZXJzLmFkZChmaWxlLnBhdGgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJldHVybiBmb2xkZXJzO1xuXHR9XG5cblx0Z2V0SXRlbXMoKTogc3RyaW5nW10ge1xuXHRcdHJldHVybiBBcnJheS5mcm9tKHRoaXMuZm9sZGVyTGlzdCkuc29ydCgpO1xuXHR9XG5cblx0Z2V0SXRlbVRleHQoaXRlbTogc3RyaW5nKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gaXRlbTtcblx0fVxuXG5cdGFzeW5jIG9uQ2hvb3NlSXRlbShpdGVtOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAodGhpcy50YXJnZXRfZmlsZS5wYXJlbnQ/LnBhdGggPT09IGl0ZW0pIHtcblx0XHRcdG5ldyBOb3RpY2UoXCJUaGUgZmlsZSBpcyBhbHJlYWR5IGluIHRoZSBmb2xkZXIhXCIsIDMwMDApO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRsZXQgY2hvb3NlZF9mb2xkZXIgPSBpdGVtLmVuZHNXaXRoKCcvJykgPyBpdGVtIDogaXRlbSArICcvJztcblx0XHRsZXQgbmV3X3BhdGggPSBjaG9vc2VkX2ZvbGRlciArIHRoaXMudGFyZ2V0X2ZpbGUubmFtZTtcblx0XHRwcmludChuZXdfcGF0aClcblx0XHRhcHAudmF1bHQuYWRhcHRlci5leGlzdHMobmV3X3BhdGgpXG5cdFx0LnRoZW4oKGV4aXN0cykgPT4ge1xuXHRcdFx0aWYoZXhpc3RzKSB7XG5cdFx0XHRcdG5ldyBOb3RpY2UoYEZhaWwgdG8gbW92ZSBmb3IgdGhlcmUgYWxyZWF5IGV4aXN0IGZpbGUgJHtuZXdfcGF0aH1gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMuYXBwLmZpbGVNYW5hZ2VyLnJlbmFtZUZpbGUodGhpcy50YXJnZXRfZmlsZSwgYCR7bmV3X3BhdGh9YCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRyZW5kZXJTdWdnZXN0aW9uKGl0ZW06IEZ1enp5TWF0Y2g8c3RyaW5nPiwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGVsLmlubmVyVGV4dCA9IGl0ZW0uaXRlbTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgTm90aWNlLCBURmlsZSwgVEZvbGRlciB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IEF0dGFjaEZsb3dQbHVnaW4gZnJvbSBcInNyYy9tYWluXCI7XG5jb25zdCBTVUNDRVNTX05PVElDRV9USU1FT1VUID0gMTgwMDtcbi8qKlxuICogRGVsZXRlIGF0dGFjaG1lbnRcbiAqIEBwYXJhbSBmaWxlXG4gKi9cbmV4cG9ydCBjb25zdCBkZWxldGVGaWxlID0gYXN5bmMgKFxuXHRmaWxlOiBURmlsZSB8IFRGb2xkZXIsXG5cdHBsdWdpbjogQXR0YWNoRmxvd1BsdWdpblxuKSA9PiB7XG5cdGNvbnN0IGRlbGV0ZU9wdGlvbiA9IHBsdWdpbi5zZXR0aW5ncy5kZWxldGVPcHRpb247XG5cdHRyeSB7XG5cdFx0aWYgKGRlbGV0ZU9wdGlvbiA9PT0gXCIudHJhc2hcIikge1xuXHRcdFx0YXdhaXQgYXBwLnZhdWx0LnRyYXNoKGZpbGUsIGZhbHNlKTtcblx0XHR9IGVsc2UgaWYgKGRlbGV0ZU9wdGlvbiA9PT0gXCJzeXN0ZW0tdHJhc2hcIikge1xuXHRcdFx0YXdhaXQgYXBwLnZhdWx0LnRyYXNoKGZpbGUsIHRydWUpO1xuXHRcdH0gZWxzZSBpZiAoZGVsZXRlT3B0aW9uID09PSBcInBlcm1hbmVudFwiKSB7XG5cdFx0XHRhd2FpdCBhcHAudmF1bHQuZGVsZXRlKGZpbGUpO1xuXHRcdH1cblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRjb25zb2xlLmVycm9yKGVycm9yKTtcblx0XHRuZXcgTm90aWNlKFwiRmFpbGQgdG8gZGVsZXRlIHRoZSBmaWxlL2ZvbGRlciAhXCIsIFNVQ0NFU1NfTk9USUNFX1RJTUVPVVQpO1xuXHR9XG59O1xuLyoqXG4gKiBEZWxldGUgbm90ZVxuICogQHBhcmFtIGZpbGVcbiAqL1xuLyogZXhwb3J0IGNvbnN0IGRlbGV0ZU5vdGUgPSAoZmlsZTogVEZpbGUpID0+IHtcblx0Ly8gQHRzLWlnbm9yZVxuXHRhcHAuZmlsZU1hbmFnZXIucHJvbXB0Rm9yRGVsZXRpb24oZmlsZSk7XG59OyAqL1xuIiwgImltcG9ydCBBdHRhY2hGbG93UGx1Z2luIGZyb20gXCJzcmMvbWFpblwiO1xuaW1wb3J0IHsgZGVsZXRlQWxsQXR0YWNocyB9IGZyb20gXCJzcmMvb3B0aW9ucy9kZWxlbGVBbGxBdHRhY2hzSW5UaGVOb3RlXCI7XG5cbmV4cG9ydCBjb25zdCBhZGRDb21tYW5kID0gKG15UGx1Z2luOiBBdHRhY2hGbG93UGx1Z2luKSA9PiB7XG5cdG15UGx1Z2luLmFkZENvbW1hbmQoe1xuXHRcdGlkOiBcImNsZWFyLWFsbC1hdHRhY2htZW50cy1pbi1jdXJyZW50LWZpbGVcIixcblx0XHRuYW1lOiBcImNsZWFyIGFsbCBhdHRhY2htZW50cyBpbiBjdXJyZW50IGZpbGVcIixcblx0XHRjYWxsYmFjazogYXN5bmMgKCkgPT4ge1xuXHRcdFx0ZGVsZXRlQWxsQXR0YWNocyhteVBsdWdpbik7XG5cdFx0fSxcblx0fSk7XG59O1xuIiwgImltcG9ydCBBdHRhY2hGbG93UGx1Z2luIGZyb20gJy4vbWFpbic7XG5pbXBvcnQgeyBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBBcHAsIE5vdGljZSB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB7IHNldERlYnVnIH0gZnJvbSAnLi91dGlsJztcblxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgQXR0YWNoRmxvd1NldHRpbmdzIHtcbiAgICBkZWxldGVPcHRpb246IHN0cmluZztcbiAgICBsb2dzTW9kYWw6IGJvb2xlYW47XG4gICAgZHJhZ1Jlc2l6ZTogYm9vbGVhbjtcbiAgICByZXNpemVJbnRlcnZhbDogbnVtYmVyO1xuICAgIGNsaWNrVmlldzogYm9vbGVhbjtcbiAgICBhZGFwdGl2ZVJhdGlvOiBudW1iZXI7XG4gICAgbW92ZUZpbGVNZW51OiBib29sZWFuO1xuICAgIGRlYnVnOiBib29sZWFuO1xufVxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogQXR0YWNoRmxvd1NldHRpbmdzID0ge1xuICAgIGRlbGV0ZU9wdGlvbjogJy50cmFzaCcsXG4gICAgbG9nc01vZGFsOiB0cnVlLFxuICAgIGRyYWdSZXNpemU6IHRydWUsXG4gICAgcmVzaXplSW50ZXJ2YWw6IDAsXG4gICAgY2xpY2tWaWV3OiBmYWxzZSxcbiAgICBhZGFwdGl2ZVJhdGlvOiAwLjksXG4gICAgbW92ZUZpbGVNZW51OiBmYWxzZSxcbiAgICBkZWJ1ZzogZmFsc2UsXG59O1xuXG5cbmV4cG9ydCBjbGFzcyBBdHRhY2hGbG93U2V0dGluZ3NUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblxuICAgIHBsdWdpbjogQXR0YWNoRmxvd1BsdWdpbjtcblxuXG4gICAgY29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogQXR0YWNoRmxvd1BsdWdpbikge1xuICAgICAgICBzdXBlcihhcHAsIHBsdWdpbik7XG4gICAgICAgIHRoaXMucGx1Z2luID0gcGx1Z2luO1xuICAgIH1cblxuXG4gICAgZGlzcGxheSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcbiAgICAgICAgY29udGFpbmVyRWwuZW1wdHkoKTtcblxuICAgICAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbCkuc2V0TmFtZSgnUmlnaHQtY2xpY2sgbWVudSBmb3IgYXR0YWNobWVudHMnKS5zZXRIZWFkaW5nKCk7XG4gICAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAgICAgLnNldE5hbWUoJ0RlbGV0ZWQgYXR0YWNobWVudCBkZXN0aW5hdGlvbicpXG4gICAgICAgICAgICAuc2V0RGVzYygnU2VsZWN0IHdoZXJlIHlvdSB3YW50IEF0dGFjaG1lbnRzIHRvIGJlIG1vdmVkIG9uY2UgdGhleSBhcmUgZGVsZXRlZCcpXG4gICAgICAgICAgICAuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PiB7XG4gICAgICAgICAgICAgICAgZHJvcGRvd24uYWRkT3B0aW9uKCdwZXJtYW5lbnQnLCAnRGVsZXRlIFBlcm1hbmVudGx5Jyk7XG4gICAgICAgICAgICAgICAgZHJvcGRvd24uYWRkT3B0aW9uKCcudHJhc2gnLCAnTW92ZSB0byBPYnNpZGlhbiBUcmFzaCcpO1xuICAgICAgICAgICAgICAgIGRyb3Bkb3duLmFkZE9wdGlvbignc3lzdGVtLXRyYXNoJywgJ01vdmUgdG8gU3lzdGVtIFRyYXNoJyk7XG4gICAgICAgICAgICAgICAgZHJvcGRvd24uc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVsZXRlT3B0aW9uKTtcbiAgICAgICAgICAgICAgICBkcm9wZG93bi5vbkNoYW5nZSgob3B0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmRlbGV0ZU9wdGlvbiA9IG9wdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKCdNb3ZlIGZpbGUgdG8uLi4nKVxuICAgICAgICAgICAgLnNldERlc2MoJ0FkZCBhIFwiTW92ZSB0by4uLlwiIG9wdGlvbiB0byB0aGUgcmlnaHQtY2xpY2sgbWVudSBmb3IgYXR0YWNobWVudHMnKVxuICAgICAgICAgICAgLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm1vdmVGaWxlTWVudSlcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MubW92ZUZpbGVNZW51ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbCkuc2V0TmFtZSgnQ2xpY2sgdG8gdmlldyBpbWFnZXMnKS5zZXRIZWFkaW5nKCk7XG4gICAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAgICAgLnNldE5hbWUoXCJDbGljayB0byB2aWV3IGltYWdlc1wiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJDbGljayB0aGUgcmlnaHQgaGFsZiBvZiB0aGUgaW1hZ2UgdG8gdmlldyB0aGUgaW1hZ2UgaW4gZGV0YWlsLlwiKVxuICAgICAgICAgICAgLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XG4gICAgICAgICAgICAgICAgdG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmNsaWNrVmlldylcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuY2xpY2tWaWV3ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAgICAgLnNldE5hbWUoJ0FkYXB0aXZlIGltYWdlIGRpc3BsYXkgcmF0aW8gYmFzZWQgb24gd2luZG93IHNpemUnKVxuICAgICAgICAgICAgLnNldERlc2MoJ1doZW4gdGhlIGltYWdlIGV4Y2VlZHMgdGhlIHdpbmRvdyBzaXplLCB0aGUgaW1hZ2UgaXMgZGlzcGxheWVkIGFkYXB0aXZlbHkgYWNjb3JkaW5nIHRvIHRoZSB3aW5kb3cgc2l6ZS4nKVxuICAgICAgICAgICAgLmFkZFNsaWRlcigoc2xpZGVyKSA9PiB7XG4gICAgICAgICAgICAgICAgc2xpZGVyLnNldExpbWl0cygwLjEsIDEsIDAuMDUpO1xuICAgICAgICAgICAgICAgIHNsaWRlci5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hZGFwdGl2ZVJhdGlvKTtcbiAgICAgICAgICAgICAgICBzbGlkZXIub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmFkYXB0aXZlUmF0aW8gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZShgQWRhcHRpdmUgcmF0aW86ICR7dmFsdWV9YCk7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNsaWRlci5zZXREeW5hbWljVG9vbHRpcCgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpLnNldE5hbWUoJ0RyYWcgdG8gcmVzaXplIGltYWdlcycpLnNldEhlYWRpbmcoKTtcbiAgICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIkRyYWcgdG8gcmVzaXplIGltYWdlc1wiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJUdXJuIG9uIHRvIGVuYWJsZSBkcmFnIHRvIHJlc2l6ZSBpbWFnZXMuXCIpXG4gICAgICAgICAgICAuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcbiAgICAgICAgICAgICAgICB0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZHJhZ1Jlc2l6ZSlcbiAgICAgICAgICAgICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZHJhZ1Jlc2l6ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgICAgICAuc2V0TmFtZShcIlJlc2l6ZSBpbnRlcnZhbFwiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJcdTYyRDZcdTYyRkRcdThDMDNcdTgyODJcdTY3MDBcdTVDMEZcdTUyM0JcdTVFQTZcdUZGMDhcdTlFRDhcdThCQTRcdTUwM0NcdTRFM0EgMCBcdTUzNzNcdTRFMERcdTVCRjlcdTlGNTBcdTUyM0JcdTVFQTZcdUZGMDlcIilcbiAgICAgICAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGV4dC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZXNpemVJbnRlcnZhbC50b1N0cmluZygpKVxuICAgICAgICAgICAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBcdTUyMjRcdTY1QURcdThGOTNcdTUxNjVcdTUwM0NcdTY2MkZcdTU0MjZcdTRFM0FcdTZCNjNcdTY1NzRcdTY1NzBcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnB1dCBpcyBlbXB0eS4gU2V0IHRvIGRlZmF1bHQgdmFsdWUgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnJlc2l6ZUludGVydmFsID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1lbHNlIGlmICgvXlxcZCskLy50ZXN0KHZhbHVlKSAmJiBOdW1iZXIodmFsdWUpID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZXNpemVJbnRlcnZhbCA9IHBhcnNlSW50KHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gXHU0RTBEXHU3QjI2XHU1NDA4XHU4OTgxXHU2QzQyXHU2NUY2XHVGRjBDXHU1M0VGXHU0RUU1XHU3RUQ5XHU1MUZBXHU2M0QwXHU3OTNBXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZSgnXHU4QkY3XHU4RjkzXHU1MTY1XHU2QjYzXHU2NTc0XHU2NTcwJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZXNpemVJbnRlcnZhbC50b1N0cmluZygpKTsgLy8gXHU5MUNEXHU2NUIwXHU4QkJFXHU3RjZFXHU0RTNBXHU1MzlGXHU2NzY1XHU3Njg0XHU1MDNDXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpLnNldE5hbWUoJ0RlYnVnJykuc2V0SGVhZGluZygpO1xuICAgICAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgICAgICAgIC5zZXROYW1lKFwiRGVidWcgbW9kZVwiKVxuICAgICAgICAgICAgLnNldERlc2MoXCJQcmludCBkZWJ1ZyBpbmZvcm1hdGlvbiBpbiBjb25zb2xlXCIpXG4gICAgICAgICAgICAuYWRkVG9nZ2xlKCh0b2dnbGUpID0+IHtcbiAgICAgICAgICAgICAgICB0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVidWcpXG4gICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmRlYnVnID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXREZWJ1Zyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG59XG4iLCAiLyoqXG4gKiBnZXQgbW91c2UgZXZlbnQgdGFyZ2V0XG4gKiBAcGFyYW0gZXZlbnQgXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRNb3VzZUV2ZW50VGFyZ2V0ID0gKGV2ZW50OiBNb3VzZUV2ZW50KTogSFRNTEVsZW1lbnQgPT4ge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIHJldHVybiB0YXJnZXQ7XG59XG4iLCAiaW1wb3J0IHsgTW9kYWwsIFRGaWxlIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgQXR0YWNoRmxvd1BsdWdpbiBmcm9tIFwic3JjL21haW5cIjtcbmltcG9ydCB7XG5cdGRlbGV0ZUFsbEF0dGFjaHMsXG5cdGdldFJlZmVuY2VkTGlua0NvdW50LFxufSBmcm9tIFwic3JjL29wdGlvbnMvZGVsZWxlQWxsQXR0YWNoc0luVGhlTm90ZVwiO1xuaW1wb3J0IHsgZGVsZXRlRmlsZSB9IGZyb20gXCJzcmMvdXRpbHMvZGVsZXRlRmlsZVwiO1xuXG5leHBvcnQgY2xhc3MgRGVsZXRlQWxsTG9nc01vZGFsIGV4dGVuZHMgTW9kYWwge1xuXHRub3RlOiBURmlsZTtcblx0bXlQbHVnaW46IEF0dGFjaEZsb3dQbHVnaW47XG5cdGNvbnN0cnVjdG9yKG5vdGU6IFRGaWxlLCBteVBsdWdpbjogQXR0YWNoRmxvd1BsdWdpbikge1xuXHRcdHN1cGVyKGFwcCk7XG5cdFx0dGhpcy5ub3RlID0gbm90ZTtcblx0XHR0aGlzLm15UGx1Z2luID0gbXlQbHVnaW47XG5cdH1cblx0Z2V0TG9nKCk6IHN0cmluZyB7XG5cdFx0Y29uc3QgcmVmZXJlbmNlTWVzc2FnZSA9IGBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIFwiJHt0aGlzLm5vdGUuYmFzZW5hbWV9Lm1kXCI/XFxuXFxuSXQgd2lsbCBiZSBtb3ZlZCB0byB5b3VyICR7dGhpcy5teVBsdWdpbi5zZXR0aW5ncy5kZWxldGVPcHRpb259LmA7XG5cdFx0cmV0dXJuIHJlZmVyZW5jZU1lc3NhZ2U7XG5cdH1cblx0c2hvd0xvZ3MoKSB7XG5cdFx0Y29uc3QgbG9ncyA9IHRoaXMuY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xuXHRcdGxvZ3MuYWRkQ2xhc3MoXCJhdHRhY2htZW50LWZsb3ctbG9nXCIpO1xuXHRcdGxvZ3Muc2V0VGV4dCh0aGlzLmdldExvZygpKTtcblx0fVxuXHRvbk9wZW4oKSB7XG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29uc3QgbXlNb2RhbCA9IHRoaXM7XG5cdFx0Y29uc3QgaGVhZGVyV3JhcHBlciA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcblx0XHRoZWFkZXJXcmFwcGVyLmFkZENsYXNzKFwiYXR0YWNobWVudC1mbG93LWNlbnRlci13cmFwcGVyXCIpO1xuXHRcdHRoaXMuc2hvd0xvZ3MoKTtcblx0XHRjb25zdCByZWZlcmVuY2VkTWVzc2FnZVdyYXBwZXIgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJzcGFuXCIpO1xuXHRcdHJlZmVyZW5jZWRNZXNzYWdlV3JhcHBlci5zdHlsZS5jb2xvciA9IFwicmVkXCI7XG5cdFx0Y29uc3QgcmVmZXJlbmNlZE1lc3NhZ2UgPSBgVGhlcmUgYXJlKGlzKSBjdXJyZW50bHkgIFske2dldFJlZmVuY2VkTGlua0NvdW50KCl9XSAgbm9uLW11bHRpLXJlZmVyZW5jZWQgbGluayhzKSBwb2ludGluZyB0byB0aGlzIG5vdGUuYDtcblx0XHRyZWZlcmVuY2VkTWVzc2FnZVdyYXBwZXIuYXBwZW5kKHJlZmVyZW5jZWRNZXNzYWdlKTtcblx0XHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRjb25zdCBidXR0b25XcmFwcGVyID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIikgYXMgSFRNTERpdkVsZW1lbnQ7XG5cdFx0YnV0dG9uV3JhcHBlci5hZGRDbGFzcyhcImF0dGFjaG1lbnQtZmxvdy1jZW50ZXItd3JhcHBlclwiKTtcblx0XHRjb25zdCBoZWFkZXJFbCA9IGhlYWRlcldyYXBwZXIuY3JlYXRlRWwoXCJoMVwiLCB7XG5cdFx0XHR0ZXh0OiBcIkRlbGV0ZSB0aGUgZmlsZSBhbmQgaXRzIGFsbCBhdHRhY2htZW50cyAtIGxvZ3MgXCIsXG5cdFx0fSk7XG5cdFx0aGVhZGVyRWwuYWRkQ2xhc3MoXCJtb2RhbC10aXRsZVwiKTtcblx0XHR0aGlzLnNob3dDb25maXJtQnV0dG9uKGJ1dHRvbldyYXBwZXIsIG15TW9kYWwpO1xuXHRcdHRoaXMuc2hvd0NhbmNlbEJ0bihidXR0b25XcmFwcGVyLCBteU1vZGFsKTtcblx0fVxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdHNob3dDYW5jZWxCdG4oYnV0dG9uV3JhcHBlcjogSFRNTERpdkVsZW1lbnQsIG15TW9kYWw6IE1vZGFsKSB7XG5cdFx0Ly8gLS0tLS0tLS1jbG9zZUJ1dHRvbi0tLS0tLS0tXG5cdFx0Y29uc3QgY2xvc2VCdXR0b24gPSBidXR0b25XcmFwcGVyLmNyZWF0ZUVsKFwiYnV0dG9uXCIsIHtcblx0XHRcdHRleHQ6IFwiQ2FuY2VsXCIsXG5cdFx0fSk7XG5cdFx0Y2xvc2VCdXR0b24uc2V0QXR0cmlidXRlKFwiYXJpYS1sYWJlbFwiLCBcIkNhbmNlbCB0aGUgb3BlcmF0aW9uXCIpO1xuXHRcdGNsb3NlQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoKSA9PiB7XG5cdFx0XHRteU1vZGFsLmNsb3NlKCk7XG5cdFx0fSk7XG5cdH1cblx0c2hvd0NvbmZpcm1CdXR0b24oYnV0dG9uV3JhcHBlcjogSFRNTERpdkVsZW1lbnQsIG15TW9kYWw6IE1vZGFsKSB7XG5cdFx0Y29uc3QgcmVtb3ZlTGlua0J1dHRvbiA9IGJ1dHRvbldyYXBwZXIuY3JlYXRlRWwoXCJidXR0b25cIiwge1xuXHRcdFx0dGV4dDogXCJDb25maXJtXCIsXG5cdFx0fSk7XG5cdFx0cmVtb3ZlTGlua0J1dHRvbi5zZXRBdHRyaWJ1dGUoXG5cdFx0XHRcImFyaWEtbGFiZWxcIixcblx0XHRcdFwiQ29udGludWUgdG8gZGVsZXRlIGN1cnJlbnQgZmlsZSBhbmQgaXRzIGFsbCBub24tbXVsdGktcmVmZXJlbmNlZCBhdHRhY2htZW50c1wiXG5cdFx0KTtcblx0XHRyZW1vdmVMaW5rQnV0dG9uLmFkZENsYXNzKFwibW9kLXdhcm5pbmdcIik7XG5cdFx0cmVtb3ZlTGlua0J1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYXN5bmMgKCkgPT4ge1xuXHRcdFx0ZGVsZXRlRmlsZSh0aGlzLm5vdGUsIHRoaXMubXlQbHVnaW4pO1xuXHRcdFx0ZGVsZXRlQWxsQXR0YWNocyh0aGlzLm15UGx1Z2luKTtcblx0XHRcdG15TW9kYWwuY2xvc2UoKTtcblx0XHR9KTtcblx0fVxufVxuIiwgIi8vIFRoaXMgZmlsZSBpcyBjb3BpZWQgZnJvbSByZXBvOiBodHRwczovL2dpdGh1Yi5jb20vTm9tYXJDdWIvb2JzaWRpYW4tY29weS11cmwtaW4tcHJldmlld1xuXG4vLyBNSVQgTGljZW5zZVxuLy8gQ29weXJpZ2h0IChjKSAyMDIyIE5vbWFyQ3ViXG5cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4vLyBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4vLyBTT0ZUV0FSRS5cblxuaW1wb3J0IHsgQXBwLCBFZGl0b3IsIEVkaXRvclBvc2l0aW9uLCBGaWxlU3lzdGVtQWRhcHRlciB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5jb25zdCBsb2FkSW1hZ2VCbG9iVGltZW91dCA9IDMwMDA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWxlY3Ryb25XaW5kb3cgZXh0ZW5kcyBXaW5kb3cge1xuICAgIFdFQlZJRVdfU0VSVkVSX1VSTDogc3RyaW5nXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWRpdG9ySW50ZXJuYWxBcGkgZXh0ZW5kcyBFZGl0b3Ige1xuICAgIHBvc0F0TW91c2UoZXZlbnQ6IE1vdXNlRXZlbnQpOiBFZGl0b3JQb3NpdGlvbjtcbiAgICBnZXRDbGlja2FibGVUb2tlbkF0KHBvc2l0aW9uOiBFZGl0b3JQb3NpdGlvbik6IHtcbiAgICAgICAgdGV4dDogc3RyaW5nXG4gICAgfSB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZVN5c3RlbUFkYXB0ZXJXaXRoSW50ZXJuYWxBcGkgZXh0ZW5kcyBGaWxlU3lzdGVtQWRhcHRlciB7XG4gICAgb3BlbihwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXBwV2l0aERlc2t0b3BJbnRlcm5hbEFwaSBleHRlbmRzIEFwcCB7XG4gICAgb3BlbldpdGhEZWZhdWx0QXBwKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gICAgc2hvd0luRm9sZGVyKHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdGVuZXIge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgKHRoaXM6IERvY3VtZW50LCBldjogRXZlbnQpOiBhbnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3aXRoVGltZW91dDxUPihtczogbnVtYmVyLCBwcm9taXNlOiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgY29uc3QgdGltZW91dCA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChpZCk7XG4gICAgICAgICAgICByZWplY3QoYHRpbWVkIG91dCBhZnRlciAke21zfSBtc2ApXG4gICAgICAgIH0sIG1zKVxuICAgIH0pXG4gICAgcmV0dXJuIFByb21pc2UucmFjZShbXG4gICAgICAgIHByb21pc2UsXG4gICAgICAgIHRpbWVvdXRcbiAgICBdKSBhcyBQcm9taXNlPFQ+XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvQ09SU19lbmFibGVkX2ltYWdlXG4vLyBvcHRpb24/OiBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9odG1sLXRvLWltYWdlXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZEltYWdlQmxvYihpbWdTcmM6IHN0cmluZywgcmV0cnlDb3VudCA9IDApOiBQcm9taXNlPEJsb2I+IHtcbiAgICBjb25zdCBsb2FkSW1hZ2VCbG9iQ29yZSA9ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPEJsb2I+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XG4gICAgICAgICAgICBpbWFnZS5jcm9zc09yaWdpbiA9IFwiYW5vbnltb3VzXCI7XG4gICAgICAgICAgICBpbWFnZS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICAgICAgICAgICAgICBjYW52YXMud2lkdGggPSBpbWFnZS53aWR0aDtcbiAgICAgICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIikhO1xuICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDApO1xuICAgICAgICAgICAgICAgIGNhbnZhcy50b0Jsb2IoKGJsb2I6IEJsb2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShibG9iKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpbWFnZS5vbmVycm9yID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXRyeUNvdW50IDwgMykge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZmV0Y2goaW1hZ2Uuc3JjLCB7IFwibW9kZVwiOiBcIm5vLWNvcnNcIiB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBhd2FpdCBsb2FkSW1hZ2VCbG9iKGBodHRwczovL2FwaS5hbGxvcmlnaW5zLndpbi9yYXc/dXJsPSR7ZW5jb2RlVVJJQ29tcG9uZW50KGltZ1NyYyl9YCwgcmV0cnlDb3VudCArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShibG9iKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1VuYWJsZSB0byByZXRyaWV2ZSB0aGUgaW1hZ2UgZGF0YSBhZnRlciAzIHJldHJpZXMuJykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpbWFnZS5zcmMgPSBpbWdTcmM7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgcmV0dXJuIHdpdGhUaW1lb3V0KGxvYWRJbWFnZUJsb2JUaW1lb3V0LCBsb2FkSW1hZ2VCbG9iQ29yZSgpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9uRWxlbWVudChcbiAgICBlbDogRG9jdW1lbnQsXG4gICAgZXZlbnQ6IGtleW9mIEhUTUxFbGVtZW50RXZlbnRNYXAsXG4gICAgc2VsZWN0b3I6IHN0cmluZyxcbiAgICBsaXN0ZW5lcjogTGlzdGVuZXIsXG4gICAgb3B0aW9ucz86IHsgY2FwdHVyZT86IGJvb2xlYW47IH1cbikge1xuICAgIGVsLm9uKGV2ZW50LCBzZWxlY3RvciwgbGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgIHJldHVybiAoKSA9PiBlbC5vZmYoZXZlbnQsIHNlbGVjdG9yLCBsaXN0ZW5lciwgb3B0aW9ucyk7XG59Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsdUJBQXNGOzs7QUNBdEYsdUJBQXVDOzs7QUNDdkMsc0JBQTREO0FBSTVELDJCQUErQjtBQUMvQixnQkFBMkI7QUFLM0IsdUJBQTBFO0FBRW5FLElBQUksUUFBZ0I7QUFDM0IsSUFBTSx5QkFBeUI7QUFFeEIsSUFBTSxRQUFNLENBQUMsWUFBa0IsbUJBQXlCO0FBQzNELE1BQUksT0FBTztBQUNQLFlBQVEsSUFBSSxTQUFTLEdBQUcsY0FBYztBQUFBLEVBQzFDO0FBQ0o7QUFFTyxrQkFBa0IsT0FBZ0I7QUFDckMsVUFBUTtBQUNaO0FBUU8sSUFBTSxxQkFBcUIsQ0FDakMsYUFDQSxjQUN5QztBQUV6QyxRQUFNLGdCQUFnQixJQUFJLGNBQWM7QUFDeEMsTUFBSTtBQUVKLE1BQUksU0FBeUI7QUFBQSxJQUM1QixPQUFPO0FBQUEsSUFDUCxRQUFRLENBQUM7QUFBQSxFQUNWO0FBQ0EsTUFBSSxTQUFTO0FBQ2IsYUFBVyxDQUFDLFFBQVEsVUFBVSxPQUFPLFFBQVEsYUFBYSxHQUFHO0FBQzVELFFBQUksVUFBVSxTQUFTLFFBQVE7QUFDOUIsa0JBQVksVUFBVTtBQUN0QixhQUFPLE9BQU8sUUFBUSxTQUFTO0FBQUEsSUFDaEM7QUFDQSxlQUFXLENBQUMsVUFBVSxPQUFPLE9BQU8sUUFBUSxLQUFLLEdBQUc7QUFDbkQsVUFBSSw0Q0FBYSxVQUFTLFVBQVU7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