mirror of
https://github.com/tazihad/obsidian-easy-keep-view.git
synced 2026-07-22 12:50:26 +00:00
410 lines
49 KiB
JavaScript
410 lines
49 KiB
JavaScript
/*
|
|
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);
|
|
|
|
// main.ts
|
|
var main_exports = {};
|
|
__export(main_exports, {
|
|
default: () => MyPlugin
|
|
});
|
|
module.exports = __toCommonJS(main_exports);
|
|
var import_obsidian = require("obsidian");
|
|
var VIEW_TYPE_EASY_KEEP = "easy-keep-view";
|
|
var DEFAULT_SETTINGS = {
|
|
mySetting: "default",
|
|
notesDB: [],
|
|
themeMode: "system",
|
|
openAsHomepage: false
|
|
};
|
|
function resolveImageByName(app, imageName) {
|
|
const target = imageName.replace(/\.(jpg|jpeg|png|webp)$/i, "").toLowerCase();
|
|
const candidates = app.vault.getFiles().filter((f) => /\.(jpg|jpeg|png|webp)$/i.test(f.name));
|
|
for (const file of candidates) {
|
|
if (file.basename.toLowerCase() === target) {
|
|
return file;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
function debounce(fn, delay = 300) {
|
|
let timer;
|
|
return (...args) => {
|
|
clearTimeout(timer);
|
|
timer = setTimeout(() => fn(...args), delay);
|
|
};
|
|
}
|
|
var EasyKeepView = class extends import_obsidian.ItemView {
|
|
constructor(leaf, plugin) {
|
|
super(leaf);
|
|
this.plugin = plugin;
|
|
}
|
|
getViewType() {
|
|
return VIEW_TYPE_EASY_KEEP;
|
|
}
|
|
getDisplayText() {
|
|
return "Easy Keep View";
|
|
}
|
|
// Build the content of the view
|
|
async buildContent() {
|
|
this.mainContainer.empty();
|
|
this.mainContainer.style.overflowY = "auto";
|
|
this.mainContainer.style.height = "100%";
|
|
const cardContainer = this.mainContainer.createDiv("easy-keep-cards-container");
|
|
this.plugin.applyTheme();
|
|
const newNoteCard = cardContainer.createDiv("easy-keep-card new-note-card");
|
|
newNoteCard.createEl("h3", { text: "+" });
|
|
newNoteCard.createEl("p", { text: "Add New Note" });
|
|
newNoteCard.onclick = () => this.plugin.createNewNote();
|
|
await this.plugin.refreshThumbnails();
|
|
let notes = this.plugin.settings.notesDB.slice().sort((a, b) => b.time - a.time).slice(0, 100);
|
|
if (notes.length) {
|
|
notes.forEach((note) => {
|
|
const card = cardContainer.createDiv("easy-keep-card");
|
|
card.createEl("h3", { text: note.title });
|
|
if (note.imageLink) {
|
|
let file = this.app.metadataCache.getFirstLinkpathDest(note.imageLink, note.path);
|
|
if (!(file instanceof import_obsidian.TFile)) {
|
|
file = resolveImageByName(this.app, note.imageLink);
|
|
}
|
|
if (file instanceof import_obsidian.TFile) {
|
|
const resourcePath = this.app.vault.getResourcePath(file);
|
|
const img = card.createEl("img", { cls: "easy-keep-thumbnail" });
|
|
img.src = resourcePath;
|
|
img.onerror = () => {
|
|
console.warn("[Easy Keep View] Failed to load thumbnail:", resourcePath);
|
|
img.remove();
|
|
if (note.excerpt)
|
|
card.createEl("p", { text: note.excerpt });
|
|
};
|
|
img.onload = () => {
|
|
console.log("[Easy Keep View] Thumbnail loaded:", resourcePath);
|
|
};
|
|
} else if (note.excerpt) {
|
|
card.createEl("p", { text: note.excerpt });
|
|
}
|
|
} else if (note.excerpt) {
|
|
card.createEl("p", { text: note.excerpt });
|
|
}
|
|
card.onclick = () => this.plugin.openNoteInNewTab(note.path);
|
|
});
|
|
} else {
|
|
const noHistory = cardContainer.createDiv("no-history-message");
|
|
noHistory.setText("No notes, create a new one!");
|
|
}
|
|
}
|
|
async refreshContent() {
|
|
await this.buildContent();
|
|
}
|
|
// Initialize view on open
|
|
async onOpen() {
|
|
this.mainContainer = this.containerEl;
|
|
await this.plugin.loadSettings();
|
|
await this.buildContent();
|
|
this.loadCSS();
|
|
}
|
|
// Load custom CSS
|
|
loadCSS() {
|
|
const link = document.createElement("link");
|
|
link.rel = "stylesheet";
|
|
link.href = `${this.plugin.manifest.dir}/assets/styles.css`;
|
|
document.head.appendChild(link);
|
|
}
|
|
async onClose() {
|
|
}
|
|
};
|
|
var SampleSettingTab = class extends import_obsidian.PluginSettingTab {
|
|
constructor(app, plugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
display() {
|
|
const { containerEl } = this;
|
|
containerEl.empty();
|
|
containerEl.createEl("h2", { text: "Easy Keep View Plugin Settings" });
|
|
new import_obsidian.Setting(containerEl).setName("Theme Mode").setDesc("Select a theme mode for the Easy Keep View").addDropdown((dropdown) => {
|
|
dropdown.addOption("system", "System (adapt)");
|
|
dropdown.addOption("light", "Light");
|
|
dropdown.addOption("dark", "Dark");
|
|
dropdown.setValue(this.plugin.settings.themeMode);
|
|
dropdown.onChange(async (value) => {
|
|
this.plugin.settings.themeMode = value;
|
|
await this.plugin.saveSettings();
|
|
this.plugin.applyTheme();
|
|
this.plugin.refreshEasyKeepViewIfOpen();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Use Easy Keep View as Home Page").setDesc("Automatically open Easy Keep View when Obsidian starts").addToggle((toggle) => {
|
|
toggle.setValue(this.plugin.settings.openAsHomepage);
|
|
toggle.onChange(async (value) => {
|
|
this.plugin.settings.openAsHomepage = value;
|
|
await this.plugin.saveSettings();
|
|
new Notice("Restart Obsidian to apply the homepage setting.");
|
|
});
|
|
});
|
|
}
|
|
};
|
|
var MyPlugin = class extends import_obsidian.Plugin {
|
|
async onload() {
|
|
await this.loadSettings();
|
|
this.applyTheme();
|
|
this.app.workspace.onLayoutReady(async () => {
|
|
await this.cleanDatabase();
|
|
this.refreshEasyKeepViewIfOpen();
|
|
if (this.settings.openAsHomepage) {
|
|
await this.activateEasyKeepView();
|
|
}
|
|
});
|
|
this.registerView(VIEW_TYPE_EASY_KEEP, (leaf) => new EasyKeepView(leaf, this));
|
|
const ribbonIconEl = this.addRibbonIcon("dice", "Easy Keep View", () => {
|
|
this.activateEasyKeepView();
|
|
});
|
|
ribbonIconEl.addClass("my-plugin-ribbon-class");
|
|
this.registerEvent(this.app.workspace.on("file-open", async (file) => {
|
|
if (file) {
|
|
await this.addToDatabase(file);
|
|
this.refreshDebounced();
|
|
}
|
|
}));
|
|
this.registerEvent(this.app.vault.on("delete", async (file) => {
|
|
if (file instanceof import_obsidian.TFile) {
|
|
await this.removeFromDatabase(file.path);
|
|
this.refreshDebounced();
|
|
}
|
|
}));
|
|
this.registerEvent(this.app.vault.on("rename", async (file, oldPath) => {
|
|
if (file instanceof import_obsidian.TFile) {
|
|
const entryIndex = this.settings.notesDB.findIndex((e) => e.path === oldPath);
|
|
if (entryIndex !== -1) {
|
|
this.settings.notesDB[entryIndex].path = file.path;
|
|
this.settings.notesDB[entryIndex].title = file.basename;
|
|
await this.saveSettings();
|
|
this.refreshDebounced();
|
|
}
|
|
}
|
|
}));
|
|
this.registerEvent(this.app.vault.on("rename", async (file, oldPath) => {
|
|
if (file instanceof import_obsidian.TFile && /\.(jpg|jpeg|png|webp)$/i.test(file.path)) {
|
|
let updated = false;
|
|
this.settings.notesDB.forEach((entry) => {
|
|
if (entry.imageLink === oldPath) {
|
|
entry.imageLink = file.path;
|
|
updated = true;
|
|
}
|
|
});
|
|
if (updated) {
|
|
await this.saveSettings();
|
|
this.refreshDebounced();
|
|
}
|
|
}
|
|
}));
|
|
this.registerEvent(this.app.vault.on("modify", async (file) => {
|
|
if (file instanceof import_obsidian.TFile) {
|
|
await this.addToDatabase(file);
|
|
this.refreshDebounced();
|
|
}
|
|
}));
|
|
this.refreshDebounced = debounce(() => this.refreshEasyKeepViewIfOpen(), 300);
|
|
this.addSettingTab(new SampleSettingTab(this.app, this));
|
|
}
|
|
// Apply theme based on settings
|
|
applyTheme() {
|
|
const theme = this.settings.themeMode;
|
|
const existingLeaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_EASY_KEEP);
|
|
if (existingLeaves.length > 0) {
|
|
const view = existingLeaves[0].view;
|
|
const container = view.containerEl;
|
|
const cardContainer = container.querySelector(".easy-keep-cards-container");
|
|
if (cardContainer) {
|
|
cardContainer.removeClass("theme-light", "theme-dark", "theme-system");
|
|
if (theme === "system") {
|
|
const isDark = document.body.hasClass("theme-dark");
|
|
cardContainer.addClass(isDark ? "theme-dark" : "theme-light");
|
|
} else {
|
|
cardContainer.addClass(`theme-${theme}`);
|
|
}
|
|
}
|
|
}
|
|
if (theme === "system") {
|
|
document.documentElement.removeAttribute("data-theme");
|
|
} else {
|
|
document.documentElement.setAttribute("data-theme", theme);
|
|
}
|
|
}
|
|
onunload() {
|
|
this.app.workspace.detachLeavesOfType(VIEW_TYPE_EASY_KEEP);
|
|
}
|
|
// Activate the view
|
|
async activateEasyKeepView() {
|
|
const existingLeaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_EASY_KEEP);
|
|
if (existingLeaves.length > 0) {
|
|
this.app.workspace.revealLeaf(existingLeaves[0]);
|
|
return;
|
|
}
|
|
const leaf = this.app.workspace.getLeaf(true);
|
|
await leaf.setViewState({ type: VIEW_TYPE_EASY_KEEP, active: true });
|
|
this.app.workspace.revealLeaf(leaf);
|
|
}
|
|
// Refresh the view if open
|
|
async refreshEasyKeepViewIfOpen() {
|
|
const existingLeaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_EASY_KEEP);
|
|
if (existingLeaves.length > 0) {
|
|
const view = existingLeaves[0].view;
|
|
await view.refreshContent();
|
|
}
|
|
}
|
|
// Refresh note thumbnails based on content
|
|
// Refresh note thumbnails based on content
|
|
async refreshThumbnails() {
|
|
for (const note of this.settings.notesDB) {
|
|
const file = this.app.vault.getAbstractFileByPath(note.path);
|
|
if (!(file instanceof import_obsidian.TFile))
|
|
continue;
|
|
const content = await this.app.vault.cachedRead(file);
|
|
const lines = content.trim().split("\n").filter((line) => line.trim() !== "");
|
|
const firstLine = lines.find((line) => line.trim() !== "");
|
|
let excerpt = "";
|
|
let imageLink;
|
|
if (firstLine && firstLine.includes("![[") && firstLine.includes("]]")) {
|
|
excerpt = lines.slice(0, 1).join(" ");
|
|
} else {
|
|
if (firstLine) {
|
|
excerpt = firstLine;
|
|
if (lines.length > 1)
|
|
excerpt += " \u2026";
|
|
}
|
|
const match = content.match(/!\[\[([^\]]+)\]\]/);
|
|
if (match) {
|
|
imageLink = match[1].trim();
|
|
if (imageLink && note.imageLink !== imageLink) {
|
|
note.imageLink = imageLink;
|
|
}
|
|
}
|
|
}
|
|
if (imageLink) {
|
|
note.imageLink = imageLink;
|
|
}
|
|
if (excerpt) {
|
|
note.excerpt = excerpt;
|
|
}
|
|
}
|
|
await this.saveSettings();
|
|
}
|
|
// Add note to the database
|
|
async addToDatabase(file) {
|
|
var _a;
|
|
const content = await this.app.vault.cachedRead(file);
|
|
const lines = content.trim().split("\n").filter((line) => line.trim() !== "");
|
|
let excerpt = "";
|
|
let imageLink;
|
|
if (/\.(jpg|jpeg|png|webp)$/i.test(file.path)) {
|
|
imageLink = file.path;
|
|
} else {
|
|
const obsidianEmbedMatch = content.match(/!\[\[([^\]]+)\]\]/);
|
|
const markdownImageMatch = content.match(/!\[.*?\]\((.*?)\)/);
|
|
if (obsidianEmbedMatch || markdownImageMatch) {
|
|
imageLink = (_a = (obsidianEmbedMatch == null ? void 0 : obsidianEmbedMatch[1]) || (markdownImageMatch == null ? void 0 : markdownImageMatch[1])) == null ? void 0 : _a.trim();
|
|
}
|
|
}
|
|
if (!imageLink && lines.length > 0) {
|
|
excerpt = lines.slice(0, 2).join(" ");
|
|
if (lines.length > 2)
|
|
excerpt = excerpt.trim() + " \u2026";
|
|
}
|
|
const titleWithoutExt = file.name.replace(/\.(md|png|jpg|jpeg|webp)$/i, "");
|
|
const newEntry = {
|
|
path: file.path,
|
|
title: titleWithoutExt,
|
|
excerpt,
|
|
time: Date.now(),
|
|
imageLink
|
|
};
|
|
this.settings.notesDB = this.settings.notesDB.filter((entry) => entry.path !== file.path);
|
|
this.settings.notesDB.unshift(newEntry);
|
|
await this.saveSettings();
|
|
}
|
|
// Remove note from the database
|
|
async removeFromDatabase(filePath) {
|
|
const initialLength = this.settings.notesDB.length;
|
|
this.settings.notesDB = this.settings.notesDB.filter((entry) => entry.path !== filePath);
|
|
if (this.settings.notesDB.length !== initialLength) {
|
|
await this.saveSettings();
|
|
}
|
|
}
|
|
// Clean up the database by removing notes that no longer exist
|
|
async cleanDatabase() {
|
|
const files = this.app.vault.getMarkdownFiles();
|
|
const existingPaths = new Set(files.map((file) => file.path));
|
|
this.settings.notesDB = this.settings.notesDB.filter((entry) => existingPaths.has(entry.path));
|
|
await this.saveSettings();
|
|
}
|
|
// Open a note in a new tab
|
|
async openNoteInNewTab(filePath) {
|
|
const file = this.app.vault.getAbstractFileByPath(filePath);
|
|
if (!(file instanceof import_obsidian.TFile))
|
|
return;
|
|
let existingLeaf = null;
|
|
this.app.workspace.iterateAllLeaves((leaf) => {
|
|
var _a;
|
|
if (leaf.view.getViewType() === "markdown" && ((_a = leaf.view.file) == null ? void 0 : _a.path) === filePath) {
|
|
existingLeaf = leaf;
|
|
}
|
|
});
|
|
if (existingLeaf) {
|
|
this.app.workspace.setActiveLeaf(existingLeaf, { focus: true });
|
|
} else {
|
|
const newLeaf = this.app.workspace.getLeaf(true);
|
|
await newLeaf.openFile(file);
|
|
this.app.workspace.setActiveLeaf(newLeaf, { focus: true });
|
|
}
|
|
}
|
|
// Load settings from storage
|
|
async loadSettings() {
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
|
}
|
|
// Save settings to storage
|
|
async saveSettings() {
|
|
await this.saveData(this.settings);
|
|
}
|
|
// Generate a unique name for an untitled note
|
|
generateUniqueUntitledName() {
|
|
const baseName = "Untitled";
|
|
const files = this.app.vault.getMarkdownFiles();
|
|
const existingNames = new Set(files.map((f) => f.basename));
|
|
if (!existingNames.has(baseName)) {
|
|
return baseName;
|
|
}
|
|
let counter = 1;
|
|
while (existingNames.has(`${baseName} ${counter}`)) {
|
|
counter++;
|
|
}
|
|
return `${baseName} ${counter}`;
|
|
}
|
|
// Create a new note
|
|
async createNewNote() {
|
|
const title = this.generateUniqueUntitledName();
|
|
const filePath = `${title}.md`;
|
|
const file = await this.app.vault.create(filePath, "");
|
|
await this.addToDatabase(file);
|
|
this.openNoteInNewTab(filePath);
|
|
}
|
|
};
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHtcblx0QXBwLFxuXHRQbHVnaW4sXG5cdFdvcmtzcGFjZUxlYWYsXG5cdEl0ZW1WaWV3LFxuXHRURmlsZSxcblx0UGx1Z2luU2V0dGluZ1RhYixcblx0U2V0dGluZyxcbn0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmltcG9ydCBcIi4vc3R5bGVzLmNzc1wiO1xuXG5jb25zdCBWSUVXX1RZUEVfRUFTWV9LRUVQID0gXCJlYXN5LWtlZXAtdmlld1wiO1xuXG5pbnRlcmZhY2UgTm90ZUVudHJ5IHtcblx0cGF0aDogc3RyaW5nO1xuXHR0aXRsZTogc3RyaW5nO1xuXHRleGNlcnB0OiBzdHJpbmc7XG5cdHRpbWU6IG51bWJlcjtcblx0aW1hZ2VMaW5rPzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgTXlQbHVnaW5TZXR0aW5ncyB7XG5cdG15U2V0dGluZzogc3RyaW5nO1xuXHRub3Rlc0RCOiBOb3RlRW50cnlbXTtcblx0dGhlbWVNb2RlOiBcInN5c3RlbVwiIHwgXCJsaWdodFwiIHwgXCJkYXJrXCI7XG5cdG9wZW5Bc0hvbWVwYWdlOiBib29sZWFuO1xufVxuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTOiBNeVBsdWdpblNldHRpbmdzID0ge1xuXHRteVNldHRpbmc6IFwiZGVmYXVsdFwiLFxuXHRub3Rlc0RCOiBbXSxcblx0dGhlbWVNb2RlOiBcInN5c3RlbVwiLFxuXHRvcGVuQXNIb21lcGFnZTogZmFsc2UsXG59O1xuXG5cblxuLy8gSGVscGVyIGZ1bmN0aW9uIHRvIHJlc29sdmUgaW1hZ2UgYnkgbmFtZVxuZnVuY3Rpb24gcmVzb2x2ZUltYWdlQnlOYW1lKGFwcDogQXBwLCBpbWFnZU5hbWU6IHN0cmluZyk6IFRGaWxlIHwgbnVsbCB7XG5cdGNvbnN0IHRhcmdldCA9IGltYWdlTmFtZS5yZXBsYWNlKC9cXC4oanBnfGpwZWd8cG5nfHdlYnApJC9pLCBcIlwiKS50b0xvd2VyQ2FzZSgpO1xuXHRjb25zdCBjYW5kaWRhdGVzID0gYXBwLnZhdWx0LmdldEZpbGVzKCkuZmlsdGVyKGYgPT4gL1xcLihqcGd8anBlZ3xwbmd8d2VicCkkL2kudGVzdChmLm5hbWUpKTtcblx0Zm9yIChjb25zdCBmaWxlIG9mIGNhbmRpZGF0ZXMpIHtcblx0XHRpZiAoZmlsZS5iYXNlbmFtZS50b0xvd2VyQ2FzZSgpID09PSB0YXJnZXQpIHtcblx0XHRcdHJldHVybiBmaWxlO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbnVsbDtcbn1cblxuLy8gRGVib3VuY2UgZnVuY3Rpb24gZm9yIHRocm90dGxpbmcgdXBkYXRlc1xuZnVuY3Rpb24gZGVib3VuY2UoZm46ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCwgZGVsYXkgPSAzMDApOiAoLi4uYXJnczogYW55W10pID0+IHZvaWQge1xuXHRsZXQgdGltZXI6IE5vZGVKUy5UaW1lb3V0O1xuXHRyZXR1cm4gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG5cdFx0Y2xlYXJUaW1lb3V0KHRpbWVyKTtcblx0XHR0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gZm4oLi4uYXJncyksIGRlbGF5KTtcblx0fTtcbn1cblxuXG5cbmNsYXNzIEVhc3lLZWVwVmlldyBleHRlbmRzIEl0ZW1WaWV3IHtcblx0cGx1Z2luOiBNeVBsdWdpbjtcblx0cHJpdmF0ZSBtYWluQ29udGFpbmVyOiBIVE1MRWxlbWVudDtcblxuXHRjb25zdHJ1Y3RvcihsZWFmOiBXb3Jrc3BhY2VMZWFmLCBwbHVnaW46IE15UGx1Z2luKSB7XG5cdFx0c3VwZXIobGVhZik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRnZXRWaWV3VHlwZSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiBWSUVXX1RZUEVfRUFTWV9LRUVQO1xuXHR9XG5cblx0Z2V0RGlzcGxheVRleHQoKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gXCJFYXN5IEtlZXAgVmlld1wiO1xuXHR9XG5cblx0Ly8gQnVpbGQgdGhlIGNvbnRlbnQgb2YgdGhlIHZpZXdcblx0YXN5bmMgYnVpbGRDb250ZW50KCkge1xuXHRcdHRoaXMubWFpbkNvbnRhaW5lci5lbXB0eSgpO1xuXHRcdHRoaXMubWFpbkNvbnRhaW5lci5zdHlsZS5vdmVyZmxvd1kgPSBcImF1dG9cIjtcblx0XHR0aGlzLm1haW5Db250YWluZXIuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG5cdFxuXHRcdGNvbnN0IGNhcmRDb250YWluZXIgPSB0aGlzLm1haW5Db250YWluZXIuY3JlYXRlRGl2KFwiZWFzeS1rZWVwLWNhcmRzLWNvbnRhaW5lclwiKTtcblx0XG5cdFx0Ly8gQXBwbHkgdGhlIHRoZW1lIHRvIHRoZSBjYXJkIGNvbnRhaW5lciBpbW1lZGlhdGVseVxuXHRcdHRoaXMucGx1Z2luLmFwcGx5VGhlbWUoKTtcblx0XG5cdFx0Ly8gTmV3IE5vdGUgQ2FyZFxuXHRcdGNvbnN0IG5ld05vdGVDYXJkID0gY2FyZENvbnRhaW5lci5jcmVhdGVEaXYoXCJlYXN5LWtlZXAtY2FyZCBuZXctbm90ZS1jYXJkXCIpO1xuXHRcdG5ld05vdGVDYXJkLmNyZWF0ZUVsKFwiaDNcIiwgeyB0ZXh0OiBcIitcIiB9KTtcblx0XHRuZXdOb3RlQ2FyZC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBcIkFkZCBOZXcgTm90ZVwiIH0pO1xuXHRcdG5ld05vdGVDYXJkLm9uY2xpY2sgPSAoKSA9PiB0aGlzLnBsdWdpbi5jcmVhdGVOZXdOb3RlKCk7XG5cdFxuXHRcdC8vIEJlZm9yZSBidWlsZGluZyBjYXJkcywgcmVmcmVzaCB0aHVtYm5haWxzIGZyb20gbm90ZSBjb250ZW50LlxuXHRcdGF3YWl0IHRoaXMucGx1Z2luLnJlZnJlc2hUaHVtYm5haWxzKCk7XG5cdFxuXHRcdGxldCBub3RlcyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLm5vdGVzREIuc2xpY2UoKVxuXHRcdFx0LnNvcnQoKGEsIGIpID0+IGIudGltZSAtIGEudGltZSlcblx0XHRcdC5zbGljZSgwLCAxMDApO1xuXHRcblx0XHRpZiAobm90ZXMubGVuZ3RoKSB7XG5cdFx0XHRub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuXHRcdFx0XHRjb25zdCBjYXJkID0gY2FyZENvbnRhaW5lci5jcmVhdGVEaXYoXCJlYXN5LWtlZXAtY2FyZFwiKTtcblx0XHRcdFx0Y2FyZC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogbm90ZS50aXRsZSB9KTtcblx0XG5cdFx0XHRcdGlmIChub3RlLmltYWdlTGluaykge1xuXHRcdFx0XHRcdGxldCBmaWxlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChub3RlLmltYWdlTGluaywgbm90ZS5wYXRoKTtcblx0XHRcdFx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7XG5cdFx0XHRcdFx0XHRmaWxlID0gcmVzb2x2ZUltYWdlQnlOYW1lKHRoaXMuYXBwLCBub3RlLmltYWdlTGluayk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHJlc291cmNlUGF0aCA9IHRoaXMuYXBwLnZhdWx0LmdldFJlc291cmNlUGF0aChmaWxlKTtcblx0XHRcdFx0XHRcdGNvbnN0IGltZyA9IGNhcmQuY3JlYXRlRWwoXCJpbWdcIiwgeyBjbHM6IFwiZWFzeS1rZWVwLXRodW1ibmFpbFwiIH0pO1xuXHRcdFx0XHRcdFx0aW1nLnNyYyA9IHJlc291cmNlUGF0aDtcblx0XHRcdFx0XHRcdGltZy5vbmVycm9yID0gKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRjb25zb2xlLndhcm4oXCJbRWFzeSBLZWVwIFZpZXddIEZhaWxlZCB0byBsb2FkIHRodW1ibmFpbDpcIiwgcmVzb3VyY2VQYXRoKTtcblx0XHRcdFx0XHRcdFx0aW1nLnJlbW92ZSgpO1xuXHRcdFx0XHRcdFx0XHRpZiAobm90ZS5leGNlcnB0KSBjYXJkLmNyZWF0ZUVsKFwicFwiLCB7IHRleHQ6IG5vdGUuZXhjZXJwdCB9KTtcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHRpbWcub25sb2FkID0gKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIltFYXN5IEtlZXAgVmlld10gVGh1bWJuYWlsIGxvYWRlZDpcIiwgcmVzb3VyY2VQYXRoKTtcblx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChub3RlLmV4Y2VycHQpIHtcblx0XHRcdFx0XHRcdGNhcmQuY3JlYXRlRWwoXCJwXCIsIHsgdGV4dDogbm90ZS5leGNlcnB0IH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmIChub3RlLmV4Y2VycHQpIHtcblx0XHRcdFx0XHRjYXJkLmNyZWF0ZUVsKFwicFwiLCB7IHRleHQ6IG5vdGUuZXhjZXJwdCB9KTtcblx0XHRcdFx0fVxuXHRcblx0XHRcdFx0Y2FyZC5vbmNsaWNrID0gKCkgPT4gdGhpcy5wbHVnaW4ub3Blbk5vdGVJbk5ld1RhYihub3RlLnBhdGgpO1xuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IG5vSGlzdG9yeSA9IGNhcmRDb250YWluZXIuY3JlYXRlRGl2KFwibm8taGlzdG9yeS1tZXNzYWdlXCIpO1xuXHRcdFx0bm9IaXN0b3J5LnNldFRleHQoXCJObyBub3RlcywgY3JlYXRlIGEgbmV3IG9uZSFcIik7XG5cdFx0fVxuXHR9XG5cblxuXG5cdGFzeW5jIHJlZnJlc2hDb250ZW50KCkge1xuXHRcdGF3YWl0IHRoaXMuYnVpbGRDb250ZW50KCk7XG5cdH1cblxuXHQvLyBJbml0aWFsaXplIHZpZXcgb24gb3BlblxuXHRhc3luYyBvbk9wZW4oKSB7XG5cdFx0dGhpcy5tYWluQ29udGFpbmVyID0gdGhpcy5jb250YWluZXJFbDtcblx0XG5cdFx0Ly8gV2FpdCB1bnRpbCBwbHVnaW4gc2V0dGluZ3MgYXJlIGxvYWRlZFxuXHRcdGF3YWl0IHRoaXMucGx1Z2luLmxvYWRTZXR0aW5ncygpO1xuXHRcblx0XHQvLyBCdWlsZCBjb250ZW50IGFuZCBhcHBseSB0aGVtZVxuXHRcdGF3YWl0IHRoaXMuYnVpbGRDb250ZW50KCk7XG5cdFxuXHRcdHRoaXMubG9hZENTUygpO1xuXHR9XG5cblx0Ly8gTG9hZCBjdXN0b20gQ1NTXG5cdGxvYWRDU1MoKSB7XG5cdFx0Y29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaW5rXCIpO1xuXHRcdGxpbmsucmVsID0gXCJzdHlsZXNoZWV0XCI7XG5cdFx0bGluay5ocmVmID0gYCR7dGhpcy5wbHVnaW4ubWFuaWZlc3QuZGlyfS9hc3NldHMvc3R5bGVzLmNzc2A7XG5cdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChsaW5rKTtcblx0fVxuXG5cdGFzeW5jIG9uQ2xvc2UoKSB7fVxufVxuXG4vLyBQbHVnaW4gc2V0dGluZ3MgdGFiXG5jbGFzcyBTYW1wbGVTZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG5cdHBsdWdpbjogTXlQbHVnaW47XG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IE15UGx1Z2luKSB7XG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHR9XG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xuXG5cdFx0Y29udGFpbmVyRWwuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwiRWFzeSBLZWVwIFZpZXcgUGx1Z2luIFNldHRpbmdzXCIgfSk7XG5cblx0XHQvLyBUaGVtZSBtb2RlIHNlbGVjdG9yXG5cdFx0Ly8gVGhlbWUgbW9kZSBzZWxlY3RvclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKFwiVGhlbWUgTW9kZVwiKVxuXHRcdC5zZXREZXNjKFwiU2VsZWN0IGEgdGhlbWUgbW9kZSBmb3IgdGhlIEVhc3kgS2VlcCBWaWV3XCIpXG5cdFx0LmFkZERyb3Bkb3duKGRyb3Bkb3duID0+IHtcblx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihcInN5c3RlbVwiLCBcIlN5c3RlbSAoYWRhcHQpXCIpO1xuXHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKFwibGlnaHRcIiwgXCJMaWdodFwiKTtcblx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbihcImRhcmtcIiwgXCJEYXJrXCIpO1xuXHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudGhlbWVNb2RlKTtcblx0XHRcdGRyb3Bkb3duLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogXCJzeXN0ZW1cIiB8IFwibGlnaHRcIiB8IFwiZGFya1wiKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRoZW1lTW9kZSA9IHZhbHVlO1xuXHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0Ly8gQXBwbHkgdGhlIHNlbGVjdGVkIHRoZW1lXG5cdFx0XHRcdHRoaXMucGx1Z2luLmFwcGx5VGhlbWUoKTtcblx0XHRcdFx0dGhpcy5wbHVnaW4ucmVmcmVzaEVhc3lLZWVwVmlld0lmT3BlbigpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHQvLyBIb21lcGFnZSB0b2dnbGVcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZShcIlVzZSBFYXN5IEtlZXAgVmlldyBhcyBIb21lIFBhZ2VcIilcblx0XHQuc2V0RGVzYyhcIkF1dG9tYXRpY2FsbHkgb3BlbiBFYXN5IEtlZXAgVmlldyB3aGVuIE9ic2lkaWFuIHN0YXJ0c1wiKVxuXHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHtcblx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuQXNIb21lcGFnZSk7XG5cdFx0XHR0b2dnbGUub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLm9wZW5Bc0hvbWVwYWdlID0gdmFsdWU7XG5cdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRuZXcgTm90aWNlKFwiUmVzdGFydCBPYnNpZGlhbiB0byBhcHBseSB0aGUgaG9tZXBhZ2Ugc2V0dGluZy5cIik7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxufVxuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE15UGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IE15UGx1Z2luU2V0dGluZ3M7XG5cdHByaXZhdGUgcmVmcmVzaERlYm91bmNlZDogKCkgPT4gdm9pZDtcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblxuXHRcdC8vIEFwcGx5IHRoZW1lIG9uIHBsdWdpbiBsb2FkXG5cdFx0dGhpcy5hcHBseVRoZW1lKCk7XG5cblxuXHRcdC8vIERlZmVyIGNsZWFuRGF0YWJhc2UgdW50aWwgdmF1bHQgaXMgcmVhZHlcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeShhc3luYyAoKSA9PiB7XG5cdFx0XHRhd2FpdCB0aGlzLmNsZWFuRGF0YWJhc2UoKTtcblx0XHRcdHRoaXMucmVmcmVzaEVhc3lLZWVwVmlld0lmT3BlbigpO1xuXG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5vcGVuQXNIb21lcGFnZSkge1xuXHRcdFx0XHRhd2FpdCB0aGlzLmFjdGl2YXRlRWFzeUtlZXBWaWV3KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblxuXHRcdHRoaXMucmVnaXN0ZXJWaWV3KFZJRVdfVFlQRV9FQVNZX0tFRVAsIChsZWFmKSA9PiBuZXcgRWFzeUtlZXBWaWV3KGxlYWYsIHRoaXMpKTtcblxuXHRcdGNvbnN0IHJpYmJvbkljb25FbCA9IHRoaXMuYWRkUmliYm9uSWNvbihcImRpY2VcIiwgXCJFYXN5IEtlZXAgVmlld1wiLCAoKSA9PiB7XG5cdFx0XHR0aGlzLmFjdGl2YXRlRWFzeUtlZXBWaWV3KCk7XG5cdFx0fSk7XG5cdFx0cmliYm9uSWNvbkVsLmFkZENsYXNzKFwibXktcGx1Z2luLXJpYmJvbi1jbGFzc1wiKTtcblxuXHRcdC8vIFJlZnJlc2ggb24gZmlsZS1vcGVuIGV2ZW50cy5cblx0XHR0aGlzLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKFwiZmlsZS1vcGVuXCIsIGFzeW5jIChmaWxlKSA9PiB7XG5cdFx0XHRpZiAoZmlsZSkge1xuXHRcdFx0XHRhd2FpdCB0aGlzLmFkZFRvRGF0YWJhc2UoZmlsZSk7XG5cdFx0XHRcdHRoaXMucmVmcmVzaERlYm91bmNlZCgpO1xuXHRcdFx0fVxuXHRcdH0pKTtcblxuXHRcdC8vIFJlZnJlc2ggb24gZmlsZSBkZWxldGlvbi5cblx0XHR0aGlzLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAudmF1bHQub24oXCJkZWxldGVcIiwgYXN5bmMgKGZpbGUpID0+IHtcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcblx0XHRcdFx0YXdhaXQgdGhpcy5yZW1vdmVGcm9tRGF0YWJhc2UoZmlsZS5wYXRoKTtcblx0XHRcdFx0dGhpcy5yZWZyZXNoRGVib3VuY2VkKCk7XG5cdFx0XHR9XG5cdFx0fSkpO1xuXG5cdFx0Ly8gUmVmcmVzaCBvbiBmaWxlIHJlbmFtZSBmb3Igbm90ZXMuXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKFwicmVuYW1lXCIsIGFzeW5jIChmaWxlLCBvbGRQYXRoKSA9PiB7XG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XG5cdFx0XHRcdGNvbnN0IGVudHJ5SW5kZXggPSB0aGlzLnNldHRpbmdzLm5vdGVzREIuZmluZEluZGV4KGUgPT4gZS5wYXRoID09PSBvbGRQYXRoKTtcblx0XHRcdFx0aWYgKGVudHJ5SW5kZXggIT09IC0xKSB7XG5cdFx0XHRcdFx0dGhpcy5zZXR0aW5ncy5ub3Rlc0RCW2VudHJ5SW5kZXhdLnBhdGggPSBmaWxlLnBhdGg7XG5cdFx0XHRcdFx0dGhpcy5zZXR0aW5ncy5ub3Rlc0RCW2VudHJ5SW5kZXhdLnRpdGxlID0gZmlsZS5iYXNlbmFtZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMucmVmcmVzaERlYm91bmNlZCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSkpO1xuXG5cdFx0Ly8gUmVmcmVzaCBvbiBmaWxlIHJlbmFtZSBmb3IgaW1hZ2UgZmlsZXMuXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKFwicmVuYW1lXCIsIGFzeW5jIChmaWxlLCBvbGRQYXRoKSA9PiB7XG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlICYmIC9cXC4oanBnfGpwZWd8cG5nfHdlYnApJC9pLnRlc3QoZmlsZS5wYXRoKSkge1xuXHRcdFx0XHRsZXQgdXBkYXRlZCA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLnNldHRpbmdzLm5vdGVzREIuZm9yRWFjaChlbnRyeSA9PiB7XG5cdFx0XHRcdFx0aWYgKGVudHJ5LmltYWdlTGluayA9PT0gb2xkUGF0aCkge1xuXHRcdFx0XHRcdFx0ZW50cnkuaW1hZ2VMaW5rID0gZmlsZS5wYXRoO1xuXHRcdFx0XHRcdFx0dXBkYXRlZCA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0aWYgKHVwZGF0ZWQpIHtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMucmVmcmVzaERlYm91bmNlZCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSkpO1xuXG5cdFx0Ly8gTmV3OiBMaXN0ZW4gZm9yIG1vZGlmeSBldmVudHMgdG8gdXBkYXRlIHRodW1ibmFpbCBpbmZvIHdoZW4gbm90ZSBjb250ZW50IGNoYW5nZXMuXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKFwibW9kaWZ5XCIsIGFzeW5jIChmaWxlKSA9PiB7XG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XG5cdFx0XHRcdGF3YWl0IHRoaXMuYWRkVG9EYXRhYmFzZShmaWxlKTtcblx0XHRcdFx0dGhpcy5yZWZyZXNoRGVib3VuY2VkKCk7XG5cdFx0XHR9XG5cdFx0fSkpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBkZWJvdW5jZSBmb3IgcmVmcmVzaCBjYWxscy5cblx0XHR0aGlzLnJlZnJlc2hEZWJvdW5jZWQgPSBkZWJvdW5jZSgoKSA9PiB0aGlzLnJlZnJlc2hFYXN5S2VlcFZpZXdJZk9wZW4oKSwgMzAwKTtcblxuXHRcdHRoaXMuYWRkU2V0dGluZ1RhYihuZXcgU2FtcGxlU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXHR9XG5cblx0Ly8gQXBwbHkgdGhlbWUgYmFzZWQgb24gc2V0dGluZ3Ncblx0YXBwbHlUaGVtZSgpIHtcblx0XHRjb25zdCB0aGVtZSA9IHRoaXMuc2V0dGluZ3MudGhlbWVNb2RlO1xuXHRcdGNvbnN0IGV4aXN0aW5nTGVhdmVzID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZShWSUVXX1RZUEVfRUFTWV9LRUVQKTtcblx0XG5cdFx0aWYgKGV4aXN0aW5nTGVhdmVzLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IHZpZXcgPSBleGlzdGluZ0xlYXZlc1swXS52aWV3IGFzIEVhc3lLZWVwVmlldztcblx0XHRcdGNvbnN0IGNvbnRhaW5lciA9IHZpZXcuY29udGFpbmVyRWw7XG5cdFx0XHRjb25zdCBjYXJkQ29udGFpbmVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoXCIuZWFzeS1rZWVwLWNhcmRzLWNvbnRhaW5lclwiKTtcblx0XG5cdFx0XHRpZiAoY2FyZENvbnRhaW5lcikge1xuXHRcdFx0XHQvLyBSZW1vdmUgYWxsIHBvc3NpYmxlIHRoZW1lIGNsYXNzZXNcblx0XHRcdFx0Y2FyZENvbnRhaW5lci5yZW1vdmVDbGFzcyhcInRoZW1lLWxpZ2h0XCIsIFwidGhlbWUtZGFya1wiLCBcInRoZW1lLXN5c3RlbVwiKTtcblx0XG5cdFx0XHRcdC8vIEFwcGx5IHRoZSBzZWxlY3RlZCB0aGVtZVxuXHRcdFx0XHRpZiAodGhlbWUgPT09IFwic3lzdGVtXCIpIHtcblx0XHRcdFx0XHQvLyBEZXRlY3QgT2JzaWRpYW4ncyBjdXJyZW50IHRoZW1lXG5cdFx0XHRcdFx0Y29uc3QgaXNEYXJrID0gZG9jdW1lbnQuYm9keS5oYXNDbGFzcyhcInRoZW1lLWRhcmtcIik7XG5cdFx0XHRcdFx0Y2FyZENvbnRhaW5lci5hZGRDbGFzcyhpc0RhcmsgPyBcInRoZW1lLWRhcmtcIiA6IFwidGhlbWUtbGlnaHRcIik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y2FyZENvbnRhaW5lci5hZGRDbGFzcyhgdGhlbWUtJHt0aGVtZX1gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XG5cdFx0Ly8gT3B0aW9uYWxseSBzZXQgZGF0YS10aGVtZSBvbiA8aHRtbD4gZm9yIGJyb2FkZXIgY29tcGF0aWJpbGl0eSAobm90IHJlcXVpcmVkIGZvciB0aGlzIGZpeClcblx0XHRpZiAodGhlbWUgPT09IFwic3lzdGVtXCIpIHtcblx0XHRcdGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJkYXRhLXRoZW1lXCIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2V0QXR0cmlidXRlKFwiZGF0YS10aGVtZVwiLCB0aGVtZSk7XG5cdFx0fVxuXHR9XG5cblx0b251bmxvYWQoKSB7XG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLmRldGFjaExlYXZlc09mVHlwZShWSUVXX1RZUEVfRUFTWV9LRUVQKTtcblx0fVxuXG5cdC8vIEFjdGl2YXRlIHRoZSB2aWV3XG5cdGFzeW5jIGFjdGl2YXRlRWFzeUtlZXBWaWV3KCkge1xuXHRcdGNvbnN0IGV4aXN0aW5nTGVhdmVzID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZShWSUVXX1RZUEVfRUFTWV9LRUVQKTtcblx0XHRpZiAoZXhpc3RpbmdMZWF2ZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLnJldmVhbExlYWYoZXhpc3RpbmdMZWF2ZXNbMF0pO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGxlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZih0cnVlKTtcblx0XHRhd2FpdCBsZWFmLnNldFZpZXdTdGF0ZSh7IHR5cGU6IFZJRVdfVFlQRV9FQVNZX0tFRVAsIGFjdGl2ZTogdHJ1ZSB9KTtcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UucmV2ZWFsTGVhZihsZWFmKTtcblx0fVxuXG5cdC8vIFJlZnJlc2ggdGhlIHZpZXcgaWYgb3BlblxuXHRhc3luYyByZWZyZXNoRWFzeUtlZXBWaWV3SWZPcGVuKCkge1xuXHRcdGNvbnN0IGV4aXN0aW5nTGVhdmVzID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZShWSUVXX1RZUEVfRUFTWV9LRUVQKTtcblx0XHRpZiAoZXhpc3RpbmdMZWF2ZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc3QgdmlldyA9IGV4aXN0aW5nTGVhdmVzWzBdLnZpZXcgYXMgRWFzeUtlZXBWaWV3O1xuXHRcdFx0YXdhaXQgdmlldy5yZWZyZXNoQ29udGVudCgpO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJlZnJlc2ggbm90ZSB0aHVtYm5haWxzIGJhc2VkIG9uIGNvbnRlbnRcblx0Ly8gUmVmcmVzaCBub3RlIHRodW1ibmFpbHMgYmFzZWQgb24gY29udGVudFxuXHRhc3luYyByZWZyZXNoVGh1bWJuYWlscygpIHtcblx0XHRmb3IgKGNvbnN0IG5vdGUgb2YgdGhpcy5zZXR0aW5ncy5ub3Rlc0RCKSB7XG5cdFx0XHRjb25zdCBmaWxlID0gdGhpcy5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5vdGUucGF0aCk7XG5cdFx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSBjb250aW51ZTtcblxuXHRcdFx0Y29uc3QgY29udGVudCA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmNhY2hlZFJlYWQoZmlsZSk7XG5cdFx0XHRjb25zdCBsaW5lcyA9IGNvbnRlbnQudHJpbSgpLnNwbGl0KFwiXFxuXCIpLmZpbHRlcihsaW5lID0+IGxpbmUudHJpbSgpICE9PSBcIlwiKTtcblxuXHRcdFx0Ly8gR2V0IHRoZSBmaXJzdCBub24tZW1wdHkgbGluZSAoY29udGVudCBvciBpbWFnZSlcblx0XHRcdGNvbnN0IGZpcnN0TGluZSA9IGxpbmVzLmZpbmQobGluZSA9PiBsaW5lLnRyaW0oKSAhPT0gXCJcIik7XG5cblx0XHRcdGxldCBleGNlcnB0ID0gXCJcIjtcblx0XHRcdGxldCBpbWFnZUxpbms6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuXHRcdFx0Ly8gSWYgdGhlIGZpcnN0IGxpbmUgY29udGFpbnMgYW4gZW1iZWRkZWQgaW1hZ2UsIGRvbid0IHNob3cgdGhlIHRodW1ibmFpbCwganVzdCB0ZXh0XG5cdFx0XHRpZiAoZmlyc3RMaW5lICYmIGZpcnN0TGluZS5pbmNsdWRlcyhcIiFbW1wiKSAmJiBmaXJzdExpbmUuaW5jbHVkZXMoXCJdXVwiKSkge1xuXHRcdFx0XHQvLyBFeGNlcnB0IHNob3VsZCBqdXN0IGJlIHRoZSBjb250ZW50IHRleHQgYmVmb3JlIHRoZSBpbWFnZSBsaW5rXG5cdFx0XHRcdGV4Y2VycHQgPSBsaW5lcy5zbGljZSgwLCAxKS5qb2luKFwiIFwiKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIENyZWF0ZSBleGNlcnB0IGZyb20gZmlyc3QgbGluZXMgKHVwIHRvIDIgbGluZXMgb2YgY29udGVudClcblx0XHRcdFx0aWYgKGZpcnN0TGluZSkge1xuXHRcdFx0XHRcdGV4Y2VycHQgPSBmaXJzdExpbmU7XG5cdFx0XHRcdFx0aWYgKGxpbmVzLmxlbmd0aCA+IDEpIGV4Y2VycHQgKz0gXCIgXFx1MjAyNlwiOyAvLyBBZGQgZWxsaXBzaXMgaWYgdGhlcmUgYXJlIG1vcmUgbGluZXNcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENoZWNrIGlmIGFuIGltYWdlIGlzIGVtYmVkZGVkIGFueXdoZXJlIGVsc2UgaW4gdGhlIGNvbnRlbnQgKG5vdCBqdXN0IHRoZSBmaXJzdCBsaW5lKVxuXHRcdFx0XHRjb25zdCBtYXRjaCA9IGNvbnRlbnQubWF0Y2goLyFcXFtcXFsoW15cXF1dKylcXF1cXF0vKTtcblx0XHRcdFx0aWYgKG1hdGNoKSB7XG5cdFx0XHRcdFx0aW1hZ2VMaW5rID0gbWF0Y2hbMV0udHJpbSgpO1xuXHRcdFx0XHRcdGlmIChpbWFnZUxpbmsgJiYgbm90ZS5pbWFnZUxpbmsgIT09IGltYWdlTGluaykge1xuXHRcdFx0XHRcdFx0bm90ZS5pbWFnZUxpbmsgPSBpbWFnZUxpbms7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFVwZGF0ZSB0aGUgbm90ZSB3aXRoIGV4Y2VycHQgYW5kIGltYWdlTGluayBpZiBmb3VuZFxuXHRcdFx0aWYgKGltYWdlTGluaykge1xuXHRcdFx0XHRub3RlLmltYWdlTGluayA9IGltYWdlTGluaztcblx0XHRcdH1cblxuXHRcdFx0aWYgKGV4Y2VycHQpIHtcblx0XHRcdFx0bm90ZS5leGNlcnB0ID0gZXhjZXJwdDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHR9XG5cblxuXG5cdC8vIEFkZCBub3RlIHRvIHRoZSBkYXRhYmFzZVxuXHRhc3luYyBhZGRUb0RhdGFiYXNlKGZpbGU6IFRGaWxlKSB7XG5cdFx0Y29uc3QgY29udGVudCA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmNhY2hlZFJlYWQoZmlsZSk7XG5cdFx0Y29uc3QgbGluZXMgPSBjb250ZW50LnRyaW0oKS5zcGxpdChcIlxcblwiKS5maWx0ZXIobGluZSA9PiBsaW5lLnRyaW0oKSAhPT0gXCJcIik7XG5cdFx0bGV0IGV4Y2VycHQgPSBcIlwiO1xuXHRcdGxldCBpbWFnZUxpbms6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuXHRcdGlmICgvXFwuKGpwZ3xqcGVnfHBuZ3x3ZWJwKSQvaS50ZXN0KGZpbGUucGF0aCkpIHtcblx0XHRcdGltYWdlTGluayA9IGZpbGUucGF0aDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3Qgb2JzaWRpYW5FbWJlZE1hdGNoID0gY29udGVudC5tYXRjaCgvIVxcW1xcWyhbXlxcXV0rKVxcXVxcXS8pO1xuXHRcdFx0Y29uc3QgbWFya2Rvd25JbWFnZU1hdGNoID0gY29udGVudC5tYXRjaCgvIVxcWy4qP1xcXVxcKCguKj8pXFwpLyk7XG5cdFx0XHRpZiAob2JzaWRpYW5FbWJlZE1hdGNoIHx8IG1hcmtkb3duSW1hZ2VNYXRjaCkge1xuXHRcdFx0XHRpbWFnZUxpbmsgPSAob2JzaWRpYW5FbWJlZE1hdGNoPy5bMV0gfHwgbWFya2Rvd25JbWFnZU1hdGNoPy5bMV0pPy50cmltKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCFpbWFnZUxpbmsgJiYgbGluZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0ZXhjZXJwdCA9IGxpbmVzLnNsaWNlKDAsIDIpLmpvaW4oXCIgXCIpO1xuXHRcdFx0aWYgKGxpbmVzLmxlbmd0aCA+IDIpIGV4Y2VycHQgPSBleGNlcnB0LnRyaW0oKSArIFwiIFx1MjAyNlwiO1xuXHRcdH1cblxuXHRcdGNvbnN0IHRpdGxlV2l0aG91dEV4dCA9IGZpbGUubmFtZS5yZXBsYWNlKC9cXC4obWR8cG5nfGpwZ3xqcGVnfHdlYnApJC9pLCBcIlwiKTtcblx0XHRjb25zdCBuZXdFbnRyeTogTm90ZUVudHJ5ID0ge1xuXHRcdFx0cGF0aDogZmlsZS5wYXRoLFxuXHRcdFx0dGl0bGU6IHRpdGxlV2l0aG91dEV4dCxcblx0XHRcdGV4Y2VycHQsXG5cdFx0XHR0aW1lOiBEYXRlLm5vdygpLFxuXHRcdFx0aW1hZ2VMaW5rLFxuXHRcdH07XG5cblx0XHR0aGlzLnNldHRpbmdzLm5vdGVzREIgPSB0aGlzLnNldHRpbmdzLm5vdGVzREIuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LnBhdGggIT09IGZpbGUucGF0aCk7XG5cdFx0dGhpcy5zZXR0aW5ncy5ub3Rlc0RCLnVuc2hpZnQobmV3RW50cnkpO1xuXHRcdGF3YWl0IHRoaXMuc2F2ZVNldHRpbmdzKCk7XG5cdH1cblxuXHQvLyBSZW1vdmUgbm90ZSBmcm9tIHRoZSBkYXRhYmFzZVxuXHRhc3luYyByZW1vdmVGcm9tRGF0YWJhc2UoZmlsZVBhdGg6IHN0cmluZykge1xuXHRcdGNvbnN0IGluaXRpYWxMZW5ndGggPSB0aGlzLnNldHRpbmdzLm5vdGVzREIubGVuZ3RoO1xuXHRcdHRoaXMuc2V0dGluZ3Mubm90ZXNEQiA9IHRoaXMuc2V0dGluZ3Mubm90ZXNEQi5maWx0ZXIoZW50cnkgPT4gZW50cnkucGF0aCAhPT0gZmlsZVBhdGgpO1xuXHRcdGlmICh0aGlzLnNldHRpbmdzLm5vdGVzREIubGVuZ3RoICE9PSBpbml0aWFsTGVuZ3RoKSB7XG5cdFx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHRcdH1cblx0fVxuXG5cdC8vIENsZWFuIHVwIHRoZSBkYXRhYmFzZSBieSByZW1vdmluZyBub3RlcyB0aGF0IG5vIGxvbmdlciBleGlzdFxuXHRhc3luYyBjbGVhbkRhdGFiYXNlKCkge1xuXHRcdGNvbnN0IGZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0TWFya2Rvd25GaWxlcygpO1xuXHRcdGNvbnN0IGV4aXN0aW5nUGF0aHMgPSBuZXcgU2V0KGZpbGVzLm1hcChmaWxlID0+IGZpbGUucGF0aCkpO1xuXHRcdHRoaXMuc2V0dGluZ3Mubm90ZXNEQiA9IHRoaXMuc2V0dGluZ3Mubm90ZXNEQi5maWx0ZXIoZW50cnkgPT4gZXhpc3RpbmdQYXRocy5oYXMoZW50cnkucGF0aCkpO1xuXHRcdGF3YWl0IHRoaXMuc2F2ZVNldHRpbmdzKCk7XG5cdH1cblxuXHQvLyBPcGVuIGEgbm90ZSBpbiBhIG5ldyB0YWJcblx0YXN5bmMgb3Blbk5vdGVJbk5ld1RhYihmaWxlUGF0aDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgZmlsZSA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlUGF0aCk7XG5cdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSkgcmV0dXJuO1xuXHRcdGxldCBleGlzdGluZ0xlYWY6IFdvcmtzcGFjZUxlYWYgfCBudWxsID0gbnVsbDtcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UuaXRlcmF0ZUFsbExlYXZlcyhsZWFmID0+IHtcblx0XHRcdGlmIChsZWFmLnZpZXcuZ2V0Vmlld1R5cGUoKSA9PT0gXCJtYXJrZG93blwiICYmIChsZWFmLnZpZXcgYXMgYW55KS5maWxlPy5wYXRoID09PSBmaWxlUGF0aCkge1xuXHRcdFx0XHRleGlzdGluZ0xlYWYgPSBsZWFmO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdGlmIChleGlzdGluZ0xlYWYpIHtcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5zZXRBY3RpdmVMZWFmKGV4aXN0aW5nTGVhZiwgeyBmb2N1czogdHJ1ZSB9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgbmV3TGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWFmKHRydWUpO1xuXHRcdFx0YXdhaXQgbmV3TGVhZi5vcGVuRmlsZShmaWxlKTtcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5zZXRBY3RpdmVMZWFmKG5ld0xlYWYsIHsgZm9jdXM6IHRydWUgfSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gTG9hZCBzZXR0aW5ncyBmcm9tIHN0b3JhZ2Vcblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHR9XG5cblx0Ly8gU2F2ZSBzZXR0aW5ncyB0byBzdG9yYWdlXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcblx0XHRhd2FpdCB0aGlzLnNhdmVEYXRhKHRoaXMuc2V0dGluZ3MpO1xuXHR9XG5cblx0Ly8gR2VuZXJhdGUgYSB1bmlxdWUgbmFtZSBmb3IgYW4gdW50aXRsZWQgbm90ZVxuXHRnZW5lcmF0ZVVuaXF1ZVVudGl0bGVkTmFtZSgpOiBzdHJpbmcge1xuXHRcdGNvbnN0IGJhc2VOYW1lID0gXCJVbnRpdGxlZFwiO1xuXHRcdGNvbnN0IGZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0TWFya2Rvd25GaWxlcygpO1xuXHRcdGNvbnN0IGV4aXN0aW5nTmFtZXMgPSBuZXcgU2V0KGZpbGVzLm1hcChmID0+IGYuYmFzZW5hbWUpKTtcblxuXHRcdGlmICghZXhpc3RpbmdOYW1lcy5oYXMoYmFzZU5hbWUpKSB7XG5cdFx0XHRyZXR1cm4gYmFzZU5hbWU7XG5cdFx0fVxuXG5cdFx0bGV0IGNvdW50ZXIgPSAxO1xuXHRcdHdoaWxlIChleGlzdGluZ05hbWVzLmhhcyhgJHtiYXNlTmFtZX0gJHtjb3VudGVyfWApKSB7XG5cdFx0XHRjb3VudGVyKys7XG5cdFx0fVxuXHRcdHJldHVybiBgJHtiYXNlTmFtZX0gJHtjb3VudGVyfWA7XG5cdH1cblxuXHQvLyBDcmVhdGUgYSBuZXcgbm90ZVxuXHRhc3luYyBjcmVhdGVOZXdOb3RlKCkge1xuXHRcdGNvbnN0IHRpdGxlID0gdGhpcy5nZW5lcmF0ZVVuaXF1ZVVudGl0bGVkTmFtZSgpO1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gYCR7dGl0bGV9Lm1kYDtcblx0XHRjb25zdCBmaWxlID0gYXdhaXQgdGhpcy5hcHAudmF1bHQuY3JlYXRlKGZpbGVQYXRoLCBcIlwiKTtcblx0XHRhd2FpdCB0aGlzLmFkZFRvRGF0YWJhc2UoZmlsZSk7XG5cdFx0dGhpcy5vcGVuTm90ZUluTmV3VGFiKGZpbGVQYXRoKTtcblx0fVxufSJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxzQkFRTztBQUlQLElBQU0sc0JBQXNCO0FBaUI1QixJQUFNLG1CQUFxQztBQUFBLEVBQzFDLFdBQVc7QUFBQSxFQUNYLFNBQVMsQ0FBQztBQUFBLEVBQ1YsV0FBVztBQUFBLEVBQ1gsZ0JBQWdCO0FBQ2pCO0FBS0EsU0FBUyxtQkFBbUIsS0FBVSxXQUFpQztBQUN0RSxRQUFNLFNB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
|