/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD */ var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && key !== "default") __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toModule = (module2) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // package.json var require_package = __commonJS({ "package.json"(exports, module2) { module2.exports = { name: "obsidian-paste-png-to-jpeg", version: "1.2.2", main: "main.js", scripts: { dev: "node esbuild.config.mjs", build: "tsc -noEmit -skipLibCheck && BUILD_ENV=production node esbuild.config.mjs && cp manifest.json build", version: "node version-bump.mjs && git add manifest.json versions.json", release: "yarn build && gh release create ${npm_package_version} build/*" }, keywords: [], author: "Reorx", license: "MIT", devDependencies: { "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "^5.2.0", "@typescript-eslint/parser": "^5.2.0", "builtin-modules": "^3.2.0", esbuild: "0.13.12", obsidian: "^0.13.26", tslib: "2.3.1", typescript: "4.4.4" }, dependencies: { "cash-dom": "^8.1.1" } }; } }); // src/main.ts __export(exports, { default: () => PastePngToJpegPlugin }); var import_obsidian = __toModule(require("obsidian")); // src/utils.ts var import_path = __toModule(require("path")); var DEBUG = !(undefined === "production"); function debugLog(...args) { if (DEBUG) { console.log(new Date().toISOString().slice(11, 23), ...args); } } var path = { join(...partSegments) { let parts = []; for (let i = 0, l = partSegments.length; i < l; i++) { parts = parts.concat(partSegments[i].split("/")); } const newParts = []; for (let i = 0, l = parts.length; i < l; i++) { const part = parts[i]; if (!part || part === ".") continue; else newParts.push(part); } if (parts[0] === "") newParts.unshift(""); return newParts.join("/"); }, basename(fullpath) { const sp = fullpath.split("/"); return sp[sp.length - 1]; }, filename(fullpath) { let filename = (0, import_path.basename)(fullpath); return filename.substring(0, filename.indexOf(".")); }, extension(fullpath) { const positions = [...fullpath.matchAll(new RegExp("\\.", "gi"))].map((a) => a.index); return fullpath.slice(positions[positions.length - 1] + 1); } }; function ConvertImage(file, quality) { return new Promise((resolve, reject) => { let reader = new FileReader(); reader.onloadend = function(e) { let image = new Image(); image.onload = function() { let canvas = document.createElement("canvas"); let context = canvas.getContext("2d"); let imageWidth = image.width; let imageHeight = image.height; let data = ""; canvas.width = imageWidth; canvas.height = imageHeight; context.fillStyle = "#fff"; context.fillRect(0, 0, imageWidth, imageHeight); context.save(); context.translate(imageWidth / 2, imageHeight / 2); context.drawImage(image, 0, 0, imageWidth, imageHeight, -imageWidth / 2, -imageHeight / 2, imageWidth, imageHeight); context.restore(); data = canvas.toDataURL("image/jpeg", quality); var arrayBuffer = base64ToArrayBuffer(data); resolve(arrayBuffer); }; image.src = e.target.result.toString(); }; reader.readAsDataURL(file); }); } function base64ToArrayBuffer(code) { const parts = code.split(";base64,"); const contentType = parts[0].split(":")[1]; const fileExt = contentType.split("/")[1]; const raw = window.atob(parts[1]); const rawLength = raw.length; const uInt8Array = new Uint8Array(rawLength); for (let i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return uInt8Array.buffer; } // src/main.ts var DEFAULT_SETTINGS = { imageNamePattern: "{{fileName}}", dupNumberAtStart: false, dupNumberDelimiter: "-", autoRename: true, autoMove: true, pngToJpeg: true, quality: "0.6", dirpath: "image/" }; var PastePngToJpegPlugin = class extends import_obsidian.Plugin { onload() { return __async(this, null, function* () { const pkg = require_package(); console.log(`Plugin loading: ${pkg.name} ${pkg.version}`); yield this.loadSettings(); this.registerEvent(this.app.vault.on("create", (file) => { if (!(file instanceof import_obsidian.TFile)) return; const timeGapMs = Date.now() - file.stat.ctime; if (timeGapMs > 1e3) return; if (isImage(file)) { debugLog("pasted image created", file); this.renameFile(file); } })); this.addSettingTab(new SettingTab(this.app, this)); }); } renameFile(file) { return __async(this, null, function* () { const activeFile = this.getActiveFile(); if (!activeFile) { new import_obsidian.Notice("Error: No active file found."); return; } let newName = yield this.keepOrgName(file, activeFile); if (this.settings.autoRename) { newName = yield this.generateNewName(file, activeFile); } const sourcePath = activeFile.path; let newPath = ""; if (this.settings.autoMove) { const imagePath = this.app.vault.getConfig("attachmentFolderPath") + "/" + this.settings.dirpath; const isCreate = yield this.app.vault.adapter.exists(imagePath); if (!isCreate) { yield this.app.vault.createFolder(imagePath); } newPath = imagePath; } else { newPath = file.parent.path + +"/" + this.settings.dirpath; } const originName = file.name; if (this.settings.pngToJpeg) { let binary = yield this.app.vault.readBinary(file); let imgBlob = new Blob([binary]); let arrayBuffer = yield ConvertImage(imgBlob, Number(this.settings.quality)); yield this.app.vault.modifyBinary(file, arrayBuffer); } const linkText = this.makeLinkText(file, sourcePath); newPath = path.join(newPath, newName); try { yield this.app.vault.rename(file, newPath); } catch (err) { new import_obsidian.Notice(`Failed to rename ${newName}: ${err}`); throw err; } const newLinkText = this.makeLinkText(file, sourcePath); debugLog("replace text", linkText, newLinkText); const editor = this.getActiveEditor(sourcePath); if (!editor) { new import_obsidian.Notice(`Failed to rename ${newName}: no active editor`); return; } const cursor = editor.getCursor(); const line = editor.getLine(cursor.line); debugLog("current line", line); editor.transaction({ changes: [ { from: __spreadProps(__spreadValues({}, cursor), { ch: 0 }), to: __spreadProps(__spreadValues({}, cursor), { ch: line.length }), text: line.replace(linkText, newLinkText) } ] }); new import_obsidian.Notice(`Renamed ${originName} to ${newName}`); }); } makeLinkText(file, sourcePath, subpath) { return this.app.fileManager.generateMarkdownLink(file, sourcePath, subpath); } generateNewName(file, activeFile) { return __async(this, null, function* () { const newName = activeFile.basename + "-" + Date.now(); const extension = this.settings.pngToJpeg ? "jpeg" : file.extension; return `${newName}.${extension}`; }); } keepOrgName(file, activeFile) { return __async(this, null, function* () { const newName = file.basename; const extension = this.settings.pngToJpeg ? "jpeg" : file.extension; return `${newName}.${extension}`; }); } getActiveFile() { const view = this.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); const file = view == null ? void 0 : view.file; debugLog("active file", file == null ? void 0 : file.path); return file; } getActiveEditor(sourcePath) { const view = this.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView); if (view) { if (view.file.path == sourcePath) { return view.editor; } } return null; } loadSettings() { return __async(this, null, function* () { this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); }); } saveSettings() { return __async(this, null, function* () { yield this.saveData(this.settings); }); } }; var IMAGE_EXTS = [ "jpg", "jpeg", "png" ]; function isImage(file) { if (file instanceof import_obsidian.TFile) { if (IMAGE_EXTS.contains(file.extension.toLowerCase())) { return true; } } return false; } var SettingTab = class extends import_obsidian.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); new import_obsidian.Setting(containerEl).setName("Png to Jpeg").setDesc(`Paste images from ClipBoard to notes by copying them through various screenshot software,turn on this feature will automatically convert png to jpeg, and more quality compression volume.`).addToggle((toggle) => toggle.setValue(this.plugin.settings.pngToJpeg).onChange((value) => __async(this, null, function* () { this.plugin.settings.pngToJpeg = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Quality").setDesc(`The smaller the Quality, the greater the compression ratio.`).addDropdown((toggle) => toggle.addOptions({ "0.1": "0.1", "0.2": "0.2", "0.3": "0.3", "0.4": "0.4", "0.5": "0.5", "0.6": "0.6", "0.7": "0.7", "0.8": "0.8", "0.9": "0.9", "1.0": "1.0" }).setValue(this.plugin.settings.quality).onChange((value) => __async(this, null, function* () { this.plugin.settings.quality = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Auto Rename").setDesc(`Automatically names the image with the name of the previous note +'-'+ the current timestamp + '.' + file type, for example, the image in test.md will be named test-1652261724173.jpeg`).addToggle((toggle) => toggle.setValue(this.plugin.settings.autoRename).onChange((value) => __async(this, null, function* () { this.plugin.settings.autoRename = value; yield this.plugin.saveSettings(); }))); new import_obsidian.Setting(containerEl).setName("Auto Move Image").setDesc(`Automatically move images to the image directory,If you do not set the default directory for attachments, then it will be stored directly under the image/ folder in the same directory as the notes, if there is a default directory, then it will be stored under the image/ folder in the Magician directory`).addToggle((toggle) => toggle.setValue(this.plugin.settings.autoMove).onChange((value) => __async(this, null, function* () { this.plugin.settings.autoMove = value; yield this.plugin.saveSettings(); }))); } }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL21haW4udHMiLCAiLi4vc3JjL3V0aWxzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge1xyXG4gIEFwcCwgUGx1Z2luLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBURmlsZSwgVEFic3RyYWN0RmlsZSxcclxuXHRNYXJrZG93blZpZXcsIE5vdGljZSwgVmF1bHQsXHJcbn0gZnJvbSAnb2JzaWRpYW4nO1xyXG5cclxuaW1wb3J0IHtcclxuICAgZGVidWdMb2csIHBhdGgsIENvbnZlcnRJbWFnZVxyXG59IGZyb20gJy4vdXRpbHMnO1xyXG5cclxuaW50ZXJmYWNlIFBsdWdpblNldHRpbmdzIHtcclxuXHQvLyB7e2ltYWdlTmFtZUtleX19LXt7REFURTpZWVlZTU1ERH19XHJcblx0aW1hZ2VOYW1lUGF0dGVybjogc3RyaW5nXHJcblx0ZHVwTnVtYmVyQXRTdGFydDogYm9vbGVhblxyXG5cdGR1cE51bWJlckRlbGltaXRlcjogc3RyaW5nXHJcblx0YXV0b1JlbmFtZTogYm9vbGVhblxyXG5cdGF1dG9Nb3ZlOmJvb2xlYW5cclxuXHRwbmdUb0pwZWc6IGJvb2xlYW5cclxuXHRxdWFsaXR5OiBzdHJpbmdcclxuXHRkaXJwYXRoOiBzdHJpbmdcclxufVxyXG5cclxuY29uc3QgREVGQVVMVF9TRVRUSU5HUzogUGx1Z2luU2V0dGluZ3MgPSB7XHJcblx0aW1hZ2VOYW1lUGF0dGVybjogJ3t7ZmlsZU5hbWV9fScsXHJcblx0ZHVwTnVtYmVyQXRTdGFydDogZmFsc2UsXHJcblx0ZHVwTnVtYmVyRGVsaW1pdGVyOiAnLScsXHJcblx0YXV0b1JlbmFtZTogdHJ1ZSxcclxuXHRhdXRvTW92ZTp0cnVlLFxyXG5cdHBuZ1RvSnBlZzp0cnVlLFxyXG5cdHF1YWxpdHk6JzAuNicsXHJcblx0ZGlycGF0aDpcImltYWdlL1wiIFxyXG59XHJcblxyXG5jb25zdCBQQVNURURfSU1BR0VfUFJFRklYID0gJ1Bhc3RlZCBpbWFnZSAnXHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYXN0ZVBuZ1RvSnBlZ1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0c2V0dGluZ3M6IFBsdWdpblNldHRpbmdzXHJcblxyXG5cdGFzeW5jIG9ubG9hZCgpIFxyXG5cdHtcclxuXHRcdGNvbnN0IHBrZyA9IHJlcXVpcmUoJy4uL3BhY2thZ2UuanNvbicpXHJcblx0XHRjb25zb2xlLmxvZyhgUGx1Z2luIGxvYWRpbmc6ICR7cGtnLm5hbWV9ICR7cGtnLnZlcnNpb259YClcclxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XHJcblxyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxyXG5cdFx0XHR0aGlzLmFwcC52YXVsdC5vbignY3JlYXRlJywgKGZpbGUpID0+IFxyXG5cdFx0XHR7XHJcblx0XHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSlcclxuXHRcdFx0XHRcdHJldHVyblxyXG5cclxuXHRcdFx0XHRjb25zdCB0aW1lR2FwTXMgPSBEYXRlLm5vdygpIC0gZmlsZS5zdGF0LmN0aW1lO1xyXG5cclxuXHRcdFx0XHQvLyBpZiB0aGUgcGFzdGVkIGltYWdlIGlzIGNyZWF0ZWQgbW9yZSB0aGFuIDEgc2Vjb25kIGFnbywgaWdub3JlIGl0XHJcblx0XHRcdFx0aWYgKHRpbWVHYXBNcyA+IDEwMDApXHJcblx0XHRcdFx0XHRyZXR1cm5cclxuXHJcblx0XHRcdFx0aWYgKGlzSW1hZ2UoZmlsZSkpIFxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGRlYnVnTG9nKCdwYXN0ZWQgaW1hZ2UgY3JlYXRlZCcsIGZpbGUpXHJcblx0XHRcdFx0XHR0aGlzLnJlbmFtZUZpbGUoZmlsZSk7XHJcblx0XHRcdFx0fSBcclxuXHRcdFx0fSlcclxuXHRcdClcclxuXHJcblx0XHQvLyBhZGQgc2V0dGluZ3MgdGFiXHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IFNldHRpbmdUYWIodGhpcy5hcHAsIHRoaXMpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHJlbmFtZUZpbGUoZmlsZTogVEZpbGUpIFxyXG5cdHtcclxuXHRcdGNvbnN0IGFjdGl2ZUZpbGUgPSB0aGlzLmdldEFjdGl2ZUZpbGUoKVxyXG5cdFx0aWYgKCFhY3RpdmVGaWxlKSBcclxuXHRcdHtcclxuXHRcdFx0bmV3IE5vdGljZSgnRXJyb3I6IE5vIGFjdGl2ZSBmaWxlIGZvdW5kLicpXHJcblx0XHRcdHJldHVyblxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGRlZHVwbGljYXRlIG5hbWVcclxuXHRcdGxldCBuZXdOYW1lOnN0cmluZyA9IGF3YWl0IHRoaXMua2VlcE9yZ05hbWUoZmlsZSwgYWN0aXZlRmlsZSk7XHJcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5hdXRvUmVuYW1lKSB7XHJcbiAgICAgICAgXHRuZXdOYW1lID0gYXdhaXQgdGhpcy5nZW5lcmF0ZU5ld05hbWUoZmlsZSwgYWN0aXZlRmlsZSk7XHJcbiAgICAgIFx0fVxyXG5cdFx0Y29uc3Qgc291cmNlUGF0aDpzdHJpbmcgPSBhY3RpdmVGaWxlLnBhdGg7XHJcblxyXG5cdFx0bGV0IG5ld1BhdGggPSBcIlwiO1xyXG5cdFx0aWYoIHRoaXMuc2V0dGluZ3MuYXV0b01vdmUgKVxyXG5cdFx0e1xyXG5cdFx0XHRjb25zdCBpbWFnZVBhdGggPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoXCJhdHRhY2htZW50Rm9sZGVyUGF0aFwiKSArIFwiL1wiICsgdGhpcy5zZXR0aW5ncy5kaXJwYXRoO1xyXG5cdFx0XHRjb25zdCBpc0NyZWF0ZSA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIuZXhpc3RzKGltYWdlUGF0aCk7XHJcblx0XHRcdGlmKCAhaXNDcmVhdGUgKVxyXG5cdFx0XHR7XHJcblx0XHRcdFx0YXdhaXQgdGhpcy5hcHAudmF1bHQuY3JlYXRlRm9sZGVyKGltYWdlUGF0aCk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdG5ld1BhdGggPSBpbWFnZVBhdGg7XHJcblx0XHR9XHJcblx0XHRlbHNlXHJcblx0XHR7XHJcblx0XHRcdG5ld1BhdGggPSBmaWxlLnBhcmVudC5wYXRoICsgKyBcIi9cIiArIHRoaXMuc2V0dGluZ3MuZGlycGF0aDtcclxuXHRcdH1cclxuXHRcdFxyXG5cdFx0Y29uc3Qgb3JpZ2luTmFtZSA9IGZpbGUubmFtZTtcclxuXHRcdGlmKCB0aGlzLnNldHRpbmdzLnBuZ1RvSnBlZylcclxuXHRcdHtcclxuXHRcdFx0bGV0IGJpbmFyeTpBcnJheUJ1ZmZlciA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LnJlYWRCaW5hcnkoZmlsZSk7XHJcblx0XHRcdGxldCBpbWdCbG9iOkJsb2IgPSBuZXcgQmxvYiggW2JpbmFyeV0gKTtcclxuXHRcdFx0bGV0IGFycmF5QnVmZmVyOkFycmF5QnVmZmVyID0gYXdhaXQgQ29udmVydEltYWdlKGltZ0Jsb2IsIE51bWJlciggdGhpcy5zZXR0aW5ncy5xdWFsaXR5ICkgKTtcclxuXHRcdFx0YXdhaXQgdGhpcy5hcHAudmF1bHQubW9kaWZ5QmluYXJ5KGZpbGUsYXJyYXlCdWZmZXIpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGdldCBvcmlnaW4gZmlsZSBsaW5rIGJlZm9yZSByZW5hbWluZ1xyXG5cdFx0Y29uc3QgbGlua1RleHQgPSB0aGlzLm1ha2VMaW5rVGV4dChmaWxlLCBzb3VyY2VQYXRoKTtcclxuXHJcblx0XHQvLyBmaWxlIHN5c3RlbSBvcGVyYXRpb25cclxuXHRcdG5ld1BhdGggPXBhdGguam9pbihuZXdQYXRoLCBuZXdOYW1lKVxyXG5cdFx0dHJ5IFxyXG5cdFx0e1xyXG5cdFx0XHRhd2FpdCB0aGlzLmFwcC52YXVsdC5yZW5hbWUoZmlsZSwgbmV3UGF0aCk7XHJcblx0XHR9IFxyXG5cdFx0Y2F0Y2ggKGVycikgXHJcblx0XHR7XHJcblx0XHRcdG5ldyBOb3RpY2UoYEZhaWxlZCB0byByZW5hbWUgJHtuZXdOYW1lfTogJHtlcnJ9YClcclxuXHRcdFx0dGhyb3cgZXJyXHJcblx0XHR9XHJcblxyXG5cdFx0Y29uc3QgbmV3TGlua1RleHQgPSB0aGlzLm1ha2VMaW5rVGV4dChmaWxlLCBzb3VyY2VQYXRoKTtcclxuXHRcdGRlYnVnTG9nKCdyZXBsYWNlIHRleHQnLCBsaW5rVGV4dCwgbmV3TGlua1RleHQpXHJcblxyXG5cdFx0Ly8gaW4gY2FzZSBmaWxlTWFuYWdlci5yZW5hbWVGaWxlIG1heSBub3QgdXBkYXRlIHRoZSBpbnRlcm5hbCBsaW5rIGluIHRoZSBhY3RpdmUgZmlsZSxcclxuXHRcdC8vIHdlIG1hbnVhbGx5IHJlcGxhY2UgYnkgbWFuaXB1bGF0aW5nIHRoZSBlZGl0b3JcclxuXHRcdGNvbnN0IGVkaXRvciA9IHRoaXMuZ2V0QWN0aXZlRWRpdG9yKCBzb3VyY2VQYXRoICk7XHJcblx0XHRpZiAoIWVkaXRvcikgXHJcblx0XHR7XHJcblx0XHRcdG5ldyBOb3RpY2UoYEZhaWxlZCB0byByZW5hbWUgJHtuZXdOYW1lfTogbm8gYWN0aXZlIGVkaXRvcmApXHJcblx0XHRcdHJldHVyblxyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGN1cnNvciA9IGVkaXRvci5nZXRDdXJzb3IoKVxyXG5cdFx0Y29uc3QgbGluZSA9IGVkaXRvci5nZXRMaW5lKGN1cnNvci5saW5lKVxyXG5cdFx0ZGVidWdMb2coJ2N1cnJlbnQgbGluZScsIGxpbmUpXHJcblx0XHQvLyBjb25zb2xlLmxvZygnZWRpdG9yIGNvbnRleHQnLCBjdXJzb3IsIClcclxuXHRcdGVkaXRvci50cmFuc2FjdGlvbih7XHJcblx0XHRcdGNoYW5nZXM6IFtcclxuXHRcdFx0XHR7XHJcblx0XHRcdFx0XHRmcm9tOiB7Li4uY3Vyc29yLCBjaDogMH0sXHJcblx0XHRcdFx0XHR0bzogey4uLmN1cnNvciwgY2g6IGxpbmUubGVuZ3RofSxcclxuXHRcdFx0XHRcdHRleHQ6IGxpbmUucmVwbGFjZShsaW5rVGV4dCwgbmV3TGlua1RleHQpLFxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XVxyXG5cdFx0fSlcclxuXHJcblx0XHRuZXcgTm90aWNlKGBSZW5hbWVkICR7b3JpZ2luTmFtZX0gdG8gJHtuZXdOYW1lfWApXHJcblx0fVxyXG5cclxuXHRtYWtlTGlua1RleHQoIGZpbGU6IFRGaWxlLCBzb3VyY2VQYXRoOiBzdHJpbmcsIHN1YnBhdGg/OnN0cmluZyk6IHN0cmluZyBcclxuXHR7XHJcblx0XHRyZXR1cm4gdGhpcy5hcHAuZmlsZU1hbmFnZXIuZ2VuZXJhdGVNYXJrZG93bkxpbmsoZmlsZSwgc291cmNlUGF0aCxzdWJwYXRoKVxyXG5cdH1cclxuXHJcblx0Ly8gcmV0dXJucyBhIG5ldyBuYW1lIGZvciB0aGUgaW5wdXQgZmlsZSwgd2l0aCBleHRlbnNpb25cclxuXHRhc3luYyBnZW5lcmF0ZU5ld05hbWUoZmlsZTogVEZpbGUsIGFjdGl2ZUZpbGU6IFRGaWxlKTpQcm9taXNlPHN0cmluZz5cclxuXHR7XHJcblx0XHRjb25zdCBuZXdOYW1lID0gYWN0aXZlRmlsZS5iYXNlbmFtZSArICctJyArIERhdGUubm93KCk7XHJcblx0XHRjb25zdCBleHRlbnNpb24gPSB0aGlzLnNldHRpbmdzLnBuZ1RvSnBlZyA/ICdqcGVnJyA6IGZpbGUuZXh0ZW5zaW9uO1xyXG5cdFx0XHJcblx0XHRyZXR1cm4gYCR7bmV3TmFtZX0uJHtleHRlbnNpb259YDtcclxuXHR9XHJcblx0XHJcblx0Ly8gY2hhbmdlcyBvbmx5IHRoZSBleHRlbnNpb25cclxuXHRhc3luYyBrZWVwT3JnTmFtZShmaWxlOiBURmlsZSwgYWN0aXZlRmlsZTogVEZpbGUpOlByb21pc2U8c3RyaW5nPlxyXG5cdHtcclxuXHRcdGNvbnN0IG5ld05hbWUgPSBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0Y29uc3QgZXh0ZW5zaW9uID0gdGhpcy5zZXR0aW5ncy5wbmdUb0pwZWcgPyAnanBlZycgOiBmaWxlLmV4dGVuc2lvbjtcclxuXHRcdFxyXG5cdFx0cmV0dXJuIGAke25ld05hbWV9LiR7ZXh0ZW5zaW9ufWA7XHJcblx0fVxyXG5cclxuXHRnZXRBY3RpdmVGaWxlKCkgXHJcblx0e1xyXG5cdFx0Y29uc3QgdmlldyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcclxuXHRcdGNvbnN0IGZpbGUgPSB2aWV3Py5maWxlXHJcblx0XHRkZWJ1Z0xvZygnYWN0aXZlIGZpbGUnLCBmaWxlPy5wYXRoKVxyXG5cdFx0cmV0dXJuIGZpbGVcclxuXHR9XHJcblxyXG5cdGdldEFjdGl2ZUVkaXRvcihzb3VyY2VQYXRoOnN0cmluZykgXHJcblx0e1xyXG5cdFx0Y29uc3QgdmlldyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldylcclxuXHRcdGlmKCB2aWV3IClcclxuXHRcdHtcclxuXHRcdFx0aWYoIHZpZXcuZmlsZS5wYXRoID09IHNvdXJjZVBhdGggKVxyXG5cdFx0XHR7XHJcblx0XHRcdFx0cmV0dXJuIHZpZXcuZWRpdG9yXHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiBudWxsXHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBpc1Bhc3RlZEltYWdlKGZpbGU6IFRBYnN0cmFjdEZpbGUpOiBib29sZWFuIHtcclxuXHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRpZiAoZmlsZS5uYW1lLnN0YXJ0c1dpdGgoUEFTVEVEX0lNQUdFX1BSRUZJWCkpIHtcclxuXHRcdFx0cmV0dXJuIHRydWVcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIGZhbHNlXHJcbn1cclxuXHJcbmNvbnN0IElNQUdFX0VYVFMgPSBbXHJcblx0J2pwZycsICdqcGVnJywgJ3BuZydcclxuXVxyXG5cclxuZnVuY3Rpb24gaXNJbWFnZShmaWxlOiBUQWJzdHJhY3RGaWxlKTogYm9vbGVhbiB7XHJcblx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0aWYgKElNQUdFX0VYVFMuY29udGFpbnMoZmlsZS5leHRlbnNpb24udG9Mb3dlckNhc2UoKSkpIHtcclxuXHRcdFx0cmV0dXJuIHRydWVcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIGZhbHNlXHJcbn1cclxuXHJcbmNsYXNzIFNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcclxuXHRwbHVnaW46IFBhc3RlUG5nVG9KcGVnUGx1Z2luO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBQYXN0ZVBuZ1RvSnBlZ1BsdWdpbikge1xyXG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0fVxyXG5cclxuXHRkaXNwbGF5KCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdQbmcgdG8gSnBlZycpXHJcblx0XHRcdC5zZXREZXNjKGBQYXN0ZSBpbWFnZXMgZnJvbSBDbGlwQm9hcmQgdG8gbm90ZXMgYnkgY29weWluZyB0aGVtIHRocm91Z2ggdmFyaW91cyBzY3JlZW5zaG90IHNvZnR3YXJlLHR1cm4gb24gdGhpcyBmZWF0dXJlIHdpbGwgYXV0b21hdGljYWxseSBjb252ZXJ0IHBuZyB0byBqcGVnLCBhbmQgbW9yZSBxdWFsaXR5IGNvbXByZXNzaW9uIHZvbHVtZS5gKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB0b2dnbGVcclxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucG5nVG9KcGVnKVxyXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnBuZ1RvSnBlZyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHQpKTtcdFxyXG5cdFx0XHRcclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnUXVhbGl0eScpXHJcblx0XHRcdC5zZXREZXNjKGBUaGUgc21hbGxlciB0aGUgUXVhbGl0eSwgdGhlIGdyZWF0ZXIgdGhlIGNvbXByZXNzaW9uIHJhdGlvLmApXHJcblx0XHRcdC5hZGREcm9wZG93bih0b2dnbGUgPT4gdG9nZ2xlXHJcblx0XHRcdFx0LmFkZE9wdGlvbnMoeycwLjEnOicwLjEnLCcwLjInOicwLjInLCcwLjMnOicwLjMnLCcwLjQnOicwLjQnLCcwLjUnOicwLjUnLCcwLjYnOicwLjYnLCcwLjcnOicwLjcnLCcwLjgnOicwLjgnLCcwLjknOicwLjknLCcxLjAnOicxLjAnfSlcclxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucXVhbGl0eSlcclxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5xdWFsaXR5ID0gdmFsdWU7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdCkpO1x0XHJcblx0XHRcdFxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdBdXRvIFJlbmFtZScpXHJcblx0XHRcdC5zZXREZXNjKGBBdXRvbWF0aWNhbGx5IG5hbWVzIHRoZSBpbWFnZSB3aXRoIHRoZSBuYW1lIG9mIHRoZSBwcmV2aW91cyBub3RlICsnLScrIHRoZSBjdXJyZW50IHRpbWVzdGFtcCArICcuJyArIGZpbGUgdHlwZSwgZm9yIGV4YW1wbGUsIHRoZSBpbWFnZSBpbiB0ZXN0Lm1kIHdpbGwgYmUgbmFtZWQgdGVzdC0xNjUyMjYxNzI0MTczLmpwZWdgKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB0b2dnbGVcclxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYXV0b1JlbmFtZSlcclxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvUmVuYW1lID0gdmFsdWU7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdCkpO1x0XHJcblx0XHRcdFxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdBdXRvIE1vdmUgSW1hZ2UnKVxyXG5cdFx0XHQuc2V0RGVzYyhgQXV0b21hdGljYWxseSBtb3ZlIGltYWdlcyB0byB0aGUgaW1hZ2UgZGlyZWN0b3J5LElmIHlvdSBkbyBub3Qgc2V0IHRoZSBkZWZhdWx0IGRpcmVjdG9yeSBmb3IgYXR0YWNobWVudHMsIHRoZW4gaXQgd2lsbCBiZSBzdG9yZWQgZGlyZWN0bHkgdW5kZXIgdGhlIGltYWdlLyBmb2xkZXIgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBub3RlcywgaWYgdGhlcmUgaXMgYSBkZWZhdWx0IGRpcmVjdG9yeSwgdGhlbiBpdCB3aWxsIGJlIHN0b3JlZCB1bmRlciB0aGUgaW1hZ2UvIGZvbGRlciBpbiB0aGUgTWFnaWNpYW4gZGlyZWN0b3J5YClcclxuXHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4gdG9nZ2xlXHJcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmF1dG9Nb3ZlKVxyXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmF1dG9Nb3ZlID0gdmFsdWU7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdCkpO1x0XHRcdFx0XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgeyBBcHAsIFZhdWx0IH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBiYXNlbmFtZSB9IGZyb20gJ3BhdGgnO1xyXG5cclxuZXhwb3J0IGNvbnN0IERFQlVHID0gIShwcm9jZXNzLmVudi5CVUlMRF9FTlYgPT09ICdwcm9kdWN0aW9uJylcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBkZWJ1Z0xvZyguLi5hcmdzOiBhbnlbXSkge1xyXG5cdGlmIChERUJVRykge1xyXG5cdFx0Y29uc29sZS5sb2coKG5ldyBEYXRlKCkpLnRvSVNPU3RyaW5nKCkuc2xpY2UoMTEsIDIzKSwgLi4uYXJncylcclxuXHR9XHJcbn1cclxuXHJcbmludGVyZmFjZSBFbGVtZW50VHJlZU9wdGlvbnMgZXh0ZW5kcyBEb21FbGVtZW50SW5mbyB7XHJcblx0dGFnOiBrZXlvZiBIVE1MRWxlbWVudFRhZ05hbWVNYXBcclxuXHRjaGlsZHJlbj86IEVsZW1lbnRUcmVlT3B0aW9uc1tdXHJcbn1cclxuXHJcbmludGVyZmFjZSBFbGVtZW50VHJlZSB7XHJcblx0ZWw6IEhUTUxFbGVtZW50XHJcblx0Y2hpbGRyZW46IEVsZW1lbnRUcmVlW11cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRUcmVlKHJvb3RFbDogSFRNTEVsZW1lbnQsIG9wdHM6IEVsZW1lbnRUcmVlT3B0aW9ucyk6IEVsZW1lbnRUcmVlIHtcclxuXHRjb25zdCByZXN1bHQ6IEVsZW1lbnRUcmVlID0ge1xyXG5cdFx0ZWw6IHJvb3RFbC5jcmVhdGVFbChvcHRzLnRhZywgb3B0cyBhcyBEb21FbGVtZW50SW5mbyksXHJcblx0XHRjaGlsZHJlbjogW10sXHJcblx0fVxyXG5cdGNvbnN0IGNoaWxkcmVuID0gb3B0cy5jaGlsZHJlbiB8fCBbXVxyXG5cdGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcclxuXHRcdHJlc3VsdC5jaGlsZHJlbi5wdXNoKGNyZWF0ZUVsZW1lbnRUcmVlKHJlc3VsdC5lbCwgY2hpbGQpKVxyXG5cdH1cclxuXHRyZXR1cm4gcmVzdWx0XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBwYXRoID0ge1xyXG5cdC8vIENyZWRpdDogQGNyZWF0aW9uaXgvcGF0aC5qc1xyXG5cdGpvaW4oLi4ucGFydFNlZ21lbnRzOiBzdHJpbmdbXSk6IHN0cmluZyB7XHJcblx0XHQvLyBTcGxpdCB0aGUgaW5wdXRzIGludG8gYSBsaXN0IG9mIHBhdGggY29tbWFuZHMuXHJcblx0XHRsZXQgcGFydHM6IHN0cmluZ1tdID0gW11cclxuXHRcdGZvciAobGV0IGkgPSAwLCBsID0gcGFydFNlZ21lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG5cdFx0XHRwYXJ0cyA9IHBhcnRzLmNvbmNhdChwYXJ0U2VnbWVudHNbaV0uc3BsaXQoJy8nKSlcclxuXHRcdH1cclxuXHRcdC8vIEludGVycHJldCB0aGUgcGF0aCBjb21tYW5kcyB0byBnZXQgdGhlIG5ldyByZXNvbHZlZCBwYXRoLlxyXG5cdFx0Y29uc3QgbmV3UGFydHMgPSBbXVxyXG5cdFx0Zm9yIChsZXQgaSA9IDAsIGwgPSBwYXJ0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuXHRcdFx0Y29uc3QgcGFydCA9IHBhcnRzW2ldXHJcblx0XHRcdC8vIFJlbW92ZSBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzXHJcblx0XHRcdC8vIEFsc28gcmVtb3ZlIFwiLlwiIHNlZ21lbnRzXHJcblx0XHRcdGlmICghcGFydCB8fCBwYXJ0ID09PSAnLicpIGNvbnRpbnVlXHJcblx0XHRcdC8vIFB1c2ggbmV3IHBhdGggc2VnbWVudHMuXHJcblx0XHRcdGVsc2UgbmV3UGFydHMucHVzaChwYXJ0KVxyXG5cdFx0fVxyXG5cdFx0Ly8gUHJlc2VydmUgdGhlIGluaXRpYWwgc2xhc2ggaWYgdGhlcmUgd2FzIG9uZS5cclxuXHRcdGlmIChwYXJ0c1swXSA9PT0gJycpIG5ld1BhcnRzLnVuc2hpZnQoJycpXHJcblx0XHQvLyBUdXJuIGJhY2sgaW50byBhIHNpbmdsZSBzdHJpbmcgcGF0aC5cclxuXHRcdHJldHVybiBuZXdQYXJ0cy5qb2luKCcvJylcclxuXHR9LFxyXG5cclxuXHQvLyByZXR1cm5zIHRoZSBsYXN0IHBhcnQgb2YgYSBwYXRoLCBlLmcuICdmb28uanBnJ1xyXG5cdGJhc2VuYW1lKGZ1bGxwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0Y29uc3Qgc3AgPSBmdWxscGF0aC5zcGxpdCgnLycpXHJcblx0XHRyZXR1cm4gc3Bbc3AubGVuZ3RoIC0gMV1cclxuXHR9LFxyXG5cclxuXHRmaWxlbmFtZShmdWxscGF0aDpzdHJpbmcpOnN0cmluZ1xyXG5cdHtcclxuXHRcdGxldCBmaWxlbmFtZSA9IGJhc2VuYW1lKGZ1bGxwYXRoKTtcclxuXHJcblx0XHRyZXR1cm4gZmlsZW5hbWUuc3Vic3RyaW5nKDAsZmlsZW5hbWUuaW5kZXhPZignLicpIClcclxuXHR9LFxyXG5cclxuXHQvLyByZXR1cm4gZXh0ZW5zaW9uIHdpdGhvdXQgZG90LCBlLmcuICdqcGcnXHJcblx0ZXh0ZW5zaW9uKGZ1bGxwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0Y29uc3QgcG9zaXRpb25zID0gWy4uLmZ1bGxwYXRoLm1hdGNoQWxsKG5ldyBSZWdFeHAoJ1xcXFwuJywgJ2dpJykpXS5tYXAoYSA9PiBhLmluZGV4KVxyXG5cdFx0cmV0dXJuIGZ1bGxwYXRoLnNsaWNlKHBvc2l0aW9uc1twb3NpdGlvbnMubGVuZ3RoIC0gMV0gKyAxKVxyXG5cdH0sXHJcbn1cclxuXHJcbmNvbnN0IGZpbGVuYW1lTm90QWxsb3dlZENoYXJzID0gL1teYS16QS1aMC05fmAhQCQmKigpXFwtXz0re307J1wiLDwuPj8gXS9nXHJcblxyXG5leHBvcnQgY29uc3Qgc2FuaXRpemVyID0ge1xyXG5cdGZpbGVuYW1lKHM6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gcy5yZXBsYWNlKGZpbGVuYW1lTm90QWxsb3dlZENoYXJzLCAnJykudHJpbSgpXHJcblx0fSxcclxuXHJcblx0ZGVsaW1pdGVyKHM6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRzID0gdGhpcy5maWxlbmFtZShzKVxyXG5cdFx0Ly8gdXNlIGRlZmF1bHQgJy0nIGlmIG5vIHZhbGlkIGNoYXJzIGZvdW5kXHJcblx0XHRpZiAoIXMpIHMgPSAnLSdcclxuXHRcdHJldHVybiBzXHJcblx0fVxyXG59XHJcblxyXG4vLyByZWY6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS82OTY5NDg2LzU5NjIwNlxyXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlUmVnRXhwKHM6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHMucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKTtcclxufVxyXG5cclxuXHJcbmludGVyZmFjZSBDb21wb3NpdGlvblN0YXRlIHtcclxuXHRsb2NrOiBib29sZWFuXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBsb2NrSW5wdXRNZXRob2RDb21wb3NpdGlvbihlbDogSFRNTElucHV0RWxlbWVudCk6IENvbXBvc2l0aW9uU3RhdGUge1xyXG5cdGNvbnN0IHN0YXRlOiBDb21wb3NpdGlvblN0YXRlID0ge1xyXG5cdFx0bG9jazogZmFsc2UsXHJcblx0fVxyXG5cdGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbXBvc2l0aW9uc3RhcnQnLCAoKSA9PiB7XHJcblx0XHRzdGF0ZS5sb2NrID0gdHJ1ZVxyXG5cdH0pXHJcblx0ZWwuYWRkRXZlbnRMaXN0ZW5lcignY29tcG9zaXRpb25lbmQnLCAoKSA9PiB7XHJcblx0XHRzdGF0ZS5sb2NrID0gZmFsc2VcclxuXHR9KVxyXG5cdHJldHVybiBzdGF0ZVxyXG59XHJcblxyXG5cclxuaW50ZXJmYWNlIFZhdWx0Q29uZmlnIHtcclxuXHR1c2VNYXJrZG93bkxpbmtzPzogYm9vbGVhblxyXG59XHJcblxyXG5pbnRlcmZhY2UgVmF1bHRXaXRoQ29uZmlnIGV4dGVuZHMgVmF1bHQge1xyXG5cdGNvbmZpZz86IFZhdWx0Q29uZmlnLFxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmF1bHRDb25maWcoYXBwOiBBcHApOiBWYXVsdENvbmZpZ3xudWxsIHtcclxuXHRjb25zdCB2YXVsdCA9IGFwcC52YXVsdCBhcyBWYXVsdFdpdGhDb25maWdcclxuXHRyZXR1cm4gdmF1bHQuY29uZmlnXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBDb252ZXJ0SW1hZ2UoZmlsZTpCbG9iLCBxdWFsaXR5Om51bWJlcik6UHJvbWlzZTxBcnJheUJ1ZmZlcj4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IFxyXG5cdHtcclxuICAgICAgICBsZXQgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsgLy9cdThCRkJcdTUzRDZmaWxlXHJcbiAgICAgICAgcmVhZGVyLm9ubG9hZGVuZCA9IGZ1bmN0aW9uIChlKSBcclxuXHRcdHtcclxuICAgICAgICAgICAgbGV0IGltYWdlID0gbmV3IEltYWdlKCkgLy9cdTY1QjBcdTVFRkFcdTRFMDBcdTRFMkFpbWdcdTY4MDdcdTdCN0VcdUZGMDhcdThGRDhcdTZDQTFcdTVENENcdTUxNjVET01cdTgyODJcdTcwQjkpXHJcbiAgICAgICAgICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIFxyXG5cdFx0XHR7XHJcbiAgICAgICAgICAgICAgICBsZXQgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XHJcbiAgICAgICAgICAgICAgICBsZXQgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGltYWdlV2lkdGggPSBpbWFnZS53aWR0aDtcclxuICAgICAgICAgICAgICAgIGxldCBpbWFnZUhlaWdodCA9IGltYWdlLmhlaWdodDtcclxuICAgICAgICAgICAgICAgIGxldCBkYXRhID0gJyc7XHJcblxyXG4gICAgICAgICAgICAgICAgY2FudmFzLndpZHRoID0gaW1hZ2VXaWR0aDtcclxuICAgICAgICAgICAgICAgIGNhbnZhcy5oZWlnaHQgPSBpbWFnZUhlaWdodDtcclxuXHJcblx0XHRcdFx0Y29udGV4dC5maWxsU3R5bGUgPSAnI2ZmZic7XHJcblx0XHRcdFx0Y29udGV4dC5maWxsUmVjdCgwLCAwLCBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodCk7XHJcblx0XHRcdFx0Y29udGV4dC5zYXZlKCk7XHJcblxyXG5cdFx0XHRcdGNvbnRleHQudHJhbnNsYXRlKGltYWdlV2lkdGggLyAyLCBpbWFnZUhlaWdodCAvIDIpO1xyXG4gICAgICAgICAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDAsIGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0LC1pbWFnZVdpZHRoLzIsLWltYWdlSGVpZ2h0LzIsaW1hZ2VXaWR0aCxpbWFnZUhlaWdodCk7XHJcblx0XHRcdFx0Y29udGV4dC5yZXN0b3JlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgZGF0YSA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL2pwZWcnLHF1YWxpdHkpO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBhcnJheUJ1ZmZlciA9IGJhc2U2NFRvQXJyYXlCdWZmZXIoZGF0YSk7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKGFycmF5QnVmZmVyKVxyXG4gICAgICAgICAgICB9XHJcblxyXG5cdFx0XHRpbWFnZS5zcmMgPSBlLnRhcmdldC5yZXN1bHQudG9TdHJpbmcoKSAvL1x1NUMwNlx1NTZGRVx1NzI0N1x1NzY4NFx1OERFRlx1NUY4NFx1OEJCRVx1NjIxMGZpbGVcdThERUZcdTVGODRcclxuICAgICAgICB9XHJcblxyXG5cdFx0cmVhZGVyLnJlYWRBc0RhdGFVUkwoZmlsZSk7XHJcbiAgICB9KVxyXG59XHJcblxyXG5mdW5jdGlvbiBiYXNlNjRUb0FycmF5QnVmZmVyIChjb2RlOnN0cmluZyk6QXJyYXlCdWZmZXJcclxue1xyXG4gICAgY29uc3QgcGFydHMgPSBjb2RlLnNwbGl0KFwiO2Jhc2U2NCxcIik7XHJcbiAgICBjb25zdCBjb250ZW50VHlwZSA9IHBhcnRzWzBdLnNwbGl0KFwiOlwiKVsxXTtcclxuICAgIGNvbnN0IGZpbGVFeHQgPSBjb250ZW50VHlwZS5zcGxpdChcIi9cIilbMV07XHJcbiAgICBjb25zdCByYXcgPSB3aW5kb3cuYXRvYihwYXJ0c1sxXSk7XHJcbiAgICBjb25zdCByYXdMZW5ndGggPSByYXcubGVuZ3RoO1xyXG5cclxuICAgIGNvbnN0IHVJbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheShyYXdMZW5ndGgpO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmF3TGVuZ3RoOyArK2kpIFxyXG5cdHtcclxuICAgICAgICB1SW50OEFycmF5W2ldID0gcmF3LmNoYXJDb2RlQXQoaSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdUludDhBcnJheS5idWZmZXI7XHJcbn07Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUEsc0JBR087OztBQ0ZQLGtCQUF5QjtBQUVsQixJQUFNLFFBQVEsQ0FBRSxlQUEwQjtBQUUxQyxxQkFBcUIsTUFBYTtBQUN4QyxNQUFJLE9BQU87QUFDVixZQUFRLElBQUssSUFBSSxPQUFRLGNBQWMsTUFBTSxJQUFJLEtBQUssR0FBRztBQUFBO0FBQUE7QUEwQnBELElBQU0sT0FBTztBQUFBLEVBRW5CLFFBQVEsY0FBZ0M7QUFFdkMsUUFBSSxRQUFrQjtBQUN0QixhQUFTLElBQUksR0FBRyxJQUFJLGFBQWEsUUFBUSxJQUFJLEdBQUcsS0FBSztBQUNwRCxjQUFRLE1BQU0sT0FBTyxhQUFhLEdBQUcsTUFBTTtBQUFBO0FBRzVDLFVBQU0s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