mirror of
https://github.com/tazihad/obsidian-easy-keep-view.git
synced 2026-07-22 05:49:04 +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("sticky-note", "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+IHtcblx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuQXNIb21lcGFnZSk7XG5cdFx0XHR0b2dnbGUub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLm9wZW5Bc0hvbWVwYWdlID0gdmFsdWU7XG5cdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRuZXcgTm90aWNlKFwiUmVzdGFydCBPYnNpZGlhbiB0byBhcHBseSB0aGUgaG9tZXBhZ2Ugc2V0dGluZy5cIik7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxufVxuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE15UGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IE15UGx1Z2luU2V0dGluZ3M7XG5cdHByaXZhdGUgcmVmcmVzaERlYm91bmNlZDogKCkgPT4gdm9pZDtcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblxuXHRcdC8vIEFwcGx5IHRoZW1lIG9uIHBsdWdpbiBsb2FkXG5cdFx0dGhpcy5hcHBseVRoZW1lKCk7XG5cblxuXHRcdC8vIERlZmVyIGNsZWFuRGF0YWJhc2UgdW50aWwgdmF1bHQgaXMgcmVhZHlcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeShhc3luYyAoKSA9PiB7XG5cdFx0XHRhd2FpdCB0aGlzLmNsZWFuRGF0YWJhc2UoKTtcblx0XHRcdHRoaXMucmVmcmVzaEVhc3lLZWVwVmlld0lmT3BlbigpO1xuXG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5vcGVuQXNIb21lcGFnZSkge1xuXHRcdFx0XHRhd2FpdCB0aGlzLmFjdGl2YXRlRWFzeUtlZXBWaWV3KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblxuXHRcdHRoaXMucmVnaXN0ZXJWaWV3KFZJRVdfVFlQRV9FQVNZX0tFRVAsIChsZWFmKSA9PiBuZXcgRWFzeUtlZXBWaWV3KGxlYWYsIHRoaXMpKTtcblxuXHRcdGNvbnN0IHJpYmJvbkljb25FbCA9IHRoaXMuYWRkUmliYm9uSWNvbihcInN0aWNreS1ub3RlXCIsIFwiRWFzeSBLZWVwIFZpZXdcIiwgKCkgPT4ge1xuXHRcdFx0dGhpcy5hY3RpdmF0ZUVhc3lLZWVwVmlldygpO1xuXHRcdH0pO1xuXHRcdHJpYmJvbkljb25FbC5hZGRDbGFzcyhcIm15LXBsdWdpbi1yaWJib24tY2xhc3NcIik7XG5cblx0XHQvLyBSZWZyZXNoIG9uIGZpbGUtb3BlbiBldmVudHMuXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLndvcmtzcGFjZS5vbihcImZpbGUtb3BlblwiLCBhc3luYyAoZmlsZSkgPT4ge1xuXHRcdFx0aWYgKGZpbGUpIHtcblx0XHRcdFx0YXdhaXQgdGhpcy5hZGRUb0RhdGFiYXNlKGZpbGUpO1xuXHRcdFx0XHR0aGlzLnJlZnJlc2hEZWJvdW5jZWQoKTtcblx0XHRcdH1cblx0XHR9KSk7XG5cblx0XHQvLyBSZWZyZXNoIG9uIGZpbGUgZGVsZXRpb24uXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKFwiZGVsZXRlXCIsIGFzeW5jIChmaWxlKSA9PiB7XG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XG5cdFx0XHRcdGF3YWl0IHRoaXMucmVtb3ZlRnJvbURhdGFiYXNlKGZpbGUucGF0aCk7XG5cdFx0XHRcdHRoaXMucmVmcmVzaERlYm91bmNlZCgpO1xuXHRcdFx0fVxuXHRcdH0pKTtcblxuXHRcdC8vIFJlZnJlc2ggb24gZmlsZSByZW5hbWUgZm9yIG5vdGVzLlxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbihcInJlbmFtZVwiLCBhc3luYyAoZmlsZSwgb2xkUGF0aCkgPT4ge1xuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xuXHRcdFx0XHRjb25zdCBlbnRyeUluZGV4ID0gdGhpcy5zZXR0aW5ncy5ub3Rlc0RCLmZpbmRJbmRleChlID0+IGUucGF0aCA9PT0gb2xkUGF0aCk7XG5cdFx0XHRcdGlmIChlbnRyeUluZGV4ICE9PSAtMSkge1xuXHRcdFx0XHRcdHRoaXMuc2V0dGluZ3Mubm90ZXNEQltlbnRyeUluZGV4XS5wYXRoID0gZmlsZS5wYXRoO1xuXHRcdFx0XHRcdHRoaXMuc2V0dGluZ3Mubm90ZXNEQltlbnRyeUluZGV4XS50aXRsZSA9IGZpbGUuYmFzZW5hbWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLnJlZnJlc2hEZWJvdW5jZWQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pKTtcblxuXHRcdC8vIFJlZnJlc2ggb24gZmlsZSByZW5hbWUgZm9yIGltYWdlIGZpbGVzLlxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbihcInJlbmFtZVwiLCBhc3luYyAoZmlsZSwgb2xkUGF0aCkgPT4ge1xuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSAmJiAvXFwuKGpwZ3xqcGVnfHBuZ3x3ZWJwKSQvaS50ZXN0KGZpbGUucGF0aCkpIHtcblx0XHRcdFx0bGV0IHVwZGF0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5zZXR0aW5ncy5ub3Rlc0RCLmZvckVhY2goZW50cnkgPT4ge1xuXHRcdFx0XHRcdGlmIChlbnRyeS5pbWFnZUxpbmsgPT09IG9sZFBhdGgpIHtcblx0XHRcdFx0XHRcdGVudHJ5LmltYWdlTGluayA9IGZpbGUucGF0aDtcblx0XHRcdFx0XHRcdHVwZGF0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdGlmICh1cGRhdGVkKSB7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLnJlZnJlc2hEZWJvdW5jZWQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pKTtcblxuXHRcdC8vIE5ldzogTGlzdGVuIGZvciBtb2RpZnkgZXZlbnRzIHRvIHVwZGF0ZSB0aHVtYm5haWwgaW5mbyB3aGVuIG5vdGUgY29udGVudCBjaGFuZ2VzLlxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbihcIm1vZGlmeVwiLCBhc3luYyAoZmlsZSkgPT4ge1xuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xuXHRcdFx0XHRhd2FpdCB0aGlzLmFkZFRvRGF0YWJhc2UoZmlsZSk7XG5cdFx0XHRcdHRoaXMucmVmcmVzaERlYm91bmNlZCgpO1xuXHRcdFx0fVxuXHRcdH0pKTtcblxuXHRcdC8vIEluaXRpYWxpemUgZGVib3VuY2UgZm9yIHJlZnJlc2ggY2FsbHMuXG5cdFx0dGhpcy5yZWZyZXNoRGVib3VuY2VkID0gZGVib3VuY2UoKCkgPT4gdGhpcy5yZWZyZXNoRWFzeUtlZXBWaWV3SWZPcGVuKCksIDMwMCk7XG5cblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IFNhbXBsZVNldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcblx0fVxuXG5cdC8vIEFwcGx5IHRoZW1lIGJhc2VkIG9uIHNldHRpbmdzXG5cdGFwcGx5VGhlbWUoKSB7XG5cdFx0Y29uc3QgdGhlbWUgPSB0aGlzLnNldHRpbmdzLnRoZW1lTW9kZTtcblx0XHRjb25zdCBleGlzdGluZ0xlYXZlcyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoVklFV19UWVBFX0VBU1lfS0VFUCk7XG5cdFxuXHRcdGlmIChleGlzdGluZ0xlYXZlcy5sZW5ndGggPiAwKSB7XG5cdFx0XHRjb25zdCB2aWV3ID0gZXhpc3RpbmdMZWF2ZXNbMF0udmlldyBhcyBFYXN5S2VlcFZpZXc7XG5cdFx0XHRjb25zdCBjb250YWluZXIgPSB2aWV3LmNvbnRhaW5lckVsO1xuXHRcdFx0Y29uc3QgY2FyZENvbnRhaW5lciA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKFwiLmVhc3kta2VlcC1jYXJkcy1jb250YWluZXJcIik7XG5cdFxuXHRcdFx0aWYgKGNhcmRDb250YWluZXIpIHtcblx0XHRcdFx0Ly8gUmVtb3ZlIGFsbCBwb3NzaWJsZSB0aGVtZSBjbGFzc2VzXG5cdFx0XHRcdGNhcmRDb250YWluZXIucmVtb3ZlQ2xhc3MoXCJ0aGVtZS1saWdodFwiLCBcInRoZW1lLWRhcmtcIiwgXCJ0aGVtZS1zeXN0ZW1cIik7XG5cdFxuXHRcdFx0XHQvLyBBcHBseSB0aGUgc2VsZWN0ZWQgdGhlbWVcblx0XHRcdFx0aWYgKHRoZW1lID09PSBcInN5c3RlbVwiKSB7XG5cdFx0XHRcdFx0Ly8gRGV0ZWN0IE9ic2lkaWFuJ3MgY3VycmVudCB0aGVtZVxuXHRcdFx0XHRcdGNvbnN0IGlzRGFyayA9IGRvY3VtZW50LmJvZHkuaGFzQ2xhc3MoXCJ0aGVtZS1kYXJrXCIpO1xuXHRcdFx0XHRcdGNhcmRDb250YWluZXIuYWRkQ2xhc3MoaXNEYXJrID8gXCJ0aGVtZS1kYXJrXCIgOiBcInRoZW1lLWxpZ2h0XCIpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNhcmRDb250YWluZXIuYWRkQ2xhc3MoYHRoZW1lLSR7dGhlbWV9YCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFxuXHRcdC8vIE9wdGlvbmFsbHkgc2V0IGRhdGEtdGhlbWUgb24gPGh0bWw+IGZvciBicm9hZGVyIGNvbXBhdGliaWxpdHkgKG5vdCByZXF1aXJlZCBmb3IgdGhpcyBmaXgpXG5cdFx0aWYgKHRoZW1lID09PSBcInN5c3RlbVwiKSB7XG5cdFx0XHRkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKFwiZGF0YS10aGVtZVwiKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZShcImRhdGEtdGhlbWVcIiwgdGhlbWUpO1xuXHRcdH1cblx0fVxuXG5cdG9udW5sb2FkKCkge1xuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5kZXRhY2hMZWF2ZXNPZlR5cGUoVklFV19UWVBFX0VBU1lfS0VFUCk7XG5cdH1cblxuXHQvLyBBY3RpdmF0ZSB0aGUgdmlld1xuXHRhc3luYyBhY3RpdmF0ZUVhc3lLZWVwVmlldygpIHtcblx0XHRjb25zdCBleGlzdGluZ0xlYXZlcyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoVklFV19UWVBFX0VBU1lfS0VFUCk7XG5cdFx0aWYgKGV4aXN0aW5nTGVhdmVzLmxlbmd0aCA+IDApIHtcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5yZXZlYWxMZWFmKGV4aXN0aW5nTGVhdmVzWzBdKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBsZWFmID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYWYodHJ1ZSk7XG5cdFx0YXdhaXQgbGVhZi5zZXRWaWV3U3RhdGUoeyB0eXBlOiBWSUVXX1RZUEVfRUFTWV9LRUVQLCBhY3RpdmU6IHRydWUgfSk7XG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLnJldmVhbExlYWYobGVhZik7XG5cdH1cblxuXHQvLyBSZWZyZXNoIHRoZSB2aWV3IGlmIG9wZW5cblx0YXN5bmMgcmVmcmVzaEVhc3lLZWVwVmlld0lmT3BlbigpIHtcblx0XHRjb25zdCBleGlzdGluZ0xlYXZlcyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoVklFV19UWVBFX0VBU1lfS0VFUCk7XG5cdFx0aWYgKGV4aXN0aW5nTGVhdmVzLmxlbmd0aCA+IDApIHtcblx0XHRcdGNvbnN0IHZpZXcgPSBleGlzdGluZ0xlYXZlc1swXS52aWV3IGFzIEVhc3lLZWVwVmlldztcblx0XHRcdGF3YWl0IHZpZXcucmVmcmVzaENvbnRlbnQoKTtcblx0XHR9XG5cdH1cblxuXHQvLyBSZWZyZXNoIG5vdGUgdGh1bWJuYWlscyBiYXNlZCBvbiBjb250ZW50XG5cdC8vIFJlZnJlc2ggbm90ZSB0aHVtYm5haWxzIGJhc2VkIG9uIGNvbnRlbnRcblx0YXN5bmMgcmVmcmVzaFRodW1ibmFpbHMoKSB7XG5cdFx0Zm9yIChjb25zdCBub3RlIG9mIHRoaXMuc2V0dGluZ3Mubm90ZXNEQikge1xuXHRcdFx0Y29uc3QgZmlsZSA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChub3RlLnBhdGgpO1xuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSkgY29udGludWU7XG5cblx0XHRcdGNvbnN0IGNvbnRlbnQgPSBhd2FpdCB0aGlzLmFwcC52YXVsdC5jYWNoZWRSZWFkKGZpbGUpO1xuXHRcdFx0Y29uc3QgbGluZXMgPSBjb250ZW50LnRyaW0oKS5zcGxpdChcIlxcblwiKS5maWx0ZXIobGluZSA9PiBsaW5lLnRyaW0oKSAhPT0gXCJcIik7XG5cblx0XHRcdC8vIEdldCB0aGUgZmlyc3Qgbm9uLWVtcHR5IGxpbmUgKGNvbnRlbnQgb3IgaW1hZ2UpXG5cdFx0XHRjb25zdCBmaXJzdExpbmUgPSBsaW5lcy5maW5kKGxpbmUgPT4gbGluZS50cmltKCkgIT09IFwiXCIpO1xuXG5cdFx0XHRsZXQgZXhjZXJwdCA9IFwiXCI7XG5cdFx0XHRsZXQgaW1hZ2VMaW5rOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cblx0XHRcdC8vIElmIHRoZSBmaXJzdCBsaW5lIGNvbnRhaW5zIGFuIGVtYmVkZGVkIGltYWdlLCBkb24ndCBzaG93IHRoZSB0aHVtYm5haWwsIGp1c3QgdGV4dFxuXHRcdFx0aWYgKGZpcnN0TGluZSAmJiBmaXJzdExpbmUuaW5jbHVkZXMoXCIhW1tcIikgJiYgZmlyc3RMaW5lLmluY2x1ZGVzKFwiXV1cIikpIHtcblx0XHRcdFx0Ly8gRXhjZXJwdCBzaG91bGQganVzdCBiZSB0aGUgY29udGVudCB0ZXh0IGJlZm9yZSB0aGUgaW1hZ2UgbGlua1xuXHRcdFx0XHRleGNlcnB0ID0gbGluZXMuc2xpY2UoMCwgMSkuam9pbihcIiBcIik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBDcmVhdGUgZXhjZXJwdCBmcm9tIGZpcnN0IGxpbmVzICh1cCB0byAyIGxpbmVzIG9mIGNvbnRlbnQpXG5cdFx0XHRcdGlmIChmaXJzdExpbmUpIHtcblx0XHRcdFx0XHRleGNlcnB0ID0gZmlyc3RMaW5lO1xuXHRcdFx0XHRcdGlmIChsaW5lcy5sZW5ndGggPiAxKSBleGNlcnB0ICs9IFwiIFxcdTIwMjZcIjsgLy8gQWRkIGVsbGlwc2lzIGlmIHRoZXJlIGFyZSBtb3JlIGxpbmVzXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDaGVjayBpZiBhbiBpbWFnZSBpcyBlbWJlZGRlZCBhbnl3aGVyZSBlbHNlIGluIHRoZSBjb250ZW50IChub3QganVzdCB0aGUgZmlyc3QgbGluZSlcblx0XHRcdFx0Y29uc3QgbWF0Y2ggPSBjb250ZW50Lm1hdGNoKC8hXFxbXFxbKFteXFxdXSspXFxdXFxdLyk7XG5cdFx0XHRcdGlmIChtYXRjaCkge1xuXHRcdFx0XHRcdGltYWdlTGluayA9IG1hdGNoWzFdLnRyaW0oKTtcblx0XHRcdFx0XHRpZiAoaW1hZ2VMaW5rICYmIG5vdGUuaW1hZ2VMaW5rICE9PSBpbWFnZUxpbmspIHtcblx0XHRcdFx0XHRcdG5vdGUuaW1hZ2VMaW5rID0gaW1hZ2VMaW5rO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBVcGRhdGUgdGhlIG5vdGUgd2l0aCBleGNlcnB0IGFuZCBpbWFnZUxpbmsgaWYgZm91bmRcblx0XHRcdGlmIChpbWFnZUxpbmspIHtcblx0XHRcdFx0bm90ZS5pbWFnZUxpbmsgPSBpbWFnZUxpbms7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChleGNlcnB0KSB7XG5cdFx0XHRcdG5vdGUuZXhjZXJwdCA9IGV4Y2VycHQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0fVxuXG5cblxuXHQvLyBBZGQgbm90ZSB0byB0aGUgZGF0YWJhc2Vcblx0YXN5bmMgYWRkVG9EYXRhYmFzZShmaWxlOiBURmlsZSkge1xuXHRcdGNvbnN0IGNvbnRlbnQgPSBhd2FpdCB0aGlzLmFwcC52YXVsdC5jYWNoZWRSZWFkKGZpbGUpO1xuXHRcdGNvbnN0IGxpbmVzID0gY29udGVudC50cmltKCkuc3BsaXQoXCJcXG5cIikuZmlsdGVyKGxpbmUgPT4gbGluZS50cmltKCkgIT09IFwiXCIpO1xuXHRcdGxldCBleGNlcnB0ID0gXCJcIjtcblx0XHRsZXQgaW1hZ2VMaW5rOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cblx0XHRpZiAoL1xcLihqcGd8anBlZ3xwbmd8d2VicCkkL2kudGVzdChmaWxlLnBhdGgpKSB7XG5cdFx0XHRpbWFnZUxpbmsgPSBmaWxlLnBhdGg7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IG9ic2lkaWFuRW1iZWRNYXRjaCA9IGNvbnRlbnQubWF0Y2goLyFcXFtcXFsoW15cXF1dKylcXF1cXF0vKTtcblx0XHRcdGNvbnN0IG1hcmtkb3duSW1hZ2VNYXRjaCA9IGNvbnRlbnQubWF0Y2goLyFcXFsuKj9cXF1cXCgoLio/KVxcKS8pO1xuXHRcdFx0aWYgKG9ic2lkaWFuRW1iZWRNYXRjaCB8fCBtYXJrZG93bkltYWdlTWF0Y2gpIHtcblx0XHRcdFx0aW1hZ2VMaW5rID0gKG9ic2lkaWFuRW1iZWRNYXRjaD8uWzFdIHx8IG1hcmtkb3duSW1hZ2VNYXRjaD8uWzFdKT8udHJpbSgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICghaW1hZ2VMaW5rICYmIGxpbmVzLmxlbmd0aCA+IDApIHtcblx0XHRcdGV4Y2VycHQgPSBsaW5lcy5zbGljZSgwLCAyKS5qb2luKFwiIFwiKTtcblx0XHRcdGlmIChsaW5lcy5sZW5ndGggPiAyKSBleGNlcnB0ID0gZXhjZXJwdC50cmltKCkgKyBcIiBcdTIwMjZcIjtcblx0XHR9XG5cblx0XHRjb25zdCB0aXRsZVdpdGhvdXRFeHQgPSBmaWxlLm5hbWUucmVwbGFjZSgvXFwuKG1kfHBuZ3xqcGd8anBlZ3x3ZWJwKSQvaSwgXCJcIik7XG5cdFx0Y29uc3QgbmV3RW50cnk6IE5vdGVFbnRyeSA9IHtcblx0XHRcdHBhdGg6IGZpbGUucGF0aCxcblx0XHRcdHRpdGxlOiB0aXRsZVdpdGhvdXRFeHQsXG5cdFx0XHRleGNlcnB0LFxuXHRcdFx0dGltZTogRGF0ZS5ub3coKSxcblx0XHRcdGltYWdlTGluayxcblx0XHR9O1xuXG5cdFx0dGhpcy5zZXR0aW5ncy5ub3Rlc0RCID0gdGhpcy5zZXR0aW5ncy5ub3Rlc0RCLmZpbHRlcihlbnRyeSA9PiBlbnRyeS5wYXRoICE9PSBmaWxlLnBhdGgpO1xuXHRcdHRoaXMuc2V0dGluZ3Mubm90ZXNEQi51bnNoaWZ0KG5ld0VudHJ5KTtcblx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHR9XG5cblx0Ly8gUmVtb3ZlIG5vdGUgZnJvbSB0aGUgZGF0YWJhc2Vcblx0YXN5bmMgcmVtb3ZlRnJvbURhdGFiYXNlKGZpbGVQYXRoOiBzdHJpbmcpIHtcblx0XHRjb25zdCBpbml0aWFsTGVuZ3RoID0gdGhpcy5zZXR0aW5ncy5ub3Rlc0RCLmxlbmd0aDtcblx0XHR0aGlzLnNldHRpbmdzLm5vdGVzREIgPSB0aGlzLnNldHRpbmdzLm5vdGVzREIuZmlsdGVyKGVudHJ5ID0+IGVudHJ5LnBhdGggIT09IGZpbGVQYXRoKTtcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5ub3Rlc0RCLmxlbmd0aCAhPT0gaW5pdGlhbExlbmd0aCkge1xuXHRcdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDbGVhbiB1cCB0aGUgZGF0YWJhc2UgYnkgcmVtb3Zpbmcgbm90ZXMgdGhhdCBubyBsb25nZXIgZXhpc3Rcblx0YXN5bmMgY2xlYW5EYXRhYmFzZSgpIHtcblx0XHRjb25zdCBmaWxlcyA9IHRoaXMuYXBwLnZhdWx0LmdldE1hcmtkb3duRmlsZXMoKTtcblx0XHRjb25zdCBleGlzdGluZ1BhdGhzID0gbmV3IFNldChmaWxlcy5tYXAoZmlsZSA9PiBmaWxlLnBhdGgpKTtcblx0XHR0aGlzLnNldHRpbmdzLm5vdGVzREIgPSB0aGlzLnNldHRpbmdzLm5vdGVzREIuZmlsdGVyKGVudHJ5ID0+IGV4aXN0aW5nUGF0aHMuaGFzKGVudHJ5LnBhdGgpKTtcblx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHR9XG5cblx0Ly8gT3BlbiBhIG5vdGUgaW4gYSBuZXcgdGFiXG5cdGFzeW5jIG9wZW5Ob3RlSW5OZXdUYWIoZmlsZVBhdGg6IHN0cmluZykge1xuXHRcdGNvbnN0IGZpbGUgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZVBhdGgpO1xuXHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcblx0XHRsZXQgZXhpc3RpbmdMZWFmOiBXb3Jrc3BhY2VMZWFmIHwgbnVsbCA9IG51bGw7XG5cdFx0dGhpcy5hcHAud29ya3NwYWNlLml0ZXJhdGVBbGxMZWF2ZXMobGVhZiA9PiB7XG5cdFx0XHRpZiAobGVhZi52aWV3LmdldFZpZXdUeXBlKCkgPT09IFwibWFya2Rvd25cIiAmJiAobGVhZi52aWV3IGFzIGFueSkuZmlsZT8ucGF0aCA9PT0gZmlsZVBhdGgpIHtcblx0XHRcdFx0ZXhpc3RpbmdMZWFmID0gbGVhZjtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRpZiAoZXhpc3RpbmdMZWFmKSB7XG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uuc2V0QWN0aXZlTGVhZihleGlzdGluZ0xlYWYsIHsgZm9jdXM6IHRydWUgfSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IG5ld0xlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZih0cnVlKTtcblx0XHRcdGF3YWl0IG5ld0xlYWYub3BlbkZpbGUoZmlsZSk7XG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uuc2V0QWN0aXZlTGVhZihuZXdMZWFmLCB7IGZvY3VzOiB0cnVlIH0pO1xuXHRcdH1cblx0fVxuXG5cdC8vIExvYWQgc2V0dGluZ3MgZnJvbSBzdG9yYWdlXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcblx0fVxuXG5cdC8vIFNhdmUgc2V0dGluZ3MgdG8gc3RvcmFnZVxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxuXG5cdC8vIEdlbmVyYXRlIGEgdW5pcXVlIG5hbWUgZm9yIGFuIHVudGl0bGVkIG5vdGVcblx0Z2VuZXJhdGVVbmlxdWVVbnRpdGxlZE5hbWUoKTogc3RyaW5nIHtcblx0XHRjb25zdCBiYXNlTmFtZSA9IFwiVW50aXRsZWRcIjtcblx0XHRjb25zdCBmaWxlcyA9IHRoaXMuYXBwLnZhdWx0LmdldE1hcmtkb3duRmlsZXMoKTtcblx0XHRjb25zdCBleGlzdGluZ05hbWVzID0gbmV3IFNldChmaWxlcy5tYXAoZiA9PiBmLmJhc2VuYW1lKSk7XG5cblx0XHRpZiAoIWV4aXN0aW5nTmFtZXMuaGFzKGJhc2VOYW1lKSkge1xuXHRcdFx0cmV0dXJuIGJhc2VOYW1lO1xuXHRcdH1cblxuXHRcdGxldCBjb3VudGVyID0gMTtcblx0XHR3aGlsZSAoZXhpc3RpbmdOYW1lcy5oYXMoYCR7YmFzZU5hbWV9ICR7Y291bnRlcn1gKSkge1xuXHRcdFx0Y291bnRlcisrO1xuXHRcdH1cblx0XHRyZXR1cm4gYCR7YmFzZU5hbWV9ICR7Y291bnRlcn1gO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgbmV3IG5vdGVcblx0YXN5bmMgY3JlYXRlTmV3Tm90ZSgpIHtcblx0XHRjb25zdCB0aXRsZSA9IHRoaXMuZ2VuZXJhdGVVbmlxdWVVbnRpdGxlZE5hbWUoKTtcblx0XHRjb25zdCBmaWxlUGF0aCA9IGAke3RpdGxlfS5tZGA7XG5cdFx0Y29uc3QgZmlsZSA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmNyZWF0ZShmaWxlUGF0aCwgXCJcIik7XG5cdFx0YXdhaXQgdGhpcy5hZGRUb0RhdGFiYXNlKGZpbGUpO1xuXHRcdHRoaXMub3Blbk5vdGVJbk5ld1RhYihmaWxlUGF0aCk7XG5cdH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxzQkFRTztBQUlQLElBQU0sc0JBQXNCO0FBaUI1QixJQUFNLG1CQUFxQztBQUFBLEVBQzFDLFdBQVc7QUFBQSxFQUNYLFNBQVMsQ0FBQztBQUFBLEVBQ1YsV0FBVztBQUFBLEVBQ1gsZ0JBQWdCO0FBQ2pCO0FBS0EsU0FBUyxtQkFBbUIsS0FBVSxXQUFpQztBQUN0RSxRQUFNLFNBQVMsVUFBVSxRQUFRLDJCQUEyQixFQUFFLEVBQUUsWUFBWTtBQUM1RSxRQUFNLGFBQWEsSUFBSSxNQUFNLFNBQVMsRUFBRSxPQUFPLE9BQUssMEJBQTBCLEtBQUssRUFBRSxJQUFJLENBQUM7QUFDMUYsYUFBVyxRQUFRLFlBQVk7QUFDOUIsUUFBSSxLQUFLLFNBQVMsWUFBWSxNQUFNLFFBQVE7QUFDM0MsYUFBTztBQUFBLElBQ1I7QUFBQSxFQUNEO0FBQ0EsU0FBTztBQUNSO0FBR0EsU0FBUyxTQUFTLElBQThCLFFBQVEsS0FBK0I7QUFDdEYsTUFBSTtBQUNKLFNBQU8sSUFBSSxTQUFnQjtBQUMxQixpQkFBYSxLQUFLO0FBQ2xCLFlBQVEsV0FBVyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsS0FBSztBQUFBLEVBQzVDO0FBQ0Q7QUFJQSxJQUFNLGVBQU4sY0FBMkIseUJBQVM7QUFBQSxFQUluQyxZQUFZLE1BQXFCLFFBQWtCO0FBQ2xELFVBQU0sSUFBSTtBQUNWLFNBQUssU0FBUztBQUFBLEVBQ2Y7QUFBQSxFQUVBLGNBQXNCO0FBQ3JCLFdBQU87QUFBQSxFQUNSO0FBQUEsRUFFQSxpQkFBeUI7QUFDeEIsV0FBTztBQUFBLEVBQ1I7QUFBQTtBQUFBLEVBR0EsTUFBTSxlQUFlO0FBQ3BCLFNBQUssY0FBYyxNQUFNO0FBQ3pCLFNBQUssY0FBYyxNQUFNLFlBQVk7QUFDckMsU0FBSyxjQUFjLE1BQU0sU0FBUztBQUVsQyxVQUFNLGdCQUFnQixLQUFLLGNBQWMsVUFBVSwyQkFBMkI7QUFHOUUsU0FBSyxPQUFPLFdBQVc7QUFHdkIsVUFBTSxjQUFjLGNBQWMsVUFBVSw4QkFBOEI7QUFDMUUsZ0JBQVksU0FBUyxNQUFNLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDeEMsZ0JBQVksU0FBUyxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbEQsZ0JBQVksVUFBVSxNQUFNLEtBQUssT0FBTyxjQUFjO0FBR3RELFVBQU0sS0FBSyxPQUFPLGtCQUFrQjtBQUVwQyxRQUFJLFFBQVEsS0FBSyxPQUFPLFNBQVMsUUFBUSxNQUFNLEVBQzdDLEtBQUssQ0FBQyxHQUFHLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUM5QixNQUFNLEdBQUcsR0FBRztBQUVkLFFBQUksTUFBTSxRQUFRO0FBQ2pCLFlBQU0sUUFBUSxVQUFRO0FBQ3JCLGNBQU0sT0FBTyxjQUFjLFVBQVUsZ0JBQWdCO0FBQ3JELGFBQUssU0FBUyxNQUFNLEVBQUUsTUFBTSxLQUFLLE1BQU0sQ0FBQztBQUV4QyxZQUFJLEtBQUssV0FBVztBQUNuQixjQUFJLE9BQU8sS0FBSyxJQUFJLGNBQWMscUJBQXFCLEtBQUssV0FBVyxLQUFLLElBQUk7QUFDaEYsY0FBSSxFQUFFLGdCQUFnQix3QkFBUTtBQUM3QixtQkFBTyxtQkFBbUIsS0FBSyxLQUFLLEtBQUssU0FBUztBQUFBLFVBQ25EO0FBQ0EsY0FBSSxnQkFBZ0IsdUJBQU87QUFDMUIsa0JBQU0sZUFBZSxLQUFLLElBQUksTUFBTSxnQkFBZ0IsSUFBSTtBQUN4RCxrQkFBTSxNQUFNLEtBQUssU0FBUyxPQUFPLEVBQUUsS0FBSyxzQkFBc0IsQ0FBQztBQUMvRCxnQkFBSSxNQUFNO0FBQ1YsZ0JBQUksVUFBVSxNQUFNO0FBQ25CLHNCQUFRLEtBQUssOENBQThDLFlBQVk7QUFDdkUsa0JBQUksT0FBTztBQUNYLGtCQUFJLEtBQUs7QUFBUyxxQkFBSyxTQUFTLEtBQUssRUFBRSxNQUFNLEtBQUssUUFBUSxDQUFDO0FBQUEsWUFDNUQ7QUFDQSxnQkFBSSxTQUFTLE1BQU07QUFDbEIsc0JBQVEsSUFBSSxzQ0FBc0MsWUFBWTtBQUFBLFlBQy9EO0FBQUEsVUFDRCxXQUFXLEtBQUssU0FBUztBQUN4QixpQkFBSyxTQUFTLEtBQUssRUFBRSxNQUFNLEtBQUssUUFBUSxDQUFDO0FBQUEsVUFDMUM7QUFBQSxRQUNELFdBQVcsS0FBSyxTQUFTO0FBQ3hCLGVBQUssU0FBUyxLQUFLLEVBQUUsTUFBTSxLQUFLLFFBQVEsQ0FBQztBQUFBLFFBQzFDO0FBRUEsYUFBSyxVQUFVLE1BQU0sS0FBSyxPQUFPLGlCQUFpQixLQUFLLElBQUk7QUFBQSxNQUM1RCxDQUFDO0FBQUEsSUFDRixPQUFPO0FBQ04sWUFBTSxZQUFZLGNBQWMsVUFBVSxvQkFBb0I7QUFDOUQsZ0JBQVUsUUFBUSw2QkFBNkI7QUFBQSxJQUNoRDtBQUFBLEVBQ0Q7QUFBQSxFQUlBLE1BQU0saUJBQWlCO0FBQ3RCLFVBQU0sS0FBSyxhQUFhO0FBQUEsRUFDekI7QUFBQTtBQUFBLEVBR0EsTUFBTSxTQUFTO0FBQ2QsU0FBSyxnQkFBZ0IsS0FBSztBQUcxQixVQUFNLEtBQUssT0FBTyxhQUFhO0FBRy9CLFVBQU0sS0FBSyxhQUFhO0FBRXhCLFNBQUssUUFBUTtBQUFBLEVBQ2Q7QUFBQTtBQUFBLEVBR0EsVUFBVTtBQUNULFVBQU0sT0FBTyxTQUFTLGNBQWMsTUFBTTtBQUMxQyxTQUFLLE1BQU07QUFDWCxTQUFLLE9BQU8sR0FBRyxLQUFLLE9BQU8sU0FBUztBQUNwQyxhQUFTLEtBQUssWUFBWSxJQUFJO0FBQUEsRUFDL0I7QUFBQSxFQUVBLE1BQU0sVUFBVTtBQUFBLEVBQUM7QUFDbEI7QUFHQSxJQUFNLG1CQUFOLGNBQStCLGlDQUFpQjtBQUFBLEVBRS9DLFlBQVksS0FBVSxRQUFrQjtBQUN2QyxVQUFNLEtBQUssTUFBTTtBQUNqQixTQUFLLFNBQVM7QUFBQSxFQUNmO0FBQUEsRUFDQSxVQUFnQjtBQUNmLFVBQU0sRUFBRSxZQUFZLElBQUk7QUFDeEIsZ0JBQVksTUFBTTtBQUVsQixnQkFBWSxTQUFTLE1BQU0sRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBSXJFLFFBQUksd0JBQVEsV0FBVyxFQUN0QixRQUFRLFlBQVksRUFDcEIsUUFBUSw0Q0FBNEMsRUFDcEQsWUFBWSxjQUFZO0FBQ3hCLGVBQVMsVUFBVSxVQUFVLGdCQUFnQjtBQUM3QyxlQUFTLFVBQVUsU0FBUyxPQUFPO0FBQ25DLGVBQVMsVUFBVSxRQUFRLE1BQU07QUFDakMsZUFBUyxTQUFTLEtBQUssT0FBTyxTQUFTLFNBQVM7QUFDaEQsZUFBUyxTQUFTLE9BQU8sVUFBdUM7QUFDL0QsYUFBSyxPQUFPLFNBQVMsWUFBWTtBQUNqQyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBRS9CLGFBQUssT0FBTyxXQUFXO0FBQ3ZCLGFBQUssT0FBTywwQkFBMEI7QUFBQSxNQUN2QyxDQUFDO0FBQUEsSUFDRixDQUFDO0FBR0QsUUFBSSx3QkFBUSxXQUFXLEVBQ3RCLFFBQVEsaUNBQWlDLEVBQ3pDLFFBQVEsd0RBQXdELEVBQ2hFLFVBQVUsWUFBVTtBQUNwQixhQUFPLFNBQVMsS0FBSyxPQUFPLFNBQVMsY0FBYztBQUNuRCxhQUFPLFNBQVMsT0FBTyxVQUFVO0FBQ2hDLGFBQUssT0FBTyxTQUFTLGlCQUFpQjtBQUN0QyxjQUFNLEtBQUssT0FBTyxhQUFhO0FBQy9CLFlBQUksT0FBTyxpREFBaUQ7QUFBQSxNQUM3RCxDQUFDO0FBQUEsSUFDRixDQUFDO0FBQUEsRUFDRjtBQUNEO0FBR0EsSUFBcUIsV0FBckIsY0FBc0MsdUJBQU87QUFBQSxFQUk1QyxNQUFNLFNBQVM7QUFDZCxVQUFNLEtBQUssYUFBYTtBQUd4QixTQUFLLFdBQVc7QUFJaEIsU0FBSyxJQUFJLFVBQVUsY0FBYyxZQUFZO0FBQzVDLFlBQU0sS0FBSyxjQUFjO0FBQ3pCLFdBQUssMEJBQTBCO0FBRS9CLFVBQUksS0FBSyxTQUFTLGdCQUFnQjtBQUNqQyxjQUFNLEtBQUsscUJBQXFCO0FBQUEsTUFDakM7QUFBQSxJQUNELENBQUM7QUFHRCxTQUFLLGFBQWEscUJBQXFCLENBQUMsU0FBUyxJQUFJLGFBQWEsTUFBTSxJQUFJLENBQUM7QUFFN0UsVUFBTSxlQUFlLEtBQUssY0FBYyxlQUFlLGtCQUFrQixNQUFNO0FBQzlFLFdBQUsscUJBQXFCO0FBQUEsSUFDM0IsQ0FBQztBQUNELGlCQUFhLFNBQVMsd0JBQXdCO0FBRzlDLFNBQUssY0FBYyxLQUFLLElBQUksVUFBVSxHQUFHLGFBQWEsT0FBTyxTQUFTO0FBQ3JFLFVBQUksTUFBTTtBQUNULGNBQU0sS0FBSyxjQUFjLElBQUk7QUFDN0IsYUFBSyxpQkFBaUI7QUFBQSxNQUN2QjtBQUFBLElBQ0QsQ0FBQyxDQUFDO0FBR0YsU0FBSyxjQUFjLEtBQUssSUFBSSxNQUFNLEdBQUcsVUFBVSxPQUFPLFNBQVM7QUFDOUQsVUFBSSxnQkFBZ0IsdUJBQU87QUFDMUIsY0FBTSxLQUFLLG1CQUFtQixLQUFLLElBQUk7QUFDdkMsYUFBSyxpQkFBaUI7QUFBQSxNQUN2QjtBQUFBLElBQ0QsQ0FBQyxDQUFDO0FBR0YsU0FBSyxjQUFjLEtBQUssSUFBSSxNQUFNLEdBQUcsVUFBVSxPQUFPLE1BQU0sWUFBWTtBQUN2RSxVQUFJLGdCQUFnQix1QkFBTztBQUMxQixjQUFNLGFBQWEsS0FBSyxTQUFTLFFBQVEsVUFBVSxPQUFLLEVBQUUsU0FBUyxPQUFPO0FBQzFFLFlBQUksZUFBZSxJQUFJO0FBQ3RCLGVBQUssU0FBUyxRQUFRLFVBQVUsRUFBRSxPQUFPLEtBQUs7QUFDOUMsZUFBSyxTQUFTLFFBQVEsVUFBVSxFQUFFLFFBQVEsS0FBSztBQUMvQyxnQkFBTSxLQUFLLGFBQWE7QUFDeEIsZUFBSyxpQkFBaUI7QUFBQSxRQUN2QjtBQUFBLE1BQ0Q7QUFBQSxJQUNELENBQUMsQ0FBQztBQUdGLFNBQUssY0FBYyxLQUFLLElBQUksTUFBTSxHQUFHLFVBQVUsT0FBTyxNQUFNLFlBQVk7QUFDdkUsVUFBSSxnQkFBZ0IseUJBQVMsMEJBQTBCLEtBQUssS0FBSyxJQUFJLEdBQUc7QUFDdkUsWUFBSSxVQUFVO0FBQ2QsYUFBSyxTQUFTLFFBQVEsUUFBUSxXQUFTO0FBQ3RDLGNBQUksTUFBTSxjQUFjLFNBQVM7QUFDaEMsa0JBQU0sWUFBWSxLQUFLO0FBQ3ZCLHNCQUFVO0FBQUEsVUFDWDtBQUFBLFFBQ0QsQ0FBQztBQUNELFlBQUksU0FBUztBQUNaLGdCQUFNLEtBQUssYUFBYTtBQUN4QixlQUFLLGlCQUFpQjtBQUFBLFFBQ3ZCO0FBQUEsTUFDRDtBQUFBLElBQ0QsQ0FBQyxDQUFDO0FBR0YsU0FBSyxjQUFjLEtBQUssSUFBSSxNQUFNLEdBQUcsVUFBVSxPQUFPLFNBQVM7QUFDOUQsVUFBSSxnQkFBZ0IsdUJBQU87QUFDMUIsY0FBTSxLQUFLLGNBQWMsSUFBSTtBQUM3QixhQUFLLGlCQUFpQjtBQUFBLE1BQ3ZCO0FBQUEsSUFDRCxDQUFDLENBQUM7QUFHRixTQUFLLG1CQUFtQixTQUFTLE1BQU0sS0FBSywwQkFBMEIsR0FBRyxHQUFHO0FBRTVFLFNBQUssY0FBYyxJQUFJLGlCQUFpQixLQUFLLEtBQUssSUFBSSxDQUFDO0FBQUEsRUFDeEQ7QUFBQTtBQUFBLEVBR0EsYUFBYTtBQUNaLFVBQU0sUUFBUSxLQUFLLFNBQVM7QUFDNUIsVUFBTSxpQkFBaUIsS0FBSyxJQUFJLFVBQVUsZ0JBQWdCLG1CQUFtQjtBQUU3RSxRQUFJLGVBQWUsU0FBUyxHQUFHO0FBQzlCLFlBQU0sT0FBTyxlQUFlLENBQUMsRUFBRTtBQUMvQixZQUFNLFlBQVksS0FBSztBQUN2QixZQUFNLGdCQUFnQixVQUFVLGNBQWMsNEJBQTRCO0FBRTFFLFVBQUksZUFBZTtBQUVsQixzQkFBYyxZQUFZLGVBQWUsY0FBYyxjQUFjO0FBR3JFLFlBQUksVUFBVSxVQUFVO0FBRXZCLGdCQUFNLFNBQVMsU0FBUyxLQUFLLFNBQVMsWUFBWTtBQUNsRCx3QkFBYyxTQUFTLFNBQVMsZUFBZSxhQUFhO0FBQUEsUUFDN0QsT0FBTztBQUNOLHdCQUFjLFNBQVMsU0FBUyxPQUFPO0FBQUEsUUFDeEM7QUFBQSxNQUNEO0FBQUEsSUFDRDtBQUdBLFFBQUksVUFBVSxVQUFVO0FBQ3ZCLGVBQVMsZ0JBQWdCLGdCQUFnQixZQUFZO0FBQUEsSUFDdEQsT0FBTztBQUNOLGVBQVMsZ0JBQWdCLGFBQWEsY0FBYyxLQUFLO0FBQUEsSUFDMUQ7QUFBQSxFQUNEO0FBQUEsRUFFQSxXQUFXO0FBQ1YsU0FBSyxJQUFJLFVBQVUsbUJBQW1CLG1CQUFtQjtBQUFBLEVBQzFEO0FBQUE7QUFBQSxFQUdBLE1BQU0sdUJBQXVCO0FBQzVCLFVBQU0saUJBQWlCLEtBQUssSUFBSSxVQUFVLGdCQUFnQixtQkFBbUI7QUFDN0UsUUFBSSxlQUFlLFNBQVMsR0FBRztBQUM5QixXQUFLLElBQUksVUFBVSxXQUFXLGVBQWUsQ0FBQyxDQUFDO0FBQy9DO0FBQUEsSUFDRDtBQUVBLFVBQU0sT0FBTyxLQUFLLElBQUksVUFBVSxRQUFRLElBQUk7QUFDNUMsVUFBTSxLQUFLLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixRQUFRLEtBQUssQ0FBQztBQUNuRSxTQUFLLElBQUksVUFBVSxXQUFXLElBQUk7QUFBQSxFQUNuQztBQUFBO0FBQUEsRUFHQSxNQUFNLDRCQUE0QjtBQUNqQyxVQUFNLGlCQUFpQixLQUFLLElBQUksVUFBVSxnQkFBZ0IsbUJBQW1CO0FBQzdFLFFBQUksZUFBZSxTQUFTLEdBQUc7QUFDOUIsWUFBTSxPQUFPLGVBQWUsQ0FBQyxFQUFFO0FBQy9CLFlBQU0sS0FBSyxlQUFlO0FBQUEsSUFDM0I7QUFBQSxFQUNEO0FBQUE7QUFBQTtBQUFBLEVBSUEsTUFBTSxvQkFBb0I7QUFDekIsZUFBVyxRQUFRLEtBQUssU0FBUyxTQUFTO0FBQ3pDLFlBQU0sT0FBTyxLQUFLLElBQUksTUFBTSxzQkFBc0IsS0FBSyxJQUFJO0FBQzNELFVBQUksRUFBRSxnQkFBZ0I7QUFBUTtBQUU5QixZQUFNLFVBQVUsTUFBTSxLQUFLLElBQUksTUFBTSxXQUFXLElBQUk7QUFDcEQsWUFBTSxRQUFRLFFBQVEsS0FBSyxFQUFFLE1BQU0sSUFBSSxFQUFFLE9BQU8sVUFBUSxLQUFLLEtBQUssTUFBTSxFQUFFO0FBRzFFLFlBQU0sWUFBWSxNQUFNLEtBQUssVUFBUSxLQUFLLEtBQUssTUFBTSxFQUFFO0FBRXZELFVBQUksVUFBVTtBQUNkLFVBQUk7QUFHSixVQUFJLGFBQWEsVUFBVSxTQUFTLEtBQUssS0FBSyxVQUFVLFNBQVMsSUFBSSxHQUFHO0FBRXZFLGtCQUFVLE1BQU0sTUFBTSxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUc7QUFBQSxNQUNyQyxPQUFPO0FBRU4sWUFBSSxXQUFXO0FBQ2Qsb0JBQVU7QUFDVixjQUFJLE1BQU0sU0FBUztBQUFHLHVCQUFXO0FBQUEsUUFDbEM7QUFHQSxjQUFNLFFBQVEsUUFBUSxNQUFNLG1CQUFtQjtBQUMvQyxZQUFJLE9BQU87QUFDVixzQkFBWSxNQUFNLENBQUMsRUFBRSxLQUFLO0FBQzFCLGNBQUksYUFBYSxLQUFLLGNBQWMsV0FBVztBQUM5QyxpQkFBSyxZQUFZO0FBQUEsVUFDbEI7QUFBQSxRQUNEO0FBQUEsTUFDRDtBQUdBLFVBQUksV0FBVztBQUNkLGFBQUssWUFBWTtBQUFBLE1BQ2xCO0FBRUEsVUFBSSxTQUFTO0FBQ1osYUFBSyxVQUFVO0FBQUEsTUFDaEI7QUFBQSxJQUNEO0FBRUEsVUFBTSxLQUFLLGFBQWE7QUFBQSxFQUN6QjtBQUFBO0FBQUEsRUFLQSxNQUFNLGNBQWMsTUFBYTtBQWxhbEM7QUFtYUUsVUFBTSxVQUFVLE1BQU0sS0FBSyxJQUFJLE1BQU0sV0FBVyxJQUFJO0FBQ3BELFVBQU0sUUFBUSxRQUFRLEtBQUssRUFBRSxNQUFNLElBQUksRUFBRSxPQUFPLFVBQVEsS0FBSyxLQUFLLE1BQU0sRUFBRTtBQUMxRSxRQUFJLFVBQVU7QUFDZCxRQUFJO0FBRUosUUFBSSwwQkFBMEIsS0FBSyxLQUFLLElBQUksR0FBRztBQUM5QyxrQkFBWSxLQUFLO0FBQUEsSUFDbEIsT0FBTztBQUNOLFlBQU0scUJBQXFCLFFBQVEsTUFBTSxtQkFBbUI7QUFDNUQsWUFBTSxxQkFBcUIsUUFBUSxNQUFNLG1CQUFtQjtBQUM1RCxVQUFJLHNCQUFzQixvQkFBb0I7QUFDN0MscUJBQWEsK0RBQXFCLFFBQU0seURBQXFCLFFBQWhELG1CQUFxRDtBQUFBLE1BQ25FO0FBQUEsSUFDRDtBQUVBLFFBQUksQ0FBQyxhQUFhLE1BQU0sU0FBUyxHQUFHO0FBQ25DLGdCQUFVLE1BQU0sTUFBTSxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUc7QUFDcEMsVUFBSSxNQUFNLFNBQVM7QUFBRyxrQkFBVSxRQUFRLEtBQUssSUFBSTtBQUFBLElBQ2xEO0FBRUEsVUFBTSxrQkFBa0IsS0FBSyxLQUFLLFFBQVEsOEJBQThCLEVBQUU7QUFDMUUsVUFBTSxXQUFzQjtBQUFBLE1BQzNCLE1BQU0sS0FBSztBQUFBLE1BQ1gsT0FBTztBQUFBLE1BQ1A7QUFBQSxNQUNBLE1BQU0sS0FBSyxJQUFJO0FBQUEsTUFDZjtBQUFBLElBQ0Q7QUFFQSxTQUFLLFNBQVMsVUFBVSxLQUFLLFNBQVMsUUFBUSxPQUFPLFdBQVMsTUFBTSxTQUFTLEtBQUssSUFBSTtBQUN0RixTQUFLLFNBQVMsUUFBUSxRQUFRLFFBQVE7QUFDdEMsVUFBTSxLQUFLLGFBQWE7QUFBQSxFQUN6QjtBQUFBO0FBQUEsRUFHQSxNQUFNLG1CQUFtQixVQUFrQjtBQUMxQyxVQUFNLGdCQUFnQixLQUFLLFNBQVMsUUFBUTtBQUM1QyxTQUFLLFNBQVMsVUFBVSxLQUFLLFNBQVMsUUFBUSxPQUFPLFdBQVMsTUFBTSxTQUFTLFFBQVE7QUFDckYsUUFBSSxLQUFLLFNBQVMsUUFBUSxXQUFXLGVBQWU7QUFDbkQsWUFBTSxLQUFLLGFBQWE7QUFBQSxJQUN6QjtBQUFBLEVBQ0Q7QUFBQTtBQUFBLEVBR0EsTUFBTSxnQkFBZ0I7QUFDckIsVUFBTSxRQUFRLEtBQUssSUFBSSxNQUFNLGlCQUFpQjtBQUM5QyxVQUFNLGdCQUFnQixJQUFJLElBQUksTUFBTSxJQUFJLFVBQVEsS0FBSyxJQUFJLENBQUM7QUFDMUQsU0FBSyxTQUFTLFVBQVUsS0FBSyxTQUFTLFFBQVEsT0FBTyxXQUFTLGNBQWMsSUFBSSxNQUFNLElBQUksQ0FBQztBQUMzRixVQUFNLEtBQUssYUFBYTtBQUFBLEVBQ3pCO0FBQUE7QUFBQSxFQUdBLE1BQU0saUJBQWlCLFVBQWtCO0FBQ3hDLFVBQU0sT0FBTyxLQUFLLElBQUksTUFBTSxzQkFBc0IsUUFBUTtBQUMxRCxRQUFJLEVBQUUsZ0JBQWdCO0FBQVE7QUFDOUIsUUFBSSxlQUFxQztBQUN6QyxTQUFLLElBQUksVUFBVSxpQkFBaUIsVUFBUTtBQTNkOUM7QUE0ZEcsVUFBSSxLQUFLLEtBQUssWUFBWSxNQUFNLGdCQUFlLFVBQUssS0FBYSxTQUFsQixtQkFBd0IsVUFBUyxVQUFVO0FBQ3pGLHVCQUFlO0FBQUEsTUFDaEI7QUFBQSxJQUNELENBQUM7QUFDRCxRQUFJLGNBQWM7QUFDakIsV0FBSyxJQUFJLFVBQVUsY0FBYyxjQUFjLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFBQSxJQUMvRCxPQUFPO0FBQ04sWUFBTSxVQUFVLEtBQUssSUFBSSxVQUFVLFFBQVEsSUFBSTtBQUMvQyxZQUFNLFFBQVEsU0FBUyxJQUFJO0FBQzNCLFdBQUssSUFBSSxVQUFVLGNBQWMsU0FBUyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUEsSUFDMUQ7QUFBQSxFQUNEO0FBQUE7QUFBQSxFQUdBLE1BQU0sZUFBZTtBQUNwQixTQUFLLFdBQVcsT0FBTyxPQUFPLENBQUMsR0FBRyxrQkFBa0IsTUFBTSxLQUFLLFNBQVMsQ0FBQztBQUFBLEVBQzFFO0FBQUE7QUFBQSxFQUdBLE1BQU0sZUFBZTtBQUNwQixVQUFNLEtBQUssU0FBUyxLQUFLLFFBQVE7QUFBQSxFQUNsQztBQUFBO0FBQUEsRUFHQSw2QkFBcUM7QUFDcEMsVUFBTSxXQUFXO0FBQ2pCLFVBQU0sUUFBUSxLQUFLLElBQUksTUFBTSxpQkFBaUI7QUFDOUMsVUFBTSxnQkFBZ0IsSUFBSSxJQUFJLE1BQU0sSUFBSSxPQUFLLEVBQUUsUUFBUSxDQUFDO0FBRXhELFFBQUksQ0FBQyxjQUFjLElBQUksUUFBUSxHQUFHO0FBQ2pDLGFBQU87QUFBQSxJQUNSO0FBRUEsUUFBSSxVQUFVO0FBQ2QsV0FBTyxjQUFjLElBQUksR0FBRyxZQUFZLFNBQVMsR0FBRztBQUNuRDtBQUFBLElBQ0Q7QUFDQSxXQUFPLEdBQUcsWUFBWTtBQUFBLEVBQ3ZCO0FBQUE7QUFBQSxFQUdBLE1BQU0sZ0JBQWdCO0FBQ3JCLFVBQU0sUUFBUSxLQUFLLDJCQUEyQjtBQUM5QyxVQUFNLFdBQVcsR0FBRztBQUNwQixVQUFNLE9BQU8sTUFBTSxLQUFLLElBQUksTUFBTSxPQUFPLFVBQVUsRUFBRTtBQUNyRCxVQUFNLEtBQUssY0FBYyxJQUFJO0FBQzdCLFNBQUssaUJBQWlCLFFBQVE7QUFBQSxFQUMvQjtBQUNEOyIsCiAgIm5hbWVzIjogW10KfQo=
|