quartz/content/Obsidian Vault/.obsidian/plugins/obsidian-link-archive/main.js
2022-06-07 14:39:39 -06:00

188 lines
42 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const defaultArchiveText = "(Archived)";
const waybackUrl = "https://web.archive.org/web/";
const waybackSaveUrl = "https://web.archive.org/save/";
const defaultSettings = {
archiveOption: 1 /* Archiveis */,
archiveText: defaultArchiveText
};
class LinkArchiveSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const plugin = this.plugin;
const { containerEl } = this;
containerEl.empty();
// add archive link text customization option
containerEl.createEl("h2", { text: "Archive Settings" });
new obsidian.Setting(containerEl)
.setName("Link text")
.setDesc("The text of the archive links")
.addText(text => text
.setValue(plugin.settings.archiveText)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
console.log(`Link text: ${value}`);
plugin.settings.archiveText = value;
yield plugin.saveSettings();
})));
// new Setting(containerEl)
// .setName('Archive Provider')
// .setDesc('Choose a provider for the link archive')
// .addDropdown((dropdown) => {
// const options: Record<ArchiveOptions, string> = {
// 0: "Internet Archive",
// 1: "archive.is",
// 2: "Both"
// };
// dropdown
// .addOptions(options)
// .setValue(plugin.settings.archiveOption.toString())
// .onChange(async (value) => {
// console.log('Archive option: ' + value);
// plugin.settings.archiveOption = +value;
// await plugin.saveSettings();
// this.display();
// })
// });
containerEl.createEl("h2", { text: "About Link Archive" });
containerEl.createEl("p", { text: "This plugin archives links in your note so they're available to you even if the original site goes down or gets removed." });
containerEl.createEl("a", { text: "Open GitHub repository", href: "https://github.com/tomzorz/obsidian-link-archive" });
// TODO github support and ko-fi
}
}
const urlRegex = /(\b(https?|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
class ObsidianLinkArchivePlugin extends obsidian.Plugin {
onload() {
return __awaiter(this, void 0, void 0, function* () {
console.log("Loading Link Archive plugin...");
yield this.loadSettings();
this.addRibbonIcon("restore-file-glyph", "Archive Links", () => __awaiter(this, void 0, void 0, function* () {
// test save
//new Notice('Archive option: ' + this.settings.archiveOption.toString());
const archiveText = `[${this.settings.archiveText}]`;
const dateLinkPart = new Date().toISOString().slice(0, 10).replace(/-/g, "");
const view = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
if (view) {
const viewData = view.getViewData();
const reverseArray = [];
let linkArray;
while ((linkArray = urlRegex.exec(viewData)) !== null) {
console.log(`Found ${linkArray[0]}. Next starts at ${urlRegex.lastIndex}.`);
//if(linkArray[0].startsWith(waybackUrl)) continue;
//if(viewData.substring(urlRegex.lastIndex, urlRegex.lastIndex + 14).contains(archiveText)) continue;
// replace clean logic with
// IF next link is the same except with archiveorg in front of it, skip it
reverseArray.unshift([linkArray[0], urlRegex.lastIndex]);
}
console.log(reverseArray);
// ReSharper marks the "some" call as an error, but it's actually correct...
const cleanedList = reverseArray.filter(x => !x[0].startsWith(waybackUrl)
&& !reverseArray.some(y => y[0].startsWith(waybackUrl) && y[0].endsWith(x[0])));
console.log(cleanedList);
if (cleanedList.length === 0) {
this.popNotice("No (new) links to archive.");
return;
}
const processingNotice = new obsidian.Notice(`Archiving ${cleanedList.length} link(s), this might take a while - please be patient...`, 0);
let i = 1;
const totalLinks = cleanedList.length;
for (const tuple of cleanedList) {
const currentLink = tuple[0];
const saveLink = `${waybackSaveUrl}${currentLink}`;
const archiveLink = ` ${archiveText}(${waybackUrl}${dateLinkPart}/${currentLink})`;
const extraOffset = viewData.charAt(tuple[1]) === ")" ? 1 : 0;
const offset = view.editor.offsetToPos(tuple[1] + extraOffset);
const message = `(${i}/${totalLinks}) Successfully archived ${currentLink}!`;
const failMessage = `(${i}/${totalLinks}) Failed to archive ${currentLink}!`;
i += 1;
yield this.delay(400);
try {
yield obsidian.request({
url: saveLink
});
view.editor.replaceRange(archiveLink, offset);
console.log(message);
this.popNotice(message);
}
catch (exception) {
this.popNotice(failMessage);
}
}
this.popNotice("Link archiving done!");
processingNotice.hide();
}
else {
this.popNotice("Link archiving only works if you have a note open.");
}
}));
this.addSettingTab(new LinkArchiveSettingTab(this.app, this));
});
}
popNotice(message, timeInSeconds) {
// ReSharper disable WrongExpressionStatement
if (arguments.length === 1) {
new obsidian.Notice(message);
}
else {
new obsidian.Notice(message, timeInSeconds * 1000);
}
// ReSharper restore WrongExpressionStatement
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
onunload() {
console.log("Unloading Link Archive plugin...");
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
this.settings = Object.assign({}, defaultSettings, yield this.loadData());
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settings);
});
}
}
module.exports = ObsidianLinkArchivePlugin;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsImNvbnN0YW50cy50cyIsInNldHRpbmdzLnRzIiwibWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH0pO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcbiIsImV4cG9ydCBjb25zdCBkZWZhdWx0QXJjaGl2ZVRleHQgPSBcIihBcmNoaXZlZClcIjtcclxuZXhwb3J0IGNvbnN0IHdheWJhY2tVcmwgPSBcImh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi9cIjtcclxuZXhwb3J0IGNvbnN0IHdheWJhY2tTYXZlVXJsID0gXCJodHRwczovL3dlYi5hcmNoaXZlLm9yZy9zYXZlL1wiOyIsImltcG9ydCB7IEFwcCwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gXCJvYnNpZGlhblwiO1xyXG5pbXBvcnQgT2JzaWRpYW5MaW5rQXJjaGl2ZVBsdWdpbiBmcm9tIFwiLi9tYWluXCI7XHJcbmltcG9ydCB7IGRlZmF1bHRBcmNoaXZlVGV4dCB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xyXG5cclxuZXhwb3J0IGNvbnN0IGVudW0gQXJjaGl2ZU9wdGlvbnMge1xyXG5cdFdheWJhY2ssXHJcblx0QXJjaGl2ZWlzLFxyXG5cdEJvdGhcclxufVxyXG5cclxuLy8gUmVTaGFycGVyIGRpc2FibGUgb25jZSBJbmNvbnNpc3RlbnROYW1pbmdcclxuZXhwb3J0IGludGVyZmFjZSBMaW5rQXJjaGl2ZVBsdWdpblNldHRpbmdzIHtcclxuXHRhcmNoaXZlT3B0aW9uOiBBcmNoaXZlT3B0aW9ucztcclxuXHRhcmNoaXZlVGV4dDogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZGVmYXVsdFNldHRpbmdzOiBMaW5rQXJjaGl2ZVBsdWdpblNldHRpbmdzID0ge1xyXG5cdGFyY2hpdmVPcHRpb246IEFyY2hpdmVPcHRpb25zLkFyY2hpdmVpcyxcclxuXHRhcmNoaXZlVGV4dDogZGVmYXVsdEFyY2hpdmVUZXh0XHJcbn1cclxuXHJcblxyXG5leHBvcnQgY2xhc3MgTGlua0FyY2hpdmVTZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcblx0cGx1Z2luOiBPYnNpZGlhbkxpbmtBcmNoaXZlUGx1Z2luO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBPYnNpZGlhbkxpbmtBcmNoaXZlUGx1Z2luKSB7XHJcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHR9XHJcblxyXG5cdGRpc3BsYXkoKTogdm9pZCB7XHJcblx0XHRjb25zdCBwbHVnaW46IE9ic2lkaWFuTGlua0FyY2hpdmVQbHVnaW4gPSAodGhpcyBhcyBhbnkpLnBsdWdpbjtcclxuXHJcbiAgICAgICAgY29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcclxuXHJcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xyXG5cclxuXHRcdC8vIGFkZCBhcmNoaXZlIGxpbmsgdGV4dCBjdXN0b21pemF0aW9uIG9wdGlvblxyXG5cclxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwge3RleHQ6IFwiQXJjaGl2ZSBTZXR0aW5nc1wifSk7XHJcblxyXG4gICAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG4gICAgICAgICAgICAuc2V0TmFtZShcIkxpbmsgdGV4dFwiKVxyXG4gICAgICAgICAgICAuc2V0RGVzYyhcIlRoZSB0ZXh0IG9mIHRoZSBhcmNoaXZlIGxpbmtzXCIpXHJcbiAgICAgICAgICAgIC5hZGRUZXh0KHRleHQgPT5cclxuICAgICAgICAgICAgICAgIHRleHRcclxuICAgICAgICAgICAgICAgICAgICAuc2V0VmFsdWUocGx1Z2luLnNldHRpbmdzLmFyY2hpdmVUZXh0KVxyXG4gICAgICAgICAgICAgICAgICAgIC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBMaW5rIHRleHQ6ICR7dmFsdWV9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbi5zZXR0aW5ncy5hcmNoaXZlVGV4dCA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG5cclxuXHRcdC8vIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0Ly8gXHQuc2V0TmFtZSgnQXJjaGl2ZSBQcm92aWRlcicpXHJcblx0XHQvLyBcdC5zZXREZXNjKCdDaG9vc2UgYSBwcm92aWRlciBmb3IgdGhlIGxpbmsgYXJjaGl2ZScpXHJcblx0XHQvLyBcdC5hZGREcm9wZG93bigoZHJvcGRvd24pID0+IHtcclxuXHRcdC8vIFx0XHRjb25zdCBvcHRpb25zOiBSZWNvcmQ8QXJjaGl2ZU9wdGlvbnMsIHN0cmluZz4gPSB7XHJcblx0XHQvLyBcdFx0XHQwOiBcIkludGVybmV0IEFyY2hpdmVcIixcclxuXHRcdC8vIFx0XHRcdDE6IFwiYXJjaGl2ZS5pc1wiLFxyXG5cdFx0Ly8gXHRcdFx0MjogXCJCb3RoXCJcclxuXHRcdC8vIFx0XHR9O1xyXG5cclxuXHRcdC8vIFx0XHRkcm9wZG93blxyXG5cdFx0Ly8gXHRcdFx0LmFkZE9wdGlvbnMob3B0aW9ucylcclxuXHRcdC8vIFx0XHRcdC5zZXRWYWx1ZShwbHVnaW4uc2V0dGluZ3MuYXJjaGl2ZU9wdGlvbi50b1N0cmluZygpKVxyXG5cdFx0Ly8gXHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0Ly8gXHRcdFx0XHRjb25zb2xlLmxvZygnQXJjaGl2ZSBvcHRpb246ICcgKyB2YWx1ZSk7XHJcblx0XHQvLyBcdFx0XHRcdHBsdWdpbi5zZXR0aW5ncy5hcmNoaXZlT3B0aW9uID0gK3ZhbHVlO1xyXG5cdFx0Ly8gXHRcdFx0XHRhd2FpdCBwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHQvLyBcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0Ly8gXHRcdH0pXHJcblx0XHQvLyBcdH0pO1xyXG5cclxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwge3RleHQ6IFwiQWJvdXQgTGluayBBcmNoaXZlXCJ9KTtcclxuXHJcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwge3RleHQ6IFwiVGhpcyBwbHVnaW4gYXJjaGl2ZXMgbGlua3MgaW4geW91ciBub3RlIHNvIHRoZXkncmUgYXZhaWxhYmxlIHRvIHlvdSBldmVuIGlmIHRoZSBvcmlnaW5hbCBzaXRlIGdvZXMgZG93biBvciBnZXRzIHJlbW92ZWQuXCJ9KTtcclxuXHJcblx0XHRjb250YWluZXJFbC5jcmVhdGVFbChcImFcIiwge3RleHQ6IFwiT3BlbiBHaXRIdWIgcmVwb3NpdG9yeVwiLCBocmVmOiBcImh0dHBzOi8vZ2l0aHViLmNvbS90b216b3J6L29ic2lkaWFuLWxpbmstYXJjaGl2ZVwifSk7XHJcblxyXG5cdFx0Ly8gVE9ETyBnaXRodWIgc3VwcG9ydCBhbmQga28tZmlcclxuXHR9XHJcbn1cclxuIiwiaW1wb3J0IHsgTWFya2Rvd25WaWV3LCBOb3RpY2UsIFBsdWdpbiwgcmVxdWVzdCB9IGZyb20gXCJvYnNpZGlhblwiO1xyXG5pbXBvcnQgeyB3YXliYWNrU2F2ZVVybCwgd2F5YmFja1VybCB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xyXG5pbXBvcnQgeyBkZWZhdWx0U2V0dGluZ3MgYXMgREVGQVVMVF9TRVRUSU5HUywgTGlua0FyY2hpdmVQbHVnaW5TZXR0aW5ncyBhcyBMaW5rQXJjaGl2ZVBsdWdpblNldHRpbmdzLCBMaW5rQXJjaGl2ZVNldHRpbmdUYWIgfSBmcm9tIFwiLi9zZXR0aW5nc1wiO1xyXG5cclxuY29uc3QgdXJsUmVnZXggPS8oXFxiKGh0dHBzP3xmaWxlKTpcXC9cXC9bLUEtWjAtOSsmQCNcXC8lPz1+X3whOiwuO10qWy1BLVowLTkrJkAjXFwvJT1+X3xdKS9pZztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9ic2lkaWFuTGlua0FyY2hpdmVQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xyXG5cdHNldHRpbmdzOiBMaW5rQXJjaGl2ZVBsdWdpblNldHRpbmdzO1xyXG5cclxuXHRhc3luYyBvbmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZyhcIkxvYWRpbmcgTGluayBBcmNoaXZlIHBsdWdpbi4uLlwiKTtcclxuXHJcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xyXG5cclxuXHRcdHRoaXMuYWRkUmliYm9uSWNvbihcInJlc3RvcmUtZmlsZS1nbHlwaFwiLCBcIkFyY2hpdmUgTGlua3NcIiwgYXN5bmMgKCkgPT4ge1xyXG5cclxuXHRcdFx0Ly8gdGVzdCBzYXZlXHJcblx0XHRcdC8vbmV3IE5vdGljZSgnQXJjaGl2ZSBvcHRpb246ICcgKyB0aGlzLnNldHRpbmdzLmFyY2hpdmVPcHRpb24udG9TdHJpbmcoKSk7XHJcblxyXG5cdFx0XHRjb25zdCBhcmNoaXZlVGV4dCA9IGBbJHt0aGlzLnNldHRpbmdzLmFyY2hpdmVUZXh0fV1gO1xyXG5cdFx0XHRjb25zdCBkYXRlTGlua1BhcnQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc2xpY2UoMCwgMTApLnJlcGxhY2UoLy0vZywgXCJcIik7XHJcblxyXG5cdFx0XHRjb25zdCB2aWV3ID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KTtcclxuXHJcblx0XHRcdGlmKHZpZXcpIHtcclxuXHRcdFx0XHRjb25zdCB2aWV3RGF0YSA9IHZpZXcuZ2V0Vmlld0RhdGEoKTtcclxuXHJcblx0XHRcdFx0Y29uc3QgcmV2ZXJzZUFycmF5OiBBcnJheTxbc3RyaW5nLCBudW1iZXJdPiA9IFtdO1xyXG5cclxuXHRcdFx0XHRsZXQgbGlua0FycmF5OiBhbnk7XHJcblx0XHRcdFx0d2hpbGUgKChsaW5rQXJyYXkgPSB1cmxSZWdleC5leGVjKHZpZXdEYXRhKSkgIT09IG51bGwpIHtcclxuXHRcdFx0XHRcdGNvbnNvbGUubG9nKGBGb3VuZCAke2xpbmtBcnJheVswXX0uIE5leHQgc3RhcnRzIGF0ICR7dXJsUmVnZXgubGFzdEluZGV4fS5gKTtcclxuXHJcblx0XHRcdFx0XHQvL2lmKGxpbmtBcnJheVswXS5zdGFydHNXaXRoKHdheWJhY2tVcmwpKSBjb250aW51ZTtcclxuXHJcblx0XHRcdFx0XHQvL2lmKHZpZXdEYXRhLnN1YnN0cmluZyh1cmxSZWdleC5sYXN0SW5kZXgsIHVybFJlZ2V4Lmxhc3RJbmRleCArIDE0KS5jb250YWlucyhhcmNoaXZlVGV4dCkpIGNvbnRpbnVlO1xyXG5cclxuXHRcdFx0XHRcdC8vIHJlcGxhY2UgY2xlYW4gbG9naWMgd2l0aFxyXG5cdFx0XHRcdFx0Ly8gSUYgbmV4dCBsaW5rIGlzIHRoZSBzYW1lIGV4Y2VwdCB3aXRoIGFyY2hpdmVvcmcgaW4gZnJvbnQgb2YgaXQsIHNraXAgaXRcclxuXHJcblx0XHRcdFx0XHRyZXZlcnNlQXJyYXkudW5zaGlmdChbbGlua0FycmF5WzBdLCB1cmxSZWdleC5sYXN0SW5kZXhdKTtcclxuXHRcdFx0XHR9XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2cocmV2ZXJzZUFycmF5KTtcclxuXHJcblx0XHRcdFx0Ly8gUmVTaGFycGVyIG1hcmtzIHRoZSBcInNvbWVcIiBjYWxsIGFzIGFuIGVycm9yLCBidXQgaXQncyBhY3R1YWxseSBjb3JyZWN0Li4uXHJcbiAgICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkTGlzdCA9IHJldmVyc2VBcnJheS5maWx0ZXIoeCA9PlxyXG4gICAgICAgICAgICAgICAgICAgICF4WzBdLnN0YXJ0c1dpdGgod2F5YmFja1VybClcclxuXHRcdFx0XHRcdCYmICFyZXZlcnNlQXJyYXkuc29tZSh5ID0+IHlbMF0uc3RhcnRzV2l0aCh3YXliYWNrVXJsKSAmJiB5WzBdLmVuZHNXaXRoKHhbMF0pKSk7XHJcblxyXG5cdFx0XHRcdGNvbnNvbGUubG9nKGNsZWFuZWRMaXN0KTtcclxuXHJcblx0XHRcdFx0aWYgKGNsZWFuZWRMaXN0Lmxlbmd0aCA9PT0gMCkge1xyXG5cdFx0XHRcdFx0dGhpcy5wb3BOb3RpY2UoXCJObyAobmV3KSBsaW5rcyB0byBhcmNoaXZlLlwiKTtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGNvbnN0IHByb2Nlc3NpbmdOb3RpY2UgPSBuZXcgTm90aWNlKGBBcmNoaXZpbmcgJHtjbGVhbmVkTGlzdC5sZW5ndGh9IGxpbmsocyksIHRoaXMgbWlnaHQgdGFrZSBhIHdoaWxlIC0gcGxlYXNlIGJlIHBhdGllbnQuLi5gLCAwKTtcclxuXHJcblx0XHRcdFx0bGV0IGkgPSAxO1xyXG5cdFx0XHRcdGNvbnN0IHRvdGFsTGlua3MgPSBjbGVhbmVkTGlzdC5sZW5ndGg7XHJcblxyXG5cdFx0XHRcdGZvciAoY29uc3QgdHVwbGUgb2YgY2xlYW5lZExpc3QpIHtcclxuXHRcdFx0XHRcdGNvbnN0IGN1cnJlbnRMaW5rID0gdHVwbGVbMF07XHJcblx0XHRcdFx0XHRjb25zdCBzYXZlTGluayA9IGAke3dheWJhY2tTYXZlVXJsfSR7Y3VycmVudExpbmt9YDtcclxuXHRcdFx0XHRcdGNvbnN0IGFyY2hpdmVMaW5rID0gYCAke2FyY2hpdmVUZXh0fSgke3dheWJhY2tVcmx9JHtkYXRlTGlua1BhcnR9LyR7Y3VycmVudExpbmt9KWA7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0cmFPZmZzZXQgPSB2aWV3RGF0YS5jaGFyQXQodHVwbGVbMV0pID09PSBcIilcIiA/IDEgOiAwO1xyXG5cdFx0XHRcdFx0Y29uc3Qgb2Zmc2V0ID0gdmlldy5lZGl0b3Iub2Zmc2V0VG9Qb3ModHVwbGVbMV0gKyBleHRyYU9mZnNldCk7XHJcblx0XHRcdFx0XHRjb25zdCBtZXNzYWdlID0gYCgke2l9LyR7dG90YWxMaW5rc30pIFN1Y2Nlc3NmdWxseSBhcmNoaXZlZCAke2N1cnJlbnRMaW5rfSFgO1xyXG5cdFx0XHRcdFx0Y29uc3QgZmFpbE1lc3NhZ2UgPSBgKCR7aX0vJHt0b3RhbExpbmtzfSkgRmFpbGVkIHRvIGFyY2hpdmUgJHtjdXJyZW50TGlua30hYDtcclxuICAgICAgICAgICAgICAgICAgICBpICs9IDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuZGVsYXkoNDAwKTtcclxuXHJcblx0XHRcdFx0XHR0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXF1ZXN0KHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogc2F2ZUxpbmtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3LmVkaXRvci5yZXBsYWNlUmFuZ2UoYXJjaGl2ZUxpbmssIG9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBvcE5vdGljZShtZXNzYWdlKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGNhdGNoIChleGNlcHRpb24pIHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wb3BOb3RpY2UoZmFpbE1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblx0XHRcdFx0dGhpcy5wb3BOb3RpY2UoXCJMaW5rIGFyY2hpdmluZyBkb25lIVwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzaW5nTm90aWNlLmhpZGUoKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucG9wTm90aWNlKFwiTGluayBhcmNoaXZpbmcgb25seSB3b3JrcyBpZiB5b3UgaGF2ZSBhIG5vdGUgb3Blbi5cIik7XHJcblx0XHRcdH1cclxuICAgICAgICB9KTtcclxuXHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IExpbmtBcmNoaXZlU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xyXG5cdH1cclxuXHJcblx0cG9wTm90aWNlKG1lc3NhZ2U6IHN0cmluZywgdGltZUluU2Vjb25kcz86IG51bWJlcikge1xyXG5cdFx0Ly8gUmVTaGFycGVyIGRpc2FibGUgV3JvbmdFeHByZXNzaW9uU3RhdGVtZW50XHJcblx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xyXG5cdFx0XHRuZXcgTm90aWNlKG1lc3NhZ2UpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0bmV3IE5vdGljZShtZXNzYWdlLCB0aW1lSW5TZWNvbmRzICogMTAwMCk7XHJcblx0XHR9XHJcblx0XHQvLyBSZVNoYXJwZXIgcmVzdG9yZSBXcm9uZ0V4cHJlc3Npb25TdGF0ZW1lbnRcclxuXHR9XHJcblxyXG5cdGRlbGF5KG1zOiBudW1iZXIpIHtcclxuICAgIFx0cmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xyXG4gICAgfVxyXG5cclxuXHRvbnVubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKFwiVW5sb2FkaW5nIExpbmsgQXJjaGl2ZSBwbHVnaW4uLi5cIik7XHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0fVxyXG59XHJcbiJdLCJuYW1lcyI6WyJQbHVnaW5TZXR0aW5nVGFiIiwiU2V0dGluZyIsIlBsdWdpbiIsIk1hcmtkb3duVmlldyIsIk5vdGljZSIsInJlcXVlc3QiLCJERUZBVUxUX1NFVFRJTkdTIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdURBO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENB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