diff --git a/.gitignore b/.gitignore index e09a007e..b5b913d1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ node_modules # Don't include the compiled main.js file in the repo. # They should be uploaded to GitHub releases instead. -main.js +# main.js # Exclude sourcemaps *.map diff --git a/main.js b/main.js new file mode 100644 index 00000000..4b796c43 --- /dev/null +++ b/main.js @@ -0,0 +1,620 @@ +/* +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, { + MultLineHandle: () => MultLineHandle, + default: () => BlockLinkPlus +}); +module.exports = __toCommonJS(main_exports); +var import_obsidian = require("obsidian"); +var import_view = require("@codemirror/view"); +var MultLineHandle = /* @__PURE__ */ ((MultLineHandle2) => { + MultLineHandle2[MultLineHandle2["oneline"] = 0] = "oneline"; + MultLineHandle2[MultLineHandle2["heading"] = 1] = "heading"; + MultLineHandle2[MultLineHandle2["multblock"] = 2] = "multblock"; + return MultLineHandle2; +})(MultLineHandle || {}); +var DEFAULT_SETTINGS = { + mult_line_handle: 0 /* oneline */, + // as one line handle + enble_prefix: false, + // no prefix + id_prefix: "", + // prefix + id_length: 4 + // id length +}; +function generateRandomId(prefix, length) { + if (length < 3 || length > 7) { + throw new Error("Length must be between 3 and 7."); + } + const separator = prefix ? "-" : ""; + return `${prefix}${separator}${Math.random().toString(36).substring(2, 2 + length)}`; +} +function shouldInsertAfter(block) { + if (block.type) { + return [ + "blockquote", + "code", + "table", + "comment", + "footnoteDefinition" + ].includes(block.type); + } +} +function analyzeHeadings(fileCache, start_line, end_line) { + var _a, _b; + if (!fileCache || end_line < start_line) { + return { + isValid: false, + start_line, + end_line, + isMultiline: false, + block: null, + nearestBeforeStartLevel: 0, + minLevelInRange: Infinity, + hasHeadingAtStart: false, + hasHeadingAtEnd: false, + headingAtStart: null, + headingAtEnd: null, + isStartHeadingMinLevel: false, + isEndLineJustBeforeHeading: false + }; + } + if (start_line == end_line) { + let head_block = (_a = fileCache.headings) == null ? void 0 : _a.find( + (heading) => { + const { start, end } = heading.position; + return start.line == start_line; + } + ); + let block2 = (fileCache.sections || []).find((section) => { + return section.position.start.line <= end_line && section.position.end.line >= end_line; + }); + return { + isValid: true, + start_line, + end_line, + isMultiline: false, + block: block2, + nearestBeforeStartLevel: 0, + minLevelInRange: head_block ? head_block.level : Infinity, + hasHeadingAtStart: !!block2, + hasHeadingAtEnd: false, + headingAtStart: head_block || null, + headingAtEnd: null, + isStartHeadingMinLevel: block2 ? true : false, + isEndLineJustBeforeHeading: false + }; + } + let nearestBeforeStartLevel = 0; + let minLevelInRange = Infinity; + let hasHeadingAtStart = false; + let hasHeadingAtEnd = false; + let headingAtStart = null; + let headingAtEnd = null; + let isStartHeadingMinLevel = false; + let isEndLineJustBeforeHeading = false; + let closestBeforeStartDistance = Infinity; + let inner_levels = new Array(); + (_b = fileCache.headings) == null ? void 0 : _b.forEach((heading) => { + const { start, end } = heading.position; + if (start.line < start_line) { + const distance = start_line - start.line; + if (start_line - start.line < closestBeforeStartDistance) { + closestBeforeStartDistance = distance; + nearestBeforeStartLevel = heading.level; + } + } + if (start.line >= start_line && end.line <= end_line) { + minLevelInRange = Math.min(minLevelInRange, heading.level); + inner_levels.push(heading.level); + } + if (start.line === start_line) { + hasHeadingAtStart = true; + headingAtStart = heading; + } + if (start.line === end_line) { + hasHeadingAtEnd = true; + headingAtEnd = heading; + } + if (start.line === end_line + 1 || start.line === end_line + 2) { + isEndLineJustBeforeHeading = true; + } + }); + if (hasHeadingAtStart && headingAtStart != null) { + if (headingAtStart.level === minLevelInRange) { + const minLevel = Math.min(...inner_levels); + const countOfMinLevel = inner_levels.filter( + (level) => level === minLevel + ).length; + if (headingAtStart && // @ts-ignore + headingAtStart.level === minLevel && countOfMinLevel === 1) { + isStartHeadingMinLevel = true; + } + } + } + let block = (fileCache.sections || []).find((section) => { + return section.position.start.line <= end_line && section.position.end.line >= end_line; + }); + return { + isValid: true, + start_line, + end_line, + isMultiline: true, + block, + nearestBeforeStartLevel, + minLevelInRange, + hasHeadingAtStart, + hasHeadingAtEnd, + headingAtStart, + headingAtEnd, + isStartHeadingMinLevel, + isEndLineJustBeforeHeading + }; +} +function get_is_heading(head_analysis) { + if (!head_analysis.isValid) { + return false; + } + if (!head_analysis.isMultiline) { + if (head_analysis.hasHeadingAtStart && head_analysis.headingAtStart != null) + return true; + } else { + if (head_analysis.hasHeadingAtStart && // start_line is a heading + head_analysis.isStartHeadingMinLevel) + return true; + } + return false; +} +function gen_insert_blocklink_singleline(block, editor, settings) { + if (block.id) { + return `^${block.id}`; + } + const sectionEnd = block.position.end; + const end = { + ch: sectionEnd.col, + line: sectionEnd.line + }; + const id = generateRandomId( + settings.enble_prefix ? settings.id_prefix : "", + settings.id_length + ); + const spacer = shouldInsertAfter(block) ? "\n\n" : " "; + editor.replaceRange(`${spacer}^${id}`, end); + return `^${id}`; +} +function gen_insert_blocklink_multline_heading(block, editor, settings, heading_level) { + const id = generateRandomId( + settings.enble_prefix ? settings.id_prefix : "", + settings.id_length + ); + const sectionEnd = block.position.end; + const end = { + ch: sectionEnd.col, + line: sectionEnd.line + }; + const heading = "#".repeat(heading_level); + editor.replaceRange(` + + ${heading} ^${id}`, end); + const cursor = editor.getCursor("from"); + editor.setCursor(cursor.line, cursor.ch); + editor.replaceRange(`${heading} \u02C5${id} + +`, { + line: cursor.line, + ch: 0 + }); + return `\u02C5${id}`; +} +function gen_insert_blocklink_multline_block(fileCache, editor, settings) { + if (fileCache.sections == null) + return ""; + const start_line = editor.getCursor("from").line; + const end_line = editor.getCursor("to").line; + const sortedSections = [...fileCache.sections].sort( + (a, b) => a.position.start.line - b.position.start.line + ); + let links = new Array(); + for (const section of sortedSections) { + if (section.position.start.line > end_line) + break; + if (section.position.start.line >= start_line && section.position.end.line <= end_line) { + const id = gen_insert_blocklink_singleline( + section, + editor, + settings + ); + links.push(id); + } + } + return links; +} +function markdownPostProcessor(el) { + if (el.firstChild instanceof Node) { + let walker = document.createTreeWalker( + el.firstChild, + NodeFilter.SHOW_TEXT, + null + ); + let currentNode = walker.currentNode; + while (currentNode) { + const originalText = currentNode.textContent; + let cleanedText = originalText ? originalText.replace(/\s*˅[a-zA-Z0-9-]*/g, "") : ""; + if (originalText !== cleanedText) { + currentNode.textContent = cleanedText; + } + currentNode = walker.nextNode(); + } + } +} +function createViewPlugin(rule = "(^| )\u02C5[a-zA-Z0-9_]+$") { + let decorator = new import_view.MatchDecorator({ + regexp: new RegExp(rule, "g"), + decoration: import_view.Decoration.mark({ class: "small-font" }) + }); + return import_view.ViewPlugin.define( + (view) => ({ + decorations: decorator.createDeco(view), + update(u) { + this.decorations = decorator.updateDeco(u, this.decorations); + } + }), + { + decorations: (v) => v.decorations + } + ); +} +var BlockLinkPlus = class extends import_obsidian.Plugin { + constructor() { + super(...arguments); + this.appName = this.manifest.name; + this.editorExtensions = []; + } + async onload() { + console.log(`loading ${this.appName}`); + await this.loadSettings(); + this.addSettingTab(new BlockLinkPlusSettingsTab(this.app, this)); + this.registerEvent( + this.app.workspace.on( + "editor-menu", + this.handleEditorMenu.bind(this) + ) + ); + this.addCommand({ + id: "copy-link-to-block2", + name: "Copy link to current block or heading", + editorCheckCallback: (isChecking, editor, view) => { + return this.handleCommand(isChecking, editor, view, false); + } + }); + this.addCommand({ + id: "copy-embed-to-block2", + name: "Copy embed to current block or heading", + editorCheckCallback: (isChecking, editor, view) => { + return this.handleCommand(isChecking, editor, view, true); + } + }); + this.registerMarkdownPostProcessor(markdownPostProcessor); + this.viewPlugin = createViewPlugin(); + this.registerEditorExtension([this.viewPlugin]); + } + // Creates new LinkifyViewPlugins and registers them. + // refreshExtensions() { + // this.viewPlugin = createViewPlugin(); + // this.app.workspace.updateOptions(); + // } + handleEditorMenu(menu, editor, view) { + const file = view.file; + if (!file) + return; + const start_line = editor.getCursor("from").line; + const end_line = editor.getCursor("to").line; + const fileCache = this.app.metadataCache.getFileCache(file); + if (!fileCache) + return; + let head_analysis = analyzeHeadings(fileCache, start_line, end_line); + if (!head_analysis.isValid) { + return; + } + let isHeading = get_is_heading(head_analysis); + const addItemToMenu = (title, isEmbed) => { + menu.addItem((item) => { + item.setTitle(title).setIcon("links-coming-in").onClick( + () => this.handleMenuItemClick( + view, + isHeading, + isEmbed, + head_analysis + ) + ); + }); + }; + addItemToMenu( + isHeading ? "Copy link to heading" : "Copy link to block", + false + ); + addItemToMenu( + isHeading ? "Copy heading embed" : "Copy block embed", + true + ); + } + handleMenuItemClick(view, isHeading, isEmbed, head_analysis) { + if (!view.file || !head_analysis.isValid) + return; + const { file, editor } = view; + const fileCache = this.app.metadataCache.getFileCache(file); + if (!fileCache) + return; + if (!head_analysis.isMultiline) { + this.handleSingleLine( + file, + isHeading, + isEmbed, + head_analysis, + editor + ); + } else { + this.handleMultiLine( + file, + isHeading, + isEmbed, + head_analysis, + editor, + fileCache + ); + } + } + handleSingleLine(file, isHeading, isEmbed, head_analysis, editor) { + if (isHeading && head_analysis.headingAtStart) { + this.copyToClipboard( + file, + head_analysis.headingAtStart.heading, + isEmbed + ); + } else if (!isHeading && head_analysis.block) { + const link = gen_insert_blocklink_singleline( + head_analysis.block, + editor, + this.settings + ); + this.copyToClipboard(file, link, isEmbed); + } + } + handleMultiLine(file, isHeading, isEmbed, head_analysis, editor, fileCache) { + if (isHeading && head_analysis.headingAtStart) { + this.copyToClipboard( + file, + head_analysis.headingAtStart.heading, + isEmbed + ); + } else { + this.handleMultiLineBlock( + file, + isEmbed, + head_analysis, + editor, + fileCache + ); + } + } + _gen_insert_blocklink_multline_heading(fileCache, editor, head_analysis) { + if (!head_analysis.block) + return ""; + return gen_insert_blocklink_multline_heading( + head_analysis.block, + editor, + this.settings, + head_analysis.nearestBeforeStartLevel + 1 + ); + } + _gen_insert_blocklink_multline_block(fileCache, editor, head_analysis) { + return gen_insert_blocklink_multline_block( + fileCache, + editor, + this.settings + ); + } + handleMultiLineBlock(file, isEmbed, head_analysis, editor, fileCache) { + if (this.settings.mult_line_handle == 0 /* oneline */) { + if (head_analysis.block) { + const link = gen_insert_blocklink_singleline( + head_analysis.block, + editor, + this.settings + ); + this.copyToClipboard(file, link, isEmbed); + } + return; + } else { + if (head_analysis.minLevelInRange != Infinity) { + new import_obsidian.Notice( + `Please select text that does not include headings`, + 1500 + ); + return; + } + const linkMethod = this.settings.mult_line_handle == 1 /* heading */ ? this._gen_insert_blocklink_multline_heading : this._gen_insert_blocklink_multline_block; + const link = linkMethod.call( + this, + fileCache, + editor, + head_analysis + ); + this.copyToClipboard(file, link, isEmbed); + return; + } + } + onunload() { + } + async loadSettings() { + this.settings = Object.assign( + {}, + DEFAULT_SETTINGS, + await this.loadData() + ); + } + async saveSettings() { + await this.saveData(this.settings); + } + handleCommand(isChecking, editor, view, isEmbed) { + if (isChecking) { + return true; + } + const file = view.file; + if (!file) + return; + const start_line = editor.getCursor("from").line; + const end_line = editor.getCursor("to").line; + const fileCache = this.app.metadataCache.getFileCache(file); + if (!fileCache) + return; + let head_analysis = analyzeHeadings(fileCache, start_line, end_line); + if (!head_analysis.isValid) { + return; + } + let isHeading = get_is_heading(head_analysis); + if (!head_analysis.isMultiline) { + this.handleSingleLine( + file, + isHeading, + isEmbed, + head_analysis, + editor + ); + } else { + this.handleMultiLine( + file, + isHeading, + isEmbed, + head_analysis, + editor, + fileCache + ); + } + return true; + } + /** + * Copies links to one or more blocks to the clipboard. + * + * @param file - The file containing the blocks. + * @param links - An array of block links (^id) or heading links (heading without `#`). + * @param isEmbed - Specifies whether the links should be embedded. + * @param alias - An optional alias for the links. + */ + copyToClipboard(file, links, isEmbed, alias) { + const linksArray = typeof links === "string" ? [links] : links; + const markdownLinks = linksArray.map((link, index) => { + const addNewLine = index < links.length - 1 ? "\n" : ""; + return `${isEmbed ? "!" : ""}${this.app.fileManager.generateMarkdownLink( + file, + "", + "#" + link, + alias + )}${addNewLine}`; + }).join(""); + navigator.clipboard.writeText(markdownLinks); + } +}; +var BlockLinkPlusSettingsTab = class extends import_obsidian.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + addToggleSetting(settingName, extraOnChange) { + return new import_obsidian.Setting(this.containerEl).addToggle((toggle) => { + toggle.setValue(this.plugin.settings[settingName]).onChange(async (value) => { + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + extraOnChange == null ? void 0 : extraOnChange(value); + }); + }); + } + // 文本输入框 + addTextInputSetting(settingName, placeholder) { + return new import_obsidian.Setting(this.containerEl).addText( + (text) => text.setPlaceholder(placeholder).setValue(this.plugin.settings[settingName]).onChange(async (value) => { + if (value.length > 0) { + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + } + }) + ); + } + addDropdownSetting(settingName, options, display) { + return new import_obsidian.Setting(this.containerEl).addDropdown((dropdown) => { + var _a; + const displayNames = /* @__PURE__ */ new Set(); + for (const option of options) { + const displayName = (_a = display == null ? void 0 : display(option)) != null ? _a : option; + if (!displayNames.has(displayName)) { + dropdown.addOption(option, displayName); + displayNames.add(displayName); + } + } + dropdown.setValue(this.plugin.settings[settingName]).onChange(async (value) => { + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + }); + }); + } + addSliderSetting(settingName, min, max, step) { + return new import_obsidian.Setting(this.containerEl).addSlider((slider) => { + slider.setLimits(min, max, step).setValue(this.plugin.settings[settingName]).setDynamicTooltip().onChange(async (value) => { + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + }); + }); + } + addHeading(heading) { + return new import_obsidian.Setting(this.containerEl).setName(heading).setHeading(); + } + display() { + const { containerEl } = this; + containerEl.empty(); + containerEl.createEl("h2", { text: "Block-link Settings" }); + this.addDropdownSetting( + //@ts-ignore + "mult_line_handle", + ["0", "1", "2"], + (option) => { + const optionsSet = /* @__PURE__ */ new Map([ + ["0", "Default"], + ["1", "Add new heading"], + ["2", "Add multi block"] + ]); + return optionsSet.get(option) || "Unknown"; + } + ).setName("Multi-line Block Behavior").setDesc( + "Define how multi-line selections generate block IDs. 'Default' treats them as a single line." + ); + this.addHeading("Block ID settings"); + this.addSliderSetting("id_length", 3, 7, 1).setName("Max Block ID Length").setDesc("Set the maximum number of characters for a block ID."); + this.addToggleSetting("enble_prefix").setName("Custom ID Prefix"); + this.addTextInputSetting("id_prefix", "").setName("Block ID Prefix").setDesc("Block ID will be: prefix-random_str"); + } +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHtcblx0QXBwLFxuXHRFZGl0b3IsXG5cdE1hcmtkb3duVmlldyxcblx0TW9kYWwsXG5cdE5vdGljZSxcblx0UGx1Z2luLFxuXHRQbHVnaW5TZXR0aW5nVGFiLFxuXHRTZXR0aW5nLFxuXHRURmlsZSxcblx0SGVhZGluZ0NhY2hlLFxuXHRMaXN0SXRlbUNhY2hlLFxuXHRTZWN0aW9uQ2FjaGUsXG5cdEVkaXRvclBvc2l0aW9uLFxuXHRNYXJrZG93bkZpbGVJbmZvLFxuXHRNZW51LFxuXHRDYWNoZWRNZXRhZGF0YSxcbn0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmltcG9ydCB7XG5cdERlY29yYXRpb24sXG5cdE1hdGNoRGVjb3JhdG9yLFxuXHRWaWV3UGx1Z2luLFxuXHRWaWV3VXBkYXRlLFxufSBmcm9tIFwiQGNvZGVtaXJyb3Ivdmlld1wiO1xuaW1wb3J0IHsgRXh0ZW5zaW9uLCBSYW5nZVNldCB9IGZyb20gXCJAY29kZW1pcnJvci9zdGF0ZVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcImNvbnNvbGVcIjtcbmltcG9ydCB7IGluZmxhdGUgfSBmcm9tIFwiemxpYlwiO1xuLy8gaW1wb3J0IHsgUmFuZ2VTZXQgfSBmcm9tIFwiQGNvZGVtaXJyb3Ivc3RhdGVcIjtcblxudHlwZSBIZWFkaW5nQW5hbHlzaXNSZXN1bHQgPSB7XG5cdGlzVmFsaWQ6IGJvb2xlYW47IC8vIFx1NjYyRlx1NTQyNlx1NjcwOVx1NjU0OFxuXHRzdGFydF9saW5lOiBudW1iZXI7IC8vIFx1OTAwOVx1NEUyRFx1NjU4N1x1NjcyQ1x1NzY4NFx1NUYwMFx1NTlDQlx1ODg0Q1xuXHRlbmRfbGluZTogbnVtYmVyOyAvLyBcdTkwMDlcdTRFMkRcdTY1ODdcdTY3MkNcdTc2ODRcdTdFRDNcdTY3NUZcdTg4NENcblx0aXNNdWx0aWxpbmU6IGJvb2xlYW47IC8vIFx1NjYyRlx1NTQyNlx1NjYyRlx1NTkxQVx1ODg0Q1x1OTAwOVx1NEUyRFxuXHRibG9jazogU2VjdGlvbkNhY2hlIHwgbnVsbDsgLy8gXHU2NjgyXHU2NUY2Zm9yIHNpbmdsZSBsaW5lXG5cdG5lYXJlc3RCZWZvcmVTdGFydExldmVsOiBudW1iZXI7IC8vIFx1OERERFx1NzlCQiBzdGFydF9saW5lIFx1NjcwMFx1OEZEMVx1NzY4NCBoZWFkaW5nIFx1NzY4NCBsZXZlbFxuXHRtaW5MZXZlbEluUmFuZ2U6IG51bWJlcjsgLy8gW3N0YXJ0X2xpbmUsIGVuZF9saW5lXSBcdTgzMDNcdTU2RjRcdTUxODVcdTc2ODRcdTY3MDBcdTVDMEYgaGVhZGluZyBsZXZlbFxuXHRoYXNIZWFkaW5nQXRTdGFydDogYm9vbGVhbjsgLy8gXHU2NjJGXHU1NDI2XHU2NzA5IGhlYWRpbmcgXHU3Njg0IHN0YXJ0LmxpbmUgXHU2QjYzXHU1OTdEXHU2NjJGIHN0YXJ0X2xpbmVcblx0aGFzSGVhZGluZ0F0RW5kOiBib29sZWFuOyAvLyBcdTY2MkZcdTU0MjZcdTY3MDkgaGVhZGluZyBcdTc2ODQgc3RhcnQubGluZSBcdTZCNjNcdTU5N0RcdTY2MkYgZW5kX2xpbmVcblx0aGVhZGluZ0F0U3RhcnQ6IEhlYWRpbmdDYWNoZSB8IG51bGw7IC8vIFx1NTcyOCBzdGFydF9saW5lIFx1NTkwNFx1NzY4NCBoZWFkaW5nIHwgXHU0RUM1XHU1NzI4IGhhc0hlYWRpbmdBdFN0YXJ0IFx1NEUzQSB0cnVlIFx1NjVGNlx1NjcwOVx1NjU0OFxuXHRoZWFkaW5nQXRFbmQ6IEhlYWRpbmdDYWNoZSB8IG51bGw7IC8vIFx1NTcyOCBlbmRfbGluZSBcdTU5MDRcdTc2ODQgaGVhZGluZyB8IFx1NEVDNVx1NTcyOCBoYXNIZWFkaW5nQXRFbmQgXHU0RTNBIHRydWUgXHU2NUY2XHU2NzA5XHU2NTQ4XG5cdGlzU3RhcnRIZWFkaW5nTWluTGV2ZWw6IGJvb2xlYW47IC8vXHRoZWFkaW5nQXRTdGFydCBcdTY2MkZcdTU0MjZcdTY2MkZcdTY3MDBcdTVDMEZcdTUxNzZcdTU1MkZcdTRFMDAgbGV2ZWwgXHU3Njg0IGhlYWRpbmcgfCBcdTRFQzVcdTU3MjggaGFzSGVhZGluZ0F0U3RhcnQgXHU0RTNBIHRydWUgXHU2NUY2XHU2NzA5XHU2NTQ4XG5cdGlzRW5kTGluZUp1c3RCZWZvcmVIZWFkaW5nOiBib29sZWFuOyAvLyBlbmRfbGluZSBcdTY2MkZcdTU0MjZcdTZCNjNcdTU5N0RcdTY2MkZcdTY3RDBcdTRFMkEgaGVhZGluZyBcdTc2ODQgc3RhcnQubGluZSAtIDFcbn07XG5cbmV4cG9ydCBjb25zdCBlbnVtIE11bHRMaW5lSGFuZGxlIHtcblx0b25lbGluZSwgLy8gYXMgb25lIGxpbmUgaGFuZGxlXG5cdGhlYWRpbmcsIC8vIGFkZCBuZXcgaGVhZGluZywgaWYgc2VsZWN0IHRleHQgY29udGFpbiBub3QgaGVhZGluZ1xuXHRtdWx0YmxvY2ssIC8vIGFkZCBuZXcgYmxvY2ssIGlmIHNlbGVjdCB0ZXh0IGNvbnRhaW4gbm90IGJsb2NrXG59XG5cbmV4cG9ydCB0eXBlIEtleXNPZlR5cGU8T2JqLCBUeXBlPiA9IHtcblx0W2sgaW4ga2V5b2YgT2JqXTogT2JqW2tdIGV4dGVuZHMgVHlwZSA/IGsgOiBuZXZlcjtcbn1ba2V5b2YgT2JqXTtcblxudHlwZSBCbG9ja0xpbmtQbHVzVmlld1BsdWdpbiA9IFZpZXdQbHVnaW48e1xuXHRkZWNvcmF0aW9uczogUmFuZ2VTZXQ8RGVjb3JhdGlvbj47XG5cdHVwZGF0ZSh1OiBWaWV3VXBkYXRlKTogdm9pZDtcbn0+O1xuXG5pbnRlcmZhY2UgUGx1Z2luU2V0dGluZ3Mge1xuXHRtdWx0X2xpbmVfaGFuZGxlOiBNdWx0TGluZUhhbmRsZTtcblx0ZW5ibGVfcHJlZml4OiBib29sZWFuO1xuXHRpZF9wcmVmaXg6IHN0cmluZztcblx0aWRfbGVuZ3RoOiBudW1iZXI7XG59XG5cbmNvbnN0IERFRkFVTFRfU0VUVElOR1M6IFBsdWdpblNldHRpbmdzID0ge1xuXHRtdWx0X2xpbmVfaGFuZGxlOiBNdWx0TGluZUhhbmRsZS5vbmVsaW5lLCAvLyBhcyBvbmUgbGluZSBoYW5kbGVcblx0ZW5ibGVfcHJlZml4OiBmYWxzZSwgLy8gbm8gcHJlZml4XG5cdGlkX3ByZWZpeDogXCJcIiwgLy8gcHJlZml4XG5cdGlkX2xlbmd0aDogNCwgLy8gaWQgbGVuZ3RoXG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBJRCB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4IGFuZCBsZW5ndGguXG4gKlxuICogQHBhcmFtIHByZWZpeCAtIFRoZSBwcmVmaXggdG8gYmUgYWRkZWQgdG8gdGhlIElEIChvcHRpb25hbCkuXG4gKiBAcGFyYW0gbGVuZ3RoIC0gVGhlIGxlbmd0aCBvZiB0aGUgcmFuZG9tIElELiBNdXN0IGJlIGJldHdlZW4gMyBhbmQgNyAoaW5jbHVzaXZlKS5cbiAqIEByZXR1cm5zIFRoZSBnZW5lcmF0ZWQgcmFuZG9tIElELlxuICogQHRocm93cyBFcnJvciBpZiB0aGUgbGVuZ3RoIGlzIG5vdCBiZXR3ZWVuIDMgYW5kIDcuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlUmFuZG9tSWQocHJlZml4OiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyKTogc3RyaW5nIHtcblx0aWYgKGxlbmd0aCA8IDMgfHwgbGVuZ3RoID4gNykge1xuXHRcdHRocm93IG5ldyBFcnJvcihcIkxlbmd0aCBtdXN0IGJlIGJldHdlZW4gMyBhbmQgNy5cIik7XG5cdH1cblx0Y29uc3Qgc2VwYXJhdG9yID0gcHJlZml4ID8gXCItXCIgOiBcIlwiO1xuXHRyZXR1cm4gYCR7cHJlZml4fSR7c2VwYXJhdG9yfSR7TWF0aC5yYW5kb20oKVxuXHRcdC50b1N0cmluZygzNilcblx0XHQuc3Vic3RyaW5nKDIsIDIgKyBsZW5ndGgpfWA7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgYmxvY2sgc2hvdWxkIGJlIGluc2VydGVkIGF0IG5leHQgbGluZS5cbiAqXG4gKiBAcGFyYW0gYmxvY2sgLSBUaGUgYmxvY2sgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGJsb2NrIHNob3VsZCBiZSBpbnNlcnRlZCBhZnRlciwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKi9cbmZ1bmN0aW9uIHNob3VsZEluc2VydEFmdGVyKGJsb2NrOiBMaXN0SXRlbUNhY2hlIHwgU2VjdGlvbkNhY2hlKSB7XG5cdGlmICgoYmxvY2sgYXMgYW55KS50eXBlKSB7XG5cdFx0cmV0dXJuIFtcblx0XHRcdFwiYmxvY2txdW90ZVwiLFxuXHRcdFx0XCJjb2RlXCIsXG5cdFx0XHRcInRhYmxlXCIsXG5cdFx0XHRcImNvbW1lbnRcIixcblx0XHRcdFwiZm9vdG5vdGVEZWZpbml0aW9uXCIsXG5cdFx0XS5pbmNsdWRlcygoYmxvY2sgYXMgU2VjdGlvbkNhY2hlKS50eXBlKTtcblx0fVxufVxuXG4vKipcbiAqIEFuYWx5emVzIHRoZSBoZWFkaW5ncyB3aXRoaW4gYSBzcGVjaWZpZWQgcmFuZ2Ugb2YgbGluZXMgaW4gYSBmaWxlLlxuICpcbiAqIEBwYXJhbSBmaWxlQ2FjaGUgLSBUaGUgY2FjaGVkIG1ldGFkYXRhIG9mIHRoZSBmaWxlLlxuICogQHBhcmFtIHN0YXJ0X2xpbmUgLSBUaGUgc3RhcnRpbmcgbGluZSBvZiB0aGUgcmFuZ2UuXG4gKiBAcGFyYW0gZW5kX2xpbmUgLSBUaGUgZW5kaW5nIGxpbmUgb2YgdGhlIHJhbmdlLlxuICogQHJldHVybnMgVGhlIGFuYWx5c2lzIHJlc3VsdCBvZiB0aGUgaGVhZGluZ3Mgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UuXG4gKi9cbmZ1bmN0aW9uIGFuYWx5emVIZWFkaW5ncyhcblx0ZmlsZUNhY2hlOiBDYWNoZWRNZXRhZGF0YSxcblx0c3RhcnRfbGluZTogbnVtYmVyLFxuXHRlbmRfbGluZTogbnVtYmVyXG4pOiBIZWFkaW5nQW5hbHlzaXNSZXN1bHQge1xuXHRpZiAoIWZpbGVDYWNoZSB8fCBlbmRfbGluZSA8IHN0YXJ0X2xpbmUpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0aXNWYWxpZDogZmFsc2UsXG5cdFx0XHRzdGFydF9saW5lLFxuXHRcdFx0ZW5kX2xpbmUsXG5cdFx0XHRpc011bHRpbGluZTogZmFsc2UsXG5cdFx0XHRibG9jazogbnVsbCxcblx0XHRcdG5lYXJlc3RCZWZvcmVTdGFydExldmVsOiAwLFxuXHRcdFx0bWluTGV2ZWxJblJhbmdlOiBJbmZpbml0eSxcblx0XHRcdGhhc0hlYWRpbmdBdFN0YXJ0OiBmYWxzZSxcblx0XHRcdGhhc0hlYWRpbmdBdEVuZDogZmFsc2UsXG5cdFx0XHRoZWFkaW5nQXRTdGFydDogbnVsbCxcblx0XHRcdGhlYWRpbmdBdEVuZDogbnVsbCxcblx0XHRcdGlzU3RhcnRIZWFkaW5nTWluTGV2ZWw6IGZhbHNlLFxuXHRcdFx0aXNFbmRMaW5lSnVzdEJlZm9yZUhlYWRpbmc6IGZhbHNlLFxuXHRcdH07XG5cdH1cblxuXHQvLyBjb25zb2xlLmxvZyhcImFuYWx5emVIZWFkaW5nc1wiLCBmaWxlQ2FjaGUsIHN0YXJ0X2xpbmUsIGVuZF9saW5lKTsgLy8gZGVidWdcblx0Ly8gb25lIGxpbmVcblx0aWYgKHN0YXJ0X2xpbmUgPT0gZW5kX2xpbmUpIHtcblx0XHRsZXQgaGVhZF9ibG9jazogSGVhZGluZ0NhY2hlIHwgdW5kZWZpbmVkID0gZmlsZUNhY2hlLmhlYWRpbmdzPy5maW5kKFxuXHRcdFx0KGhlYWRpbmcpID0+IHtcblx0XHRcdFx0Y29uc3QgeyBzdGFydCwgZW5kIH0gPSBoZWFkaW5nLnBvc2l0aW9uO1xuXHRcdFx0XHRyZXR1cm4gc3RhcnQubGluZSA9PSBzdGFydF9saW5lO1xuXHRcdFx0fVxuXHRcdCk7XG5cblx0XHRsZXQgYmxvY2sgPSAoZmlsZUNhY2hlLnNlY3Rpb25zIHx8IFtdKS5maW5kKChzZWN0aW9uKSA9PiB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRzZWN0aW9uLnBvc2l0aW9uLnN0YXJ0LmxpbmUgPD0gZW5kX2xpbmUgJiZcblx0XHRcdFx0c2VjdGlvbi5wb3NpdGlvbi5lbmQubGluZSA+PSBlbmRfbGluZVxuXHRcdFx0KTtcblx0XHR9KSE7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGlzVmFsaWQ6IHRydWUsXG5cdFx0XHRzdGFydF9saW5lLFxuXHRcdFx0ZW5kX2xpbmUsXG5cdFx0XHRpc011bHRpbGluZTogZmFsc2UsXG5cdFx0XHRibG9jayxcblx0XHRcdG5lYXJlc3RCZWZvcmVTdGFydExldmVsOiAwLFxuXHRcdFx0bWluTGV2ZWxJblJhbmdlOiBoZWFkX2Jsb2NrID8gaGVhZF9ibG9jay5sZXZlbCA6IEluZmluaXR5LFxuXHRcdFx0aGFzSGVhZGluZ0F0U3RhcnQ6ICEhYmxvY2ssXG5cdFx0XHRoYXNIZWFkaW5nQXRFbmQ6IGZhbHNlLFxuXHRcdFx0aGVhZGluZ0F0U3RhcnQ6IGhlYWRfYmxvY2sgfHwgbnVsbCxcblx0XHRcdGhlYWRpbmdBdEVuZDogbnVsbCxcblx0XHRcdGlzU3RhcnRIZWFkaW5nTWluTGV2ZWw6IGJsb2NrID8gdHJ1ZSA6IGZhbHNlLFxuXHRcdFx0aXNFbmRMaW5lSnVzdEJlZm9yZUhlYWRpbmc6IGZhbHNlLFxuXHRcdH07XG5cdH1cblxuXHRsZXQgbmVhcmVzdEJlZm9yZVN0YXJ0TGV2ZWwgPSAwO1xuXHRsZXQgbWluTGV2ZWxJblJhbmdlID0gSW5maW5pdHk7XG5cdGxldCBoYXNIZWFkaW5nQXRTdGFydCA9IGZhbHNlO1xuXHRsZXQgaGFzSGVhZGluZ0F0RW5kID0gZmFsc2U7XG5cblx0bGV0IGhlYWRpbmdBdFN0YXJ0OiBIZWFkaW5nQ2FjaGUgfCBudWxsID0gbnVsbDtcblx0bGV0IGhlYWRpbmdBdEVuZDogSGVhZGluZ0NhY2hlIHwgbnVsbCA9IG51bGw7XG5cdGxldCBpc1N0YXJ0SGVhZGluZ01pbkxldmVsID0gZmFsc2U7XG5cblx0bGV0IGlzRW5kTGluZUp1c3RCZWZvcmVIZWFkaW5nID0gZmFsc2U7XG5cblx0bGV0IGNsb3Nlc3RCZWZvcmVTdGFydERpc3RhbmNlID0gSW5maW5pdHk7IC8vIHJlY29yZCB0aGUgY2xvc2VzdCBoZWFkaW5nIGRpc3RhbmNlIGF0IFswLCBzdGFydF9saW5lKVxuXG5cdGxldCBpbm5lcl9sZXZlbHMgPSBuZXcgQXJyYXk8bnVtYmVyPigpO1xuXG5cdGZpbGVDYWNoZS5oZWFkaW5ncz8uZm9yRWFjaCgoaGVhZGluZykgPT4ge1xuXHRcdGNvbnN0IHsgc3RhcnQsIGVuZCB9ID0gaGVhZGluZy5wb3NpdGlvbjtcblx0XHQvLyBcdTVCRjlcdTRFOEUgc3RhcnQubGluZSBcdTU3MjggKDAsIHN0YXJ0X2xpbmUpIFx1NUYwMFx1NTMzQVx1OTVGNFx1NzY4NFx1NTkwNFx1NzQwNlxuXHRcdGlmIChzdGFydC5saW5lIDwgc3RhcnRfbGluZSkge1xuXHRcdFx0Y29uc3QgZGlzdGFuY2UgPSBzdGFydF9saW5lIC0gc3RhcnQubGluZTtcblx0XHRcdGlmIChzdGFydF9saW5lIC0gc3RhcnQubGluZSA8IGNsb3Nlc3RCZWZvcmVTdGFydERpc3RhbmNlKSB7XG5cdFx0XHRcdGNsb3Nlc3RCZWZvcmVTdGFydERpc3RhbmNlID0gZGlzdGFuY2U7XG5cdFx0XHRcdG5lYXJlc3RCZWZvcmVTdGFydExldmVsID0gaGVhZGluZy5sZXZlbDtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gXHU1QkY5XHU0RThFIHN0YXJ0LmxpbmUgXHU1NzI4IFtzdGFydF9saW5lLCBlbmRfbGluZV0gXHU1MTY4XHU5NUVEXHU1MzNBXHU5NUY0XHU3Njg0XHU1OTA0XHU3NDA2XG5cdFx0aWYgKHN0YXJ0LmxpbmUgPj0gc3RhcnRfbGluZSAmJiBlbmQubGluZSA8PSBlbmRfbGluZSkge1xuXHRcdFx0bWluTGV2ZWxJblJhbmdlID0gTWF0aC5taW4obWluTGV2ZWxJblJhbmdlLCBoZWFkaW5nLmxldmVsKTtcblx0XHRcdGlubmVyX2xldmVscy5wdXNoKGhlYWRpbmcubGV2ZWwpO1xuXHRcdH1cblx0XHQvLyBcdTY4QzBcdTY3RTVcdTY2MkZcdTU0MjZcdTY3MDkgaGVhZGluZyBcdTc2ODQgc3RhcnQubGluZSBcdTZCNjNcdTU5N0RcdTY2MkYgc3RhcnRfbGluZSBcdTYyMTYgZW5kX2xpbmVcblx0XHRpZiAoc3RhcnQubGluZSA9PT0gc3RhcnRfbGluZSkge1xuXHRcdFx0aGFzSGVhZGluZ0F0U3RhcnQgPSB0cnVlO1xuXHRcdFx0aGVhZGluZ0F0U3RhcnQgPSBoZWFkaW5nO1xuXHRcdH1cblx0XHRpZiAoc3RhcnQubGluZSA9PT0gZW5kX2xpbmUpIHtcblx0XHRcdGhhc0hlYWRpbmdBdEVuZCA9IHRydWU7XG5cdFx0XHRoZWFkaW5nQXRFbmQgPSBoZWFkaW5nO1xuXHRcdH1cblx0XHQvLyBcdTY4QzBcdTY3RTUgZW5kX2xpbmUgXHU2NjJGXHU1NDI2XHU2MDcwXHU1OTdEXHU1NzI4XHU0RTAwXHU0RTJBIGhlYWRpbmcgXHU3Njg0XHU0RTBBXHU0RTAwXHU4ODRDXG5cdFx0aWYgKHN0YXJ0LmxpbmUgPT09IGVuZF9saW5lICsgMSB8fCBzdGFydC5saW5lID09PSBlbmRfbGluZSArIDIpIHtcblx0XHRcdGlzRW5kTGluZUp1c3RCZWZvcmVIZWFkaW5nID0gdHJ1ZTtcblx0XHR9XG5cdH0pO1xuXG5cdC8vIFx1NjhDMFx1NjdFNVx1NTcyOCBoYXNIZWFkaW5nQXRTdGFydCBcdTRFM0EgdHJ1ZSBcdTY1RjZcdUZGMENcdTUxNzYgbGV2ZWwgXHU2NjJGXHU1NDI2XHU2NjJGXHU4MzAzXHU1NkY0XHU1MTg1XHU2NzAwXHU1QzBGXHU3Njg0XHVGRjBDXHU1RTc2XHU0RTE0XHU4RkQ5XHU0RTJBXHU1MDNDXHU3Njg0IGhlYWRpbmcgXHU2NjJGXHU1NDI2XHU1NTJGXHU0RTAwXG5cdGlmIChoYXNIZWFkaW5nQXRTdGFydCAmJiBoZWFkaW5nQXRTdGFydCAhPSBudWxsKSB7XG5cdFx0Ly8gQHRzLWlnbm9yZSB8IHRzIFx1N0M3Qlx1NTc4Qlx1OEJDNlx1NTIyQlx1OTUxOVx1OEJFRlx1NEU4NlxuXHRcdGlmIChoZWFkaW5nQXRTdGFydC5sZXZlbCA9PT0gbWluTGV2ZWxJblJhbmdlKSB7XG5cdFx0XHRjb25zdCBtaW5MZXZlbCA9IE1hdGgubWluKC4uLmlubmVyX2xldmVscyk7XG5cdFx0XHRjb25zdCBjb3VudE9mTWluTGV2ZWwgPSBpbm5lcl9sZXZlbHMuZmlsdGVyKFxuXHRcdFx0XHQobGV2ZWwpID0+IGxldmVsID09PSBtaW5MZXZlbFxuXHRcdFx0KS5sZW5ndGg7XG5cdFx0XHQvLyBoZWFkaW5nQXRTdGFydC5sZXZlbCBpcyB0aGUgbWluIGxldmVsIGluIHRoZSByYW5nZVxuXHRcdFx0Ly8gYW5kIGl0IGlzIHRoZSBvbmx5IGhlYWRpbmcgaW4gdGhlIHJhbmdlXG5cdFx0XHRpZiAoXG5cdFx0XHRcdGhlYWRpbmdBdFN0YXJ0ICYmXG5cdFx0XHRcdC8vIEB0cy1pZ25vcmVcblx0XHRcdFx0aGVhZGluZ0F0U3RhcnQubGV2ZWwgPT09IG1pbkxldmVsICYmXG5cdFx0XHRcdGNvdW50T2ZNaW5MZXZlbCA9PT0gMVxuXHRcdFx0KSB7XG5cdFx0XHRcdGlzU3RhcnRIZWFkaW5nTWluTGV2ZWwgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRsZXQgYmxvY2sgPSAoZmlsZUNhY2hlLnNlY3Rpb25zIHx8IFtdKS5maW5kKChzZWN0aW9uKSA9PiB7XG5cdFx0cmV0dXJuIChcblx0XHRcdHNlY3Rpb24ucG9zaXRpb24uc3RhcnQubGluZSA8PSBlbmRfbGluZSAmJlxuXHRcdFx0c2VjdGlvbi5wb3NpdGlvbi5lbmQubGluZSA+PSBlbmRfbGluZVxuXHRcdCk7XG5cdH0pITtcblx0cmV0dXJuIHtcblx0XHRpc1ZhbGlkOiB0cnVlLFxuXHRcdHN0YXJ0X2xpbmUsXG5cdFx0ZW5kX2xpbmUsXG5cdFx0aXNNdWx0aWxpbmU6IHRydWUsXG5cdFx0YmxvY2s6IGJsb2NrLFxuXHRcdG5lYXJlc3RCZWZvcmVTdGFydExldmVsLFxuXHRcdG1pbkxldmVsSW5SYW5nZSxcblx0XHRoYXNIZWFkaW5nQXRTdGFydCxcblx0XHRoYXNIZWFkaW5nQXRFbmQsXG5cdFx0aGVhZGluZ0F0U3RhcnQsXG5cdFx0aGVhZGluZ0F0RW5kLFxuXHRcdGlzU3RhcnRIZWFkaW5nTWluTGV2ZWwsXG5cdFx0aXNFbmRMaW5lSnVzdEJlZm9yZUhlYWRpbmcsXG5cdH07XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBgaGVhZF9hbmFseXNpc2AgaXMgYSBoZWFkaW5nLlxuICpcbiAqIEBwYXJhbSBoZWFkX2FuYWx5c2lzIC0gVGhlIGFuYWx5c2lzIHJlc3VsdCBvZiBhIGhlYWRpbmcuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGBoZWFkX2FuYWx5c2lzYCBpcyBhIGhlYWRpbmcsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICovXG5mdW5jdGlvbiBnZXRfaXNfaGVhZGluZyhoZWFkX2FuYWx5c2lzOiBIZWFkaW5nQW5hbHlzaXNSZXN1bHQpOiBib29sZWFuIHtcblx0Ly8gaW52YWxpZCBpbnB1dFxuXHRpZiAoIWhlYWRfYW5hbHlzaXMuaXNWYWxpZCkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHQvLyBjb25zb2xlLmxvZyhcImhlYWRfYW5hbHlzaXNcIiwgaGVhZF9hbmFseXNpcyk7IC8vIGRlYnVnXG5cblx0aWYgKCFoZWFkX2FuYWx5c2lzLmlzTXVsdGlsaW5lKSB7XG5cdFx0Ly8gc2luZ2xlIGxpbmVcblx0XHRpZiAoXG5cdFx0XHRoZWFkX2FuYWx5c2lzLmhhc0hlYWRpbmdBdFN0YXJ0ICYmXG5cdFx0XHRoZWFkX2FuYWx5c2lzLmhlYWRpbmdBdFN0YXJ0ICE9IG51bGxcblx0XHQpXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0fSBlbHNlIHtcblx0XHQvLyBtdWx0aSBsaW5lXG5cdFx0aWYgKFxuXHRcdFx0aGVhZF9hbmFseXNpcy5oYXNIZWFkaW5nQXRTdGFydCAmJiAvLyBzdGFydF9saW5lIGlzIGEgaGVhZGluZ1xuXHRcdFx0aGVhZF9hbmFseXNpcy5pc1N0YXJ0SGVhZGluZ01pbkxldmVsIC8vIHN0YXJ0X2xpbmUncyBoZWFkaW5nIGxldmVsIGlzIHRoZSBtaW4gYW5kIG9ubHkgbGV2ZWwgaW4gdGhlIHJhbmdlXG5cdFx0KVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhbmQgaW5zZXJ0cyBhIGJsb2NrIGxpbmsgZm9yIGEgc2luZ2xlIGxpbmUgYmxvY2suXG4gKiBJZiB0aGUgYmxvY2sgYWxyZWFkeSBoYXMgYW4gSUQsIHJldHVybnMgdGhlIGV4aXN0aW5nIElELlxuICogT3RoZXJ3aXNlLCBnZW5lcmF0ZXMgYSByYW5kb20gSUQgYW5kIGluc2VydHMgaXQgYXQgdGhlIGVuZCBvZiB0aGUgYmxvY2suXG4gKiBAcGFyYW0gYmxvY2sgLSBUaGUgc2VjdGlvbiBjYWNoZSByZXByZXNlbnRpbmcgdGhlIGJsb2NrLlxuICogQHBhcmFtIGVkaXRvciAtIFRoZSBlZGl0b3IgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyBUaGUgSUQgb2YgdGhlIGJsb2NrIGxpbmsuXG4gKi9cbmZ1bmN0aW9uIGdlbl9pbnNlcnRfYmxvY2tsaW5rX3NpbmdsZWxpbmUoXG5cdGJsb2NrOiBTZWN0aW9uQ2FjaGUsXG5cdGVkaXRvcjogRWRpdG9yLFxuXHRzZXR0aW5nczogUGx1Z2luU2V0dGluZ3Ncbik6IHN0cmluZyB7XG5cdGlmIChibG9jay5pZCkge1xuXHRcdHJldHVybiBgXiR7YmxvY2suaWR9YDtcblx0fVxuXG5cdGNvbnN0IHNlY3Rpb25FbmQgPSBibG9jay5wb3NpdGlvbi5lbmQ7XG5cdGNvbnN0IGVuZDogRWRpdG9yUG9zaXRpb24gPSB7XG5cdFx0Y2g6IHNlY3Rpb25FbmQuY29sLFxuXHRcdGxpbmU6IHNlY3Rpb25FbmQubGluZSxcblx0fTtcblxuXHRjb25zdCBpZCA9IGdlbmVyYXRlUmFuZG9tSWQoXG5cdFx0c2V0dGluZ3MuZW5ibGVfcHJlZml4ID8gc2V0dGluZ3MuaWRfcHJlZml4IDogXCJcIixcblx0XHRzZXR0aW5ncy5pZF9sZW5ndGhcblx0KTtcblx0Y29uc3Qgc3BhY2VyID0gc2hvdWxkSW5zZXJ0QWZ0ZXIoYmxvY2spID8gXCJcXG5cXG5cIiA6IFwiIFwiOyAvLyBpbnNlcnQgdG8gbGluZSBvciBuZXh0IGxpbmVcblxuXHRlZGl0b3IucmVwbGFjZVJhbmdlKGAke3NwYWNlcn1eJHtpZH1gLCBlbmQpOyAvLyBpbnNlcnQgYmxvY2sgaWQgYXQgZW5kIG9mIGJsb2NrXG5cdHJldHVybiBgXiR7aWR9YDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYW5kIGluc2VydHMgYSBibG9jayBsaW5rIHdpdGggYSBtdWx0aWxpbmUgaGVhZGluZy5cbiAqXG4gKiBAcGFyYW0gYmxvY2sgLSBUaGUgc2VjdGlvbiBjYWNoZSByZXByZXNlbnRpbmcgdGhlIGJsb2NrLlxuICogQHBhcmFtIGVkaXRvciAtIFRoZSBlZGl0b3IgaW5zdGFuY2UuXG4gKiBAcGFyYW0gc2V0dGluZ3MgLSBUaGUgcGx1Z2luIHNldHRpbmdzLlxuICogQHBhcmFtIGhlYWRpbmdfbGV2ZWwgLSBUaGUgbGV2ZWwgb2YgdGhlIGhlYWRpbmcuXG4gKiBAcmV0dXJucyBUaGUgZ2VuZXJhdGVkIGJsb2NrIElELlxuICovXG5mdW5jdGlvbiBnZW5faW5zZXJ0X2Jsb2NrbGlua19tdWx0bGluZV9oZWFkaW5nKFxuXHRibG9jazogU2VjdGlvbkNhY2hlLFxuXHRlZGl0b3I6IEVkaXRvcixcblx0c2V0dGluZ3M6IFBsdWdpblNldHRpbmdzLFxuXHRoZWFkaW5nX2xldmVsOiBudW1iZXJcbikge1xuXHRjb25zdCBpZCA9IGdlbmVyYXRlUmFuZG9tSWQoXG5cdFx0c2V0dGluZ3MuZW5ibGVfcHJlZml4ID8gc2V0dGluZ3MuaWRfcHJlZml4IDogXCJcIixcblx0XHRzZXR0aW5ncy5pZF9sZW5ndGhcblx0KTtcblxuXHRjb25zdCBzZWN0aW9uRW5kID0gYmxvY2sucG9zaXRpb24uZW5kO1xuXHRjb25zdCBlbmQ6IEVkaXRvclBvc2l0aW9uID0ge1xuXHRcdGNoOiBzZWN0aW9uRW5kLmNvbCxcblx0XHRsaW5lOiBzZWN0aW9uRW5kLmxpbmUsXG5cdH07XG5cblx0Ly8gY29uc3Qgc3BhY2VyID0gc2hvdWxkSW5zZXJ0QWZ0ZXIoYmxvY2spID8gXCJcXG5cXG5cIiA6IFwiIFwiOyAvLyBpbnNlcnQgdG8gbGluZSBvciBuZXh0IGxpbmVcblx0Y29uc3QgaGVhZGluZyA9IFwiI1wiLnJlcGVhdChoZWFkaW5nX2xldmVsKTsgLy8gZ2VuZXJhdGUgaGVhZGluZ1xuXHRlZGl0b3IucmVwbGFjZVJhbmdlKGBcXG5cXG4gJHtoZWFkaW5nfSBeJHtpZH1gLCBlbmQpOyAvLyBpbnNlcnQgYmxvY2sgaWQgYXQgZW5kIG9mIGJsb2NrXG5cblx0Y29uc3QgY3Vyc29yID0gZWRpdG9yLmdldEN1cnNvcihcImZyb21cIik7IC8vIGdldEN1cnNvclxuXHQvLyBjb25zdCBsaW5lTGVuZ3RoID0gZWRpdG9yLmdldExpbmUoY3Vyc29yLmxpbmUpLmxlbmd0aDtcblx0ZWRpdG9yLnNldEN1cnNvcihjdXJzb3IubGluZSwgY3Vyc29yLmNoKTtcblx0ZWRpdG9yLnJlcGxhY2VSYW5nZShgJHtoZWFkaW5nfSBcdTAyQzUke2lkfVxcblxcbmAsIHtcblx0XHRsaW5lOiBjdXJzb3IubGluZSxcblx0XHRjaDogMCxcblx0fSk7XG5cblx0cmV0dXJuIGBcdTAyQzUke2lkfWA7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGJsb2NrIGxpbmtzIGZvciBtdWx0aXBsZSBsaW5lcyBvZiBhIGJsb2NrLlxuICpcbiAqIEBwYXJhbSBmaWxlQ2FjaGUgLSBUaGUgY2FjaGVkIG1ldGFkYXRhIG9mIHRoZSBmaWxlLlxuICogQHBhcmFtIGVkaXRvciAtIFRoZSBlZGl0b3IgaW5zdGFuY2UuXG4gKiBAcGFyYW0gc2V0dGluZ3MgLSBUaGUgcGx1Z2luIHNldHRpbmdzLlxuICogQHJldHVybnMgQW4gYXJyYXkgb2YgYmxvY2sgbGluayBJRHMgb3IgYW4gZW1wdHkgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBnZW5faW5zZXJ0X2Jsb2NrbGlua19tdWx0bGluZV9ibG9jayhcblx0ZmlsZUNhY2hlOiBDYWNoZWRNZXRhZGF0YSxcblx0ZWRpdG9yOiBFZGl0b3IsXG5cdHNldHRpbmdzOiBQbHVnaW5TZXR0aW5nc1xuKTogc3RyaW5nW10gfCBzdHJpbmcge1xuXHRpZiAoZmlsZUNhY2hlLnNlY3Rpb25zID09IG51bGwpIHJldHVybiBcIlwiO1xuXG5cdGNvbnN0IHN0YXJ0X2xpbmUgPSBlZGl0b3IuZ2V0Q3Vyc29yKFwiZnJvbVwiKS5saW5lO1xuXHRjb25zdCBlbmRfbGluZSA9IGVkaXRvci5nZXRDdXJzb3IoXCJ0b1wiKS5saW5lO1xuXG5cdGNvbnN0IHNvcnRlZFNlY3Rpb25zID0gWy4uLmZpbGVDYWNoZS5zZWN0aW9uc10uc29ydChcblx0XHQoYSwgYikgPT4gYS5wb3NpdGlvbi5zdGFydC5saW5lIC0gYi5wb3NpdGlvbi5zdGFydC5saW5lXG5cdCk7XG5cdGxldCBsaW5rcyA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG5cblx0Zm9yIChjb25zdCBzZWN0aW9uIG9mIHNvcnRlZFNlY3Rpb25zKSB7XG5cdFx0aWYgKHNlY3Rpb24ucG9zaXRpb24uc3RhcnQubGluZSA+IGVuZF9saW5lKSBicmVhaztcblx0XHRpZiAoXG5cdFx0XHRzZWN0aW9uLnBvc2l0aW9uLnN0YXJ0LmxpbmUgPj0gc3RhcnRfbGluZSAmJlxuXHRcdFx0c2VjdGlvbi5wb3NpdGlvbi5lbmQubGluZSA8PSBlbmRfbGluZVxuXHRcdCkge1xuXHRcdFx0Y29uc3QgaWQgPSBnZW5faW5zZXJ0X2Jsb2NrbGlua19zaW5nbGVsaW5lKFxuXHRcdFx0XHRzZWN0aW9uLFxuXHRcdFx0XHRlZGl0b3IsXG5cdFx0XHRcdHNldHRpbmdzXG5cdFx0XHQpO1xuXHRcdFx0bGlua3MucHVzaChpZCk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGxpbmtzO1xufVxuXG4vKipcbiAqIFByb2Nlc3NlcyB0aGUgbWFya2Rvd24gZWxlbWVudCBieSByZW1vdmluZyBzcGVjaWZpYyB0ZXh0IHBhdHRlcm5zLlxuICogbWFrZSBcdTAyQzVpZCB0byBcIlwiXG4gKiBAcGFyYW0gZWwgLSBUaGUgSFRNTCBlbGVtZW50IHRvIHByb2Nlc3MuXG4gKi9cbmZ1bmN0aW9uIG1hcmtkb3duUG9zdFByb2Nlc3NvcihlbDogSFRNTEVsZW1lbnQpIHtcblx0aWYgKGVsLmZpcnN0Q2hpbGQgaW5zdGFuY2VvZiBOb2RlKSB7XG5cdFx0bGV0IHdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoXG5cdFx0XHRlbC5maXJzdENoaWxkLFxuXHRcdFx0Tm9kZUZpbHRlci5TSE9XX1RFWFQsXG5cdFx0XHRudWxsXG5cdFx0KTtcblx0XHRsZXQgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gd2Fsa2VyLmN1cnJlbnROb2RlO1xuXG5cdFx0d2hpbGUgKGN1cnJlbnROb2RlKSB7XG5cdFx0XHRjb25zdCBvcmlnaW5hbFRleHQgPSBjdXJyZW50Tm9kZS50ZXh0Q29udGVudDsgLy8gXHU3NkY0XHU2M0E1XHU1OTA0XHU3NDA2XHU2QkNGXHU0RTJBXHU4MjgyXHU3MEI5XG5cdFx0XHRsZXQgY2xlYW5lZFRleHQgPSBvcmlnaW5hbFRleHRcblx0XHRcdFx0PyBvcmlnaW5hbFRleHQucmVwbGFjZSgvXFxzKlx1MDJDNVthLXpBLVowLTktXSovZywgXCJcIilcblx0XHRcdFx0OiBcIlwiO1xuXHRcdFx0aWYgKG9yaWdpbmFsVGV4dCAhPT0gY2xlYW5lZFRleHQpIHtcblx0XHRcdFx0Y3VycmVudE5vZGUudGV4dENvbnRlbnQgPSBjbGVhbmVkVGV4dDtcblx0XHRcdH1cblx0XHRcdGN1cnJlbnROb2RlID0gd2Fsa2VyLm5leHROb2RlKCk7IC8vIFx1NzlGQlx1NTJBOFx1NTIzMFx1NEUwQlx1NEUwMFx1NEUyQVx1ODI4Mlx1NzBCOVxuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBCbG9ja0xpbmtQbHVzVmlld1BsdWdpbiB3aXRoIHRoZSBzcGVjaWZpZWQgcnVsZS5cbiAqXG4gKiBAcGFyYW0gcnVsZSAtIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gcnVsZSB1c2VkIHRvIG1hdGNoIHRoZSBibG9jayBsaW5rcy5cbiAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIEJsb2NrTGlua1BsdXNWaWV3UGx1Z2luLlxuICovXG5mdW5jdGlvbiBjcmVhdGVWaWV3UGx1Z2luKFxuXHRydWxlOiBzdHJpbmcgPSBcIihefCApXHUwMkM1W2EtekEtWjAtOV9dKyRcIlxuKTogQmxvY2tMaW5rUGx1c1ZpZXdQbHVnaW4ge1xuXHRsZXQgZGVjb3JhdG9yID0gbmV3IE1hdGNoRGVjb3JhdG9yKHtcblx0XHRyZWdleHA6IG5ldyBSZWdFeHAocnVsZSwgXCJnXCIpLFxuXHRcdGRlY29yYXRpb246IERlY29yYXRpb24ubWFyayh7IGNsYXNzOiBcInNtYWxsLWZvbnRcIiB9KSxcblx0fSk7XG5cdHJldHVybiBWaWV3UGx1Z2luLmRlZmluZShcblx0XHQodmlldykgPT4gKHtcblx0XHRcdGRlY29yYXRpb25zOiBkZWNvcmF0b3IuY3JlYXRlRGVjbyh2aWV3KSxcblx0XHRcdHVwZGF0ZSh1KSB7XG5cdFx0XHRcdHRoaXMuZGVjb3JhdGlvbnMgPSBkZWNvcmF0b3IudXBkYXRlRGVjbyh1LCB0aGlzLmRlY29yYXRpb25zKTtcblx0XHRcdH0sXG5cdFx0fSksXG5cdFx0e1xuXHRcdFx0ZGVjb3JhdGlvbnM6ICh2KSA9PiB2LmRlY29yYXRpb25zLFxuXHRcdH1cblx0KTtcbn1cblxuLy8gYWxsIHBsdWdpbiBuZWVkIGV4dGVuZHMgUGx1Z2luXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCbG9ja0xpbmtQbHVzIGV4dGVuZHMgUGx1Z2luIHtcblx0YXBwTmFtZSA9IHRoaXMubWFuaWZlc3QubmFtZTtcblx0c2V0dGluZ3M6IFBsdWdpblNldHRpbmdzO1xuXHR2aWV3UGx1Z2luOiBCbG9ja0xpbmtQbHVzVmlld1BsdWdpbjtcblx0ZWRpdG9yRXh0ZW5zaW9uczogRXh0ZW5zaW9uW10gPSBbXTtcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coYGxvYWRpbmcgJHt0aGlzLmFwcE5hbWV9YCk7XG5cblx0XHQvLyBMb2FkIHNldHRpbmdzLlxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XG5cdFx0Ly8gQ3JlYXRlIHNldHRpbmdzIHRhYi5cblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IEJsb2NrTGlua1BsdXNTZXR0aW5nc1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG5cdFx0Ly8gUmVnaXN0ZXIgcmlnaHQgY2xpY2sgbWVudVxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudChcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbihcblx0XHRcdFx0XCJlZGl0b3ItbWVudVwiLFxuXHRcdFx0XHR0aGlzLmhhbmRsZUVkaXRvck1lbnUuYmluZCh0aGlzKVxuXHRcdFx0KVxuXHRcdCk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6IFwiY29weS1saW5rLXRvLWJsb2NrMlwiLFxuXHRcdFx0bmFtZTogXCJDb3B5IGxpbmsgdG8gY3VycmVudCBibG9jayBvciBoZWFkaW5nXCIsXG5cdFx0XHRlZGl0b3JDaGVja0NhbGxiYWNrOiAoaXNDaGVja2luZywgZWRpdG9yLCB2aWV3KSA9PiB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmhhbmRsZUNvbW1hbmQoaXNDaGVja2luZywgZWRpdG9yLCB2aWV3LCBmYWxzZSk7XG5cdFx0XHR9LFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiBcImNvcHktZW1iZWQtdG8tYmxvY2syXCIsXG5cdFx0XHRuYW1lOiBcIkNvcHkgZW1iZWQgdG8gY3VycmVudCBibG9jayBvciBoZWFkaW5nXCIsXG5cdFx0XHRlZGl0b3JDaGVja0NhbGxiYWNrOiAoaXNDaGVja2luZywgZWRpdG9yLCB2aWV3KSA9PiB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmhhbmRsZUNvbW1hbmQoaXNDaGVja2luZywgZWRpdG9yLCB2aWV3LCB0cnVlKTtcblx0XHRcdH0sXG5cdFx0fSk7XG5cblx0XHQvLyBmb3IgcmVhZGluZyBtb2RlXG5cdFx0dGhpcy5yZWdpc3Rlck1hcmtkb3duUG9zdFByb2Nlc3NvcihtYXJrZG93blBvc3RQcm9jZXNzb3IpO1xuXHRcdC8vIGZvciBsaXZlIHByZXZpZXdcblx0XHR0aGlzLnZpZXdQbHVnaW4gPSBjcmVhdGVWaWV3UGx1Z2luKCk7XG5cdFx0dGhpcy5yZWdpc3RlckVkaXRvckV4dGVuc2lvbihbdGhpcy52aWV3UGx1Z2luXSk7XG5cdFx0Ly8gdGhpcy5yZWZyZXNoRXh0ZW5zaW9ucygpO1xuXHR9XG5cblx0Ly8gQ3JlYXRlcyBuZXcgTGlua2lmeVZpZXdQbHVnaW5zIGFuZCByZWdpc3RlcnMgdGhlbS5cblx0Ly8gcmVmcmVzaEV4dGVuc2lvbnMoKSB7XG5cdC8vIFx0dGhpcy52aWV3UGx1Z2luID0gY3JlYXRlVmlld1BsdWdpbigpO1xuXHQvLyBcdHRoaXMuYXBwLndvcmtzcGFjZS51cGRhdGVPcHRpb25zKCk7XG5cdC8vIH1cblxuXHRwcml2YXRlIGhhbmRsZUVkaXRvck1lbnUoXG5cdFx0bWVudTogTWVudSxcblx0XHRlZGl0b3I6IEVkaXRvcixcblx0XHR2aWV3OiBNYXJrZG93blZpZXcgfCBNYXJrZG93bkZpbGVJbmZvXG5cdCkge1xuXHRcdGNvbnN0IGZpbGU6IFRGaWxlIHwgbnVsbCA9IHZpZXcuZmlsZTtcblx0XHRpZiAoIWZpbGUpIHJldHVybjsgLy8gbm8gZmlsZSAsIHJldHVyblxuXG5cdFx0Y29uc3Qgc3RhcnRfbGluZSA9IGVkaXRvci5nZXRDdXJzb3IoXCJmcm9tXCIpLmxpbmU7XG5cdFx0Y29uc3QgZW5kX2xpbmUgPSBlZGl0b3IuZ2V0Q3Vyc29yKFwidG9cIikubGluZTtcblx0XHRjb25zdCBmaWxlQ2FjaGUgPSB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLmdldEZpbGVDYWNoZShmaWxlKTtcblx0XHRpZiAoIWZpbGVDYWNoZSkgcmV0dXJuOyAvLyBubyBmaWxlQ2FjaGUsIHJldHVyblxuXG5cdFx0bGV0IGhlYWRfYW5hbHlzaXMgPSBhbmFseXplSGVhZGluZ3MoZmlsZUNhY2hlLCBzdGFydF9saW5lLCBlbmRfbGluZSk7XG5cdFx0Ly8gY29uc29sZS5sb2coXCJoZWFkX2FuYWx5c2lzXCIsIGhlYWRfYW5hbHlzaXMpOyAvLyBkZWJ1Z1xuXG5cdFx0aWYgKCFoZWFkX2FuYWx5c2lzLmlzVmFsaWQpIHtcblx0XHRcdHJldHVybjsgLy8gaW52YWxpZCBpbnB1dFxuXHRcdH1cblx0XHRsZXQgaXNIZWFkaW5nID0gZ2V0X2lzX2hlYWRpbmcoaGVhZF9hbmFseXNpcyk7IC8vIGlzIGhlYWRpbmc/XG5cblx0XHQvLyBpbm5lciBmdW5jdGlvblxuXHRcdGNvbnN0IGFkZEl0ZW1Ub01lbnUgPSAodGl0bGU6IHN0cmluZywgaXNFbWJlZDogYm9vbGVhbikgPT4ge1xuXHRcdFx0bWVudS5hZGRJdGVtKChpdGVtOiBhbnkpID0+IHtcblx0XHRcdFx0aXRlbS5zZXRUaXRsZSh0aXRsZSlcblx0XHRcdFx0XHQuc2V0SWNvbihcImxpbmtzLWNvbWluZy1pblwiKVxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+XG5cdFx0XHRcdFx0XHR0aGlzLmhhbmRsZU1lbnVJdGVtQ2xpY2soXG5cdFx0XHRcdFx0XHRcdHZpZXcsXG5cdFx0XHRcdFx0XHRcdGlzSGVhZGluZyxcblx0XHRcdFx0XHRcdFx0aXNFbWJlZCxcblx0XHRcdFx0XHRcdFx0aGVhZF9hbmFseXNpc1xuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdCk7XG5cdFx0XHR9KTtcblx0XHR9O1xuXG5cdFx0Ly8gYWRkIG1lbnUgaXRlbVxuXHRcdGFkZEl0ZW1Ub01lbnUoXG5cdFx0XHRpc0hlYWRpbmcgPyBcIkNvcHkgbGluayB0byBoZWFkaW5nXCIgOiBcIkNvcHkgbGluayB0byBibG9ja1wiLFxuXHRcdFx0ZmFsc2Vcblx0XHQpO1xuXHRcdGFkZEl0ZW1Ub01lbnUoXG5cdFx0XHRpc0hlYWRpbmcgPyBcIkNvcHkgaGVhZGluZyBlbWJlZFwiIDogXCJDb3B5IGJsb2NrIGVtYmVkXCIsXG5cdFx0XHR0cnVlXG5cdFx0KTtcblx0fVxuXG5cdHByaXZhdGUgaGFuZGxlTWVudUl0ZW1DbGljayhcblx0XHR2aWV3OiBhbnksXG5cdFx0aXNIZWFkaW5nOiBib29sZWFuLFxuXHRcdGlzRW1iZWQ6IGJvb2xlYW4sXG5cdFx0aGVhZF9hbmFseXNpczogSGVhZGluZ0FuYWx5c2lzUmVzdWx0XG5cdCkge1xuXHRcdGlmICghdmlldy5maWxlIHx8ICFoZWFkX2FuYWx5c2lzLmlzVmFsaWQpIHJldHVybjsgLy8gbm8gZmlsZSBvciBpbnZhbGlkIGlucHV0XG5cblx0XHRjb25zdCB7IGZpbGUsIGVkaXRvciB9ID0gdmlldztcblx0XHRjb25zdCBmaWxlQ2FjaGUgPSB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLmdldEZpbGVDYWNoZShmaWxlKTtcblx0XHRpZiAoIWZpbGVDYWNoZSkgcmV0dXJuOyAvLyBubyBmaWxlQ2FjaGUsIHJldHVyblxuXG5cdFx0Ly8gY29uc29sZS5sb2coXCJoYW5kbGVNZW51SXRlbUNsaWNrXCIsIGZpbGVDYWNoZSk7XG5cblx0XHRpZiAoIWhlYWRfYW5hbHlzaXMuaXNNdWx0aWxpbmUpIHtcblx0XHRcdC8vIFNpbmdsZSBsaW5lXG5cdFx0XHR0aGlzLmhhbmRsZVNpbmdsZUxpbmUoXG5cdFx0XHRcdGZpbGUsXG5cdFx0XHRcdGlzSGVhZGluZyxcblx0XHRcdFx0aXNFbWJlZCxcblx0XHRcdFx0aGVhZF9hbmFseXNpcyxcblx0XHRcdFx0ZWRpdG9yXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBNdWx0aSBsaW5lXG5cdFx0XHR0aGlzLmhhbmRsZU11bHRpTGluZShcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0aXNIZWFkaW5nLFxuXHRcdFx0XHRpc0VtYmVkLFxuXHRcdFx0XHRoZWFkX2FuYWx5c2lzLFxuXHRcdFx0XHRlZGl0b3IsXG5cdFx0XHRcdGZpbGVDYWNoZVxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGhhbmRsZVNpbmdsZUxpbmUoXG5cdFx0ZmlsZTogYW55LFxuXHRcdGlzSGVhZGluZzogYm9vbGVhbixcblx0XHRpc0VtYmVkOiBib29sZWFuLFxuXHRcdGhlYWRfYW5hbHlzaXM6IEhlYWRpbmdBbmFseXNpc1Jlc3VsdCxcblx0XHRlZGl0b3I6IGFueVxuXHQpIHtcblx0XHRpZiAoaXNIZWFkaW5nICYmIGhlYWRfYW5hbHlzaXMuaGVhZGluZ0F0U3RhcnQpIHtcblx0XHRcdC8vIHN0YXJ0X2xpbmUgaXMgYSBoZWFkaW5nXG5cdFx0XHR0aGlzLmNvcHlUb0NsaXBib2FyZChcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0aGVhZF9hbmFseXNpcy5oZWFkaW5nQXRTdGFydC5oZWFkaW5nLFxuXHRcdFx0XHRpc0VtYmVkXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSBpZiAoIWlzSGVhZGluZyAmJiBoZWFkX2FuYWx5c2lzLmJsb2NrKSB7XG5cdFx0XHQvLyBzdGFydF9saW5lIGlzIG5vdCBhIGhlYWRpbmdcblx0XHRcdGNvbnN0IGxpbmsgPSBnZW5faW5zZXJ0X2Jsb2NrbGlua19zaW5nbGVsaW5lKFxuXHRcdFx0XHRoZWFkX2FuYWx5c2lzLmJsb2NrLFxuXHRcdFx0XHRlZGl0b3IsXG5cdFx0XHRcdHRoaXMuc2V0dGluZ3Ncblx0XHRcdCk7XG5cdFx0XHR0aGlzLmNvcHlUb0NsaXBib2FyZChmaWxlLCBsaW5rLCBpc0VtYmVkKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGhhbmRsZU11bHRpTGluZShcblx0XHRmaWxlOiBhbnksXG5cdFx0aXNIZWFkaW5nOiBib29sZWFuLFxuXHRcdGlzRW1iZWQ6IGJvb2xlYW4sXG5cdFx0aGVhZF9hbmFseXNpczogSGVhZGluZ0FuYWx5c2lzUmVzdWx0LFxuXHRcdGVkaXRvcjogYW55LFxuXHRcdGZpbGVDYWNoZTogYW55XG5cdCkge1xuXHRcdGlmIChpc0hlYWRpbmcgJiYgaGVhZF9hbmFseXNpcy5oZWFkaW5nQXRTdGFydCkge1xuXHRcdFx0Ly8gc3RhcnRfbGluZSBpcyBhIGhlYWRpbmdcblx0XHRcdHRoaXMuY29weVRvQ2xpcGJvYXJkKFxuXHRcdFx0XHRmaWxlLFxuXHRcdFx0XHRoZWFkX2FuYWx5c2lzLmhlYWRpbmdBdFN0YXJ0LmhlYWRpbmcsXG5cdFx0XHRcdGlzRW1iZWRcblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuaGFuZGxlTXVsdGlMaW5lQmxvY2soXG5cdFx0XHRcdGZpbGUsXG5cdFx0XHRcdGlzRW1iZWQsXG5cdFx0XHRcdGhlYWRfYW5hbHlzaXMsXG5cdFx0XHRcdGVkaXRvcixcblx0XHRcdFx0ZmlsZUNhY2hlXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgX2dlbl9pbnNlcnRfYmxvY2tsaW5rX211bHRsaW5lX2hlYWRpbmcoXG5cdFx0ZmlsZUNhY2hlOiBDYWNoZWRNZXRhZGF0YSxcblx0XHRlZGl0b3I6IGFueSxcblx0XHRoZWFkX2FuYWx5c2lzOiBIZWFkaW5nQW5hbHlzaXNSZXN1bHRcblx0KTogc3RyaW5nIHtcblx0XHRpZiAoIWhlYWRfYW5hbHlzaXMuYmxvY2spIHJldHVybiBcIlwiO1xuXG5cdFx0cmV0dXJuIGdlbl9pbnNlcnRfYmxvY2tsaW5rX211bHRsaW5lX2hlYWRpbmcoXG5cdFx0XHRoZWFkX2FuYWx5c2lzLmJsb2NrLFxuXHRcdFx0ZWRpdG9yLFxuXHRcdFx0dGhpcy5zZXR0aW5ncyxcblx0XHRcdGhlYWRfYW5hbHlzaXMubmVhcmVzdEJlZm9yZVN0YXJ0TGV2ZWwgKyAxXG5cdFx0KTtcblx0fVxuXG5cdHByaXZhdGUgX2dlbl9pbnNlcnRfYmxvY2tsaW5rX211bHRsaW5lX2Jsb2NrKFxuXHRcdGZpbGVDYWNoZTogQ2FjaGVkTWV0YWRhdGEsXG5cdFx0ZWRpdG9yOiBhbnksXG5cdFx0aGVhZF9hbmFseXNpczogSGVhZGluZ0FuYWx5c2lzUmVzdWx0XG5cdCkge1xuXHRcdHJldHVybiBnZW5faW5zZXJ0X2Jsb2NrbGlua19tdWx0bGluZV9ibG9jayhcblx0XHRcdGZpbGVDYWNoZSxcblx0XHRcdGVkaXRvcixcblx0XHRcdHRoaXMuc2V0dGluZ3Ncblx0XHQpO1xuXHR9XG5cblx0cHJpdmF0ZSBoYW5kbGVNdWx0aUxpbmVCbG9jayhcblx0XHRmaWxlOiBhbnksXG5cdFx0aXNFbWJlZDogYm9vbGVhbixcblx0XHRoZWFkX2FuYWx5c2lzOiBIZWFkaW5nQW5hbHlzaXNSZXN1bHQsXG5cdFx0ZWRpdG9yOiBhbnksXG5cdFx0ZmlsZUNhY2hlOiBhbnlcblx0KSB7XG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MubXVsdF9saW5lX2hhbmRsZSA9PSBNdWx0TGluZUhhbmRsZS5vbmVsaW5lKSB7XG5cdFx0XHRpZiAoaGVhZF9hbmFseXNpcy5ibG9jaykge1xuXHRcdFx0XHRjb25zdCBsaW5rID0gZ2VuX2luc2VydF9ibG9ja2xpbmtfc2luZ2xlbGluZShcblx0XHRcdFx0XHRoZWFkX2FuYWx5c2lzLmJsb2NrLFxuXHRcdFx0XHRcdGVkaXRvcixcblx0XHRcdFx0XHR0aGlzLnNldHRpbmdzXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHRoaXMuY29weVRvQ2xpcGJvYXJkKGZpbGUsIGxpbmssIGlzRW1iZWQpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoaGVhZF9hbmFseXNpcy5taW5MZXZlbEluUmFuZ2UgIT0gSW5maW5pdHkpIHtcblx0XHRcdFx0bmV3IE5vdGljZShcblx0XHRcdFx0XHRgUGxlYXNlIHNlbGVjdCB0ZXh0IHRoYXQgZG9lcyBub3QgaW5jbHVkZSBoZWFkaW5nc2AsXG5cdFx0XHRcdFx0MTUwMFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBsaW5rTWV0aG9kID1cblx0XHRcdFx0dGhpcy5zZXR0aW5ncy5tdWx0X2xpbmVfaGFuZGxlID09IE11bHRMaW5lSGFuZGxlLmhlYWRpbmdcblx0XHRcdFx0XHQ/IHRoaXMuX2dlbl9pbnNlcnRfYmxvY2tsaW5rX211bHRsaW5lX2hlYWRpbmdcblx0XHRcdFx0XHQ6IHRoaXMuX2dlbl9pbnNlcnRfYmxvY2tsaW5rX211bHRsaW5lX2Jsb2NrO1xuXHRcdFx0Y29uc3QgbGluayA9IGxpbmtNZXRob2QuY2FsbChcblx0XHRcdFx0dGhpcyxcblx0XHRcdFx0ZmlsZUNhY2hlLFxuXHRcdFx0XHRlZGl0b3IsXG5cdFx0XHRcdGhlYWRfYW5hbHlzaXNcblx0XHRcdCk7XG5cdFx0XHR0aGlzLmNvcHlUb0NsaXBib2FyZChmaWxlLCBsaW5rLCBpc0VtYmVkKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdH1cblxuXHRvbnVubG9hZCgpIHt9XG5cblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKFxuXHRcdFx0e30sXG5cdFx0XHRERUZBVUxUX1NFVFRJTkdTLFxuXHRcdFx0YXdhaXQgdGhpcy5sb2FkRGF0YSgpXG5cdFx0KTtcblx0fVxuXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcblx0XHRhd2FpdCB0aGlzLnNhdmVEYXRhKHRoaXMuc2V0dGluZ3MpO1xuXHR9XG5cblx0cHJpdmF0ZSBoYW5kbGVDb21tYW5kKFxuXHRcdGlzQ2hlY2tpbmc6IGJvb2xlYW4sXG5cdFx0ZWRpdG9yOiBFZGl0b3IsXG5cdFx0dmlldzogTWFya2Rvd25WaWV3IHwgTWFya2Rvd25GaWxlSW5mbyxcblx0XHRpc0VtYmVkOiBib29sZWFuXG5cdCkge1xuXHRcdGlmIChpc0NoZWNraW5nKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRjb25zdCBmaWxlOiBURmlsZSB8IG51bGwgPSB2aWV3LmZpbGU7XG5cdFx0aWYgKCFmaWxlKSByZXR1cm47IC8vIG5vIGZpbGUgLCByZXR1cm5cblxuXHRcdGNvbnN0IHN0YXJ0X2xpbmUgPSBlZGl0b3IuZ2V0Q3Vyc29yKFwiZnJvbVwiKS5saW5lO1xuXHRcdGNvbnN0IGVuZF9saW5lID0gZWRpdG9yLmdldEN1cnNvcihcInRvXCIpLmxpbmU7XG5cdFx0Y29uc3QgZmlsZUNhY2hlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaWxlQ2FjaGUoZmlsZSk7XG5cdFx0aWYgKCFmaWxlQ2FjaGUpIHJldHVybjsgLy8gbm8gZmlsZUNhY2hlLCByZXR1cm5cblxuXHRcdGxldCBoZWFkX2FuYWx5c2lzID0gYW5hbHl6ZUhlYWRpbmdzKGZpbGVDYWNoZSwgc3RhcnRfbGluZSwgZW5kX2xpbmUpO1xuXHRcdGlmICghaGVhZF9hbmFseXNpcy5pc1ZhbGlkKSB7XG5cdFx0XHRyZXR1cm47IC8vIGludmFsaWQgaW5wdXRcblx0XHR9XG5cblx0XHRsZXQgaXNIZWFkaW5nID0gZ2V0X2lzX2hlYWRpbmcoaGVhZF9hbmFseXNpcyk7IC8vIGlzIGhlYWRpbmc/XG5cblx0XHRpZiAoIWhlYWRfYW5hbHlzaXMuaXNNdWx0aWxpbmUpIHtcblx0XHRcdC8vIFNpbmdsZSBsaW5lXG5cdFx0XHR0aGlzLmhhbmRsZVNpbmdsZUxpbmUoXG5cdFx0XHRcdGZpbGUsXG5cdFx0XHRcdGlzSGVhZGluZyxcblx0XHRcdFx0aXNFbWJlZCxcblx0XHRcdFx0aGVhZF9hbmFseXNpcyxcblx0XHRcdFx0ZWRpdG9yXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBNdWx0aSBsaW5lXG5cdFx0XHR0aGlzLmhhbmRsZU11bHRpTGluZShcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0aXNIZWFkaW5nLFxuXHRcdFx0XHRpc0VtYmVkLFxuXHRcdFx0XHRoZWFkX2FuYWx5c2lzLFxuXHRcdFx0XHRlZGl0b3IsXG5cdFx0XHRcdGZpbGVDYWNoZVxuXHRcdFx0KTtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHQvKipcblx0ICogQ29waWVzIGxpbmtzIHRvIG9uZSBvciBtb3JlIGJsb2NrcyB0byB0aGUgY2xpcGJvYXJkLlxuXHQgKlxuXHQgKiBAcGFyYW0gZmlsZSAtIFRoZSBmaWxlIGNvbnRhaW5pbmcgdGhlIGJsb2Nrcy5cblx0ICogQHBhcmFtIGxpbmtzIC0gQW4gYXJyYXkgb2YgYmxvY2sgbGlua3MgKF5pZCkgb3IgaGVhZGluZyBsaW5rcyAoaGVhZGluZyB3aXRob3V0IGAjYCkuXG5cdCAqIEBwYXJhbSBpc0VtYmVkIC0gU3BlY2lmaWVzIHdoZXRoZXIgdGhlIGxpbmtzIHNob3VsZCBiZSBlbWJlZGRlZC5cblx0ICogQHBhcmFtIGFsaWFzIC0gQW4gb3B0aW9uYWwgYWxpYXMgZm9yIHRoZSBsaW5rcy5cblx0ICovXG5cdGNvcHlUb0NsaXBib2FyZChcblx0XHRmaWxlOiBURmlsZSxcblx0XHRsaW5rczogc3RyaW5nIHwgc3RyaW5nW10sXG5cdFx0aXNFbWJlZDogYm9vbGVhbixcblx0XHRhbGlhcz86IHN0cmluZ1xuXHQpIHtcblx0XHQvLyBDb252ZXJ0IHNpbmdsZSBsaW5rIHRvIGFycmF5IGlmIG5lY2Vzc2FyeVxuXHRcdGNvbnN0IGxpbmtzQXJyYXkgPSB0eXBlb2YgbGlua3MgPT09IFwic3RyaW5nXCIgPyBbbGlua3NdIDogbGlua3M7XG5cblx0XHRjb25zdCBtYXJrZG93bkxpbmtzID0gbGlua3NBcnJheVxuXHRcdFx0Lm1hcCgobGluaywgaW5kZXgpID0+IHtcblx0XHRcdFx0Y29uc3QgYWRkTmV3TGluZSA9IGluZGV4IDwgbGlua3MubGVuZ3RoIC0gMSA/IFwiXFxuXCIgOiBcIlwiO1xuXHRcdFx0XHRyZXR1cm4gYCR7XG5cdFx0XHRcdFx0aXNFbWJlZCA/IFwiIVwiIDogXCJcIlxuXHRcdFx0XHR9JHt0aGlzLmFwcC5maWxlTWFuYWdlci5nZW5lcmF0ZU1hcmtkb3duTGluayhcblx0XHRcdFx0XHRmaWxlLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdFx0XCIjXCIgKyBsaW5rLFxuXHRcdFx0XHRcdGFsaWFzXG5cdFx0XHRcdCl9JHthZGROZXdMaW5lfWA7XG5cdFx0XHR9KVxuXHRcdFx0LmpvaW4oXCJcIik7XG5cblx0XHRuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dChtYXJrZG93bkxpbmtzKTtcblx0fVxufVxuXG5jbGFzcyBCbG9ja0xpbmtQbHVzU2V0dGluZ3NUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBCbG9ja0xpbmtQbHVzO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEJsb2NrTGlua1BsdXMpIHtcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRhZGRUb2dnbGVTZXR0aW5nKFxuXHRcdHNldHRpbmdOYW1lOiBLZXlzT2ZUeXBlPFBsdWdpblNldHRpbmdzLCBib29sZWFuPixcblx0XHRleHRyYU9uQ2hhbmdlPzogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkXG5cdCkge1xuXHRcdHJldHVybiBuZXcgU2V0dGluZyh0aGlzLmNvbnRhaW5lckVsKS5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xuXHRcdFx0dG9nZ2xlXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5nc1tzZXR0aW5nTmFtZV0pXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Nbc2V0dGluZ05hbWVdID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0ZXh0cmFPbkNoYW5nZT8uKHZhbHVlKTtcblx0XHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHQvLyBcdTY1ODdcdTY3MkNcdThGOTNcdTUxNjVcdTY4NDZcblx0YWRkVGV4dElucHV0U2V0dGluZyhcblx0XHRzZXR0aW5nTmFtZTogS2V5c09mVHlwZTxQbHVnaW5TZXR0aW5ncywgc3RyaW5nPixcblx0XHRwbGFjZWhvbGRlcjogc3RyaW5nXG5cdCkge1xuXHRcdHJldHVybiBuZXcgU2V0dGluZyh0aGlzLmNvbnRhaW5lckVsKS5hZGRUZXh0KCh0ZXh0KSA9PlxuXHRcdFx0dGV4dFxuXHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIocGxhY2Vob2xkZXIpXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5nc1tzZXR0aW5nTmFtZV0pXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHRpZiAodmFsdWUubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Nbc2V0dGluZ05hbWVdID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0KTtcblx0fVxuXG5cdGFkZERyb3Bkb3duU2V0dGluZyhcblx0XHRzZXR0aW5nTmFtZTogS2V5c09mVHlwZTxQbHVnaW5TZXR0aW5ncywgc3RyaW5nPixcblx0XHRvcHRpb25zOiBzdHJpbmdbXSxcblx0XHRkaXNwbGF5PzogKG9wdGlvbjogc3RyaW5nKSA9PiBzdHJpbmdcblx0KSB7XG5cdFx0cmV0dXJuIG5ldyBTZXR0aW5nKHRoaXMuY29udGFpbmVyRWwpLmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xuXHRcdFx0Y29uc3QgZGlzcGxheU5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cdFx0XHRmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRpb25zKSB7XG5cdFx0XHRcdGNvbnN0IGRpc3BsYXlOYW1lID0gZGlzcGxheT8uKG9wdGlvbikgPz8gb3B0aW9uO1xuXHRcdFx0XHRpZiAoIWRpc3BsYXlOYW1lcy5oYXMoZGlzcGxheU5hbWUpKSB7XG5cdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKG9wdGlvbiwgZGlzcGxheU5hbWUpO1xuXHRcdFx0XHRcdGRpc3BsYXlOYW1lcy5hZGQoZGlzcGxheU5hbWUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRkcm9wZG93blxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Nbc2V0dGluZ05hbWVdKVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzW3NldHRpbmdOYW1lXSA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdGFkZFNsaWRlclNldHRpbmcoXG5cdFx0c2V0dGluZ05hbWU6IEtleXNPZlR5cGU8UGx1Z2luU2V0dGluZ3MsIG51bWJlcj4sXG5cdFx0bWluOiBudW1iZXIsXG5cdFx0bWF4OiBudW1iZXIsXG5cdFx0c3RlcDogbnVtYmVyXG5cdCkge1xuXHRcdHJldHVybiBuZXcgU2V0dGluZyh0aGlzLmNvbnRhaW5lckVsKS5hZGRTbGlkZXIoKHNsaWRlcikgPT4ge1xuXHRcdFx0c2xpZGVyXG5cdFx0XHRcdC5zZXRMaW1pdHMobWluLCBtYXgsIHN0ZXApXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5nc1tzZXR0aW5nTmFtZV0pXG5cdFx0XHRcdC5zZXREeW5hbWljVG9vbHRpcCgpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Nbc2V0dGluZ05hbWVdID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0YWRkSGVhZGluZyhoZWFkaW5nOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gbmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbCkuc2V0TmFtZShoZWFkaW5nKS5zZXRIZWFkaW5nKCk7XG5cdH1cblxuXHRkaXNwbGF5KCk6IHZvaWQge1xuXHRcdGNvbnN0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG5cdFx0Ly8gdGl0bGVcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIkJsb2NrLWxpbmsgU2V0dGluZ3NcIiB9KTtcblxuXHRcdHRoaXMuYWRkRHJvcGRvd25TZXR0aW5nKFxuXHRcdFx0Ly9AdHMtaWdub3JlXG5cdFx0XHRcIm11bHRfbGluZV9oYW5kbGVcIixcblx0XHRcdFtcIjBcIiwgXCIxXCIsIFwiMlwiXSxcblx0XHRcdChvcHRpb24pID0+IHtcblx0XHRcdFx0Y29uc3Qgb3B0aW9uc1NldCA9IG5ldyBNYXAoW1xuXHRcdFx0XHRcdFtcIjBcIiwgXCJEZWZhdWx0XCJdLFxuXHRcdFx0XHRcdFtcIjFcIiwgXCJBZGQgbmV3IGhlYWRpbmdcIl0sXG5cdFx0XHRcdFx0W1wiMlwiLCBcIkFkZCBtdWx0aSBibG9ja1wiXSxcblx0XHRcdFx0XSk7XG5cdFx0XHRcdHJldHVybiBvcHRpb25zU2V0LmdldChvcHRpb24pIHx8IFwiVW5rbm93blwiO1xuXHRcdFx0fVxuXHRcdClcblx0XHRcdC5zZXROYW1lKFwiTXVsdGktbGluZSBCbG9jayBCZWhhdmlvclwiKVxuXHRcdFx0LnNldERlc2MoXG5cdFx0XHRcdFwiRGVmaW5lIGhvdyBtdWx0aS1saW5lIHNlbGVjdGlvbnMgZ2VuZXJhdGUgYmxvY2sgSURzLiAnRGVmYXVsdCcgdHJlYXRzIHRoZW0gYXMgYSBzaW5nbGUgbGluZS5cIlxuXHRcdFx0KTtcblxuXHRcdHRoaXMuYWRkSGVhZGluZyhcIkJsb2NrIElEIHNldHRpbmdzXCIpO1xuXHRcdHRoaXMuYWRkU2xpZGVyU2V0dGluZyhcImlkX2xlbmd0aFwiLCAzLCA3LCAxKVxuXHRcdFx0LnNldE5hbWUoXCJNYXggQmxvY2sgSUQgTGVuZ3RoXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlNldCB0aGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBmb3IgYSBibG9jayBJRC5cIik7XG5cblx0XHR0aGlzLmFkZFRvZ2dsZVNldHRpbmcoXCJlbmJsZV9wcmVmaXhcIikuc2V0TmFtZShcIkN1c3RvbSBJRCBQcmVmaXhcIik7XG5cblx0XHR0aGlzLmFkZFRleHRJbnB1dFNldHRpbmcoXCJpZF9wcmVmaXhcIiwgXCJcIilcblx0XHRcdC5zZXROYW1lKFwiQmxvY2sgSUQgUHJlZml4XCIpXG5cdFx0XHQuc2V0RGVzYyhcIkJsb2NrIElEIHdpbGwgYmU6IHByZWZpeC1yYW5kb21fc3RyXCIpO1xuXHR9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7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QkFBVyxVQUFVLFNBQVM7QUFDN0IsY0FBTSxlQUFjLHdDQUFVLFlBQVYsWUFBcUI7QUFDekMsWUFBSSxDQUFDLGFBQWEsSUFBSSxXQUFXLEdBQUc7QUFDbkMsbUJBQVMsVUFBVSxRQUFRLFdBQVc7QUFDdEMsdUJBQWEsSUFBSSxXQUFXO0FBQUEsUUFDN0I7QUFBQSxNQUNEO0FBQ0EsZUFDRSxTQUFTLEtBQUssT0FBTyxTQUFTLFdBQVcsQ0FBQyxFQUMxQyxTQUFTLE9BQU8sVUFBVTtBQUUxQixhQUFLLE9BQU8sU0FBUyxXQUFXLElBQUk7QUFDcEMsY0FBTSxLQUFLLE9BQU8sYUFBYTtBQUFBLE1BQ2hDLENBQUM7QUFBQSxJQUNILENBQUM7QUFBQSxFQUNGO0FBQUEsRUFFQSxpQkFDQyxhQUNBLEtBQ0EsS0FDQSxNQUNDO0FBQ0QsV0FBTyxJQUFJLHdCQUFRLEtBQUssV0FBVyxFQUFFLFVBQVUsQ0FBQyxXQUFXO0FBQzFELGFBQ0UsVUFBVSxLQUFLLEtBQUssSUFBSSxFQUN4QixTQUFTLEtBQUssT0FBTyxTQUFTLFdBQVcsQ0FBQyxFQUMxQyxrQkFBa0IsRUFDbEIsU0FBUyxPQUFPLFVBQVU7QUFFMUIsYUFBSyxPQUFPLFNBQVMsV0FBVyxJQUFJO0FBQ3BDLGNBQU0sS0FBSyxPQUFPLGFBQWE7QUFBQSxNQUNoQyxDQUFDO0FBQUEsSUFDSCxDQUFDO0FBQUEsRUFDRjtBQUFBLEVBRUEsV0FBVyxTQUFpQjtBQUMzQixXQUFPLElBQUksd0JBQVEsS0FBSyxXQUFXLEVBQUUsUUFBUSxPQUFPLEVBQUUsV0FBVztBQUFBLEVBQ2xFO0FBQUEsRUFFQSxVQUFnQjtBQUNmLFVBQU0sRUFBRSxZQUFZLElBQUk7QUFFeEIsZ0JBQVksTUFBTTtBQUNsQixnQkFBWSxTQUFTLE1BQU0sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRTFELFNBQUs7QUFBQTtBQUFBLE1BRUo7QUFBQSxNQUNBLENBQUMsS0FBSyxLQUFLLEdBQUc7QUFBQSxNQUNkLENBQUMsV0FBVztBQUNYLGNBQU0sYUFBYSxvQkFBSSxJQUFJO0FBQUEsVUFDMUIsQ0FBQyxLQUFLLFNBQVM7QUFBQSxVQUNmLENBQUMsS0FBSyxpQkFBaUI7QUFBQSxVQUN2QixDQUFDLEtBQUssaUJBQWlCO0FBQUEsUUFDeEIsQ0FBQztBQUNELGVBQU8sV0FBVyxJQUFJLE1BQU0sS0FBSztBQUFBLE1BQ2xDO0FBQUEsSUFDRCxFQUNFLFFBQVEsMkJBQTJCLEVBQ25DO0FBQUEsTUFDQTtBQUFBLElBQ0Q7QUFFRCxTQUFLLFdBQVcsbUJBQW1CO0FBQ25DLFNBQUssaUJBQWlCLGFBQWEsR0FBRyxHQUFHLENBQUMsRUFDeEMsUUFBUSxxQkFBcUIsRUFDN0IsUUFBUSxzREFBc0Q7QUFFaEUsU0FBSyxpQkFBaUIsY0FBYyxFQUFFLFFBQVEsa0JBQWtCO0FBRWhFLFNBQUssb0JBQW9CLGFBQWEsRUFBRSxFQUN0QyxRQUFRLGlCQUFpQixFQUN6QixRQUFRLHFDQUFxQztBQUFBLEVBQ2hEO0FBQ0Q7IiwKICAibmFtZXMiOiBbIk11bHRMaW5lSGFuZGxlIiwgImJsb2NrIl0KfQo=