/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; 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 __export(exports, { default: () => CustomFramesPlugin }); var import_obsidian4 = __toModule(require("obsidian")); // src/frame.ts var import_obsidian = __toModule(require("obsidian")); // src/settings.ts var defaultSettings = { frames: [], padding: 5 }; var presets = { "obsidian": { url: "https://forum.obsidian.md/", displayName: "Obsidian Forum", icon: "edit", hideOnMobile: true, addRibbonIcon: true, openInCenter: true, zoomLevel: 1, forceIframe: false, customCss: "" }, "detexify": { url: "https://detexify.kirelabs.org/classify.html", displayName: "Detexify", icon: "type", hideOnMobile: true, addRibbonIcon: true, openInCenter: false, zoomLevel: 0.95, forceIframe: false, customCss: `/* hide info clutter and ad banner */ #classify--info-area, .adsbygoogle { display: none !important }` }, "calendar": { url: "https://calendar.google.com/calendar", displayName: "Google Calendar", icon: "calendar", hideOnMobile: true, addRibbonIcon: true, openInCenter: true, zoomLevel: 1, forceIframe: false, customCss: `/* hide the menu bar, "Keep" text, and logo */ html > body > div:nth-child(2) > div:nth-child(2) > div:first-child[class*=" "], html > body > div:first-child > header:first-child > div > div:first-child > div > div:first-child, html > body > div:nth-child(2) > div:nth-child(2) > div:first-child > div:first-child { display: none !important; }` }, "keep": { url: "https://keep.google.com", displayName: "Google Keep", icon: "files", hideOnMobile: true, addRibbonIcon: false, openInCenter: false, zoomLevel: 1, forceIframe: false, customCss: `/* hide the menu bar and the "Keep" text */ html > body > div:nth-child(2) > div:nth-child(2) > div:first-child, html > body > div:first-child > header:first-child > div > div:first-child > div > div:first-child > a:first-child > span { display: none !important; }` }, "todoist": { url: "https://todoist.com", displayName: "Todoist", icon: "list-checks", hideOnMobile: true, addRibbonIcon: false, openInCenter: false, zoomLevel: 1, forceIframe: false, customCss: `/* hide the help, home, search, and productivity overview buttons, create extra space, and prevent toast pop-up from acting weird */ [aria-label="Go to Home view"], #quick_find, [aria-label="Productivity"], [aria-label="Help & Feedback"] { display: none !important; } .view_content { padding-left: 15px; } .view_header { padding-left: 15px; padding-top: 10px; } .undo_toast { width: 95%; }` }, "notion": { url: "https://www.notion.so/", displayName: "Notion", icon: "box", hideOnMobile: true, addRibbonIcon: true, openInCenter: true, zoomLevel: 1, forceIframe: false, customCss: "" }, "twitter": { url: "https://twitter.com", displayName: "Twitter", icon: "twitter", hideOnMobile: true, addRibbonIcon: false, openInCenter: false, zoomLevel: 1, forceIframe: false, customCss: "" } }; function getIcon(settings) { return settings.icon ? `lucide-${settings.icon}` : "documents"; } function getId(settings) { return settings.displayName.toLowerCase().replace(/\s/g, "-"); } // src/frame.ts var CustomFrame = class { constructor(settings, data) { this.settings = settings; this.data = data; } create(additionalStyle = void 0, urlSuffix = void 0) { let style = `padding: ${this.settings.padding}px;`; if (additionalStyle) style += additionalStyle; if (import_obsidian.Platform.isDesktopApp && !this.data.forceIframe) { this.frame = document.createElement("webview"); this.frame.setAttribute("allowpopups", ""); this.frame.addEventListener("dom-ready", () => { this.frame.setZoomFactor(this.data.zoomLevel); this.frame.insertCSS(this.data.customCss); }); } else { this.frame = document.createElement("iframe"); this.frame.setAttribute("sandbox", "allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation"); this.frame.setAttribute("allow", "encrypted-media; fullscreen; oversized-images; picture-in-picture; sync-xhr; geolocation;"); style += `transform: scale(${this.data.zoomLevel}); transform-origin: 0 0;`; } this.frame.addClass("custom-frames-frame"); this.frame.addClass(`custom-frames-${getId(this.data)}`); this.frame.setAttribute("style", style); let src = this.data.url; if (urlSuffix) { if (!urlSuffix.startsWith("/")) src += "/"; src += urlSuffix; } this.frame.setAttribute("src", src); return this.frame; } refresh() { if (this.frame instanceof HTMLIFrameElement) { this.frame.contentWindow.location.reload(); } else { this.frame.reload(); } } return() { if (this.frame instanceof HTMLIFrameElement) { this.frame.contentWindow.open(this.data.url); } else { this.frame.loadURL(this.data.url); } } goBack() { if (this.frame instanceof HTMLIFrameElement) { this.frame.contentWindow.history.back(); } else { this.frame.goBack(); } } goForward() { if (this.frame instanceof HTMLIFrameElement) { this.frame.contentWindow.history.forward(); } else { this.frame.goForward(); } } toggleDevTools() { if (!(this.frame instanceof HTMLIFrameElement)) { if (!this.frame.isDevToolsOpened()) { this.frame.openDevTools(); } else { this.frame.closeDevTools(); } } } getCurrentUrl() { return this.frame instanceof HTMLIFrameElement ? this.frame.contentWindow.location.href : this.frame.getURL(); } }; // src/settings-tab.ts var import_obsidian2 = __toModule(require("obsidian")); var CustomFramesSettingTab = class extends import_obsidian2.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { this.containerEl.empty(); this.containerEl.createEl("h2", { text: "Custom Frames Settings" }); this.containerEl.createEl("p", { text: "Please note that Obsidian has to be restarted or reloaded for most of these settings to take effect.", cls: "mod-warning" }); new import_obsidian2.Setting(this.containerEl).setName("Frame Padding").setDesc("The padding that should be left around the inside of custom frame panes, in pixels.").addText((t) => { t.inputEl.type = "number"; t.setValue(String(this.plugin.settings.padding)); t.onChange((v) => __async(this, null, function* () { this.plugin.settings.padding = v.length ? Number(v) : defaultSettings.padding; yield this.plugin.saveSettings(); })); }); for (let frame of this.plugin.settings.frames) { let heading = this.containerEl.createEl("h3", { text: frame.displayName || "Unnamed Frame" }); let toggle = new import_obsidian2.ButtonComponent(this.containerEl).setButtonText("Show Settings").setClass("custom-frames-show").onClick(() => __async(this, null, function* () { content.hidden = !content.hidden; toggle.setButtonText(content.hidden ? "Show Settings" : "Hide Settings"); })); let content = this.containerEl.createDiv(); content.hidden = true; new import_obsidian2.Setting(content).setName("Display Name").setDesc("The display name that this frame should have.").addText((t) => { t.setValue(frame.displayName); t.onChange((v) => __async(this, null, function* () { frame.displayName = v; heading.setText(frame.displayName || "Unnamed Frame"); yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Icon").setDesc(createFragment((f) => { f.createSpan({ text: "The icon that this frame's pane should have. The names of any " }); f.createEl("a", { text: "Lucide icons", href: "https://lucide.dev/" }); f.createSpan({ text: " can be used." }); })).addText((t) => { t.setValue(frame.icon); t.onChange((v) => __async(this, null, function* () { frame.icon = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("URL").setDesc("The URL that should be opened in this frame.").addText((t) => { t.setValue(frame.url); t.onChange((v) => __async(this, null, function* () { frame.url = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Disable on Mobile").setDesc("Custom Frames is a lot more restricted on mobile devices and doesn't allow for the same types of content to be displayed. If a frame doesn't work as expected on mobile, it can be disabled.").addToggle((t) => { t.setValue(frame.hideOnMobile); t.onChange((v) => __async(this, null, function* () { frame.hideOnMobile = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Add Ribbon Icon").setDesc("Whether a button to open this frame should be added to the ribbon.").addToggle((t) => { t.setValue(frame.addRibbonIcon); t.onChange((v) => __async(this, null, function* () { frame.addRibbonIcon = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Open in Center").setDesc("Whether this frame should be opened in the unpinned center editor rather than one of the panes on the side. This is useful for sites that don't work well in a narrow view, or sites that don't require a note to be open when viewed.").addToggle((t) => { t.setValue(frame.openInCenter); t.onChange((v) => __async(this, null, function* () { frame.openInCenter = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Force iframe").setDesc(createFragment((f) => { f.createSpan({ text: "Whether this frame should use iframes on desktop as opposed to Electron webviews." }); f.createEl("br"); f.createEl("em", { text: "Only enable this setting if the frame is causing issues or frequent crashes. This setting causes all Desktop-only settings to be ignored." }); })).addToggle((t) => { t.setValue(frame.forceIframe); t.onChange((v) => __async(this, null, function* () { frame.forceIframe = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Page Zoom").setDesc("The zoom that this frame's page should be displayed with, as a percentage.").addText((t) => { t.inputEl.type = "number"; t.setValue(String(frame.zoomLevel * 100)); t.onChange((v) => __async(this, null, function* () { frame.zoomLevel = v.length ? Number(v) / 100 : 1; yield this.plugin.saveSettings(); })); }); new import_obsidian2.Setting(content).setName("Additional CSS").setDesc(createFragment((f) => { f.createSpan({ text: "A snippet of additional CSS that should be applied to this frame." }); f.createEl("br"); f.createEl("em", { text: "Note that this is only applied on Desktop." }); })).addTextArea((t) => { t.inputEl.rows = 5; t.inputEl.cols = 50; t.setValue(frame.customCss); t.onChange((v) => __async(this, null, function* () { frame.customCss = v; yield this.plugin.saveSettings(); })); }); new import_obsidian2.ButtonComponent(content).setButtonText("Remove Frame").onClick(() => __async(this, null, function* () { this.plugin.settings.frames.remove(frame); yield this.plugin.saveSettings(); this.display(); })); } this.containerEl.createEl("hr"); this.containerEl.createEl("p", { text: `Create a new frame, either from a preset shipped with the plugin, or a custom one that you can edit yourself. Each frame's pane can be opened using the "Custom Frames: Open" command.` }); let addDiv = this.containerEl.createDiv(); let dropdown = new import_obsidian2.DropdownComponent(addDiv); dropdown.addOption("new", "Custom"); for (let key of Object.keys(presets)) dropdown.addOption(key, presets[key].displayName); new import_obsidian2.ButtonComponent(addDiv).setButtonText("Add Frame").setClass("custom-frames-add").onClick(() => __async(this, null, function* () { let option = dropdown.getValue(); if (option == "new") { this.plugin.settings.frames.push({ url: "", displayName: "New Frame", icon: "", hideOnMobile: true, addRibbonIcon: false, openInCenter: false, zoomLevel: 1, forceIframe: false, customCss: "" }); } else { this.plugin.settings.frames.push(presets[option]); } yield this.plugin.saveSettings(); this.display(); })); var disclaimer = this.containerEl.createEl("p", { cls: "mod-warning" }); disclaimer.createSpan({ text: "Please be advised that, when adding a site as a custom frame, you potentially expose personal information you enter to other plugins you have installed. For more information, see " }); disclaimer.createEl("a", { text: "this discussion", href: "https://github.com/Ellpeck/ObsidianCustomFrames/issues/54#issuecomment-1210879685", cls: "mod-warning" }); disclaimer.createSpan({ text: "." }); this.containerEl.createEl("hr"); this.containerEl.createEl("p", { text: "If you like this plugin and want to support its development, you can do so through my website by clicking this fancy image!" }); this.containerEl.createEl("a", { href: "https://ellpeck.de/support" }).createEl("img", { attr: { src: "https://ellpeck.de/res/generalsupport.png" }, cls: "custom-frames-support" }); } }; // src/view.ts var import_obsidian3 = __toModule(require("obsidian")); var _CustomFrameView = class extends import_obsidian3.ItemView { constructor(leaf, settings, data, name) { super(leaf); this.data = data; this.name = name; this.frame = new CustomFrame(settings, data); for (let action of _CustomFrameView.actions) this.addAction(action.icon, action.name, () => action.action(this)); } onload() { this.contentEl.empty(); this.contentEl.addClass("custom-frames-view"); this.contentEl.appendChild(this.frame.create()); } onPaneMenu(menu, source) { super.onPaneMenu(menu, source); if (source == "tab-header") { for (let action of _CustomFrameView.actions) { menu.addItem((i) => { i.setTitle(action.name); i.setIcon(action.icon); i.onClick(() => action.action(this)); }); } } } getViewType() { return this.name; } getDisplayText() { return this.data.displayName; } getIcon() { return getIcon(this.data); } }; var CustomFrameView = _CustomFrameView; CustomFrameView.actions = [ { name: "Return to original page", icon: "home", action: (v) => v.frame.return() }, { name: "Open dev tools", icon: "binary", action: (v) => v.frame.toggleDevTools() }, { name: "Copy link", icon: "link", action: (v) => navigator.clipboard.writeText(v.frame.getCurrentUrl()) }, { name: "Open in browser", icon: "globe", action: (v) => open(v.frame.getCurrentUrl()) }, { name: "Refresh", icon: "refresh-cw", action: (v) => v.frame.refresh() }, { name: "Go back", icon: "arrow-left", action: (v) => v.frame.goBack() }, { name: "Go forward", icon: "arrow-right", action: (v) => v.frame.goForward() } ]; // src/main.ts var CustomFramesPlugin = class extends import_obsidian4.Plugin { onload() { return __async(this, null, function* () { yield this.loadSettings(); for (let frame of this.settings.frames) { if (!frame.url || !frame.displayName) continue; let name = `custom-frames-${getId(frame)}`; if (import_obsidian4.Platform.isMobileApp && frame.hideOnMobile) { console.log(`Skipping frame ${name} which is hidden on mobile`); continue; } try { console.log(`Registering frame ${name} for URL ${frame.url}`); this.registerView(name, (l) => new CustomFrameView(l, this.settings, frame, name)); this.addCommand({ id: `open-${name}`, name: `Open ${frame.displayName}`, callback: () => this.openLeaf(name, frame.openInCenter, false) }); if (frame.addRibbonIcon) this.addRibbonIcon(getIcon(frame), `Open ${frame.displayName}`, (e) => this.openLeaf(name, frame.openInCenter, import_obsidian4.Platform.isMacOS ? e.metaKey : e.ctrlKey)); } catch (e) { console.error(`Couldn't register frame ${name}, is there already one with the same name?`); } } this.addSettingTab(new CustomFramesSettingTab(this.app, this)); this.registerMarkdownCodeBlockProcessor("custom-frames", (s, e) => { e.empty(); e.addClass("custom-frames-view-file"); let frameMatch = /frame:([^\n]+)/gi.exec(s); let frameName = frameMatch && frameMatch[1].trim(); if (!frameName) { e.createSpan({ text: "Couldn't parse frame name" }); return; } let data = this.settings.frames.find((f) => f.displayName == frameName); if (!data) { e.createSpan({ text: `Couldn't find a frame with name ${frameName}` }); return; } if (import_obsidian4.Platform.isMobileApp && data.hideOnMobile) { e.createSpan({ text: `${frameName} is hidden on mobile` }); return; } let styleMatch = /style:([^\n]+)/gi.exec(s); let style = styleMatch && styleMatch[1].trim(); style || (style = "height: 600px;"); let urlSuffixMatch = /urlsuffix:([^\n]+)/gi.exec(s); let urlSuffix = urlSuffixMatch && urlSuffixMatch[1].trim(); urlSuffix || (urlSuffix = ""); let frame = new CustomFrame(this.settings, data); e.appendChild(frame.create(style, urlSuffix)); }); }); } loadSettings() { return __async(this, null, function* () { this.settings = Object.assign({}, defaultSettings, yield this.loadData()); }); } saveSettings() { return __async(this, null, function* () { yield this.saveData(this.settings); }); } openLeaf(name, center, split) { return __async(this, null, function* () { if (center) { this.app.workspace.detachLeavesOfType(name); let leaf = this.app.workspace.getLeaf(split); yield leaf.setViewState({ type: name, active: true }); } else { if (!this.app.workspace.getLeavesOfType(name).length) yield this.app.workspace.getRightLeaf(false).setViewState({ type: name, active: true }); this.app.workspace.revealLeaf(this.app.workspace.getLeavesOfType(name)[0]); } }); } }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL2ZyYW1lLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvc2V0dGluZ3MtdGFiLnRzIiwgInNyYy92aWV3LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBQbHVnaW4sIFBsYXRmb3JtIH0gZnJvbSBcIm9ic2lkaWFuXCI7XHJcbmltcG9ydCB7IEN1c3RvbUZyYW1lIH0gZnJvbSBcIi4vZnJhbWVcIjtcclxuaW1wb3J0IHsgQ3VzdG9tRnJhbWVzU2V0dGluZ3MsIGRlZmF1bHRTZXR0aW5ncywgZ2V0SWNvbiwgZ2V0SWQgfSBmcm9tIFwiLi9zZXR0aW5nc1wiO1xyXG5pbXBvcnQgeyBDdXN0b21GcmFtZXNTZXR0aW5nVGFiIH0gZnJvbSBcIi4vc2V0dGluZ3MtdGFiXCI7XHJcbmltcG9ydCB7IEN1c3RvbUZyYW1lVmlldyB9IGZyb20gXCIuL3ZpZXdcIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEN1c3RvbUZyYW1lc1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblxyXG5cdHNldHRpbmdzOiBDdXN0b21GcmFtZXNTZXR0aW5ncztcclxuXHJcblx0YXN5bmMgb25sb2FkKCk6IFByb21pc2U8dm9pZD4ge1xyXG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcclxuXHJcblx0XHRmb3IgKGxldCBmcmFtZSBvZiB0aGlzLnNldHRpbmdzLmZyYW1lcykge1xyXG5cdFx0XHRpZiAoIWZyYW1lLnVybCB8fCAhZnJhbWUuZGlzcGxheU5hbWUpXHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdGxldCBuYW1lID0gYGN1c3RvbS1mcmFtZXMtJHtnZXRJZChmcmFtZSl9YDtcclxuXHRcdFx0aWYgKFBsYXRmb3JtLmlzTW9iaWxlQXBwICYmIGZyYW1lLmhpZGVPbk1vYmlsZSkge1xyXG5cdFx0XHRcdGNvbnNvbGUubG9nKGBTa2lwcGluZyBmcmFtZSAke25hbWV9IHdoaWNoIGlzIGhpZGRlbiBvbiBtb2JpbGVgKTtcclxuXHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHR0cnkge1xyXG5cdFx0XHRcdGNvbnNvbGUubG9nKGBSZWdpc3RlcmluZyBmcmFtZSAke25hbWV9IGZvciBVUkwgJHtmcmFtZS51cmx9YCk7XHJcblxyXG5cdFx0XHRcdHRoaXMucmVnaXN0ZXJWaWV3KG5hbWUsIGwgPT4gbmV3IEN1c3RvbUZyYW1lVmlldyhsLCB0aGlzLnNldHRpbmdzLCBmcmFtZSwgbmFtZSkpO1xyXG5cdFx0XHRcdHRoaXMuYWRkQ29tbWFuZCh7XHJcblx0XHRcdFx0XHRpZDogYG9wZW4tJHtuYW1lfWAsXHJcblx0XHRcdFx0XHRuYW1lOiBgT3BlbiAke2ZyYW1lLmRpc3BsYXlOYW1lfWAsXHJcblx0XHRcdFx0XHRjYWxsYmFjazogKCkgPT4gdGhpcy5vcGVuTGVhZihuYW1lLCBmcmFtZS5vcGVuSW5DZW50ZXIsIGZhbHNlKSxcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0aWYgKGZyYW1lLmFkZFJpYmJvbkljb24pXHJcblx0XHRcdFx0XHR0aGlzLmFkZFJpYmJvbkljb24oZ2V0SWNvbihmcmFtZSksIGBPcGVuICR7ZnJhbWUuZGlzcGxheU5hbWV9YCxcclxuXHRcdFx0XHRcdFx0ZSA9PiB0aGlzLm9wZW5MZWFmKG5hbWUsIGZyYW1lLm9wZW5JbkNlbnRlciwgUGxhdGZvcm0uaXNNYWNPUyA/IGUubWV0YUtleSA6IGUuY3RybEtleSkpO1xyXG5cdFx0XHR9IGNhdGNoIHtcclxuXHRcdFx0XHRjb25zb2xlLmVycm9yKGBDb3VsZG4ndCByZWdpc3RlciBmcmFtZSAke25hbWV9LCBpcyB0aGVyZSBhbHJlYWR5IG9uZSB3aXRoIHRoZSBzYW1lIG5hbWU/YCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IEN1c3RvbUZyYW1lc1NldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcclxuXHJcblx0XHR0aGlzLnJlZ2lzdGVyTWFya2Rvd25Db2RlQmxvY2tQcm9jZXNzb3IoXCJjdXN0b20tZnJhbWVzXCIsIChzLCBlKSA9PiB7XHJcblx0XHRcdGUuZW1wdHkoKTtcclxuXHRcdFx0ZS5hZGRDbGFzcyhcImN1c3RvbS1mcmFtZXMtdmlldy1maWxlXCIpO1xyXG5cclxuXHRcdFx0bGV0IGZyYW1lTWF0Y2ggPSAvZnJhbWU6KFteXFxuXSspL2dpLmV4ZWMocyk7XHJcblx0XHRcdGxldCBmcmFtZU5hbWUgPSBmcmFtZU1hdGNoICYmIGZyYW1lTWF0Y2hbMV0udHJpbSgpO1xyXG5cdFx0XHRpZiAoIWZyYW1lTmFtZSkge1xyXG5cdFx0XHRcdGUuY3JlYXRlU3Bhbih7IHRleHQ6IFwiQ291bGRuJ3QgcGFyc2UgZnJhbWUgbmFtZVwiIH0pO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRsZXQgZGF0YSA9IHRoaXMuc2V0dGluZ3MuZnJhbWVzLmZpbmQoZiA9PiBmLmRpc3BsYXlOYW1lID09IGZyYW1lTmFtZSk7XHJcblx0XHRcdGlmICghZGF0YSkge1xyXG5cdFx0XHRcdGUuY3JlYXRlU3Bhbih7IHRleHQ6IGBDb3VsZG4ndCBmaW5kIGEgZnJhbWUgd2l0aCBuYW1lICR7ZnJhbWVOYW1lfWAgfSk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChQbGF0Zm9ybS5pc01vYmlsZUFwcCAmJiBkYXRhLmhpZGVPbk1vYmlsZSkge1xyXG5cdFx0XHRcdGUuY3JlYXRlU3Bhbih7IHRleHQ6IGAke2ZyYW1lTmFtZX0gaXMgaGlkZGVuIG9uIG1vYmlsZWAgfSk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRsZXQgc3R5bGVNYXRjaCA9IC9zdHlsZTooW15cXG5dKykvZ2kuZXhlYyhzKTtcclxuXHRcdFx0bGV0IHN0eWxlID0gc3R5bGVNYXRjaCAmJiBzdHlsZU1hdGNoWzFdLnRyaW0oKTtcclxuXHRcdFx0c3R5bGUgfHw9IFwiaGVpZ2h0OiA2MDBweDtcIjtcclxuXHJcblx0XHRcdGxldCB1cmxTdWZmaXhNYXRjaCA9IC91cmxzdWZmaXg6KFteXFxuXSspL2dpLmV4ZWMocyk7XHJcblx0XHRcdGxldCB1cmxTdWZmaXggPSB1cmxTdWZmaXhNYXRjaCAmJiB1cmxTdWZmaXhNYXRjaFsxXS50cmltKCk7XHJcblx0XHRcdHVybFN1ZmZpeCB8fD0gXCJcIjtcclxuXHJcblx0XHRcdGxldCBmcmFtZSA9IG5ldyBDdXN0b21GcmFtZSh0aGlzLnNldHRpbmdzLCBkYXRhKTtcclxuXHRcdFx0ZS5hcHBlbmRDaGlsZChmcmFtZS5jcmVhdGUoc3R5bGUsIHVybFN1ZmZpeCkpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdFNldHRpbmdzLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xyXG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgYXN5bmMgb3BlbkxlYWYobmFtZTogc3RyaW5nLCBjZW50ZXI6IGJvb2xlYW4sIHNwbGl0OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XHJcblx0XHRpZiAoY2VudGVyKSB7XHJcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5kZXRhY2hMZWF2ZXNPZlR5cGUobmFtZSk7XHJcblx0XHRcdGxldCBsZWFmID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYWYoc3BsaXQpO1xyXG5cdFx0XHRhd2FpdCBsZWFmLnNldFZpZXdTdGF0ZSh7IHR5cGU6IG5hbWUsIGFjdGl2ZTogdHJ1ZSB9KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGlmICghdGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZShuYW1lKS5sZW5ndGgpXHJcblx0XHRcdFx0YXdhaXQgdGhpcy5hcHAud29ya3NwYWNlLmdldFJpZ2h0TGVhZihmYWxzZSkuc2V0Vmlld1N0YXRlKHsgdHlwZTogbmFtZSwgYWN0aXZlOiB0cnVlIH0pO1xyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2UucmV2ZWFsTGVhZih0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKG5hbWUpWzBdKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSBcIm9ic2lkaWFuXCI7XHJcbmltcG9ydCB7IEN1c3RvbUZyYW1lU2V0dGluZ3MsIEN1c3RvbUZyYW1lc1NldHRpbmdzLCBnZXRJZCB9IGZyb20gXCIuL3NldHRpbmdzXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQ3VzdG9tRnJhbWUge1xyXG5cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgc2V0dGluZ3M6IEN1c3RvbUZyYW1lc1NldHRpbmdzO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBkYXRhOiBDdXN0b21GcmFtZVNldHRpbmdzO1xyXG4gICAgcHJpdmF0ZSBmcmFtZTogSFRNTElGcmFtZUVsZW1lbnQgfCBhbnk7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3M6IEN1c3RvbUZyYW1lc1NldHRpbmdzLCBkYXRhOiBDdXN0b21GcmFtZVNldHRpbmdzKSB7XHJcbiAgICAgICAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xyXG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNyZWF0ZShhZGRpdGlvbmFsU3R5bGU6IHN0cmluZyA9IHVuZGVmaW5lZCwgdXJsU3VmZml4OiBzdHJpbmcgPSB1bmRlZmluZWQpOiBhbnkge1xyXG4gICAgICAgIGxldCBzdHlsZSA9IGBwYWRkaW5nOiAke3RoaXMuc2V0dGluZ3MucGFkZGluZ31weDtgO1xyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsU3R5bGUpXHJcbiAgICAgICAgICAgIHN0eWxlICs9IGFkZGl0aW9uYWxTdHlsZTtcclxuICAgICAgICBpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwICYmICF0aGlzLmRhdGEuZm9yY2VJZnJhbWUpIHtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ3ZWJ2aWV3XCIpO1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lLnNldEF0dHJpYnV0ZShcImFsbG93cG9wdXBzXCIsIFwiXCIpO1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lLmFkZEV2ZW50TGlzdGVuZXIoXCJkb20tcmVhZHlcIiwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZS5zZXRab29tRmFjdG9yKHRoaXMuZGF0YS56b29tTGV2ZWwpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZS5pbnNlcnRDU1ModGhpcy5kYXRhLmN1c3RvbUNzcyk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaWZyYW1lXCIpO1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lLnNldEF0dHJpYnV0ZShcInNhbmRib3hcIiwgXCJhbGxvdy1mb3JtcyBhbGxvdy1tb2RhbHMgYWxsb3ctcG9wdXBzIGFsbG93LXByZXNlbnRhdGlvbiBhbGxvdy1zYW1lLW9yaWdpbiBhbGxvdy1zY3JpcHRzIGFsbG93LXRvcC1uYXZpZ2F0aW9uLWJ5LXVzZXItYWN0aXZhdGlvblwiKTtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZS5zZXRBdHRyaWJ1dGUoXCJhbGxvd1wiLCBcImVuY3J5cHRlZC1tZWRpYTsgZnVsbHNjcmVlbjsgb3ZlcnNpemVkLWltYWdlczsgcGljdHVyZS1pbi1waWN0dXJlOyBzeW5jLXhocjsgZ2VvbG9jYXRpb247XCIpO1xyXG4gICAgICAgICAgICBzdHlsZSArPSBgdHJhbnNmb3JtOiBzY2FsZSgke3RoaXMuZGF0YS56b29tTGV2ZWx9KTsgdHJhbnNmb3JtLW9yaWdpbjogMCAwO2A7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZnJhbWUuYWRkQ2xhc3MoXCJjdXN0b20tZnJhbWVzLWZyYW1lXCIpO1xyXG4gICAgICAgIHRoaXMuZnJhbWUuYWRkQ2xhc3MoYGN1c3RvbS1mcmFtZXMtJHtnZXRJZCh0aGlzLmRhdGEpfWApO1xyXG4gICAgICAgIHRoaXMuZnJhbWUuc2V0QXR0cmlidXRlKFwic3R5bGVcIiwgc3R5bGUpO1xyXG5cclxuICAgICAgICBsZXQgc3JjID0gdGhpcy5kYXRhLnVybDtcclxuICAgICAgICBpZiAodXJsU3VmZml4KSB7XHJcbiAgICAgICAgICAgIGlmICghdXJsU3VmZml4LnN0YXJ0c1dpdGgoXCIvXCIpKVxyXG4gICAgICAgICAgICAgICAgc3JjICs9IFwiL1wiO1xyXG4gICAgICAgICAgICBzcmMgKz0gdXJsU3VmZml4O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmZyYW1lLnNldEF0dHJpYnV0ZShcInNyY1wiLCBzcmMpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmVmcmVzaCgpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5mcmFtZSBpbnN0YW5jZW9mIEhUTUxJRnJhbWVFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lLnJlbG9hZCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmV0dXJuKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmZyYW1lIGluc3RhbmNlb2YgSFRNTElGcmFtZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZS5jb250ZW50V2luZG93Lm9wZW4odGhpcy5kYXRhLnVybCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZS5sb2FkVVJMKHRoaXMuZGF0YS51cmwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ29CYWNrKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmZyYW1lIGluc3RhbmNlb2YgSFRNTElGcmFtZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZS5jb250ZW50V2luZG93Lmhpc3RvcnkuYmFjaygpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJhbWUuZ29CYWNrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnb0ZvcndhcmQoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZnJhbWUgaW5zdGFuY2VvZiBIVE1MSUZyYW1lRWxlbWVudCkge1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lLmNvbnRlbnRXaW5kb3cuaGlzdG9yeS5mb3J3YXJkKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZS5nb0ZvcndhcmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHRvZ2dsZURldlRvb2xzKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghKHRoaXMuZnJhbWUgaW5zdGFuY2VvZiBIVE1MSUZyYW1lRWxlbWVudCkpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmZyYW1lLmlzRGV2VG9vbHNPcGVuZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZS5vcGVuRGV2VG9vbHMoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWUuY2xvc2VEZXZUb29scygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRDdXJyZW50VXJsKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJhbWUgaW5zdGFuY2VvZiBIVE1MSUZyYW1lRWxlbWVudCA/IHRoaXMuZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5ocmVmIDogdGhpcy5mcmFtZS5nZXRVUkwoKTtcclxuICAgIH1cclxufVxyXG4iLCAiZXhwb3J0IGNvbnN0IGRlZmF1bHRTZXR0aW5nczogQ3VzdG9tRnJhbWVzU2V0dGluZ3MgPSB7XHJcbiAgICBmcmFtZXM6IFtdLFxyXG4gICAgcGFkZGluZzogNVxyXG59O1xyXG5leHBvcnQgY29uc3QgcHJlc2V0czogUmVjb3JkPHN0cmluZywgQ3VzdG9tRnJhbWVTZXR0aW5ncz4gPSB7XHJcbiAgICBcIm9ic2lkaWFuXCI6IHtcclxuICAgICAgICB1cmw6IFwiaHR0cHM6Ly9mb3J1bS5vYnNpZGlhbi5tZC9cIixcclxuICAgICAgICBkaXNwbGF5TmFtZTogXCJPYnNpZGlhbiBGb3J1bVwiLFxyXG4gICAgICAgIGljb246IFwiZWRpdFwiLFxyXG4gICAgICAgIGhpZGVPbk1vYmlsZTogdHJ1ZSxcclxuICAgICAgICBhZGRSaWJib25JY29uOiB0cnVlLFxyXG4gICAgICAgIG9wZW5JbkNlbnRlcjogdHJ1ZSxcclxuICAgICAgICB6b29tTGV2ZWw6IDEsXHJcbiAgICAgICAgZm9yY2VJZnJhbWU6IGZhbHNlLFxyXG4gICAgICAgIGN1c3RvbUNzczogXCJcIlxyXG4gICAgfSxcclxuICAgIFwiZGV0ZXhpZnlcIjoge1xyXG4gICAgICAgIHVybDogXCJodHRwczovL2RldGV4aWZ5LmtpcmVsYWJzLm9yZy9jbGFzc2lmeS5odG1sXCIsXHJcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiRGV0ZXhpZnlcIixcclxuICAgICAgICBpY29uOiBcInR5cGVcIixcclxuICAgICAgICBoaWRlT25Nb2JpbGU6IHRydWUsXHJcbiAgICAgICAgYWRkUmliYm9uSWNvbjogdHJ1ZSxcclxuICAgICAgICBvcGVuSW5DZW50ZXI6IGZhbHNlLFxyXG4gICAgICAgIHpvb21MZXZlbDogLjk1LFxyXG4gICAgICAgIGZvcmNlSWZyYW1lOiBmYWxzZSxcclxuICAgICAgICBjdXN0b21Dc3M6IGAvKiBoaWRlIGluZm8gY2x1dHRlciBhbmQgYWQgYmFubmVyICovXHJcbiNjbGFzc2lmeS0taW5mby1hcmVhLFxyXG4uYWRzYnlnb29nbGUge1xyXG5cdGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudFxyXG59YFxyXG4gICAgfSxcclxuICAgIFwiY2FsZW5kYXJcIjoge1xyXG4gICAgICAgIHVybDogXCJodHRwczovL2NhbGVuZGFyLmdvb2dsZS5jb20vY2FsZW5kYXJcIixcclxuICAgICAgICBkaXNwbGF5TmFtZTogXCJHb29nbGUgQ2FsZW5kYXJcIixcclxuICAgICAgICBpY29uOiBcImNhbGVuZGFyXCIsXHJcbiAgICAgICAgaGlkZU9uTW9iaWxlOiB0cnVlLFxyXG4gICAgICAgIGFkZFJpYmJvbkljb246IHRydWUsXHJcbiAgICAgICAgb3BlbkluQ2VudGVyOiB0cnVlLFxyXG4gICAgICAgIHpvb21MZXZlbDogMSxcclxuICAgICAgICBmb3JjZUlmcmFtZTogZmFsc2UsXHJcbiAgICAgICAgY3VzdG9tQ3NzOiBgLyogaGlkZSB0aGUgbWVudSBiYXIsIFwiS2VlcFwiIHRleHQsIGFuZCBsb2dvICovXHJcbmh0bWwgPiBib2R5ID4gZGl2Om50aC1jaGlsZCgyKSA+IGRpdjpudGgtY2hpbGQoMikgPiBkaXY6Zmlyc3QtY2hpbGRbY2xhc3MqPVwiIFwiXSxcclxuaHRtbCA+IGJvZHkgPiBkaXY6Zmlyc3QtY2hpbGQgPiBoZWFkZXI6Zmlyc3QtY2hpbGQgPiBkaXYgPiBkaXY6Zmlyc3QtY2hpbGQgPiBkaXYgPiBkaXY6Zmlyc3QtY2hpbGQsXHJcbmh0bWwgPiBib2R5ID4gZGl2Om50aC1jaGlsZCgyKSA+IGRpdjpudGgtY2hpbGQoMikgPiBkaXY6Zmlyc3QtY2hpbGQgPiBkaXY6Zmlyc3QtY2hpbGQge1xyXG5kaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XHJcbn1gXHJcbiAgICB9LFxyXG4gICAgXCJrZWVwXCI6IHtcclxuICAgICAgICB1cmw6IFwiaHR0cHM6Ly9rZWVwLmdvb2dsZS5jb21cIixcclxuICAgICAgICBkaXNwbGF5TmFtZTogXCJHb29nbGUgS2VlcFwiLFxyXG4gICAgICAgIGljb246IFwiZmlsZXNcIixcclxuICAgICAgICBoaWRlT25Nb2JpbGU6IHRydWUsXHJcbiAgICAgICAgYWRkUmliYm9uSWNvbjogZmFsc2UsXHJcbiAgICAgICAgb3BlbkluQ2VudGVyOiBmYWxzZSxcclxuICAgICAgICB6b29tTGV2ZWw6IDEsXHJcbiAgICAgICAgZm9yY2VJZnJhbWU6IGZhbHNlLFxyXG4gICAgICAgIGN1c3RvbUNzczogYC8qIGhpZGUgdGhlIG1lbnUgYmFyIGFuZCB0aGUgXCJLZWVwXCIgdGV4dCAqL1xyXG5odG1sID4gYm9keSA+IGRpdjpudGgtY2hpbGQoMikgPiBkaXY6bnRoLWNoaWxkKDIpID4gZGl2OmZpcnN0LWNoaWxkLFxyXG5odG1sID4gYm9keSA+IGRpdjpmaXJzdC1jaGlsZCA+IGhlYWRlcjpmaXJzdC1jaGlsZCA+IGRpdiA+IGRpdjpmaXJzdC1jaGlsZCA+IGRpdiA+IGRpdjpmaXJzdC1jaGlsZCA+IGE6Zmlyc3QtY2hpbGQgPiBzcGFuIHtcclxuXHRkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XHJcbn1gXHJcbiAgICB9LFxyXG4gICAgXCJ0b2RvaXN0XCI6IHtcclxuICAgICAgICB1cmw6IFwiaHR0cHM6Ly90b2RvaXN0LmNvbVwiLFxyXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlRvZG9pc3RcIixcclxuICAgICAgICBpY29uOiBcImxpc3QtY2hlY2tzXCIsXHJcbiAgICAgICAgaGlkZU9uTW9iaWxlOiB0cnVlLFxyXG4gICAgICAgIGFkZFJpYmJvbkljb246IGZhbHNlLFxyXG4gICAgICAgIG9wZW5JbkNlbnRlcjogZmFsc2UsXHJcbiAgICAgICAgem9vbUxldmVsOiAxLFxyXG4gICAgICAgIGZvcmNlSWZyYW1lOiBmYWxzZSxcclxuICAgICAgICBjdXN0b21Dc3M6IGAvKiBoaWRlIHRoZSBoZWxwLCBob21lLCBzZWFyY2gsIGFuZCBwcm9kdWN0aXZpdHkgb3ZlcnZpZXcgYnV0dG9ucywgY3JlYXRlIGV4dHJhIHNwYWNlLCBhbmQgcHJldmVudCB0b2FzdCBwb3AtdXAgZnJvbSBhY3Rpbmcgd2VpcmQgKi9cclxuW2FyaWEtbGFiZWw9XCJHbyB0byBIb21lIHZpZXdcIl0sICNxdWlja19maW5kLCBbYXJpYS1sYWJlbD1cIlByb2R1Y3Rpdml0eVwiXSwgW2FyaWEtbGFiZWw9XCJIZWxwICYgRmVlZGJhY2tcIl0ge1xyXG5cdGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcclxufVxyXG5cclxuLnZpZXdfY29udGVudCB7XHJcblx0cGFkZGluZy1sZWZ0OiAxNXB4O1xyXG59XHJcblxyXG4udmlld19oZWFkZXIge1xyXG5cdHBhZGRpbmctbGVmdDogMTVweDtcclxuXHRwYWRkaW5nLXRvcDogMTBweDtcclxufVxyXG5cclxuLnVuZG9fdG9hc3Qge1xyXG5cdHdpZHRoOiA5NSU7XHJcbn1gXHJcbiAgICB9LFxyXG4gICAgXCJub3Rpb25cIjoge1xyXG4gICAgICAgIHVybDogXCJodHRwczovL3d3dy5ub3Rpb24uc28vXCIsXHJcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiTm90aW9uXCIsXHJcbiAgICAgICAgaWNvbjogXCJib3hcIixcclxuICAgICAgICBoaWRlT25Nb2JpbGU6IHRydWUsXHJcbiAgICAgICAgYWRkUmliYm9uSWNvbjogdHJ1ZSxcclxuICAgICAgICBvcGVuSW5DZW50ZXI6IHRydWUsXHJcbiAgICAgICAgem9vbUxldmVsOiAxLFxyXG4gICAgICAgIGZvcmNlSWZyYW1lOiBmYWxzZSxcclxuICAgICAgICBjdXN0b21Dc3M6IFwiXCJcclxuICAgIH0sXHJcbiAgICBcInR3aXR0ZXJcIjoge1xyXG4gICAgICAgIHVybDogXCJodHRwczovL3R3aXR0ZXIuY29tXCIsXHJcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiVHdpdHRlclwiLFxyXG4gICAgICAgIGljb246IFwidHdpdHRlclwiLFxyXG4gICAgICAgIGhpZGVPbk1vYmlsZTogdHJ1ZSxcclxuICAgICAgICBhZGRSaWJib25JY29uOiBmYWxzZSxcclxuICAgICAgICBvcGVuSW5DZW50ZXI6IGZhbHNlLFxyXG4gICAgICAgIHpvb21MZXZlbDogMSxcclxuICAgICAgICBmb3JjZUlmcmFtZTogZmFsc2UsXHJcbiAgICAgICAgY3VzdG9tQ3NzOiBcIlwiXHJcbiAgICB9XHJcbn07XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbUZyYW1lc1NldHRpbmdzIHtcclxuICAgIGZyYW1lczogQ3VzdG9tRnJhbWVTZXR0aW5nc1tdO1xyXG4gICAgcGFkZGluZzogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEN1c3RvbUZyYW1lU2V0dGluZ3Mge1xyXG4gICAgdXJsOiBzdHJpbmc7XHJcbiAgICBkaXNwbGF5TmFtZTogc3RyaW5nO1xyXG4gICAgaWNvbjogc3RyaW5nO1xyXG4gICAgaGlkZU9uTW9iaWxlOiBib29sZWFuO1xyXG4gICAgYWRkUmliYm9uSWNvbjogYm9vbGVhbjtcclxuICAgIG9wZW5JbkNlbnRlcjogYm9vbGVhbjtcclxuICAgIHpvb21MZXZlbDogbnVtYmVyO1xyXG4gICAgZm9yY2VJZnJhbWU6IGJvb2xlYW47XHJcbiAgICBjdXN0b21Dc3M6IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEljb24oc2V0dGluZ3M6IEN1c3RvbUZyYW1lU2V0dGluZ3MpIHtcclxuICAgIHJldHVybiBzZXR0aW5ncy5pY29uID8gYGx1Y2lkZS0ke3NldHRpbmdzLmljb259YCA6IFwiZG9jdW1lbnRzXCI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRJZChzZXR0aW5nczogQ3VzdG9tRnJhbWVTZXR0aW5ncykge1xyXG4gICAgcmV0dXJuIHNldHRpbmdzLmRpc3BsYXlOYW1lLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxzL2csIFwiLVwiKTtcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBCdXR0b25Db21wb25lbnQsIERyb3Bkb3duQ29tcG9uZW50LCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nIH0gZnJvbSBcIm9ic2lkaWFuXCI7XHJcbmltcG9ydCB7IGRlZmF1bHRTZXR0aW5ncywgcHJlc2V0cyB9IGZyb20gXCIuL3NldHRpbmdzXCI7XHJcbmltcG9ydCBDdXN0b21GcmFtZXNQbHVnaW4gZnJvbSBcIi4vbWFpblwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIEN1c3RvbUZyYW1lc1NldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcclxuXHJcbiAgICBwbHVnaW46IEN1c3RvbUZyYW1lc1BsdWdpbjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBDdXN0b21GcmFtZXNQbHVnaW4pIHtcclxuICAgICAgICBzdXBlcihhcHAsIHBsdWdpbik7XHJcbiAgICAgICAgdGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcbiAgICB9XHJcblxyXG4gICAgZGlzcGxheSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmVtcHR5KCk7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJDdXN0b20gRnJhbWVzIFNldHRpbmdzXCIgfSk7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBcIlBsZWFzZSBub3RlIHRoYXQgT2JzaWRpYW4gaGFzIHRvIGJlIHJlc3RhcnRlZCBvciByZWxvYWRlZCBmb3IgbW9zdCBvZiB0aGVzZSBzZXR0aW5ncyB0byB0YWtlIGVmZmVjdC5cIiwgY2xzOiBcIm1vZC13YXJuaW5nXCIgfSk7XHJcblxyXG4gICAgICAgIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpXHJcbiAgICAgICAgICAgIC5zZXROYW1lKFwiRnJhbWUgUGFkZGluZ1wiKVxyXG4gICAgICAgICAgICAuc2V0RGVzYyhcIlRoZSBwYWRkaW5nIHRoYXQgc2hvdWxkIGJlIGxlZnQgYXJvdW5kIHRoZSBpbnNpZGUgb2YgY3VzdG9tIGZyYW1lIHBhbmVzLCBpbiBwaXhlbHMuXCIpXHJcbiAgICAgICAgICAgIC5hZGRUZXh0KHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdC5pbnB1dEVsLnR5cGUgPSBcIm51bWJlclwiO1xyXG4gICAgICAgICAgICAgICAgdC5zZXRWYWx1ZShTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3MucGFkZGluZykpO1xyXG4gICAgICAgICAgICAgICAgdC5vbkNoYW5nZShhc3luYyB2ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5wYWRkaW5nID0gdi5sZW5ndGggPyBOdW1iZXIodikgOiBkZWZhdWx0U2V0dGluZ3MucGFkZGluZztcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgZnJhbWUgb2YgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJhbWVzKSB7XHJcbiAgICAgICAgICAgIGxldCBoZWFkaW5nID0gdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogZnJhbWUuZGlzcGxheU5hbWUgfHwgXCJVbm5hbWVkIEZyYW1lXCIgfSk7XHJcbiAgICAgICAgICAgIGxldCB0b2dnbGUgPSBuZXcgQnV0dG9uQ29tcG9uZW50KHRoaXMuY29udGFpbmVyRWwpXHJcbiAgICAgICAgICAgICAgICAuc2V0QnV0dG9uVGV4dChcIlNob3cgU2V0dGluZ3NcIilcclxuICAgICAgICAgICAgICAgIC5zZXRDbGFzcyhcImN1c3RvbS1mcmFtZXMtc2hvd1wiKVxyXG4gICAgICAgICAgICAgICAgLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnQuaGlkZGVuID0gIWNvbnRlbnQuaGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgICAgIHRvZ2dsZS5zZXRCdXR0b25UZXh0KGNvbnRlbnQuaGlkZGVuID8gXCJTaG93IFNldHRpbmdzXCIgOiBcIkhpZGUgU2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbGV0IGNvbnRlbnQgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZURpdigpO1xyXG4gICAgICAgICAgICBjb250ZW50LmhpZGRlbiA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICBuZXcgU2V0dGluZyhjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgLnNldE5hbWUoXCJEaXNwbGF5IE5hbWVcIilcclxuICAgICAgICAgICAgICAgIC5zZXREZXNjKFwiVGhlIGRpc3BsYXkgbmFtZSB0aGF0IHRoaXMgZnJhbWUgc2hvdWxkIGhhdmUuXCIpXHJcbiAgICAgICAgICAgICAgICAuYWRkVGV4dCh0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKGZyYW1lLmRpc3BsYXlOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB0Lm9uQ2hhbmdlKGFzeW5jIHYgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS5kaXNwbGF5TmFtZSA9IHY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRpbmcuc2V0VGV4dChmcmFtZS5kaXNwbGF5TmFtZSB8fCBcIlVubmFtZWQgRnJhbWVcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG5ldyBTZXR0aW5nKGNvbnRlbnQpXHJcbiAgICAgICAgICAgICAgICAuc2V0TmFtZShcIkljb25cIilcclxuICAgICAgICAgICAgICAgIC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KGYgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGYuY3JlYXRlU3Bhbih7IHRleHQ6IFwiVGhlIGljb24gdGhhdCB0aGlzIGZyYW1lJ3MgcGFuZSBzaG91bGQgaGF2ZS4gVGhlIG5hbWVzIG9mIGFueSBcIiB9KTtcclxuICAgICAgICAgICAgICAgICAgICBmLmNyZWF0ZUVsKFwiYVwiLCB7IHRleHQ6IFwiTHVjaWRlIGljb25zXCIsIGhyZWY6IFwiaHR0cHM6Ly9sdWNpZGUuZGV2L1wiIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGYuY3JlYXRlU3Bhbih7IHRleHQ6IFwiIGNhbiBiZSB1c2VkLlwiIH0pO1xyXG4gICAgICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgICAgICAgICAuYWRkVGV4dCh0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKGZyYW1lLmljb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHQub25DaGFuZ2UoYXN5bmMgdiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLmljb24gPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBuZXcgU2V0dGluZyhjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgLnNldE5hbWUoXCJVUkxcIilcclxuICAgICAgICAgICAgICAgIC5zZXREZXNjKFwiVGhlIFVSTCB0aGF0IHNob3VsZCBiZSBvcGVuZWQgaW4gdGhpcyBmcmFtZS5cIilcclxuICAgICAgICAgICAgICAgIC5hZGRUZXh0KHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHQuc2V0VmFsdWUoZnJhbWUudXJsKTtcclxuICAgICAgICAgICAgICAgICAgICB0Lm9uQ2hhbmdlKGFzeW5jIHYgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS51cmwgPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBuZXcgU2V0dGluZyhjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgLnNldE5hbWUoXCJEaXNhYmxlIG9uIE1vYmlsZVwiKVxyXG4gICAgICAgICAgICAgICAgLnNldERlc2MoXCJDdXN0b20gRnJhbWVzIGlzIGEgbG90IG1vcmUgcmVzdHJpY3RlZCBvbiBtb2JpbGUgZGV2aWNlcyBhbmQgZG9lc24ndCBhbGxvdyBmb3IgdGhlIHNhbWUgdHlwZXMgb2YgY29udGVudCB0byBiZSBkaXNwbGF5ZWQuIElmIGEgZnJhbWUgZG9lc24ndCB3b3JrIGFzIGV4cGVjdGVkIG9uIG1vYmlsZSwgaXQgY2FuIGJlIGRpc2FibGVkLlwiKVxyXG4gICAgICAgICAgICAgICAgLmFkZFRvZ2dsZSh0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKGZyYW1lLmhpZGVPbk1vYmlsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vbkNoYW5nZShhc3luYyB2ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUuaGlkZU9uTW9iaWxlID0gdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbmV3IFNldHRpbmcoY29udGVudClcclxuICAgICAgICAgICAgICAgIC5zZXROYW1lKFwiQWRkIFJpYmJvbiBJY29uXCIpXHJcbiAgICAgICAgICAgICAgICAuc2V0RGVzYyhcIldoZXRoZXIgYSBidXR0b24gdG8gb3BlbiB0aGlzIGZyYW1lIHNob3VsZCBiZSBhZGRlZCB0byB0aGUgcmliYm9uLlwiKVxyXG4gICAgICAgICAgICAgICAgLmFkZFRvZ2dsZSh0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKGZyYW1lLmFkZFJpYmJvbkljb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHQub25DaGFuZ2UoYXN5bmMgdiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lLmFkZFJpYmJvbkljb24gPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBuZXcgU2V0dGluZyhjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgLnNldE5hbWUoXCJPcGVuIGluIENlbnRlclwiKVxyXG4gICAgICAgICAgICAgICAgLnNldERlc2MoXCJXaGV0aGVyIHRoaXMgZnJhbWUgc2hvdWxkIGJlIG9wZW5lZCBpbiB0aGUgdW5waW5uZWQgY2VudGVyIGVkaXRvciByYXRoZXIgdGhhbiBvbmUgb2YgdGhlIHBhbmVzIG9uIHRoZSBzaWRlLiBUaGlzIGlzIHVzZWZ1bCBmb3Igc2l0ZXMgdGhhdCBkb24ndCB3b3JrIHdlbGwgaW4gYSBuYXJyb3cgdmlldywgb3Igc2l0ZXMgdGhhdCBkb24ndCByZXF1aXJlIGEgbm90ZSB0byBiZSBvcGVuIHdoZW4gdmlld2VkLlwiKVxyXG4gICAgICAgICAgICAgICAgLmFkZFRvZ2dsZSh0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKGZyYW1lLm9wZW5JbkNlbnRlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vbkNoYW5nZShhc3luYyB2ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUub3BlbkluQ2VudGVyID0gdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbmV3IFNldHRpbmcoY29udGVudClcclxuICAgICAgICAgICAgICAgIC5zZXROYW1lKFwiRm9yY2UgaWZyYW1lXCIpXHJcbiAgICAgICAgICAgICAgICAuc2V0RGVzYyhjcmVhdGVGcmFnbWVudChmID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBmLmNyZWF0ZVNwYW4oeyB0ZXh0OiBcIldoZXRoZXIgdGhpcyBmcmFtZSBzaG91bGQgdXNlIGlmcmFtZXMgb24gZGVza3RvcCBhcyBvcHBvc2VkIHRvIEVsZWN0cm9uIHdlYnZpZXdzLlwiIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGYuY3JlYXRlRWwoXCJiclwiKTtcclxuICAgICAgICAgICAgICAgICAgICBmLmNyZWF0ZUVsKFwiZW1cIiwgeyB0ZXh0OiBcIk9ubHkgZW5hYmxlIHRoaXMgc2V0dGluZyBpZiB0aGUgZnJhbWUgaXMgY2F1c2luZyBpc3N1ZXMgb3IgZnJlcXVlbnQgY3Jhc2hlcy4gVGhpcyBzZXR0aW5nIGNhdXNlcyBhbGwgRGVza3RvcC1vbmx5IHNldHRpbmdzIHRvIGJlIGlnbm9yZWQuXCIgfSk7XHJcbiAgICAgICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgICAgIC5hZGRUb2dnbGUodCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5zZXRWYWx1ZShmcmFtZS5mb3JjZUlmcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vbkNoYW5nZShhc3luYyB2ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUuZm9yY2VJZnJhbWUgPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBuZXcgU2V0dGluZyhjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgLnNldE5hbWUoXCJQYWdlIFpvb21cIilcclxuICAgICAgICAgICAgICAgIC5zZXREZXNjKFwiVGhlIHpvb20gdGhhdCB0aGlzIGZyYW1lJ3MgcGFnZSBzaG91bGQgYmUgZGlzcGxheWVkIHdpdGgsIGFzIGEgcGVyY2VudGFnZS5cIilcclxuICAgICAgICAgICAgICAgIC5hZGRUZXh0KHQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHQuaW5wdXRFbC50eXBlID0gXCJudW1iZXJcIjtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKFN0cmluZyhmcmFtZS56b29tTGV2ZWwgKiAxMDApKTtcclxuICAgICAgICAgICAgICAgICAgICB0Lm9uQ2hhbmdlKGFzeW5jIHYgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZS56b29tTGV2ZWwgPSB2Lmxlbmd0aCA/IE51bWJlcih2KSAvIDEwMCA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG5ldyBTZXR0aW5nKGNvbnRlbnQpXHJcbiAgICAgICAgICAgICAgICAuc2V0TmFtZShcIkFkZGl0aW9uYWwgQ1NTXCIpXHJcbiAgICAgICAgICAgICAgICAuc2V0RGVzYyhjcmVhdGVGcmFnbWVudChmID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBmLmNyZWF0ZVNwYW4oeyB0ZXh0OiBcIkEgc25pcHBldCBvZiBhZGRpdGlvbmFsIENTUyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIHRvIHRoaXMgZnJhbWUuXCIgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZi5jcmVhdGVFbChcImJyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGYuY3JlYXRlRWwoXCJlbVwiLCB7IHRleHQ6IFwiTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhcHBsaWVkIG9uIERlc2t0b3AuXCIgfSk7XHJcbiAgICAgICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgICAgIC5hZGRUZXh0QXJlYSh0ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0LmlucHV0RWwucm93cyA9IDU7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5pbnB1dEVsLmNvbHMgPSA1MDtcclxuICAgICAgICAgICAgICAgICAgICB0LnNldFZhbHVlKGZyYW1lLmN1c3RvbUNzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdC5vbkNoYW5nZShhc3luYyB2ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWUuY3VzdG9tQ3NzID0gdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbmV3IEJ1dHRvbkNvbXBvbmVudChjb250ZW50KVxyXG4gICAgICAgICAgICAgICAgLnNldEJ1dHRvblRleHQoXCJSZW1vdmUgRnJhbWVcIilcclxuICAgICAgICAgICAgICAgIC5vbkNsaWNrKGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mcmFtZXMucmVtb3ZlKGZyYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXkoKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImhyXCIpO1xyXG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJwXCIsIHsgdGV4dDogXCJDcmVhdGUgYSBuZXcgZnJhbWUsIGVpdGhlciBmcm9tIGEgcHJlc2V0IHNoaXBwZWQgd2l0aCB0aGUgcGx1Z2luLCBvciBhIGN1c3RvbSBvbmUgdGhhdCB5b3UgY2FuIGVkaXQgeW91cnNlbGYuIEVhY2ggZnJhbWUncyBwYW5lIGNhbiBiZSBvcGVuZWQgdXNpbmcgdGhlIFxcXCJDdXN0b20gRnJhbWVzOiBPcGVuXFxcIiBjb21tYW5kLlwiIH0pO1xyXG5cclxuICAgICAgICBsZXQgYWRkRGl2ID0gdGhpcy5jb250YWluZXJFbC5jcmVhdGVEaXYoKTtcclxuICAgICAgICBsZXQgZHJvcGRvd24gPSBuZXcgRHJvcGRvd25Db21wb25lbnQoYWRkRGl2KTtcclxuICAgICAgICBkcm9wZG93bi5hZGRPcHRpb24oXCJuZXdcIiwgXCJDdXN0b21cIik7XHJcbiAgICAgICAgZm9yIChsZXQga2V5IG9mIE9iamVjdC5rZXlzKHByZXNldHMpKVxyXG4gICAgICAgICAgICBkcm9wZG93bi5hZGRPcHRpb24oa2V5LCBwcmVzZXRzW2tleV0uZGlzcGxheU5hbWUpO1xyXG4gICAgICAgIG5ldyBCdXR0b25Db21wb25lbnQoYWRkRGl2KVxyXG4gICAgICAgICAgICAuc2V0QnV0dG9uVGV4dChcIkFkZCBGcmFtZVwiKVxyXG4gICAgICAgICAgICAuc2V0Q2xhc3MoXCJjdXN0b20tZnJhbWVzLWFkZFwiKVxyXG4gICAgICAgICAgICAub25DbGljayhhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBsZXQgb3B0aW9uID0gZHJvcGRvd24uZ2V0VmFsdWUoKTtcclxuICAgICAgICAgICAgICAgIGlmIChvcHRpb24gPT0gXCJuZXdcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmZyYW1lcy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBcIlwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5TmFtZTogXCJOZXcgRnJhbWVcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbjogXCJcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU9uTW9iaWxlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSaWJib25JY29uOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbkluQ2VudGVyOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9vbUxldmVsOiAxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3JjZUlmcmFtZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1c3RvbUNzczogXCJcIlxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mcmFtZXMucHVzaChwcmVzZXRzW29wdGlvbl0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXkoKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHZhciBkaXNjbGFpbWVyID0gdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwgeyBjbHM6IFwibW9kLXdhcm5pbmdcIiB9KTtcclxuICAgICAgICBkaXNjbGFpbWVyLmNyZWF0ZVNwYW4oeyB0ZXh0OiBcIlBsZWFzZSBiZSBhZHZpc2VkIHRoYXQsIHdoZW4gYWRkaW5nIGEgc2l0ZSBhcyBhIGN1c3RvbSBmcmFtZSwgeW91IHBvdGVudGlhbGx5IGV4cG9zZSBwZXJzb25hbCBpbmZvcm1hdGlvbiB5b3UgZW50ZXIgdG8gb3RoZXIgcGx1Z2lucyB5b3UgaGF2ZSBpbnN0YWxsZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgXCIgfSk7XHJcbiAgICAgICAgZGlzY2xhaW1lci5jcmVhdGVFbChcImFcIiwgeyB0ZXh0OiBcInRoaXMgZGlzY3Vzc2lvblwiLCBocmVmOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9FbGxwZWNrL09ic2lkaWFuQ3VzdG9tRnJhbWVzL2lzc3Vlcy81NCNpc3N1ZWNvbW1lbnQtMTIxMDg3OTY4NVwiLCBjbHM6IFwibW9kLXdhcm5pbmdcIiB9KTtcclxuICAgICAgICBkaXNjbGFpbWVyLmNyZWF0ZVNwYW4oeyB0ZXh0OiBcIi5cIiB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5jcmVhdGVFbChcImhyXCIpO1xyXG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwuY3JlYXRlRWwoXCJwXCIsIHsgdGV4dDogXCJJZiB5b3UgbGlrZSB0aGlzIHBsdWdpbiBhbmQgd2FudCB0byBzdXBwb3J0IGl0cyBkZXZlbG9wbWVudCwgeW91IGNhbiBkbyBzbyB0aHJvdWdoIG15IHdlYnNpdGUgYnkgY2xpY2tpbmcgdGhpcyBmYW5jeSBpbWFnZSFcIiB9KTtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiYVwiLCB7IGhyZWY6IFwiaHR0cHM6Ly9lbGxwZWNrLmRlL3N1cHBvcnRcIiB9KVxyXG4gICAgICAgICAgICAuY3JlYXRlRWwoXCJpbWdcIiwgeyBhdHRyOiB7IHNyYzogXCJodHRwczovL2VsbHBlY2suZGUvcmVzL2dlbmVyYWxzdXBwb3J0LnBuZ1wiIH0sIGNsczogXCJjdXN0b20tZnJhbWVzLXN1cHBvcnRcIiB9KTtcclxuICAgIH1cclxufVxyXG4iLCAiaW1wb3J0IHsgSXRlbVZpZXcsIFdvcmtzcGFjZUxlYWYsIE1lbnUgfSBmcm9tIFwib2JzaWRpYW5cIjtcclxuaW1wb3J0IHsgQ3VzdG9tRnJhbWUgfSBmcm9tIFwiLi9mcmFtZVwiO1xyXG5pbXBvcnQgeyBDdXN0b21GcmFtZVNldHRpbmdzLCBDdXN0b21GcmFtZXNTZXR0aW5ncywgZ2V0SWNvbiB9IGZyb20gXCIuL3NldHRpbmdzXCI7XHJcblxyXG5leHBvcnQgY2xhc3MgQ3VzdG9tRnJhbWVWaWV3IGV4dGVuZHMgSXRlbVZpZXcge1xyXG5cclxuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IGFjdGlvbnM6IEFjdGlvbltdID0gW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgbmFtZTogXCJSZXR1cm4gdG8gb3JpZ2luYWwgcGFnZVwiLFxyXG4gICAgICAgICAgICBpY29uOiBcImhvbWVcIixcclxuICAgICAgICAgICAgYWN0aW9uOiB2ID0+IHYuZnJhbWUucmV0dXJuKClcclxuICAgICAgICB9LCB7XHJcbiAgICAgICAgICAgIG5hbWU6IFwiT3BlbiBkZXYgdG9vbHNcIixcclxuICAgICAgICAgICAgaWNvbjogXCJiaW5hcnlcIixcclxuICAgICAgICAgICAgYWN0aW9uOiB2ID0+IHYuZnJhbWUudG9nZ2xlRGV2VG9vbHMoKVxyXG4gICAgICAgIH0sIHtcclxuICAgICAgICAgICAgbmFtZTogXCJDb3B5IGxpbmtcIixcclxuICAgICAgICAgICAgaWNvbjogXCJsaW5rXCIsXHJcbiAgICAgICAgICAgIGFjdGlvbjogdiA9PiBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCh2LmZyYW1lLmdldEN1cnJlbnRVcmwoKSlcclxuICAgICAgICB9LCB7XHJcbiAgICAgICAgICAgIG5hbWU6IFwiT3BlbiBpbiBicm93c2VyXCIsXHJcbiAgICAgICAgICAgIGljb246IFwiZ2xvYmVcIixcclxuICAgICAgICAgICAgYWN0aW9uOiB2ID0+IG9wZW4odi5mcmFtZS5nZXRDdXJyZW50VXJsKCkpXHJcbiAgICAgICAgfSwge1xyXG4gICAgICAgICAgICBuYW1lOiBcIlJlZnJlc2hcIixcclxuICAgICAgICAgICAgaWNvbjogXCJyZWZyZXNoLWN3XCIsXHJcbiAgICAgICAgICAgIGFjdGlvbjogdiA9PiB2LmZyYW1lLnJlZnJlc2goKVxyXG4gICAgICAgIH0sIHtcclxuICAgICAgICAgICAgbmFtZTogXCJHbyBiYWNrXCIsXHJcbiAgICAgICAgICAgIGljb246IFwiYXJyb3ctbGVmdFwiLFxyXG4gICAgICAgICAgICBhY3Rpb246IHYgPT4gdi5mcmFtZS5nb0JhY2soKVxyXG4gICAgICAgIH0sIHtcclxuICAgICAgICAgICAgbmFtZTogXCJHbyBmb3J3YXJkXCIsXHJcbiAgICAgICAgICAgIGljb246IFwiYXJyb3ctcmlnaHRcIixcclxuICAgICAgICAgICAgYWN0aW9uOiB2ID0+IHYuZnJhbWUuZ29Gb3J3YXJkKClcclxuICAgICAgICB9XHJcbiAgICBdO1xyXG5cclxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGF0YTogQ3VzdG9tRnJhbWVTZXR0aW5ncztcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBmcmFtZTogQ3VzdG9tRnJhbWU7XHJcblxyXG4gICAgY29uc3RydWN0b3IobGVhZjogV29ya3NwYWNlTGVhZiwgc2V0dGluZ3M6IEN1c3RvbUZyYW1lc1NldHRpbmdzLCBkYXRhOiBDdXN0b21GcmFtZVNldHRpbmdzLCBuYW1lOiBzdHJpbmcpIHtcclxuICAgICAgICBzdXBlcihsZWFmKTtcclxuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xyXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5mcmFtZSA9IG5ldyBDdXN0b21GcmFtZShzZXR0aW5ncywgZGF0YSk7XHJcblxyXG4gICAgICAgIGZvciAobGV0IGFjdGlvbiBvZiBDdXN0b21GcmFtZVZpZXcuYWN0aW9ucylcclxuICAgICAgICAgICAgdGhpcy5hZGRBY3Rpb24oYWN0aW9uLmljb24sIGFjdGlvbi5uYW1lLCAoKSA9PiBhY3Rpb24uYWN0aW9uKHRoaXMpKTtcclxuICAgIH1cclxuXHJcbiAgICBvbmxvYWQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5jb250ZW50RWwuZW1wdHkoKTtcclxuICAgICAgICB0aGlzLmNvbnRlbnRFbC5hZGRDbGFzcyhcImN1c3RvbS1mcmFtZXMtdmlld1wiKTtcclxuICAgICAgICB0aGlzLmNvbnRlbnRFbC5hcHBlbmRDaGlsZCh0aGlzLmZyYW1lLmNyZWF0ZSgpKTtcclxuICAgIH1cclxuXHJcbiAgICBvblBhbmVNZW51KG1lbnU6IE1lbnUsIHNvdXJjZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgc3VwZXIub25QYW5lTWVudShtZW51LCBzb3VyY2UpO1xyXG4gICAgICAgIGlmIChzb3VyY2UgPT0gXCJ0YWItaGVhZGVyXCIpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgYWN0aW9uIG9mIEN1c3RvbUZyYW1lVmlldy5hY3Rpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBtZW51LmFkZEl0ZW0oaSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaS5zZXRUaXRsZShhY3Rpb24ubmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaS5zZXRJY29uKGFjdGlvbi5pY29uKTtcclxuICAgICAgICAgICAgICAgICAgICBpLm9uQ2xpY2soKCkgPT4gYWN0aW9uLmFjdGlvbih0aGlzKSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXRWaWV3VHlwZSgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0RGlzcGxheVRleHQoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5kYXRhLmRpc3BsYXlOYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEljb24oKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gZ2V0SWNvbih0aGlzLmRhdGEpO1xyXG4gICAgfVxyXG59XHJcblxyXG5pbnRlcmZhY2UgQWN0aW9uIHtcclxuICAgIG5hbWU6IHN0cmluZztcclxuICAgIGljb246IHN0cmluZztcclxuICAgIGFjdGlvbjogKHZpZXc6IEN1c3RvbUZyYW1lVmlldykgPT4gYW55O1xy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