diff --git a/main.js b/main.js new file mode 100644 index 0000000..a1119f0 --- /dev/null +++ b/main.js @@ -0,0 +1,1122 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// main.ts +var main_exports = {}; +__export(main_exports, { + default: () => ObsidianProgressBars +}); +module.exports = __toCommonJS(main_exports); +var import_obsidian = require("obsidian"); +var DEFAULT_SETTINGS = { + /* Progress Bar Settings */ + APB_title: "Progress", + APB_widthToggle: true, + APB_width: 190, + APB_height: 8, + APB_progressBarPercentage: 83, + APB_total: 100, + APB_endcapToggle: true, + APB_marksToggle: true, + APB_marksColor: "#000000", + APB_marksLightColor: "#ffffff", + APB_marksWidth: 3, + /* Text Settings */ + APB_titleToggle: true, + APB_titleColor: "#8fa0ba", + APB_titleLightColor: "#44546f", + APB_percentageToggle: true, + APB_percentageColor: "#c1d7f9", + APB_percentageLightColor: "#6d85ad", + APB_fractionToggle: true, + APB_fractionColor: "#8fa0ba", + APB_fractionLightColor: "#576a8a", + APB_completedToggle: true, + APB_completedColor: "#c1d7f9", + APB_completedLightColor: "#44546f", + /* Container Settings */ + APB_borderToggle: true, + APB_colorBorder: "#474f62", + APB_colorLightBorder: "#ced0d6", + APB_backgroundToggle: true, + APB_colorBackground: "#242a35", + APB_colorLightBackground: "#f1f2f4", + /* Progress Bar Color Settings */ + APB_colornumber: "option5", + APB_color1: "#2978ef", + APB_color2: "#8ec822", + APB_color3: "#dfaa22", + APB_color4: "#c84922", + APB_color5: "#dd4a86", + APB_color1Light: "#278378", + APB_color2Light: "#2baab9", + APB_color3Light: "#4a32e2", + APB_color4Light: "#7c328e", + APB_color5Light: "#c11e49", + APB_colorBarCompleted: "#576178", + APB_colorLightBarCompleted: "#fcfcfd", + APB_colorBarBackground: "#3b4252", + APB_colorLightBarBackground: "#d9dde2", + /* Additional Settings */ + APB_progressBarChange: true +}; +var ObsidianProgressBars = class extends import_obsidian.Plugin { + async onload() { + console.log("loading APB plugin"); + await this.loadSettings(); + this.addSettingTab(new ObsidianProgressBarsSettingTab(this.app, this)); + this.app.workspace.onLayoutReady(this.initializeProgressBars.bind(this)); + } + initializeProgressBars() { + this.registerMarkdownCodeBlockProcessor("obsidian-apb", (source, el, ctx) => { + const rows = source.trim().split("\n"); + el.empty(); + rows.forEach((row, index) => { + console.log("Processing line " + (index + 1), row); + const match = row.match(/^(.+):\s*(\d+)\/(\d+)$/); + if (!match) { + console.error("Invalid format for advanced progress bar block:", row); + const APB_errorContainer = document.createElement("div"); + APB_errorContainer.addClass("error-container"); + const APB_errorMessage = document.createElement("div"); + APB_errorMessage.addClass("error-text-container"); + APB_errorMessage.createEl("span", { text: "APB_ Error: Invalid block format" }); + APB_errorContainer.appendChild(APB_errorMessage); + el.appendChild(APB_errorContainer); + return; + } + const label = match[1]; + const current = parseInt(match[2], 10); + const total = parseInt(match[3], 10); + if (current > total && total !== 0) { + console.error("Invalid value for advanced progress bar block:", row); + const APB_errorContainer = document.createElement("div"); + APB_errorContainer.addClass("error-container"); + const APB_errorMessage = document.createElement("div"); + APB_errorMessage.addClass("error-text-container"); + APB_errorMessage.createEl("span", { text: "APB_ Error: Value is too large" }); + APB_errorContainer.appendChild(APB_errorMessage); + el.appendChild(APB_errorContainer); + return; + } + if (isNaN(current) || isNaN(total) || total === 0) { + console.error("Invalid advanced progress bar values:", row); + const APB_errorContainer = document.createElement("div"); + APB_errorContainer.addClass("error-container"); + const APB_errorMessage = document.createElement("div"); + APB_errorMessage.addClass("error-text-container"); + APB_errorMessage.createEl("span", { text: "APB_ Error: Invalid number" }); + APB_errorContainer.appendChild(APB_errorMessage); + el.appendChild(APB_errorContainer); + return; + } + const percentage = current / total * 100; + const clampedPercentage = Math.min(Math.max(Math.round(percentage), 0), 100); + const APB_container = document.createElement("div"); + APB_container.addClass("progressBar-container"); + if (this.settings.APB_borderToggle) { + APB_container.style.border = "1px solid ${this.settings.APB_colorBorder}"; + } else { + APB_container.style.border = "0px"; + } + if (this.settings.APB_backgroundToggle) { + APB_container.style.background = this.settings.APB_colorBackground; + } else { + APB_container.style.background = "transparent"; + } + const APB_textContainer = document.createElement("div"); + APB_textContainer.addClass("progressBar-text-container"); + const APB_backgroundToggle = document.createElement("div"); + APB_backgroundToggle.addClass("progressBar-background"); + APB_backgroundToggle.style.background = this.settings.APB_colorBarBackground; + const APB_title = document.createElement("div"); + APB_title.addClass("progressBar-title"); + if (this.settings.APB_titleToggle) { + APB_title.createEl("span", { text: label }); + APB_title.style.color = this.settings.APB_titleColor; + } + const APB_percentage = document.createElement("div"); + APB_percentage.addClass("progressBar-percentage"); + if (this.settings.APB_percentageToggle) { + APB_percentage.createEl("span", { text: clampedPercentage + "%" }); + APB_percentage.style.color = this.settings.APB_percentageColor; + } + const APB_value = document.createElement("div"); + APB_value.addClass("progressBar-value"); + if (this.settings.APB_fractionToggle) { + APB_value.createEl("span", { text: "(" + current + "/" + total + ")" }); + APB_value.style.color = this.settings.APB_fractionColor; + } + const APB_completed = document.createElement("div"); + APB_completed.addClass("progressBar-completed"); + if (this.settings.APB_completedToggle) { + APB_completed.createEl("span", { text: "" }); + APB_completed.style.color = this.settings.APB_percentageColor; + } + const APB = document.createElement("div"); + APB.addClass("progressBar"); + const progressBarwidth = this.settings.APB_width; + let numericWidth = parseInt(progressBarwidth.toString(), 10); + if (this.settings.APB_widthToggle) { + APB_container.style.width = "100%"; + APB_backgroundToggle.style.width = "100%"; + APB.style.width = `${clampedPercentage}%`; + } else { + APB_backgroundToggle.style.width = `${progressBarwidth}px`; + APB_container.style.width = `${numericWidth + 10}px`; + APB.style.width = `${numericWidth / 100 * clampedPercentage}px`; + } + APB.style.height = `${this.settings.APB_height}px`; + setEndCaps(APB_backgroundToggle, APB, this.settings.APB_endcapToggle); + APB_backgroundToggle.appendChild(APB); + const marks = document.createElement("div"); + marks.addClass("marks"); + const numberOfSections = parseInt(this.settings.APB_colornumber.replace(/\D/g, "")); + if (clampedPercentage !== 100) { + APB_backgroundToggle.appendChild(marks); + if (this.settings.APB_marksToggle) { + for (let i = 1; i <= numberOfSections - 1; i++) { + const mark = document.createElement("div"); + mark.addClass("mark"); + mark.style.left = `${i * (100 / numberOfSections)}%`; + marks.appendChild(mark); + const dpr = window.devicePixelRatio || 1; + const adjustedBorderWidth = this.settings.APB_marksWidth / dpr; + const rgbaColor = hexToRgba(this.settings.APB_marksColor, 0.5); + mark.style.borderLeft = adjustedBorderWidth + "px solid " + rgbaColor; + } + } + } + APB.appendChild(APB_completed); + for (let i = 1; i <= numberOfSections; i++) { + let sectionsize = `${i * (100 / numberOfSections)}%`; + const markLeftValue = parseFloat(sectionsize); + if (clampedPercentage <= markLeftValue && this.settings.APB_progressBarChange) { + APB.style.backgroundColor = String(this.settings[`APB_color${i}`]); + if (clampedPercentage == 100) { + APB.style.backgroundColor = this.settings.APB_colorBarCompleted; + if (this.settings.APB_completedToggle) { + APB_completed.textContent = "COMPLETED"; + } + } + this.settings.APB_progressBarChange = false; + this.saveSettings(); + } + } + this.settings.APB_progressBarChange = true; + APB_container.appendChild(APB_textContainer); + if (this.settings.APB_titleToggle) { + APB_textContainer.appendChild(APB_title); + } + if (this.settings.APB_percentageToggle) { + APB_textContainer.appendChild(APB_percentage); + } + if (this.settings.APB_fractionToggle) { + APB_textContainer.appendChild(APB_value); + } + APB_container.appendChild(APB_backgroundToggle); + el.appendChild(APB_container); + }); + }); + this.addCommand({ + id: "paste-code-block", + name: "Paste Code Block", + editorCallback: async (editor, view) => { + editor.focus(); + if (!editor) { + new import_obsidian.Notice("No active editor found!"); + return; + } + const valueFromPercentageOfTotal = Math.floor(this.settings.APB_total / 100 * this.settings.APB_progressBarPercentage); + const codeBlockText = `\`\`\`obsidian-apb +${this.settings.APB_title}: ${valueFromPercentageOfTotal}/${this.settings.APB_total} +\`\`\``; + const cursor = editor.getCursor(); + editor.replaceRange(codeBlockText, cursor); + const lines = codeBlockText.split("\n"); + const newCursor = { + line: cursor.line + lines.length - 1, + ch: lines[lines.length - 1].length + // Length of the last line + }; + setTimeout(() => { + editor.setCursor(newCursor); + editor.refresh(); + }, 0); + } + }); + } + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } + async saveSettings() { + await this.saveData(this.settings); + } + async onunload() { + console.log("Cleaning up resources when plugin unloads..."); + const copyButton = document.querySelector("button"); + if (copyButton) { + console.log("Found the copyButton in the DOM."); + copyButton.removeEventListener("click", this.copyButtonListener); + console.log("Event listener removed."); + } else { + console.log("No copyButton found in the DOM."); + } + } +}; +var ObsidianProgressBarsSettingTab = class extends import_obsidian.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + async display() { + const { containerEl } = this; + containerEl.empty(); + containerEl.createEl("h3", { text: "Advanced Progress Bars" }); + const paragraph = containerEl.createEl("p", { text: "If you find value in this plugin and would like to support us, please consider using our " }); + paragraph.createEl("a", { + href: "https://ko-fi.com/cactuzhead", + text: "ko-fi", + cls: "custom-link" + }); + const container = containerEl.createEl("div"); + container.addClass("custom-container"); + container.appendChild(paragraph); + const koFiLink = container.createEl("a"); + koFiLink.href = "https://ko-fi.com/cactuzhead"; + koFiLink.target = "_blank"; + const koFiImage = koFiLink.createEl("img"); + koFiImage.setAttribute("src", "https://storage.ko-fi.com/cdn/fullLogoKofi.png"); + koFiImage.setAttribute("alt", "Support us on Ko-fi"); + koFiImage.style.width = "100px"; + koFiImage.style.height = "auto"; + koFiLink.style.display = "inline-block"; + koFiLink.style.marginLeft = "10px"; + new import_obsidian.Setting(containerEl).setName("Usage Example Code Block").setDesc(createFragment((frag) => { + frag.appendText("Use this code block and edit the "); + const customElement = frag.createEl("span"); + customElement.setText("Title: Value/Total"); + customElement.classList.add("highlight-text"); + frag.appendText(" as needed."); + frag.createEl("br"); + frag.appendText("If you require more than one bar, simply create additional "); + const customElement2 = frag.createEl("span"); + customElement2.setText("Title: Value/Total"); + customElement2.classList.add("highlight-text"); + frag.appendText(" lines within the code block."); + frag.createEl("br"); + frag.appendText("Note: "); + const customElement3 = frag.createEl("span"); + customElement3.setText("Total"); + customElement3.classList.add("highlight-text"); + frag.appendText(" does not need to be 100."); + frag.createEl("br"); + frag.appendText("Visit "); + frag.createEl("a", { + href: "https://cactuzhead.github.io/Advanced-Progress-Bars/", + text: "cactuzhead", + cls: "custom-link" + }); + frag.appendText(" for more detailed information."); + })).addTextArea((textArea) => { + const valueFromPercentageOfTotal2 = Math.floor(this.plugin.settings.APB_total / 100 * this.plugin.settings.APB_progressBarPercentage); + textArea.setValue(`\`\`\`obsidian-apb +${this.plugin.settings.APB_title}: ${valueFromPercentageOfTotal2}/${this.plugin.settings.APB_total} +\`\`\``); + textArea.inputEl.style.height = "80px"; + textArea.inputEl.style.width = "200px"; + textArea.inputEl.style.resize = "none"; + const container2 = textArea.inputEl.parentElement; + if (container2) { + const copyButton = containerEl.createEl("button", { text: "Copy to Clipboard" }); + this.copyButtonListener = (event) => { + navigator.clipboard.writeText(textArea.inputEl.value).then(() => { + new import_obsidian.Notice("Content copied to clipboard!"); + }).catch((err) => { + new import_obsidian.Notice("Failed to copy content: " + err); + }); + }; + copyButton.addEventListener("click", this.copyButtonListener); + copyButton.style.marginTop = "10px"; + copyButton.style.display = "block"; + container2.style.display = "flex"; + container2.style.flexDirection = "column"; + } else { + console.error("Unable to find the parent container for the textarea"); + } + }); + containerEl.createEl("h4", { text: "Light & Dark" }); + new import_obsidian.Setting(containerEl).setName("Apply all Light & Dark color defaults").setDesc(createFragment((frag) => { + frag.appendText("These two options "); + frag.createEl("span", { + text: "(Light & Dark)", + cls: "highlight-text" + }); + frag.appendText(" will change ALL the color settings below to their respective defaults. (All other settings will remain unchanged)."); + frag.createEl("br"); + frag.appendText(" Note: once selected, all previous colors will be lost forever and can not be retrieved."); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_marksColor = DEFAULT_SETTINGS.APB_marksLightColor; + this.plugin.settings.APB_titleColor = DEFAULT_SETTINGS.APB_titleLightColor; + this.plugin.settings.APB_percentageColor = DEFAULT_SETTINGS.APB_percentageLightColor; + this.plugin.settings.APB_fractionColor = DEFAULT_SETTINGS.APB_fractionLightColor; + this.plugin.settings.APB_colorBorder = DEFAULT_SETTINGS.APB_colorLightBorder; + this.plugin.settings.APB_colorBackground = DEFAULT_SETTINGS.APB_colorLightBackground; + this.plugin.settings.APB_colorBarCompleted = DEFAULT_SETTINGS.APB_colorLightBarCompleted; + this.plugin.settings.APB_colorBarBackground = DEFAULT_SETTINGS.APB_colorLightBarBackground; + this.plugin.settings.APB_completedColor = DEFAULT_SETTINGS.APB_completedLightColor; + this.plugin.settings.APB_color1 = DEFAULT_SETTINGS.APB_color1Light; + this.plugin.settings.APB_color2 = DEFAULT_SETTINGS.APB_color2Light; + this.plugin.settings.APB_color3 = DEFAULT_SETTINGS.APB_color3Light; + this.plugin.settings.APB_color4 = DEFAULT_SETTINGS.APB_color4Light; + this.plugin.settings.APB_color5 = DEFAULT_SETTINGS.APB_color5Light; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_marksColor = DEFAULT_SETTINGS.APB_marksColor; + this.plugin.settings.APB_colorBorder = DEFAULT_SETTINGS.APB_colorBorder; + this.plugin.settings.APB_titleColor = DEFAULT_SETTINGS.APB_titleColor; + this.plugin.settings.APB_percentageColor = DEFAULT_SETTINGS.APB_percentageColor; + this.plugin.settings.APB_fractionColor = DEFAULT_SETTINGS.APB_fractionColor; + this.plugin.settings.APB_colorBorder = DEFAULT_SETTINGS.APB_colorBorder; + this.plugin.settings.APB_colorBackground = DEFAULT_SETTINGS.APB_colorBackground; + this.plugin.settings.APB_colorBarCompleted = DEFAULT_SETTINGS.APB_colorBarCompleted; + this.plugin.settings.APB_colorBarBackground = DEFAULT_SETTINGS.APB_colorBarBackground; + this.plugin.settings.APB_completedColor = DEFAULT_SETTINGS.APB_completedColor; + this.plugin.settings.APB_color1 = DEFAULT_SETTINGS.APB_color1; + this.plugin.settings.APB_color2 = DEFAULT_SETTINGS.APB_color2; + this.plugin.settings.APB_color3 = DEFAULT_SETTINGS.APB_color3; + this.plugin.settings.APB_color4 = DEFAULT_SETTINGS.APB_color4; + this.plugin.settings.APB_color5 = DEFAULT_SETTINGS.APB_color5; + this.plugin.saveSettings(); + this.display(); + }) + ); + containerEl.createEl("h4", { text: "Demonstration Progress Bar" }); + new import_obsidian.Setting(containerEl).setDesc("Any changes you make to this settings page will be instantly reflected in the demonstration progress bar below. Use it as a guide when making your decisions."); + const progressBarContainer = containerEl.createEl("div"); + progressBarContainer.addClass("progressBar-container"); + if (this.plugin.settings.APB_borderToggle) { + progressBarContainer.style.border = "1px solid" + this.plugin.settings.APB_colorBorder; + } else { + progressBarContainer.style.border = "0px"; + } + if (this.plugin.settings.APB_backgroundToggle) { + progressBarContainer.style.background = this.plugin.settings.APB_colorBackground; + } else { + progressBarContainer.style.background = "transparent"; + } + const progressBarTextContainer = containerEl.createEl("div"); + progressBarTextContainer.addClass("progressBar-text-container"); + const progressBarBackground = containerEl.createEl("div"); + progressBarBackground.addClass("progressBar-background"); + progressBarBackground.style.background = this.plugin.settings.APB_colorBarBackground; + const progressBarTitle = containerEl.createEl("div"); + progressBarTitle.addClass("progressBar-title"); + if (this.plugin.settings.APB_titleToggle) { + progressBarTitle.createEl("span", { text: this.plugin.settings.APB_title }); + progressBarTitle.style.color = this.plugin.settings.APB_titleColor; + } + const progressBarPercentage = containerEl.createEl("div"); + progressBarPercentage.addClass("progressBar-percentage"); + if (this.plugin.settings.APB_percentageToggle) { + progressBarPercentage.createEl("span", { text: this.plugin.settings.APB_progressBarPercentage + "%" }); + progressBarPercentage.style.color = this.plugin.settings.APB_percentageColor; + } + const progressBarValue = containerEl.createEl("div"); + progressBarValue.addClass("progressBar-value"); + const valueFromPercentageOfTotal = Math.floor(this.plugin.settings.APB_total / 100 * this.plugin.settings.APB_progressBarPercentage); + if (this.plugin.settings.APB_fractionToggle) { + progressBarValue.createEl("span", { text: "(" + valueFromPercentageOfTotal + "/" + this.plugin.settings.APB_total + ")" }); + progressBarValue.style.color = this.plugin.settings.APB_fractionColor; + } + const completed = containerEl.createEl("div"); + completed.addClass("progressBar-completed"); + if (this.plugin.settings.APB_completedToggle) { + completed.style.color = this.plugin.settings.APB_completedColor; + if (this.plugin.settings.APB_progressBarPercentage == 100) { + completed.textContent = "COMPLETED"; + } + } + const progressbar = containerEl.createEl("div"); + progressbar.addClass("progressBar"); + const progressBarwidth = this.plugin.settings.APB_width; + let numericWidth = parseInt(progressBarwidth.toString(), 10); + const clampedPercentage = Math.min(Math.max(Math.round(this.plugin.settings.APB_progressBarPercentage), 0), 100); + if (this.plugin.settings.APB_widthToggle) { + progressBarContainer.style.width = "100%"; + progressBarBackground.style.width = "100%"; + progressbar.style.width = `${clampedPercentage}%`; + } else { + progressBarContainer.style.width = `${numericWidth}px`; + progressBarBackground.style.width = `${String(numericWidth - 12)}px`; + progressbar.style.width = `${(numericWidth - 12) / 100 * clampedPercentage}px`; + } + progressBarContainer.style.margin = "17px"; + progressbar.style.height = `${this.plugin.settings.APB_height}px`; + setEndCaps(progressBarBackground, progressbar, this.plugin.settings.APB_endcapToggle); + progressBarBackground.appendChild(progressbar); + progressbar.appendChild(completed); + const marks = containerEl.createEl("div"); + marks.addClass("marks"); + const numberOfSections = parseInt(this.plugin.settings.APB_colornumber.replace(/\D/g, "")); + if (this.plugin.settings.APB_progressBarPercentage !== 100) { + progressBarBackground.appendChild(marks); + if (this.plugin.settings.APB_marksToggle) { + for (let i = 1; i <= numberOfSections - 1; i++) { + const mark = containerEl.createEl("div"); + mark.addClass("mark"); + mark.style.left = `${i * (100 / numberOfSections)}%`; + marks.appendChild(mark); + const dpr = window.devicePixelRatio || 1; + const adjustedBorderWidth = this.plugin.settings.APB_marksWidth / dpr; + const rgbaColor = hexToRgba(this.plugin.settings.APB_marksColor, 0.5); + mark.style.borderLeft = adjustedBorderWidth + "px solid " + rgbaColor; + } + } + } + for (let i = 1; i <= numberOfSections; i++) { + let sectionsize = `${i * (100 / numberOfSections)}%`; + const progressBarPercentage2 = parseFloat(this.plugin.settings.APB_progressBarPercentage.toString()); + const markLeftValue = parseFloat(sectionsize); + if (progressBarPercentage2 <= markLeftValue && this.plugin.settings.APB_progressBarChange) { + progressbar.style.backgroundColor = String(this.plugin.settings[`APB_color${i}`]); + if (progressBarPercentage2 == 100) { + progressbar.style.backgroundColor = this.plugin.settings.APB_colorBarCompleted; + } + this.plugin.settings.APB_progressBarChange = false; + this.plugin.saveSettings(); + } + } + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + const progresstext = containerEl.createEl("p", { text: "This is a Demo Progress Bar." }); + const containerprogress = containerEl.createEl("div"); + containerprogress.addClass("custom-container"); + containerprogress.appendChild(progresstext); + progressBarContainer.appendChild(progressBarTextContainer); + if (this.plugin.settings.APB_titleToggle) { + progressBarTextContainer.appendChild(progressBarTitle); + } + if (this.plugin.settings.APB_percentageToggle) { + progressBarTextContainer.appendChild(progressBarPercentage); + } + if (this.plugin.settings.APB_fractionToggle) { + progressBarTextContainer.appendChild(progressBarValue); + } + containerprogress.appendChild(progressBarContainer); + progressBarContainer.appendChild(progressBarBackground); + containerEl.createEl("h4", { text: "Progress Bar" }); + new import_obsidian.Setting(containerEl).setName("Default title").setDesc(createFragment((frag) => { + frag.appendText("Set the default title of a new progress bar. If you change this, the "); + frag.createEl("span", { + text: "Title", + cls: "highlight-text" + }); + frag.appendText(" will be automatically changed in the example code block at the top of the settings for easy copy and pasting later on."); + })).addText((text) => { + let debounceTimeout; + text.setPlaceholder("Enter your title").setValue(this.plugin.settings.APB_title || "").onChange((value) => { + clearTimeout(debounceTimeout); + debounceTimeout = setTimeout(() => { + this.plugin.settings.APB_title = value; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }, 2e3); + }); + }).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_title = DEFAULT_SETTINGS.APB_title; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }) + ); + let timeoutId; + new import_obsidian.Setting(containerEl).setName("Default total").setDesc(createFragment((frag) => { + frag.appendText("Set the default "); + frag.createEl("span", { + text: "Total", + cls: "highlight-text" + }); + frag.appendText(" of a new progress bar. If you change this, the "); + frag.createEl("span", { + text: "Total", + cls: "highlight-text" + }); + frag.appendText(" will be automatically changed in the example code block above for easy copy and pasting later on."); + })).addText( + (text) => text.setPlaceholder("100").setValue(this.plugin.settings.APB_total !== void 0 ? String(this.plugin.settings.APB_total) : String(DEFAULT_SETTINGS.APB_total)).onChange((value) => { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + var _a; + const parsedValue = parseInt(value, 10); + if (parsedValue >= 1 && (!isNaN(parsedValue) && parsedValue === parseFloat(value))) { + this.plugin.settings.APB_total = parsedValue; + this.plugin.saveSettings(); + this.display(); + } else { + text.setValue(String((_a = this.plugin.settings.APB_total) != null ? _a : DEFAULT_SETTINGS.APB_total)); + this.plugin.saveSettings(); + this.display(); + new import_obsidian.Notice("Please enter a value 1 or above."); + } + }, 1e3); + }).inputEl.classList.add("custom-textbox") + ).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_total = DEFAULT_SETTINGS.APB_total; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Progress percentage").setDesc(createFragment((frag) => { + frag.appendText("Set the percentage for the demonstration progress bar above. This will also update the "); + frag.createEl("span", { + text: "Value", + cls: "highlight-text" + }); + frag.appendText(" parameter in the Example Code at the top of the settings. Once you are satisfied with all other settings, you will likely want to set this back to 0."); + })).addSlider((slider) => { + var _a2; + var _a; + slider.setLimits(0, 100, 1).setDynamicTooltip().setValue((_a2 = this.plugin.settings.APB_progressBarPercentage) != null ? _a2 : DEFAULT_SETTINGS.APB_progressBarPercentage).onChange((value) => { + this.plugin.settings.APB_progressBarPercentage = value; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }); + }).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_progressBarPercentage = DEFAULT_SETTINGS.APB_progressBarPercentage; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Full width").setDesc(createFragment((frag) => { + frag.appendText("Toggle this on to set the progress bar to fill the entire width of its container. For a fixed width, toggle this off and use the "); + frag.createEl("span", { + text: "Width", + cls: "highlight-text" + }); + frag.appendText(" option that will appear below."); + })).addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_widthToggle).onChange((value) => { + this.plugin.settings.APB_widthToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_widthToggle = DEFAULT_SETTINGS.APB_widthToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + if (!this.plugin.settings.APB_widthToggle) { + let timeoutId2; + new import_obsidian.Setting(containerEl).setName("Width").setDesc("Set the width of the progress bar container in pixels (minimum 100). Note: If you want it to span the full width, make sure to enable the toggle above.").addText( + (text) => text.setPlaceholder("200").setValue(this.plugin.settings.APB_width !== void 0 ? String(this.plugin.settings.APB_width) : String(DEFAULT_SETTINGS.APB_width)).onChange((value) => { + clearTimeout(timeoutId2); + timeoutId2 = setTimeout(() => { + var _a; + const parsedValue = parseInt(value, 10); + if (parsedValue >= 100 && (!isNaN(parsedValue) && parsedValue === parseFloat(value))) { + this.plugin.settings.APB_width = parsedValue; + this.plugin.saveSettings(); + this.display(); + } else { + text.setValue(String((_a = this.plugin.settings.APB_width) != null ? _a : DEFAULT_SETTINGS.APB_width)); + this.plugin.saveSettings(); + this.display(); + new import_obsidian.Notice("Please enter a value 100 or above."); + } + }, 1e3); + }).inputEl.classList.add("custom-textbox") + ).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_width = DEFAULT_SETTINGS.APB_width; + this.plugin.saveSettings(); + this.display(); + }) + ); + } + new import_obsidian.Setting(containerEl).setName("Height").setDesc("Set the height of the progress bar in pixels. (See demonstration progress bar above)").addSlider((slider) => { + var _a2; + var _a; + slider.setLimits(1, 15, 1).setDynamicTooltip().setValue((_a2 = this.plugin.settings.APB_height) != null ? _a2 : DEFAULT_SETTINGS.APB_height).onChange((value) => { + this.plugin.settings.APB_height = value; + setEndCaps(progressBarBackground, progressbar, this.plugin.settings.APB_endcapToggle); + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }); + }).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_height = DEFAULT_SETTINGS.APB_height; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Round end caps").setDesc("When toggled, the progress bar will have either a round or square end cap. (See demonstration progress bar above)").addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_endcapToggle).onChange((value) => { + this.plugin.settings.APB_endcapToggle = value; + setEndCaps(progressBarBackground, progressbar, this.plugin.settings.APB_endcapToggle); + this.plugin.saveSettings(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_endcapToggle = DEFAULT_SETTINGS.APB_endcapToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + containerEl.createEl("h4", { text: "Section Marks" }); + new import_obsidian.Setting(containerEl).setName("Section marks").setDesc(createFragment((frag) => { + frag.appendText("When toggled on, the progress bar will have vertical section marks equally spaced along its length. The number and spacing of these will change depending on how many colors your progress bar uses (see "); + frag.createEl("span", { + text: "Number of colors", + cls: "highlight-text" + }); + frag.appendText(" setting below). Note: if the bar reaches 100% or the bar has only one color, no marks will not be displayed. (See demonstration progress bar above)"); + })).addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_marksToggle).onChange((value) => { + this.plugin.settings.APB_marksToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_marksToggle = DEFAULT_SETTINGS.APB_marksToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Section Mark color").setDesc(createFragment((frag) => { + frag.appendText("Select the color of the section "); + frag.createEl("span", { + text: "Marks", + cls: "highlight-text" + }); + frag.appendText(". Note: The color will be set to 50% transparency, allowing the progress bar's color to blend and influence the final appearance."); + })).addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_marksColor).onChange((value) => { + this.plugin.settings.APB_marksColor = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_marksColor = DEFAULT_SETTINGS.APB_marksLightColor; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_marksColor = DEFAULT_SETTINGS.APB_marksColor; + this.plugin.saveSettings(); + this.display(); + }) + ); + if (this.plugin.settings.APB_marksToggle) { + new import_obsidian.Setting(containerEl).setName("Section mark width").setDesc("Set the width of the section mark lines on the progress bar from a range of 1 to 5 pixels. (See demonstration progress bar above)").addSlider((slider) => { + var _a2; + var _a; + slider.setLimits(1, 5, 1).setDynamicTooltip().setValue((_a2 = this.plugin.settings.APB_marksWidth) != null ? _a2 : DEFAULT_SETTINGS.APB_marksWidth).onChange((value) => { + this.plugin.settings.APB_marksWidth = value; + this.plugin.saveSettings(); + this.display(); + }); + }).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_marksWidth = DEFAULT_SETTINGS.APB_marksWidth; + this.plugin.saveSettings(); + this.display(); + }) + ); + } + containerEl.createEl("h4", { text: "Text" }); + new import_obsidian.Setting(containerEl).setName("Show title text").setDesc(createFragment((frag) => { + frag.appendText("When toggled on, the "); + frag.createEl("span", { + text: "Title", + cls: "highlight-text" + }); + frag.appendText(" text will be displayed above the progress bar. (See demonstration progress bar above)"); + })).addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_titleToggle).onChange((value) => { + this.plugin.settings.APB_titleToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_titleToggle = DEFAULT_SETTINGS.APB_titleToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Title text color").setDesc(createFragment((frag) => { + frag.appendText("Select the color of the "); + frag.createEl("span", { + text: "Title", + cls: "highlight-text" + }); + frag.appendText(" text."); + })).addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_titleColor).onChange((value) => { + this.plugin.settings.APB_titleColor = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_titleColor = DEFAULT_SETTINGS.APB_titleLightColor; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_titleColor = DEFAULT_SETTINGS.APB_titleColor; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Show percentage text").setDesc(createFragment((frag) => { + frag.appendText("When toggled on, the "); + frag.createEl("span", { + text: "Percentage", + cls: "highlight-text" + }); + frag.appendText(" text will be displayed above the progress bar. (See demonstration progress bar above)"); + })).addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_percentageToggle).onChange((value) => { + this.plugin.settings.APB_percentageToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_percentageToggle = DEFAULT_SETTINGS.APB_percentageToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Percentage text color").setDesc(createFragment((frag) => { + frag.appendText("Select the color of the "); + frag.createEl("span", { + text: "Percentage", + cls: "highlight-text" + }); + frag.appendText(" text."); + })).addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_percentageColor).onChange((value) => { + this.plugin.settings.APB_percentageColor = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_percentageColor = DEFAULT_SETTINGS.APB_percentageLightColor; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_percentageColor = DEFAULT_SETTINGS.APB_percentageColor; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Show fraction text (Value/Total)").setDesc(createFragment((frag) => { + frag.appendText("When toggled on, the fraction text "); + frag.createEl("span", { + text: "(Value/Total)", + cls: "highlight-text" + }); + frag.appendText(" will be displayed above the progress bar. (See demonstration progress bar above)"); + })).addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_fractionToggle).onChange((value) => { + this.plugin.settings.APB_fractionToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_fractionToggle = DEFAULT_SETTINGS.APB_fractionToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Fraction text color").setDesc(createFragment((frag) => { + frag.appendText("Select the color of the "); + frag.createEl("span", { + text: "Fraction", + cls: "highlight-text" + }); + frag.appendText(" text."); + })).addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_fractionColor).onChange((value) => { + this.plugin.settings.APB_fractionColor = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_fractionColor = DEFAULT_SETTINGS.APB_fractionLightColor; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_fractionColor = DEFAULT_SETTINGS.APB_fractionColor; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Show completed text").setDesc("When toggled on, the word COMPLETED will be displayed on the progress bar when it reaches 100%. (See demonstration progress bar above)").addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_completedToggle).onChange((value) => { + this.plugin.settings.APB_completedToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_completedToggle = DEFAULT_SETTINGS.APB_completedToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Completed text color").setDesc(createFragment((frag) => { + frag.appendText("Select the color of the "); + frag.createEl("span", { + text: "Completed", + cls: "highlight-text" + }); + frag.appendText(" text."); + })).addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_completedColor).onChange((value) => { + this.plugin.settings.APB_completedColor = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_completedColor = DEFAULT_SETTINGS.APB_completedLightColor; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_completedColor = DEFAULT_SETTINGS.APB_completedColor; + this.plugin.saveSettings(); + this.display(); + }) + ); + containerEl.createEl("h4", { text: "Progress Bar Container" }); + new import_obsidian.Setting(containerEl).setName("Border").setDesc("When toggled on, a border will be displayed around the progress bar container.").addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_borderToggle).onChange((value) => { + this.plugin.settings.APB_borderToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_borderToggle = DEFAULT_SETTINGS.APB_borderToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Border color").setDesc("Select the color of the border around the progress bar container.").addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_colorBorder).onChange((value) => { + this.plugin.settings.APB_colorBorder = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_colorBorder = DEFAULT_SETTINGS.APB_colorLightBorder; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_colorBorder = DEFAULT_SETTINGS.APB_colorBorder; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Background").setDesc("When toggled on, the background of the progress bar container will show.").addToggle((toggle) => toggle.setValue(this.plugin.settings.APB_backgroundToggle).onChange((value) => { + this.plugin.settings.APB_backgroundToggle = value; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_backgroundToggle = DEFAULT_SETTINGS.APB_backgroundToggle; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Background color").setDesc("Select the background color of the progress bar container.").addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_colorBackground).onChange((value) => { + this.plugin.settings.APB_colorBackground = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_colorBackground = DEFAULT_SETTINGS.APB_colorLightBackground; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_colorBackground = DEFAULT_SETTINGS.APB_colorBackground; + this.plugin.saveSettings(); + this.display(); + }) + ); + containerEl.createEl("h4", { text: "Progress Bar Color" }); + new import_obsidian.Setting(this.containerEl).setName("Number of colors").setDesc("Select how many different colors you want the progress bar to use. Each color will be used for the entire bar depending on its percentage completed. (See demonstration progress bar above)").addDropdown((dropdown) => { + dropdown.addOptions({ + option1: "1 color", + option2: "2 colors", + option3: "3 colors", + option4: "4 colors", + option5: "5 colors" + }).setValue(this.plugin.settings.APB_colornumber).onChange((value) => { + this.plugin.settings.APB_colornumber = value; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }); + }).addButton( + (button) => button.setIcon("rotate-ccw").setTooltip("Reset to default").onClick(() => { + this.plugin.settings.APB_colornumber = DEFAULT_SETTINGS.APB_colornumber; + this.plugin.settings.APB_progressBarChange = true; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("1st color").setDesc("This color will be used for the entire progrees bar if the percentage is within the first section.").addColorPicker( + (PBcolorpicker1) => PBcolorpicker1.setValue(this.plugin.settings.APB_color1).onChange((value) => { + this.plugin.settings.APB_color1 = value; + this.plugin.saveSettings(); + this.display(); + }) + ).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_color1 = DEFAULT_SETTINGS.APB_color1Light; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_color1 = DEFAULT_SETTINGS.APB_color1; + this.plugin.saveSettings(); + this.display(); + }) + ); + if (this.plugin.settings.APB_colornumber !== "option1") { + new import_obsidian.Setting(containerEl).setName("2nd color").setDesc("This color will be used for the entire progrees bar if the percentage is within the second section.").addColorPicker((PBcolorpicker2) => PBcolorpicker2.setValue(this.plugin.settings.APB_color2).onChange((value) => { + this.plugin.settings.APB_color2 = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_color2 = DEFAULT_SETTINGS.APB_color2Light; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_color2 = DEFAULT_SETTINGS.APB_color2; + this.plugin.saveSettings(); + this.display(); + }) + ); + if (this.plugin.settings.APB_colornumber !== "option2") { + new import_obsidian.Setting(containerEl).setName("3rd color").setDesc("This color will be used for the entire progrees bar if the percentage is within the third section.").addColorPicker((PBcolorpicker3) => PBcolorpicker3.setValue(this.plugin.settings.APB_color3).onChange((value) => { + this.plugin.settings.APB_color3 = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_color3 = DEFAULT_SETTINGS.APB_color3Light; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_color3 = DEFAULT_SETTINGS.APB_color3; + this.plugin.saveSettings(); + this.display(); + }) + ); + if (this.plugin.settings.APB_colornumber !== "option3") { + new import_obsidian.Setting(containerEl).setName("4th color").setDesc("This color will be used for the entire progrees bar if the percentage is within the fourth section.").addColorPicker((PBcolorpicker4) => PBcolorpicker4.setValue(this.plugin.settings.APB_color4).onChange((value) => { + this.plugin.settings.APB_color4 = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_color4 = DEFAULT_SETTINGS.APB_color4Light; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_color4 = DEFAULT_SETTINGS.APB_color4; + this.plugin.saveSettings(); + this.display(); + }) + ); + if (this.plugin.settings.APB_colornumber !== "option4") { + new import_obsidian.Setting(containerEl).setName("5th color").setDesc("This color will be used for the entire progrees bar if the percentage is within the fifth section.").addColorPicker((PBcolorpicker5) => PBcolorpicker5.setValue(this.plugin.settings.APB_color5).onChange((value) => { + this.plugin.settings.APB_color5 = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_color5 = DEFAULT_SETTINGS.APB_color5Light; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_color5 = DEFAULT_SETTINGS.APB_color5; + this.plugin.saveSettings(); + this.display(); + }) + ); + } + } + } + } + new import_obsidian.Setting(containerEl).setName("Completed color").setDesc("Select the color the entire progress bar will use when it reaches 100% completion.").addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_colorBarCompleted).onChange((value) => { + this.plugin.settings.APB_colorBarCompleted = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_colorBarCompleted = DEFAULT_SETTINGS.APB_colorLightBarCompleted; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_colorBarCompleted = DEFAULT_SETTINGS.APB_colorBarCompleted; + this.plugin.saveSettings(); + this.display(); + }) + ); + new import_obsidian.Setting(containerEl).setName("Bar background color").setDesc("This color will be used for the progress bar's background, representing the remaining percentage.").addColorPicker((PBcolorpicker0) => PBcolorpicker0.setValue(this.plugin.settings.APB_colorBarBackground).onChange((value) => { + this.plugin.settings.APB_colorBarBackground = value; + this.plugin.saveSettings(); + this.display(); + })).addButton((button) => button.setIcon("sun").setTooltip("Reset to Light default").onClick(() => { + this.plugin.settings.APB_colorBarBackground = DEFAULT_SETTINGS.APB_colorLightBarBackground; + this.plugin.saveSettings(); + this.display(); + })).addButton( + (button) => button.setIcon("moon").setTooltip("Reset to Dark default").onClick(() => { + this.plugin.settings.APB_colorBarBackground = DEFAULT_SETTINGS.APB_colorBarBackground; + this.plugin.saveSettings(); + this.display(); + }) + ); + } +}; +function setEndCaps(progressBarBackground, progressbar, endCap) { + if (progressBarBackground && progressbar) { + if (endCap) { + progressBarBackground.style.borderRadius = "7px"; + progressbar.style.borderRadius = "7px"; + } else { + progressBarBackground.style.borderRadius = "0px"; + progressbar.style.borderRadius = "0px"; + } + } else { + console.error("Elements are not defined"); + } +} +function hexToRgba(hex, alpha = 1) { + hex = hex.replace("#", ""); + if (hex.length === 3) { + hex = hex.split("").map((char) => char + char).join(""); + } + const r = parseInt(hex.slice(0, 2), 16); + const g = parseInt(hex.slice(2, 4), 16); + const b = parseInt(hex.slice(4, 6), 16); + return `rgba(${r}, ${g}, ${b}, ${alpha})`; +} +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgQXBwLCBQbHVnaW4sIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcsICBOb3RpY2UgIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG4vLyBQb3B1bGF0ZSBzZXR0aW5ncyB3aXRoIHZhbHVlc1xuaW50ZXJmYWNlIE9ic2lkaWFuUHJvZ3Jlc3NCYXJzU2V0dGluZ3Mge1xuXHQvKiBQcm9ncmVzcyBCYXIgU2V0dGluZ3MgKi9cblx0QVBCX3RpdGxlOiBzdHJpbmc7XG5cdEFQQl93aWR0aFRvZ2dsZTogYm9vbGVhbjtcblx0QVBCX3dpZHRoOiBudW1iZXI7XHRcblx0QVBCX2hlaWdodDogbnVtYmVyO1xuXHRBUEJfcHJvZ3Jlc3NCYXJQZXJjZW50YWdlOiBudW1iZXI7XG5cdEFQQl90b3RhbDogbnVtYmVyO1xuXHRBUEJfZW5kY2FwVG9nZ2xlOiBib29sZWFuO1xuXHRBUEJfbWFya3NUb2dnbGU6IGJvb2xlYW47XG5cdEFQQl9tYXJrc0NvbG9yOiBzdHJpbmc7XG5cdEFQQl9tYXJrc0xpZ2h0Q29sb3I6IHN0cmluZztcblx0QVBCX21hcmtzV2lkdGg6IG51bWJlcjtcblx0LyogVGV4dCBTZXR0aW5ncyAqL1xuXHRBUEJfdGl0bGVUb2dnbGU6IGJvb2xlYW47XG5cdEFQQl90aXRsZUNvbG9yOiBzdHJpbmc7XG5cdEFQQl90aXRsZUxpZ2h0Q29sb3I6IHN0cmluZztcblx0QVBCX3BlcmNlbnRhZ2VUb2dnbGU6IGJvb2xlYW47XG5cdEFQQl9wZXJjZW50YWdlQ29sb3I6IHN0cmluZztcblx0QVBCX3BlcmNlbnRhZ2VMaWdodENvbG9yOiBzdHJpbmc7XG5cdEFQQl9mcmFjdGlvblRvZ2dsZTogYm9vbGVhbjtcblx0QVBCX2ZyYWN0aW9uQ29sb3I6IHN0cmluZztcblx0QVBCX2ZyYWN0aW9uTGlnaHRDb2xvcjogc3RyaW5nO1xuXHRBUEJfY29tcGxldGVkVG9nZ2xlOiBib29sZWFuO1xuXHRBUEJfY29tcGxldGVkQ29sb3I6IHN0cmluZztcblx0QVBCX2NvbXBsZXRlZExpZ2h0Q29sb3I6IHN0cmluZztcblx0LyogQ29udGFpbmVyIFNldHRpbmdzICovXG5cdEFQQl9ib3JkZXJUb2dnbGU6IGJvb2xlYW47XG5cdEFQQl9jb2xvckJvcmRlcjogc3RyaW5nO1xuXHRBUEJfY29sb3JMaWdodEJvcmRlcjogc3RyaW5nO1xuXHRBUEJfYmFja2dyb3VuZFRvZ2dsZTogYm9vbGVhbjtcblx0QVBCX2NvbG9yQmFja2dyb3VuZDogc3RyaW5nO1xuXHRBUEJfY29sb3JMaWdodEJhY2tncm91bmQ6IHN0cmluZztcblx0LyogUHJvZ3Jlc3MgQmFyIENvbG9yIFNldHRpbmdzICovXG5cdEFQQl9jb2xvcm51bWJlcjogc3RyaW5nO1xuXHRBUEJfY29sb3IxOiBzdHJpbmc7XG5cdEFQQl9jb2xvcjI6IHN0cmluZztcblx0QVBCX2NvbG9yMzogc3RyaW5nO1xuXHRBUEJfY29sb3I0OiBzdHJpbmc7XG5cdEFQQl9jb2xvcjU6IHN0cmluZztcblx0QVBCX2NvbG9yMUxpZ2h0OiBzdHJpbmc7XG5cdEFQQl9jb2xvcjJMaWdodDogc3RyaW5nO1xuXHRBUEJfY29sb3IzTGlnaHQ6IHN0cmluZztcblx0QVBCX2NvbG9yNExpZ2h0OiBzdHJpbmc7XG5cdEFQQl9jb2xvcjVMaWdodDogc3RyaW5nO1xuXHRBUEJfY29sb3JCYXJDb21wbGV0ZWQ6IHN0cmluZztcblx0QVBCX2NvbG9yTGlnaHRCYXJDb21wbGV0ZWQ6IHN0cmluZztcblx0QVBCX2NvbG9yQmFyQmFja2dyb3VuZDogc3RyaW5nO1xuXHRBUEJfY29sb3JMaWdodEJhckJhY2tncm91bmQ6IHN0cmluZztcblx0LyogQWRkaXRpb25hbCBTZXR0aW5ncyAqL1xuXHRBUEJfcHJvZ3Jlc3NCYXJDaGFuZ2U6IGJvb2xlYW47XG59XG5cbmNvbnN0IERFRkFVTFRfU0VUVElOR1M6IFBhcnRpYWw8T2JzaWRpYW5Qcm9ncmVzc0JhcnNTZXR0aW5ncz4gPSB7XG5cdC8qIFByb2dyZXNzIEJhciBTZXR0aW5ncyAqL1xuXHRBUEJfdGl0bGU6ICdQcm9ncmVzcycsXG5cdEFQQl93aWR0aFRvZ2dsZTogdHJ1ZSxcblx0QVBCX3dpZHRoOiAxOTAsXHRcblx0QVBCX2hlaWdodDogOCxcblx0QVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZTogODMsXG5cdEFQQl90b3RhbDogMTAwLFxuXHRBUEJfZW5kY2FwVG9nZ2xlOiB0cnVlLFxuXHRBUEJfbWFya3NUb2dnbGU6IHRydWUsXG5cdEFQQl9tYXJrc0NvbG9yOiAnIzAwMDAwMCcsXG5cdEFQQl9tYXJrc0xpZ2h0Q29sb3I6ICcjZmZmZmZmJyxcblx0QVBCX21hcmtzV2lkdGg6IDMsXG5cdC8qIFRleHQgU2V0dGluZ3MgKi9cblx0QVBCX3RpdGxlVG9nZ2xlOiB0cnVlLFxuXHRBUEJfdGl0bGVDb2xvcjogJyM4ZmEwYmEnLFxuXHRBUEJfdGl0bGVMaWdodENvbG9yOiAnIzQ0NTQ2ZicsXG5cdEFQQl9wZXJjZW50YWdlVG9nZ2xlOiB0cnVlLFxuXHRBUEJfcGVyY2VudGFnZUNvbG9yOiAnI2MxZDdmOScsXG5cdEFQQl9wZXJjZW50YWdlTGlnaHRDb2xvcjogJyM2ZDg1YWQnLFxuXHRBUEJfZnJhY3Rpb25Ub2dnbGU6IHRydWUsXG5cdEFQQl9mcmFjdGlvbkNvbG9yOiAnIzhmYTBiYScsXG5cdEFQQl9mcmFjdGlvbkxpZ2h0Q29sb3I6ICcjNTc2YThhJyxcblx0QVBCX2NvbXBsZXRlZFRvZ2dsZTogdHJ1ZSxcblx0QVBCX2NvbXBsZXRlZENvbG9yOiAnI2MxZDdmOScsXG5cdEFQQl9jb21wbGV0ZWRMaWdodENvbG9yOiAnIzQ0NTQ2ZicsXG5cdC8qIENvbnRhaW5lciBTZXR0aW5ncyAqL1xuXHRBUEJfYm9yZGVyVG9nZ2xlOiB0cnVlLFxuXHRBUEJfY29sb3JCb3JkZXI6ICcjNDc0ZjYyJyxcblx0QVBCX2NvbG9yTGlnaHRCb3JkZXI6ICcjY2VkMGQ2Jyxcblx0QVBCX2JhY2tncm91bmRUb2dnbGU6IHRydWUsXG5cdEFQQl9jb2xvckJhY2tncm91bmQ6ICcjMjQyYTM1Jyxcblx0QVBCX2NvbG9yTGlnaHRCYWNrZ3JvdW5kOiAnI2YxZjJmNCcsXG5cdC8qIFByb2dyZXNzIEJhciBDb2xvciBTZXR0aW5ncyAqL1xuXHRBUEJfY29sb3JudW1iZXI6ICdvcHRpb241Jyxcblx0QVBCX2NvbG9yMTogJyMyOTc4ZWYnLFxuXHRBUEJfY29sb3IyOiAnIzhlYzgyMicsXG5cdEFQQl9jb2xvcjM6ICcjZGZhYTIyJyxcblx0QVBCX2NvbG9yNDogJyNjODQ5MjInLFxuXHRBUEJfY29sb3I1OiAnI2RkNGE4NicsXG5cdEFQQl9jb2xvcjFMaWdodDogJyMyNzgzNzgnLFxuXHRBUEJfY29sb3IyTGlnaHQ6ICcjMmJhYWI5Jyxcblx0QVBCX2NvbG9yM0xpZ2h0OiAnIzRhMzJlMicsXG5cdEFQQl9jb2xvcjRMaWdodDogJyM3YzMyOGUnLFxuXHRBUEJfY29sb3I1TGlnaHQ6ICcjYzExZTQ5Jyxcblx0QVBCX2NvbG9yQmFyQ29tcGxldGVkOiAnIzU3NjE3OCcsXG5cdEFQQl9jb2xvckxpZ2h0QmFyQ29tcGxldGVkOiAnI2ZjZmNmZCcsXG5cdEFQQl9jb2xvckJhckJhY2tncm91bmQ6ICcjM2I0MjUyJyxcblx0QVBCX2NvbG9yTGlnaHRCYXJCYWNrZ3JvdW5kOiAnI2Q5ZGRlMicsXG5cdC8qIEFkZGl0aW9uYWwgU2V0dGluZ3MgKi9cblx0QVBCX3Byb2dyZXNzQmFyQ2hhbmdlOiB0cnVlLFxufVxuLy8gTG9hZGluZyBhbmQgc2F2aW5nIG9mIHNldHRpbmdzXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBPYnNpZGlhblByb2dyZXNzQmFycyBleHRlbmRzIFBsdWdpbiB7XG5cdHNldHRpbmdzOiBPYnNpZGlhblByb2dyZXNzQmFyc1NldHRpbmdzO1xuICBcblx0Y29weUJ1dHRvbkxpc3RlbmVyOiAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHZvaWQ7XG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGNvbnNvbGUubG9nKCdsb2FkaW5nIEFQQiBwbHVnaW4nKVxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XG5cdFxuXHRcdHRoaXMuYWRkU2V0dGluZ1RhYihuZXcgT2JzaWRpYW5Qcm9ncmVzc0JhcnNTZXR0aW5nVGFiKHRoaXMuYXBwLCB0aGlzKSk7XG5cdFxuXHRcdFxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KHRoaXMuaW5pdGlhbGl6ZVByb2dyZXNzQmFycy5iaW5kKHRoaXMpKTtcblx0fVxuICBcblx0aW5pdGlhbGl6ZVByb2dyZXNzQmFycygpIHtcblx0XHR0aGlzLnJlZ2lzdGVyTWFya2Rvd25Db2RlQmxvY2tQcm9jZXNzb3IoJ29ic2lkaWFuLWFwYicsIChzb3VyY2UsIGVsLCBjdHgpID0+IHtcblxuXHRcdFx0Ly8gU3BsaXQgdGhlIHNvdXJjZSBzdHJpbmcgaW50byByb3dzXG5cdFx0XHRjb25zdCByb3dzID0gc291cmNlLnRyaW0oKS5zcGxpdCgnXFxuJyk7XG5cdFx0XHRlbC5lbXB0eSgpOyAvLyBDbGVhciB0aGUgZGVmYXVsdCByZW5kZXJpbmdcblxuXHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGVhY2ggbGluZSBhbmQgZG8gc29tZXRoaW5nIHdpdGggaXRcblx0XHRcdHJvd3MuZm9yRWFjaCgocm93LCBpbmRleCkgPT4ge1xuXHRcdFx0XHRjb25zb2xlLmxvZygnUHJvY2Vzc2luZyBsaW5lICcrIChpbmRleCArIDEpLCByb3cpOyBcblxuXHRcdFx0XHQvLyBVc2UgcmVnZXggdG8gZXh0cmFjdCB0aGUgbGFiZWwgYW5kIHByb2dyZXNzIChWYWx1ZS9Ub3RhbClcblx0XHRcdFx0Y29uc3QgbWF0Y2ggPSByb3cubWF0Y2goL14oLispOlxccyooXFxkKylcXC8oXFxkKykkLyk7XHRcdFxuXG5cdFx0XHRcdGlmICghbWF0Y2gpIHtcblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKCdJbnZhbGlkIGZvcm1hdCBmb3IgYWR2YW5jZWQgcHJvZ3Jlc3MgYmFyIGJsb2NrOicsIHJvdyk7XG5cblx0XHRcdFx0XHRjb25zdCBBUEJfZXJyb3JDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRcdFx0XHRBUEJfZXJyb3JDb250YWluZXIuYWRkQ2xhc3MoJ2Vycm9yLWNvbnRhaW5lcicpO1xuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdGNvbnN0IEFQQl9lcnJvck1lc3NhZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRcdFx0XHRBUEJfZXJyb3JNZXNzYWdlLmFkZENsYXNzKCdlcnJvci10ZXh0LWNvbnRhaW5lcicpO1x0XHRcdFx0XG5cdFx0XHRcdFx0QVBCX2Vycm9yTWVzc2FnZS5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0FQQl8gRXJyb3I6IEludmFsaWQgYmxvY2sgZm9ybWF0JyB9KTtcblxuXHRcdFx0XHRcdEFQQl9lcnJvckNvbnRhaW5lci5hcHBlbmRDaGlsZChBUEJfZXJyb3JNZXNzYWdlKTtcblx0XHRcdFx0XHRlbC5hcHBlbmRDaGlsZChBUEJfZXJyb3JDb250YWluZXIpO1xuXHRcdFxuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEV4dHJhY3QgbGFiZWwsIGN1cnJlbnQgdmFsdWUsIGFuZCB0b3RhbCB2YWx1ZSBmcm9tIHRoZSBtYXRjaFxuXHRcdFx0XHRjb25zdCBsYWJlbCA9IG1hdGNoWzFdO1xuXHRcdFx0XHRjb25zdCBjdXJyZW50ID0gcGFyc2VJbnQobWF0Y2hbMl0sIDEwKTtcblx0XHRcdFx0Y29uc3QgdG90YWwgPSBwYXJzZUludChtYXRjaFszXSwgMTApO1xuXG5cdFx0XHRcdC8vIENoZWNrIGlmIGN1cnJlbnQgdmFsdWUgaXMgdG9vIGxhcmdlIG9yIHRvdGFsIGlzIHplcm9cblx0XHRcdFx0aWYgKGN1cnJlbnQgPiB0b3RhbCAmJiB0b3RhbCAhPT0gMCkge1xuXHRcdFx0XHRcdGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgdmFsdWUgZm9yIGFkdmFuY2VkIHByb2dyZXNzIGJhciBibG9jazonLCByb3cpO1xuXG5cdFx0XHRcdFx0Y29uc3QgQVBCX2Vycm9yQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRcdFx0QVBCX2Vycm9yQ29udGFpbmVyLmFkZENsYXNzKCdlcnJvci1jb250YWluZXInKTtcblxuXHRcdFx0XHRcdGNvbnN0IEFQQl9lcnJvck1lc3NhZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRcdFx0XHRBUEJfZXJyb3JNZXNzYWdlLmFkZENsYXNzKCdlcnJvci10ZXh0LWNvbnRhaW5lcicpO1xuXHRcdFx0XHRcdEFQQl9lcnJvck1lc3NhZ2UuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICdBUEJfIEVycm9yOiBWYWx1ZSBpcyB0b28gbGFyZ2UnIH0pO1xuXG5cdFx0XHRcdFx0QVBCX2Vycm9yQ29udGFpbmVyLmFwcGVuZENoaWxkKEFQQl9lcnJvck1lc3NhZ2UpO1xuXHRcdFx0XHRcdGVsLmFwcGVuZENoaWxkKEFQQl9lcnJvckNvbnRhaW5lcik7XG5cblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0ICBcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgcGFyc2luZyB3YXMgc3VjY2Vzc2Z1bCBhbmQgdGhhdCB0b3RhbCBpcyBub3QgemVyb1xuXHRcdFx0XHRpZiAoaXNOYU4oY3VycmVudCkgfHwgaXNOYU4odG90YWwpIHx8IHRvdGFsID09PSAwKSB7XG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvcignSW52YWxpZCBhZHZhbmNlZCBwcm9ncmVzcyBiYXIgdmFsdWVzOicsIHJvdyk7XHRcblxuXHRcdFx0XHRcdGNvbnN0IEFQQl9lcnJvckNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0XHRcdEFQQl9lcnJvckNvbnRhaW5lci5hZGRDbGFzcygnZXJyb3ItY29udGFpbmVyJyk7XG5cblx0XHRcdFx0XHRjb25zdCBBUEJfZXJyb3JNZXNzYWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRcdFx0QVBCX2Vycm9yTWVzc2FnZS5hZGRDbGFzcygnZXJyb3ItdGV4dC1jb250YWluZXInKTtcblx0XHRcdFx0XHRBUEJfZXJyb3JNZXNzYWdlLmNyZWF0ZUVsKCdzcGFuJywgeyB0ZXh0OiAnQVBCXyBFcnJvcjogSW52YWxpZCBudW1iZXInIH0pO1xuXG5cdFx0XHRcdFx0QVBCX2Vycm9yQ29udGFpbmVyLmFwcGVuZENoaWxkKEFQQl9lcnJvck1lc3NhZ2UpO1xuXHRcdFx0XHRcdGVsLmFwcGVuZENoaWxkKEFQQl9lcnJvckNvbnRhaW5lcik7XG5cblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0ICBcblx0XHRcdFx0Ly8gQ2FsY3VsYXRlIHRoZSB3aWR0aCBwZXJjZW50YWdlIG9mIHRoZSBwcm9ncmVzcyBiYXJcblx0XHRcdFx0Y29uc3QgcGVyY2VudGFnZSA9IChjdXJyZW50IC8gdG90YWwpICogMTAwO1xuXHRcdFxuXHRcdFx0XHQvLyBFbnN1cmUgdGhlIHdpZHRoIHBlcmNlbnRhZ2UgaXMgYmV0d2VlbiAwIGFuZCAxMDBcblx0XHRcdFx0Y29uc3QgY2xhbXBlZFBlcmNlbnRhZ2UgPSBNYXRoLm1pbihNYXRoLm1heChNYXRoLnJvdW5kKHBlcmNlbnRhZ2UpLCAwKSwgMTAwKTtcblx0XHRcblx0XHRcdFx0Y29uc3QgQVBCX2NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0XHRBUEJfY29udGFpbmVyLmFkZENsYXNzKCdwcm9ncmVzc0Jhci1jb250YWluZXInKTtcblxuXHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5BUEJfYm9yZGVyVG9nZ2xlKSB7XG5cdFx0XHRcdFx0QVBCX2NvbnRhaW5lci5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkICR7dGhpcy5zZXR0aW5ncy5BUEJfY29sb3JCb3JkZXJ9Jztcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRBUEJfY29udGFpbmVyLnN0eWxlLmJvcmRlciA9ICcwcHgnO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQVBCX2JhY2tncm91bmRUb2dnbGUpIHtcblx0XHRcdFx0XHRBUEJfY29udGFpbmVyLnN0eWxlLmJhY2tncm91bmQgPSB0aGlzLnNldHRpbmdzLkFQQl9jb2xvckJhY2tncm91bmQ7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0QVBCX2NvbnRhaW5lci5zdHlsZS5iYWNrZ3JvdW5kID0gJ3RyYW5zcGFyZW50Jztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFQQl9UZXh0IENvbnRhaW5lclxuXHRcdFx0XHRjb25zdCBBUEJfdGV4dENvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0XHRBUEJfdGV4dENvbnRhaW5lci5hZGRDbGFzcygncHJvZ3Jlc3NCYXItdGV4dC1jb250YWluZXInKTtcblxuXHRcdFx0XHQvLyBBUEJfIEJhckJhY2tncm91bmQgY29udGFpbmVyXG5cdFx0XHRcdGNvbnN0IEFQQl9iYWNrZ3JvdW5kVG9nZ2xlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRcdEFQQl9iYWNrZ3JvdW5kVG9nZ2xlLmFkZENsYXNzKCdwcm9ncmVzc0Jhci1iYWNrZ3JvdW5kJyk7XG5cdFx0XHRcdEFQQl9iYWNrZ3JvdW5kVG9nZ2xlLnN0eWxlLmJhY2tncm91bmQgPSB0aGlzLnNldHRpbmdzLkFQQl9jb2xvckJhckJhY2tncm91bmQ7XG5cblx0XHRcdFx0Ly8gQVBCX1RpdGxlXG5cdFx0XHRcdGNvbnN0IEFQQl90aXRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0XHRBUEJfdGl0bGUuYWRkQ2xhc3MoJ3Byb2dyZXNzQmFyLXRpdGxlJyk7XG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkFQQl90aXRsZVRvZ2dsZSkge1xuXHRcdFx0XHRcdEFQQl90aXRsZS5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogbGFiZWwgfSk7XG5cdFx0XHRcdFx0QVBCX3RpdGxlLnN0eWxlLmNvbG9yID0gdGhpcy5zZXR0aW5ncy5BUEJfdGl0bGVDb2xvcjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFQQl9QZXJjZW50YWdlXG5cdFx0XHRcdGNvbnN0IEFQQl9wZXJjZW50YWdlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRcdEFQQl9wZXJjZW50YWdlLmFkZENsYXNzKCdwcm9ncmVzc0Jhci1wZXJjZW50YWdlJyk7XG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkFQQl9wZXJjZW50YWdlVG9nZ2xlKSB7XG5cdFx0XHRcdFx0QVBCX3BlcmNlbnRhZ2UuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6IGNsYW1wZWRQZXJjZW50YWdlKyclJyB9KTtcblx0XHRcdFx0XHRBUEJfcGVyY2VudGFnZS5zdHlsZS5jb2xvciA9IHRoaXMuc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VDb2xvcjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFQQl9WYWx1ZVxuXHRcdFx0XHRjb25zdCBBUEJfdmFsdWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRcdFx0QVBCX3ZhbHVlLmFkZENsYXNzKCdwcm9ncmVzc0Jhci12YWx1ZScpO1xuXHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5BUEJfZnJhY3Rpb25Ub2dnbGUpIHtcblx0XHRcdFx0XHRBUEJfdmFsdWUuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICcoJytjdXJyZW50KycvJyt0b3RhbCsnKScgfSk7XG5cdFx0XHRcdFx0QVBCX3ZhbHVlLnN0eWxlLmNvbG9yID0gdGhpcy5zZXR0aW5ncy5BUEJfZnJhY3Rpb25Db2xvcjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFQQl9Db21wbGV0ZWRcblx0XHRcdFx0Y29uc3QgQVBCX2NvbXBsZXRlZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdFx0XHRBUEJfY29tcGxldGVkLmFkZENsYXNzKCdwcm9ncmVzc0Jhci1jb21wbGV0ZWQnKTtcblx0XHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQVBCX2NvbXBsZXRlZFRvZ2dsZSkge1xuXHRcdFx0XHRcdEFQQl9jb21wbGV0ZWQuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICcnIH0pO1xuXHRcdFx0XHRcdEFQQl9jb21wbGV0ZWQuc3R5bGUuY29sb3IgPSB0aGlzLnNldHRpbmdzLkFQQl9wZXJjZW50YWdlQ29sb3I7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBwcm9ncmVzc0JhclxuXHRcdFx0XHRjb25zdCBBUEIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRcdFx0QVBCLmFkZENsYXNzKCdwcm9ncmVzc0JhcicpO1xuXG5cdFx0XHRcdGNvbnN0IHByb2dyZXNzQmFyd2lkdGg6IG51bWJlciA9IHRoaXMuc2V0dGluZ3MuQVBCX3dpZHRoO1xuXHRcdFx0XHRsZXQgbnVtZXJpY1dpZHRoID0gcGFyc2VJbnQocHJvZ3Jlc3NCYXJ3aWR0aC50b1N0cmluZygpLCAxMCk7XG5cblx0XHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQVBCX3dpZHRoVG9nZ2xlKSB7XHRcdFx0XG5cdFx0XHRcdFx0QVBCX2NvbnRhaW5lci5zdHlsZS53aWR0aCA9ICcxMDAlJztcblx0XHRcdFx0XHRBUEJfYmFja2dyb3VuZFRvZ2dsZS5zdHlsZS53aWR0aCA9ICcxMDAlJztcblx0XHRcdFx0XHRBUEIuc3R5bGUud2lkdGggPSBgJHtjbGFtcGVkUGVyY2VudGFnZX0lYDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRBUEJfYmFja2dyb3VuZFRvZ2dsZS5zdHlsZS53aWR0aCA9IGAke3Byb2dyZXNzQmFyd2lkdGh9cHhgO1xuXHRcdFx0XHRcdEFQQl9jb250YWluZXIuc3R5bGUud2lkdGggPSBgJHtudW1lcmljV2lkdGggKyAxMH1weGA7XG5cdFx0XHRcdFx0QVBCLnN0eWxlLndpZHRoID0gYCR7bnVtZXJpY1dpZHRoIC8gMTAwICogY2xhbXBlZFBlcmNlbnRhZ2V9cHhgO1xuXHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XG5cdFx0XHRcdEFQQi5zdHlsZS5oZWlnaHQgPSBgJHt0aGlzLnNldHRpbmdzLkFQQl9oZWlnaHR9cHhgO1xuXHRcdFxuXHRcdFx0XHRzZXRFbmRDYXBzKEFQQl9iYWNrZ3JvdW5kVG9nZ2xlLCBBUEIsIHRoaXMuc2V0dGluZ3MuQVBCX2VuZGNhcFRvZ2dsZSk7XG5cdFx0XHRcdEFQQl9iYWNrZ3JvdW5kVG9nZ2xlLmFwcGVuZENoaWxkKEFQQik7XG5cdFx0XG5cdFx0XHRcdGNvbnN0IG1hcmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRcdG1hcmtzLmFkZENsYXNzKCdtYXJrcycpO1x0XHRcdFxuXHRcdFxuXHRcdFx0XHRjb25zdCBudW1iZXJPZlNlY3Rpb25zID0gcGFyc2VJbnQodGhpcy5zZXR0aW5ncy5BUEJfY29sb3JudW1iZXIucmVwbGFjZSgvXFxEL2csICcnKSk7XG5cblx0XHRcdFx0Ly8gY3JlYXRlIHJlcXVpcmVkIG51bWJlciBvZiBzZWN0aW9uIG1hcmtzIGlmIE5PVCBjb21wbGV0ZWRcblx0XHRcdFx0aWYgKGNsYW1wZWRQZXJjZW50YWdlICE9PSAxMDApIHtcblx0XHRcdFx0XHRBUEJfYmFja2dyb3VuZFRvZ2dsZS5hcHBlbmRDaGlsZChtYXJrcyk7XG5cblx0XHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5BUEJfbWFya3NUb2dnbGUpIHtcdFx0XHRcblx0XHRcdFx0XHRcdGZvciAobGV0IGkgPSAxOyBpIDw9IChudW1iZXJPZlNlY3Rpb25zIC0gMSk7IGkrKykge1x0XHRcdFxuXHRcdFx0XHRcdFx0XHRjb25zdCBtYXJrID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cdFx0XHRcdFx0XHRcdG1hcmsuYWRkQ2xhc3MoJ21hcmsnKTtcblx0XHRcdFx0XHRcdFx0bWFyay5zdHlsZS5sZWZ0ID0gYCR7KGkgKiAoMTAwL251bWJlck9mU2VjdGlvbnMpKX0lYDtcblx0XHRcdFx0XHRcdFx0bWFya3MuYXBwZW5kQ2hpbGQobWFyayk7XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFxuXHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGRwciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7IC8vIEdldCB0aGUgZGV2aWNlIHBpeGVsIHJhdGlvXG5cdFx0XHRcdFx0XHRcdGNvbnN0IGFkanVzdGVkQm9yZGVyV2lkdGggPSB0aGlzLnNldHRpbmdzLkFQQl9tYXJrc1dpZHRoIC8gZHByOyAvLyB1c2UgRFBJIHRvIGNyZWF0ZSBjb3JyZWN0IHBpeGVsIHdpZHRoIFxuXG5cdFx0XHRcdFx0XHRcdFxuXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHJnYmFDb2xvciA9IGhleFRvUmdiYSh0aGlzLnNldHRpbmdzLkFQQl9tYXJrc0NvbG9yLCAwLjUpO1xuXHRcdFx0XHRcdFx0XHRtYXJrLnN0eWxlLmJvcmRlckxlZnQgPSBhZGp1c3RlZEJvcmRlcldpZHRoICsgJ3B4IHNvbGlkICcgKyByZ2JhQ29sb3I7XHRcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRBUEIuYXBwZW5kQ2hpbGQoQVBCX2NvbXBsZXRlZCk7XG5cblx0XHRcdFx0Ly8gbG9vcCB0byBzZXQgY29ycmVjdCBwcm9ncmVzcyBiYXIgY29sb3Jcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDE7IGkgPD0gbnVtYmVyT2ZTZWN0aW9uczsgaSsrKSB7XG5cdFx0XHRcdFx0bGV0IHNlY3Rpb25zaXplID0gYCR7KGkgKiAoMTAwL251bWJlck9mU2VjdGlvbnMpKX0lYDtcblx0XHRcdFx0XHRcblx0XHRcdFx0XHRjb25zdCBtYXJrTGVmdFZhbHVlID0gcGFyc2VGbG9hdChzZWN0aW9uc2l6ZSk7XG5cdFx0XHRcdFx0XG5cdFx0XHRcdFx0aWYgKChjbGFtcGVkUGVyY2VudGFnZSA8PSBtYXJrTGVmdFZhbHVlKSAmJiB0aGlzLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhckNoYW5nZSkge1xuXHRcdFx0XHRcdFx0QVBCLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFN0cmluZyh0aGlzLnNldHRpbmdzW2BBUEJfY29sb3Ike2l9YCBhcyBrZXlvZiBPYnNpZGlhblByb2dyZXNzQmFyc1NldHRpbmdzXSk7XG5cdFxuXHRcdFx0XHRcdFx0aWYgKGNsYW1wZWRQZXJjZW50YWdlID09IDEwMCkge1xuXHRcdFx0XHRcdFx0XHRBUEIuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5zZXR0aW5ncy5BUEJfY29sb3JCYXJDb21wbGV0ZWQ7XG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRUb2dnbGUpIHtcblx0XHRcdFx0XHRcdFx0XHRBUEJfY29tcGxldGVkLnRleHRDb250ZW50ID0nQ09NUExFVEVEJztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0dGhpcy5zZXR0aW5ncy5BUEJfcHJvZ3Jlc3NCYXJDaGFuZ2UgPSBmYWxzZTtcblx0XHRcdFx0XHRcdHRoaXMuc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5zZXR0aW5ncy5BUEJfcHJvZ3Jlc3NCYXJDaGFuZ2UgPSB0cnVlO1xuXG5cdFx0XHRcdEFQQl9jb250YWluZXIuYXBwZW5kQ2hpbGQoQVBCX3RleHRDb250YWluZXIpO1xuXHRcdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLkFQQl90aXRsZVRvZ2dsZSkge1xuXHRcdFx0XHRcdFx0QVBCX3RleHRDb250YWluZXIuYXBwZW5kQ2hpbGQoQVBCX3RpdGxlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VUb2dnbGUpIHtcblx0XHRcdFx0XHRcdEFQQl90ZXh0Q29udGFpbmVyLmFwcGVuZENoaWxkKEFQQl9wZXJjZW50YWdlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuQVBCX2ZyYWN0aW9uVG9nZ2xlKSB7XG5cdFx0XHRcdFx0XHRBUEJfdGV4dENvbnRhaW5lci5hcHBlbmRDaGlsZChBUEJfdmFsdWUpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRBUEJfY29udGFpbmVyLmFwcGVuZENoaWxkKEFQQl9iYWNrZ3JvdW5kVG9nZ2xlKTtcblxuXHRcdFx0XHRlbC5hcHBlbmRDaGlsZChBUEJfY29udGFpbmVyKTtcblx0XHQgIH0pO1xuXHRcdH0pO1xuXG5cdFx0Ly8gUmVnaXN0ZXIgYSBjdXN0b20gY29tbWFuZCB0byBwYXN0ZSB0ZXh0XG4gICAgICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICAgICAgICBpZDogJ3Bhc3RlLWNvZGUtYmxvY2snLFxuICAgICAgICAgICAgbmFtZTogJ1Bhc3RlIENvZGUgQmxvY2snLFxuXG5cdFx0XHRlZGl0b3JDYWxsYmFjazogYXN5bmMgKGVkaXRvciwgdmlldykgPT4ge1xuXHRcdFx0XHRlZGl0b3IuZm9jdXMoKTtcblx0XHRcdFx0Ly8gRW5zdXJlIGVkaXRvciBpcyB2YWxpZFxuXHRcdFx0XHRpZiAoIWVkaXRvcikge1xuXHRcdFx0XHQgIG5ldyBOb3RpY2UoXCJObyBhY3RpdmUgZWRpdG9yIGZvdW5kIVwiKTtcblx0XHRcdFx0ICByZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdC8vIENvbnN0cnVjdCB0aGUgY29kZSBibG9jayB0ZXh0XG5cdFx0XHRcdGNvbnN0IHZhbHVlRnJvbVBlcmNlbnRhZ2VPZlRvdGFsID0gTWF0aC5mbG9vcigodGhpcy5zZXR0aW5ncy5BUEJfdG90YWwvMTAwKSAqIHRoaXMuc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSk7XG5cdFx0XHRcdGNvbnN0IGNvZGVCbG9ja1RleHQgPSBgXFxgXFxgXFxgb2JzaWRpYW4tYXBiXFxuJHt0aGlzLnNldHRpbmdzLkFQQl90aXRsZX06ICR7dmFsdWVGcm9tUGVyY2VudGFnZU9mVG90YWx9LyR7dGhpcy5zZXR0aW5ncy5BUEJfdG90YWx9XFxuXFxgXFxgXFxgYDtcblx0XHRcblx0XHRcdFx0Ly8gR2V0IHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvblxuXHRcdFx0XHRjb25zdCBjdXJzb3IgPSBlZGl0b3IuZ2V0Q3Vyc29yKCk7XG5cdFx0XG5cdFx0XHRcdC8vIEluc2VydCB0aGUgY29kZSBibG9jayB0ZXh0IGF0IHRoZSBjdXJzb3IgcG9zaXRpb25cblx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VSYW5nZShjb2RlQmxvY2tUZXh0LCBjdXJzb3IpO1xuXHRcdFxuXHRcdFx0XHQvLyBDYWxjdWxhdGUgdGhlIG5ldyBjdXJzb3IgcG9zaXRpb25cblx0XHRcdFx0Y29uc3QgbGluZXMgPSBjb2RlQmxvY2tUZXh0LnNwbGl0KCdcXG4nKTtcblx0XHRcdFx0Y29uc3QgbmV3Q3Vyc29yID0ge1xuXHRcdFx0XHRcdGxpbmU6IGN1cnNvci5saW5lICsgbGluZXMubGVuZ3RoIC0gMSxcblx0XHRcdFx0XHRjaDogbGluZXNbbGluZXMubGVuZ3RoIC0gMV0ubGVuZ3RoIC8vIExlbmd0aCBvZiB0aGUgbGFzdCBsaW5lXG5cdFx0XHRcdH07XG5cblx0XHRcdFx0Ly8gRW5zdXJlIHRoZSBjdXJzb3IgbW92ZXMgYWZ0ZXIgdGhlIGluc2VydGlvblxuXHRcdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0XHRlZGl0b3Iuc2V0Q3Vyc29yKG5ld0N1cnNvcik7XG5cdFx0XHRcdFx0ZWRpdG9yLnJlZnJlc2goKTtcblx0XHRcdFx0fSwgMCk7IC8vIFplcm8tZGVsYXkgdGltZW91dCBlbnN1cmVzIHRoaXMgcnVucyBhZnRlciBET00gdXBkYXRlc1xuXHRcdFx0fSxcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XG5cdCAgXHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcblx0fVxuXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcblx0ICBcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XG5cdH1cblxuXHRhc3luYyBvbnVubG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBDaGVjayB0aGlzIG1ldGhvZCBpcyBiZWluZyB0cmlnZ2VyZWRcblx0XHRjb25zb2xlLmxvZygnQ2xlYW5pbmcgdXAgcmVzb3VyY2VzIHdoZW4gcGx1Z2luIHVubG9hZHMuLi4nKTtcblxuXHRcdC8vIENoZWNrIGlmIHRoZSBidXR0b24gc3RpbGwgZXhpc3RzIGluIHRoZSBET01cblx0XHRjb25zdCBjb3B5QnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYnV0dG9uJyk7XG5cdFx0aWYgKGNvcHlCdXR0b24pIHtcblx0XHRcdGNvbnNvbGUubG9nKCdGb3VuZCB0aGUgY29weUJ1dHRvbiBpbiB0aGUgRE9NLicpO1xuXG5cdFx0XHQvLyBSZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyIHRvIGNsZWFuIHVwIHJlc291cmNlc1xuXHRcdFx0Y29weUJ1dHRvbi5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuY29weUJ1dHRvbkxpc3RlbmVyKTtcblx0XHRcdGNvbnNvbGUubG9nKCdFdmVudCBsaXN0ZW5lciByZW1vdmVkLicpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zb2xlLmxvZygnTm8gY29weUJ1dHRvbiBmb3VuZCBpbiB0aGUgRE9NLicpO1xuXHRcdH1cblx0fVxuXG59XG5cbi8vIENyZWF0ZSBTZXR0aW5ncyBUYWIgQ29udGVudFxuY2xhc3MgT2JzaWRpYW5Qcm9ncmVzc0JhcnNTZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG5cdHBsdWdpbjogT2JzaWRpYW5Qcm9ncmVzc0JhcnM7XG5cblx0Ly8gRXhwbGljaXRseSBkZWZpbmUgdGhlIHR5cGUgb2YgdGhlIGV2ZW50IGxpc3RlbmVyXG4gICAgcHJpdmF0ZSBjb3B5QnV0dG9uTGlzdGVuZXI6IChldmVudDogTW91c2VFdmVudCkgPT4gdm9pZDtcblxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBPYnNpZGlhblByb2dyZXNzQmFycykge1xuXHRcdHN1cGVyKGFwcCwgcGx1Z2luKTtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblx0fVxuXG5cdGFzeW5jIGRpc3BsYXkoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpc1xuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cblx0XHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDMnLCB7IHRleHQ6ICdBZHZhbmNlZCBQcm9ncmVzcyBCYXJzJyB9KTtcblxuXHRcdGNvbnN0IHBhcmFncmFwaCA9IGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnSWYgeW91IGZpbmQgdmFsdWUgaW4gdGhpcyBwbHVnaW4gYW5kIHdvdWxkIGxpa2UgdG8gc3VwcG9ydCB1cywgcGxlYXNlIGNvbnNpZGVyIHVzaW5nIG91ciAnIH0pO1xuXG5cdFx0cGFyYWdyYXBoLmNyZWF0ZUVsKCdhJywge1xuXHRcdFx0aHJlZjogJ2h0dHBzOi8va28tZmkuY29tL2NhY3R1emhlYWQnLFxuXHRcdFx0dGV4dDogJ2tvLWZpJyxcblx0XHRcdGNsczogJ2N1c3RvbS1saW5rJ1xuXHRcdH0pO1xuXG5cdFx0Y29uc3QgY29udGFpbmVyID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdGNvbnRhaW5lci5hZGRDbGFzcygnY3VzdG9tLWNvbnRhaW5lcicpO1xuXHRcdGNvbnRhaW5lci5hcHBlbmRDaGlsZChwYXJhZ3JhcGgpO1xuXG5cdFx0Ly8gQ3JlYXRlIEtvLUZpIGxpbmtcblx0XHRjb25zdCBrb0ZpTGluayA9IGNvbnRhaW5lci5jcmVhdGVFbCgnYScpO1xuXHRcdGtvRmlMaW5rLmhyZWYgPSAnaHR0cHM6Ly9rby1maS5jb20vY2FjdHV6aGVhZCc7XG5cdFx0a29GaUxpbmsudGFyZ2V0ID0gJ19ibGFuayc7XG5cblx0XHQvLyBLby1GaSBsb2dvXG5cdFx0Y29uc3Qga29GaUltYWdlID0ga29GaUxpbmsuY3JlYXRlRWwoJ2ltZycpO1xuXHRcdGtvRmlJbWFnZS5zZXRBdHRyaWJ1dGUoJ3NyYycsICdodHRwczovL3N0b3JhZ2Uua28tZmkuY29tL2Nkbi9mdWxsTG9nb0tvZmkucG5nJyk7XG5cdFx0a29GaUltYWdlLnNldEF0dHJpYnV0ZSgnYWx0JywgJ1N1cHBvcnQgdXMgb24gS28tZmknKTtcblxuXHRcdC8vIFN0eWxlIHRoZSBpbWFnZSBsaW5rXG5cdFx0a29GaUltYWdlLnN0eWxlLndpZHRoID0gJzEwMHB4Jztcblx0XHRrb0ZpSW1hZ2Uuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xuXHRcdGtvRmlMaW5rLnN0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJztcblx0XHRrb0ZpTGluay5zdHlsZS5tYXJnaW5MZWZ0ID0gJzEwcHgnO1xuXG5cdFx0LyoqKioqKioqKioqKiBVc2FnZSBFeGFtcGxlIENvZGUgQmxvY2sgKioqKioqKioqKioqKi9cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdVc2FnZSBFeGFtcGxlIENvZGUgQmxvY2snKVxuXHRcdFx0LnNldERlc2MoY3JlYXRlRnJhZ21lbnQoKGZyYWcpID0+IHtcblx0XHRcdGZyYWcuYXBwZW5kVGV4dCgnVXNlIHRoaXMgY29kZSBibG9jayBhbmQgZWRpdCB0aGUgJyk7XG5cblx0XHRcdGNvbnN0IGN1c3RvbUVsZW1lbnQgPSBmcmFnLmNyZWF0ZUVsKCdzcGFuJyk7XG5cdFx0XHRjdXN0b21FbGVtZW50LnNldFRleHQoJ1RpdGxlOiBWYWx1ZS9Ub3RhbCcpO1xuXHRcdFx0Y3VzdG9tRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdoaWdobGlnaHQtdGV4dCcpO1xuXG5cdFx0XHRmcmFnLmFwcGVuZFRleHQoJyBhcyBuZWVkZWQuJyk7XG5cdFx0XHRmcmFnLmNyZWF0ZUVsKCdicicpO1xuXHRcdFx0ZnJhZy5hcHBlbmRUZXh0KCdJZiB5b3UgcmVxdWlyZSBtb3JlIHRoYW4gb25lIGJhciwgc2ltcGx5IGNyZWF0ZSBhZGRpdGlvbmFsICcpO1xuXG5cdFx0XHRjb25zdCBjdXN0b21FbGVtZW50MiA9IGZyYWcuY3JlYXRlRWwoJ3NwYW4nKTtcblx0XHRcdGN1c3RvbUVsZW1lbnQyLnNldFRleHQoJ1RpdGxlOiBWYWx1ZS9Ub3RhbCcpO1xuXHRcdFx0Y3VzdG9tRWxlbWVudDIuY2xhc3NMaXN0LmFkZCgnaGlnaGxpZ2h0LXRleHQnKTtcblxuXHRcdFx0ZnJhZy5hcHBlbmRUZXh0KCcgbGluZXMgd2l0aGluIHRoZSBjb2RlIGJsb2NrLicpO1xuXHRcdFx0ZnJhZy5jcmVhdGVFbCgnYnInKTtcblx0XHRcdGZyYWcuYXBwZW5kVGV4dCgnTm90ZTogJyk7XG5cblx0XHRcdGNvbnN0IGN1c3RvbUVsZW1lbnQzID0gZnJhZy5jcmVhdGVFbCgnc3BhbicpO1xuXHRcdFx0Y3VzdG9tRWxlbWVudDMuc2V0VGV4dCgnVG90YWwnKTtcblx0XHRcdGN1c3RvbUVsZW1lbnQzLmNsYXNzTGlzdC5hZGQoJ2hpZ2hsaWdodC10ZXh0Jyk7XG5cblx0XHRcdGZyYWcuYXBwZW5kVGV4dCgnIGRvZXMgbm90IG5lZWQgdG8gYmUgMTAwLicpO1xuXHRcdFx0ZnJhZy5jcmVhdGVFbCgnYnInKTtcblx0XHRcdGZyYWcuYXBwZW5kVGV4dCgnVmlzaXQgJyk7XG5cblx0XHRcdGZyYWcuY3JlYXRlRWwoJ2EnLCB7XG5cdFx0XHRcdGhyZWY6ICdodHRwczovL2NhY3R1emhlYWQuZ2l0aHViLmlvL0FkdmFuY2VkLVByb2dyZXNzLUJhcnMvJyxcblx0XHRcdFx0dGV4dDogJ2NhY3R1emhlYWQnLFxuXHRcdFx0XHRjbHM6ICdjdXN0b20tbGluaydcblx0XHRcdH0pO1xuXG5cdFx0XHRmcmFnLmFwcGVuZFRleHQoJyBmb3IgbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbi4nKTtcblx0XHR9KSlcblxuICAgIC5hZGRUZXh0QXJlYSgodGV4dEFyZWEpID0+IHtcblx0XHRjb25zdCB2YWx1ZUZyb21QZXJjZW50YWdlT2ZUb3RhbCA9IE1hdGguZmxvb3IoKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90b3RhbC8xMDApICogdGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSk7XG5cdFx0dGV4dEFyZWEuc2V0VmFsdWUoYFxcYFxcYFxcYG9ic2lkaWFuLWFwYlxcbiR7dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RpdGxlfTogJHt2YWx1ZUZyb21QZXJjZW50YWdlT2ZUb3RhbH0vJHt0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfdG90YWx9XFxuXFxgXFxgXFxgYCk7XG5cbiAgICAgICAgdGV4dEFyZWEuaW5wdXRFbC5zdHlsZS5oZWlnaHQgPSAnODBweCc7XG4gICAgICAgIHRleHRBcmVhLmlucHV0RWwuc3R5bGUud2lkdGggPSAnMjAwcHgnO1xuICAgICAgICB0ZXh0QXJlYS5pbnB1dEVsLnN0eWxlLnJlc2l6ZSA9ICdub25lJztcblxuXHRcdGNvbnN0IGNvbnRhaW5lciA9IHRleHRBcmVhLmlucHV0RWwucGFyZW50RWxlbWVudDtcblx0XHQvLyBjaGVjayBjb250YWluZXIgZXhpc3RzIGJlZm9yZSBhcHBlbmRpbmcgdGhlIGJ1dHRvblxuXHRcdGlmIChjb250YWluZXIpIHtcblx0XHRcdC8vIEV4YW1wbGUgZm9yIGFkZGluZyB0aGUgY29weSBidXR0b24gYW5kIHRleHQgYXJlYSB0byB0aGUgc2V0dGluZ3Ncblx0XHRcdGNvbnN0IGNvcHlCdXR0b24gPSBjb250YWluZXJFbC5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnQ29weSB0byBDbGlwYm9hcmQnIH0pO1xuXG5cdFx0XHQvLyBTdG9yZSB0aGUgY2xpY2sgZXZlbnQgbGlzdGVuZXIgaW4gYSBjbGFzcyBwcm9wZXJ0eVxuXHRcdFx0dGhpcy5jb3B5QnV0dG9uTGlzdGVuZXIgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcblx0XHRcdFx0bmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodGV4dEFyZWEuaW5wdXRFbC52YWx1ZSlcblx0XHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdDb250ZW50IGNvcGllZCB0byBjbGlwYm9hcmQhJyk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuY2F0Y2goKGVycikgPT4ge1xuXHRcdFx0XHRcdFx0bmV3IE5vdGljZSgnRmFpbGVkIHRvIGNvcHkgY29udGVudDogJyArIGVycik7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBBZGQgdGhlIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBidXR0b25cblx0XHRcdGNvcHlCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLmNvcHlCdXR0b25MaXN0ZW5lcik7XG5cblx0XHRcdGNvcHlCdXR0b24uc3R5bGUubWFyZ2luVG9wID0gJzEwcHgnO1xuXHRcdFx0Y29weUJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0XHRcdGNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ2ZsZXgnO1xuICAgICAgICBcdGNvbnRhaW5lci5zdHlsZS5mbGV4RGlyZWN0aW9uID0gJ2NvbHVtbic7XG5cdH0gZWxzZSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKCdVbmFibGUgdG8gZmluZCB0aGUgcGFyZW50IGNvbnRhaW5lciBmb3IgdGhlIHRleHRhcmVhJyk7XG5cdFx0fVxuXHR9KTtcblxuXHQvKioqKioqKioqKioqIFNFQ1RJT04gTGlnaHQgJiBEYXJrIFNldHRpbmdzICoqKioqKioqKioqKiovXG5cdCBjb250YWluZXJFbC5jcmVhdGVFbCgnaDQnLCB7IHRleHQ6ICdMaWdodCAmIERhcmsnIH0pO1xuXG5cdC8qKioqKioqKioqKiogTGlnaHQgJiBEYXJrIFF1aWNrIEFwcGx5ICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdBcHBseSBhbGwgTGlnaHQgJiBEYXJrIGNvbG9yIGRlZmF1bHRzJylcblx0XHQuc2V0RGVzYyhjcmVhdGVGcmFnbWVudCgoZnJhZykgPT4ge1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCdUaGVzZSB0d28gb3B0aW9ucyAnKTtcbiAgICAgICAgICAgIGZyYWcuY3JlYXRlRWwoJ3NwYW4nLCB7XG4gICAgICAgICAgICAgICAgdGV4dDogJyhMaWdodCAmIERhcmspJyxcblx0XHRcdFx0Y2xzOiAnaGlnaGxpZ2h0LXRleHQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnIHdpbGwgY2hhbmdlIEFMTCB0aGUgY29sb3Igc2V0dGluZ3MgYmVsb3cgdG8gdGhlaXIgcmVzcGVjdGl2ZSBkZWZhdWx0cy4gKEFsbCBvdGhlciBzZXR0aW5ncyB3aWxsIHJlbWFpbiB1bmNoYW5nZWQpLicpO1xuXHRcdFx0ZnJhZy5jcmVhdGVFbCgnYnInKTtcblx0XHRcdGZyYWcuYXBwZW5kVGV4dCgnIE5vdGU6IG9uY2Ugc2VsZWN0ZWQsIGFsbCBwcmV2aW91cyBjb2xvcnMgd2lsbCBiZSBsb3N0IGZvcmV2ZXIgYW5kIGNhbiBub3QgYmUgcmV0cmlldmVkLicpO1xuXG5cdFx0fSkpXG5cdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignc3VuJykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gTGlnaHQgZGVmYXVsdCcpXHRcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcdFx0XHRcdFxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfbWFya3NDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX21hcmtzTGlnaHRDb2xvciBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZUNvbG9yID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfdGl0bGVMaWdodENvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX3BlcmNlbnRhZ2VMaWdodENvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2ZyYWN0aW9uQ29sb3IgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9mcmFjdGlvbkxpZ2h0Q29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCb3JkZXIgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckxpZ2h0Qm9yZGVyIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yQmFja2dyb3VuZCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yTGlnaHRCYWNrZ3JvdW5kIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yQmFyQ29tcGxldGVkID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3JMaWdodEJhckNvbXBsZXRlZCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhckJhY2tncm91bmQgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckxpZ2h0QmFyQmFja2dyb3VuZCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbXBsZXRlZExpZ2h0Q29sb3IgYXMgc3RyaW5nO1xuXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjEgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjFMaWdodCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjIgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjJMaWdodCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjMgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjNMaWdodCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjQgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjRMaWdodCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjUgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjVMaWdodCBhcyBzdHJpbmc7XG5cblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ21vb24nKS5zZXRUb29sdGlwKCdSZXNldCB0byBEYXJrIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfbWFya3NDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX21hcmtzQ29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCb3JkZXIgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckJvcmRlciBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZUNvbG9yID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfdGl0bGVDb2xvciBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wZXJjZW50YWdlQ29sb3IgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9wZXJjZW50YWdlQ29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZnJhY3Rpb25Db2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2ZyYWN0aW9uQ29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCb3JkZXIgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckJvcmRlciBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhY2tncm91bmQgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckJhY2tncm91bmQgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYXJDb21wbGV0ZWQgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckJhckNvbXBsZXRlZCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhckJhY2tncm91bmQgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckJhckJhY2tncm91bmQgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29tcGxldGVkQ29sb3IgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb21wbGV0ZWRDb2xvciBhcyBzdHJpbmc7XG5cblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yMSA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yMSBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjIgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjIgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3IzID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3IzIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yNCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yNCBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjUgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjUgYXMgc3RyaW5nO1xuXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIFNFQ1RJT04gcHJvZ3Jlc3MgUHJvZ3Jlc3MgQmFyICoqKioqKioqKioqKiovXG5cdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoNCcsIHsgdGV4dDogJ0RlbW9uc3RyYXRpb24gUHJvZ3Jlc3MgQmFyJyB9KTtcblxuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0RGVzYygnQW55IGNoYW5nZXMgeW91IG1ha2UgdG8gdGhpcyBzZXR0aW5ncyBwYWdlIHdpbGwgYmUgaW5zdGFudGx5IHJlZmxlY3RlZCBpbiB0aGUgZGVtb25zdHJhdGlvbiBwcm9ncmVzcyBiYXIgYmVsb3cuICBVc2UgaXQgYXMgYSBndWlkZSB3aGVuIG1ha2luZyB5b3VyIGRlY2lzaW9ucy4nKVxuXG5cdFx0LyoqKioqKioqKioqKiBEZW1vIFByb2dyZXNzIEJhciAqKioqKioqKioqKioqL1xuXHRcdGNvbnN0IHByb2dyZXNzQmFyQ29udGFpbmVyID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdHByb2dyZXNzQmFyQ29udGFpbmVyLmFkZENsYXNzKCdwcm9ncmVzc0Jhci1jb250YWluZXInKTtcblxuXHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfYm9yZGVyVG9nZ2xlKSB7XG5cdFx0XHRwcm9ncmVzc0JhckNvbnRhaW5lci5zdHlsZS5ib3JkZXIgPSAnMXB4IHNvbGlkJysgdGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yQm9yZGVyO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9ncmVzc0JhckNvbnRhaW5lci5zdHlsZS5ib3JkZXIgPSAnMHB4Jztcblx0XHR9XG5cblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2JhY2tncm91bmRUb2dnbGUpIHtcblx0XHRcdHByb2dyZXNzQmFyQ29udGFpbmVyLnN0eWxlLmJhY2tncm91bmQgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYWNrZ3JvdW5kO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9ncmVzc0JhckNvbnRhaW5lci5zdHlsZS5iYWNrZ3JvdW5kID0gJ3RyYW5zcGFyZW50Jztcblx0XHR9XG5cblx0XHQvLyBEZW1vQmFyIFRleHQgQ29udGFpbmVyXG5cdFx0Y29uc3QgcHJvZ3Jlc3NCYXJUZXh0Q29udGFpbmVyID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdHByb2dyZXNzQmFyVGV4dENvbnRhaW5lci5hZGRDbGFzcygncHJvZ3Jlc3NCYXItdGV4dC1jb250YWluZXInKTtcblxuXHRcdC8vIERlbW9CYXIgQmFyQmFja2dyb3VuZCBjb250YWluZXJcblx0XHRjb25zdCBwcm9ncmVzc0JhckJhY2tncm91bmQgPSBjb250YWluZXJFbC5jcmVhdGVFbCgnZGl2Jyk7XG5cdFx0cHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kLmFkZENsYXNzKCdwcm9ncmVzc0Jhci1iYWNrZ3JvdW5kJyk7XG5cdFx0cHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kLnN0eWxlLmJhY2tncm91bmQgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYXJCYWNrZ3JvdW5kO1xuXG5cdFx0Ly8gRGVtb0JhciBUaXRsZVxuXHRcdGNvbnN0IHByb2dyZXNzQmFyVGl0bGUgPSBjb250YWluZXJFbC5jcmVhdGVFbCgnZGl2Jyk7XG5cdFx0cHJvZ3Jlc3NCYXJUaXRsZS5hZGRDbGFzcygncHJvZ3Jlc3NCYXItdGl0bGUnKTtcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RpdGxlVG9nZ2xlKSB7XG5cdFx0XHRwcm9ncmVzc0JhclRpdGxlLmNyZWF0ZUVsKCdzcGFuJywgeyB0ZXh0OiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfdGl0bGUgfSk7XG5cdFx0XHRwcm9ncmVzc0JhclRpdGxlLnN0eWxlLmNvbG9yID0gdGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RpdGxlQ29sb3I7XG5cdFx0fVxuXG5cdFx0Ly8gRGVtb0JhciBQZXJjZW50YWdlXG5cdFx0Y29uc3QgcHJvZ3Jlc3NCYXJQZXJjZW50YWdlID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdHByb2dyZXNzQmFyUGVyY2VudGFnZS5hZGRDbGFzcygncHJvZ3Jlc3NCYXItcGVyY2VudGFnZScpO1xuXHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcGVyY2VudGFnZVRvZ2dsZSkge1xuXHRcdFx0cHJvZ3Jlc3NCYXJQZXJjZW50YWdlLmNyZWF0ZUVsKCdzcGFuJywgeyB0ZXh0OiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcHJvZ3Jlc3NCYXJQZXJjZW50YWdlKyclJyB9KTtcblx0XHRcdHByb2dyZXNzQmFyUGVyY2VudGFnZS5zdHlsZS5jb2xvciA9IHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wZXJjZW50YWdlQ29sb3I7XG5cdFx0fVxuXG5cdFx0Ly8gRGVtb0JhciBWYWx1ZVxuXHRcdGNvbnN0IHByb2dyZXNzQmFyVmFsdWUgPSBjb250YWluZXJFbC5jcmVhdGVFbCgnZGl2Jyk7XG5cdFx0cHJvZ3Jlc3NCYXJWYWx1ZS5hZGRDbGFzcygncHJvZ3Jlc3NCYXItdmFsdWUnKTtcblx0XHRjb25zdCB2YWx1ZUZyb21QZXJjZW50YWdlT2ZUb3RhbCA9IE1hdGguZmxvb3IoKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90b3RhbC8xMDApICogdGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSk7XG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9mcmFjdGlvblRvZ2dsZSkge1xuXHRcdFx0cHJvZ3Jlc3NCYXJWYWx1ZS5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJygnK3ZhbHVlRnJvbVBlcmNlbnRhZ2VPZlRvdGFsKycvJyt0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfdG90YWwrJyknIH0pO1xuXHRcdFx0cHJvZ3Jlc3NCYXJWYWx1ZS5zdHlsZS5jb2xvciA9IHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9mcmFjdGlvbkNvbG9yO1xuXHRcdH1cblxuXHRcdC8vIERlbW9CYXIgQ29tcGxldGVkXG5cdFx0Y29uc3QgY29tcGxldGVkID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdGNvbXBsZXRlZC5hZGRDbGFzcygncHJvZ3Jlc3NCYXItY29tcGxldGVkJyk7XG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRUb2dnbGUpIHtcblx0XHRcdGNvbXBsZXRlZC5zdHlsZS5jb2xvciA9IHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRDb2xvcjtcblxuXHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhclBlcmNlbnRhZ2UgPT0gMTAwKSB7XG5cdFx0XHRcdGNvbXBsZXRlZC50ZXh0Q29udGVudCA9ICdDT01QTEVURUQnO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIERlbW9CYXJcblx0XHRjb25zdCBwcm9ncmVzc2JhciA9IGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdkaXYnKTtcblx0XHRwcm9ncmVzc2Jhci5hZGRDbGFzcygncHJvZ3Jlc3NCYXInKTtcblxuXHRcdGNvbnN0IHByb2dyZXNzQmFyd2lkdGg6IG51bWJlciA9IHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl93aWR0aDtcblx0XHRsZXQgbnVtZXJpY1dpZHRoID0gcGFyc2VJbnQocHJvZ3Jlc3NCYXJ3aWR0aC50b1N0cmluZygpLCAxMCk7XG5cblx0XHQvLyBFbnN1cmUgdGhlIHdpZHRoIHBlcmNlbnRhZ2UgaXMgYmV0d2VlbiAwIGFuZCAxMDBcblx0XHRjb25zdCBjbGFtcGVkUGVyY2VudGFnZSA9IE1hdGgubWluKE1hdGgubWF4KE1hdGgucm91bmQodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSksIDApLCAxMDApO1xuXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl93aWR0aFRvZ2dsZSkge1xuXHRcdFx0cHJvZ3Jlc3NCYXJDb250YWluZXIuc3R5bGUud2lkdGggPSAnMTAwJSc7XG5cdFx0XHRwcm9ncmVzc0JhckJhY2tncm91bmQuc3R5bGUud2lkdGggPSAnMTAwJSc7XG5cdFx0XHRwcm9ncmVzc2Jhci5zdHlsZS53aWR0aCA9IGAke2NsYW1wZWRQZXJjZW50YWdlfSVgO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9ncmVzc0JhckNvbnRhaW5lci5zdHlsZS53aWR0aCA9IGAke251bWVyaWNXaWR0aH1weGA7XG5cdFx0XHRwcm9ncmVzc0JhckJhY2tncm91bmQuc3R5bGUud2lkdGggPSBgJHtTdHJpbmcobnVtZXJpY1dpZHRoIC0gMTIpfXB4YDsgLy8gLTEyIGZvciA1cHggcGFkZGluZyBhbmQgZm9yIDFweCBib3JkZXJcblx0XHRcdHByb2dyZXNzYmFyLnN0eWxlLndpZHRoID0gYCR7KChudW1lcmljV2lkdGggLSAxMikgLyAxMDAgKiBjbGFtcGVkUGVyY2VudGFnZSl9cHhgOyAvLyAtMTIgZm9yIDVweCBwYWRkaW5nIGFuZCBmb3IgMXB4IGJvcmRlclxuXHRcdH1cblxuXHRcdHByb2dyZXNzQmFyQ29udGFpbmVyLnN0eWxlLm1hcmdpbiA9ICcxN3B4JztcblxuXHRcdHByb2dyZXNzYmFyLnN0eWxlLmhlaWdodCA9IGAke3RoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9oZWlnaHR9cHhgO1xuXG5cdFx0c2V0RW5kQ2Fwcyhwcm9ncmVzc0JhckJhY2tncm91bmQsIHByb2dyZXNzYmFyLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZW5kY2FwVG9nZ2xlKTtcblx0XHRwcm9ncmVzc0JhckJhY2tncm91bmQuYXBwZW5kQ2hpbGQocHJvZ3Jlc3NiYXIpO1xuXG5cdFx0cHJvZ3Jlc3NiYXIuYXBwZW5kQ2hpbGQoY29tcGxldGVkKTtcblxuXHRcdGNvbnN0IG1hcmtzID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdG1hcmtzLmFkZENsYXNzKCdtYXJrcycpO1xuXG5cdFx0Y29uc3QgbnVtYmVyT2ZTZWN0aW9ucyA9IHBhcnNlSW50KHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcm51bWJlci5yZXBsYWNlKC9cXEQvZywgJycpKTtcblxuXHRcdC8vIGNyZWF0ZSByZXF1aXJlZCBudW1iZXIgb2Ygc2VjdGlvbiBtYXJrcyBpZiBOT1QgY29tcGxldGVkXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhclBlcmNlbnRhZ2UgIT09IDEwMCkge1xuXHRcdFx0cHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kLmFwcGVuZENoaWxkKG1hcmtzKTtcblxuXHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc1RvZ2dsZSkge1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMTsgaSA8PSAobnVtYmVyT2ZTZWN0aW9ucyAtIDEpOyBpKyspIHtcblx0XHRcdFx0XHRjb25zdCBtYXJrID0gY29udGFpbmVyRWwuY3JlYXRlRWwoJ2RpdicpO1xuXHRcdFx0XHRcdG1hcmsuYWRkQ2xhc3MoJ21hcmsnKTtcblx0XHRcdFx0XHRtYXJrLnN0eWxlLmxlZnQgPSBgJHsoaSAqICgxMDAvbnVtYmVyT2ZTZWN0aW9ucykpfSVgO1xuXHRcdFx0XHRcdG1hcmtzLmFwcGVuZENoaWxkKG1hcmspO1xuXG5cdFx0XHRcdFx0Y29uc3QgZHByID0gd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMTsgLy8gR2V0IHRoZSBkZXZpY2UgcGl4ZWwgcmF0aW9cblx0XHRcdFx0XHRjb25zdCBhZGp1c3RlZEJvcmRlcldpZHRoID0gdGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX21hcmtzV2lkdGggLyBkcHI7IC8vIHVzZSBEUEkgdG8gY3JlYXRlIGNvcnJlY3QgcGl4ZWwgd2lkdGhcblxuXHRcdFx0XHRcdGNvbnN0IHJnYmFDb2xvciA9IGhleFRvUmdiYSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfbWFya3NDb2xvciwgMC41KTtcblx0XHRcdFx0XHRtYXJrLnN0eWxlLmJvcmRlckxlZnQgPSBhZGp1c3RlZEJvcmRlcldpZHRoICsgJ3B4IHNvbGlkICcgKyByZ2JhQ29sb3I7XHRcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGxvb3AgdG8gc2V0IGNvcnJlY3QgcHJvZ3Jlc3MgYmFyIGNvbG9yXG5cdFx0Zm9yIChsZXQgaSA9IDE7IGkgPD0gbnVtYmVyT2ZTZWN0aW9uczsgaSsrKSB7XG5cdFx0XHRsZXQgc2VjdGlvbnNpemUgPSBgJHsoaSAqICgxMDAvbnVtYmVyT2ZTZWN0aW9ucykpfSVgO1xuXG5cdFx0XHRjb25zdCBwcm9ncmVzc0JhclBlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhclBlcmNlbnRhZ2UudG9TdHJpbmcoKSk7XG5cdFx0XHRjb25zdCBtYXJrTGVmdFZhbHVlID0gcGFyc2VGbG9hdChzZWN0aW9uc2l6ZSk7XG5cblx0XHRcdGlmICgocHJvZ3Jlc3NCYXJQZXJjZW50YWdlIDw9IG1hcmtMZWZ0VmFsdWUpICYmIHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhckNoYW5nZSkge1xuXHRcdFx0XHRwcm9ncmVzc2Jhci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3NbYEFQQl9jb2xvciR7aX1gIGFzIGtleW9mIE9ic2lkaWFuUHJvZ3Jlc3NCYXJzU2V0dGluZ3NdKTtcblx0XHRcdFx0aWYgKHByb2dyZXNzQmFyUGVyY2VudGFnZSA9PSAxMDApIHtcblx0XHRcdFx0XHRwcm9ncmVzc2Jhci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYXJDb21wbGV0ZWQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyQ2hhbmdlID0gZmFsc2U7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhckNoYW5nZSA9IHRydWU7XG5cdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cblx0XHRjb25zdCBwcm9ncmVzc3RleHQgPSBjb250YWluZXJFbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogJ1RoaXMgaXMgYSBEZW1vIFByb2dyZXNzIEJhci4nIH0pO1xuXG5cdFx0Ly8gRGVtbyBDb250YWluZXJcblx0XHRjb25zdCBjb250YWluZXJwcm9ncmVzcyA9IGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdkaXYnKTtcblx0XHRjb250YWluZXJwcm9ncmVzcy5hZGRDbGFzcygnY3VzdG9tLWNvbnRhaW5lcicpO1xuXHRcdGNvbnRhaW5lcnByb2dyZXNzLmFwcGVuZENoaWxkKHByb2dyZXNzdGV4dCk7XG5cblx0XHRwcm9ncmVzc0JhckNvbnRhaW5lci5hcHBlbmRDaGlsZChwcm9ncmVzc0JhclRleHRDb250YWluZXIpO1xuXHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZVRvZ2dsZSkge1xuXHRcdFx0XHRwcm9ncmVzc0JhclRleHRDb250YWluZXIuYXBwZW5kQ2hpbGQocHJvZ3Jlc3NCYXJUaXRsZSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VUb2dnbGUpIHtcblx0XHRcdFx0cHJvZ3Jlc3NCYXJUZXh0Q29udGFpbmVyLmFwcGVuZENoaWxkKHByb2dyZXNzQmFyUGVyY2VudGFnZSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2ZyYWN0aW9uVG9nZ2xlKSB7XG5cdFx0XHRcdHByb2dyZXNzQmFyVGV4dENvbnRhaW5lci5hcHBlbmRDaGlsZChwcm9ncmVzc0JhclZhbHVlKTtcblx0XHRcdH1cblxuXHRcdGNvbnRhaW5lcnByb2dyZXNzLmFwcGVuZENoaWxkKHByb2dyZXNzQmFyQ29udGFpbmVyKTtcblxuXHRcdHByb2dyZXNzQmFyQ29udGFpbmVyLmFwcGVuZENoaWxkKHByb2dyZXNzQmFyQmFja2dyb3VuZCk7XG5cblxuXHQvKioqKioqKioqKioqIFNFQ1RJT04gUHJvZ3Jlc3MgQmFyIEFwcGVhcmFuY2UgKioqKioqKioqKioqKi9cblx0Y29udGFpbmVyRWwuY3JlYXRlRWwoJ2g0JywgeyB0ZXh0OiAnUHJvZ3Jlc3MgQmFyJyB9KTtcblxuXHQvKioqKioqKioqKioqIERlZmF1bHQgVGl0bGUgKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ0RlZmF1bHQgdGl0bGUnKVxuXHRcdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJ1NldCB0aGUgZGVmYXVsdCB0aXRsZSBvZiBhIG5ldyBwcm9ncmVzcyBiYXIuIElmIHlvdSBjaGFuZ2UgdGhpcywgdGhlICcpO1xuICAgICAgICAgICAgZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAnVGl0bGUnLFxuXHRcdFx0XHRjbHM6ICdoaWdobGlnaHQtdGV4dCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCcgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGNoYW5nZWQgaW4gdGhlIGV4YW1wbGUgY29kZSBibG9jayBhdCB0aGUgdG9wIG9mIHRoZSBzZXR0aW5ncyBmb3IgZWFzeSBjb3B5IGFuZCBwYXN0aW5nIGxhdGVyIG9uLicpO1xuICAgICAgICB9KSlcblx0XHQuYWRkVGV4dCh0ZXh0ID0+IHtcblx0XHRcdGxldCBkZWJvdW5jZVRpbWVvdXQ6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+O1x0XHRcdFx0XHRcdFx0XG5cdFx0XHR0ZXh0XG5cdFx0XHQuc2V0UGxhY2Vob2xkZXIoJ0VudGVyIHlvdXIgdGl0bGUnKVxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZSB8fCAnJylcblx0XHRcdC5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KGRlYm91bmNlVGltZW91dCk7XG5cblx0XHRcdFx0ZGVib3VuY2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XHRcdFxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZSA9IHZhbHVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhckNoYW5nZSA9IHRydWU7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdH0sIDIwMDApO1xuXHRcdFx0fSlcblx0XHR9KVxuXHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdGJ1dHRvbi5zZXRJY29uKCdyb3RhdGUtY2N3Jykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZSA9IERFRkFVTFRfU0VUVElOR1MuQVBCX3RpdGxlIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyQ2hhbmdlID0gdHJ1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogRGVmYXVsdCBUb3RhbCAqKioqKioqKioqKioqL1xuXHRsZXQgdGltZW91dElkOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0Pjtcblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdC5zZXROYW1lKCdEZWZhdWx0IHRvdGFsJylcblx0LnNldERlc2MoY3JlYXRlRnJhZ21lbnQoKGZyYWcpID0+IHtcblx0XHRmcmFnLmFwcGVuZFRleHQoJ1NldCB0aGUgZGVmYXVsdCAnKTtcblx0XHRmcmFnLmNyZWF0ZUVsKCdzcGFuJywge1xuXHRcdFx0dGV4dDogJ1RvdGFsJyxcblx0XHRcdGNsczogJ2hpZ2hsaWdodC10ZXh0J1xuXHRcdH0pO1xuXHRcdGZyYWcuYXBwZW5kVGV4dCgnIG9mIGEgbmV3IHByb2dyZXNzIGJhci4gSWYgeW91IGNoYW5nZSB0aGlzLCB0aGUgJyk7XG5cdFx0ZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcblx0XHRcdHRleHQ6ICdUb3RhbCcsXG5cdFx0XHRjbHM6ICdoaWdobGlnaHQtdGV4dCdcblx0XHR9KTtcblx0XHRmcmFnLmFwcGVuZFRleHQoJyB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY2hhbmdlZCBpbiB0aGUgZXhhbXBsZSBjb2RlIGJsb2NrIGFib3ZlIGZvciBlYXN5IGNvcHkgYW5kIHBhc3RpbmcgbGF0ZXIgb24uJyk7XG5cdH0pKVxuXHQuYWRkVGV4dCh0ZXh0ID0+IHRleHRcblx0XHQuc2V0UGxhY2Vob2xkZXIoJzEwMCcpXG5cdFx0LnNldFZhbHVlICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfdG90YWwgIT09IHVuZGVmaW5lZCA/IFN0cmluZyh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfdG90YWwpIDogU3RyaW5nKERFRkFVTFRfU0VUVElOR1MuQVBCX3RvdGFsKSlcblx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRjbGVhclRpbWVvdXQodGltZW91dElkKTtcblx0XHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRjb25zdCBwYXJzZWRWYWx1ZSA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG5cblx0XHRcdFx0aWYgKHBhcnNlZFZhbHVlID49IDEgJiYgKCFpc05hTihwYXJzZWRWYWx1ZSkgJiYgcGFyc2VkVmFsdWUgPT09IHBhcnNlRmxvYXQodmFsdWUpKSkge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90b3RhbCA9IHBhcnNlZFZhbHVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9IGVsc2Uge1x0XHRcdFx0XHRcdFxuXHRcdFx0XHRcdHRleHQuc2V0VmFsdWUoU3RyaW5nKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90b3RhbCA/PyBERUZBVUxUX1NFVFRJTkdTLkFQQl90b3RhbCkpO1xuXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdFx0bmV3IE5vdGljZSgnUGxlYXNlIGVudGVyIGEgdmFsdWUgMSBvciBhYm92ZS4nKTtcblx0XHRcdFx0fVxuXHRcdFx0fSwgMTAwMCk7XG5cdFx0fSlcblx0XHQuaW5wdXRFbC5jbGFzc0xpc3QuYWRkKCdjdXN0b20tdGV4dGJveCcpXG5cdClcblx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdGJ1dHRvbi5zZXRJY29uKCdyb3RhdGUtY2N3Jykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gZGVmYXVsdCcpXG5cdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RvdGFsID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfdG90YWwgYXMgbnVtYmVyO1xuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyQ2hhbmdlID0gdHJ1ZTtcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0fSlcblx0KTtcblxuXHQvKioqKioqKioqKioqIFByb2dyZXNzIFBlcmNlbnRhZ2UgKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ1Byb2dyZXNzIHBlcmNlbnRhZ2UnKVxuXHRcdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJ1NldCB0aGUgcGVyY2VudGFnZSBmb3IgdGhlIGRlbW9uc3RyYXRpb24gcHJvZ3Jlc3MgYmFyIGFib3ZlLiBUaGlzIHdpbGwgYWxzbyB1cGRhdGUgdGhlICcpO1xuICAgICAgICAgICAgZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAnVmFsdWUnLFxuXHRcdFx0XHRjbHM6ICdoaWdobGlnaHQtdGV4dCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCcgcGFyYW1ldGVyIGluIHRoZSBFeGFtcGxlIENvZGUgYXQgdGhlIHRvcCBvZiB0aGUgc2V0dGluZ3MuIE9uY2UgeW91IGFyZSBzYXRpc2ZpZWQgd2l0aCBhbGwgb3RoZXIgc2V0dGluZ3MsIHlvdSB3aWxsIGxpa2VseSB3YW50IHRvIHNldCB0aGlzIGJhY2sgdG8gMC4nKTtcbiAgICAgICAgfSkpXG5cdFx0LmFkZFNsaWRlcigoc2xpZGVyKSA9PiB7XG5cdFx0XHR2YXIgX2E7XG5cdFx0XHRzbGlkZXJcblx0XHRcdC5zZXRMaW1pdHMoMCwgMTAwLCAxKVxuXHRcdFx0LnNldER5bmFtaWNUb29sdGlwKClcdFx0XHRcdFxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhclBlcmNlbnRhZ2UgPz8gREVGQVVMVF9TRVRUSU5HUy5BUEJfcHJvZ3Jlc3NCYXJQZXJjZW50YWdlKVxuXHRcdFx0Lm9uQ2hhbmdlKCh2YWx1ZSkgPT4gIHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSA9IHZhbHVlO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcHJvZ3Jlc3NCYXJDaGFuZ2UgPSB0cnVlO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHRcdFx0XHRcdFx0XHRcblx0XHRcdH0pXG5cdFx0fSlcdFx0XHRcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1x0XHRcdFx0XHRcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSA9IERFRkFVTFRfU0VUVElOR1MuQVBCX3Byb2dyZXNzQmFyUGVyY2VudGFnZSBhcyBudW1iZXI7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wcm9ncmVzc0JhckNoYW5nZSA9IHRydWU7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIEZ1bGwgV2lkdGggKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ0Z1bGwgd2lkdGgnKVxuXHRcdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJ1RvZ2dsZSB0aGlzIG9uIHRvIHNldCB0aGUgcHJvZ3Jlc3MgYmFyIHRvIGZpbGwgdGhlIGVudGlyZSB3aWR0aCBvZiBpdHMgY29udGFpbmVyLiBGb3IgYSBmaXhlZCB3aWR0aCwgdG9nZ2xlIHRoaXMgb2ZmIGFuZCB1c2UgdGhlICcpO1xuICAgICAgICAgICAgZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAnV2lkdGgnLFxuXHRcdFx0XHRjbHM6ICdoaWdobGlnaHQtdGV4dCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCcgb3B0aW9uIHRoYXQgd2lsbCBhcHBlYXIgYmVsb3cuJyk7XG4gICAgICAgIH0pKVxuXHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cblx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfd2lkdGhUb2dnbGUpXG5cdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl93aWR0aFRvZ2dsZSA9IHZhbHVlO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfd2lkdGhUb2dnbGUgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl93aWR0aFRvZ2dsZSBhcyBib29sZWFuO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KVxuXHRcdCk7XG5cblx0aWYgKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfd2lkdGhUb2dnbGUpIHtcblx0XHQvKioqKioqKioqKioqIFdpZHRoICoqKioqKioqKioqKiovXG5cdFx0bGV0IHRpbWVvdXRJZDogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnV2lkdGgnKVxuXHRcdFx0LnNldERlc2MoJ1NldCB0aGUgd2lkdGggb2YgdGhlIHByb2dyZXNzIGJhciBjb250YWluZXIgaW4gcGl4ZWxzIChtaW5pbXVtIDEwMCkuIE5vdGU6IElmIHlvdSB3YW50IGl0IHRvIHNwYW4gdGhlIGZ1bGwgd2lkdGgsIG1ha2Ugc3VyZSB0byBlbmFibGUgdGhlIHRvZ2dsZSBhYm92ZS4nKVxuXHRcdFx0LmFkZFRleHQodGV4dCA9PiB0ZXh0XG5cdFx0XHRcdC5zZXRQbGFjZWhvbGRlcignMjAwJylcblx0XHRcdFx0LnNldFZhbHVlICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfd2lkdGggIT09IHVuZGVmaW5lZCA/IFN0cmluZyh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfd2lkdGgpIDogU3RyaW5nKERFRkFVTFRfU0VUVElOR1MuQVBCX3dpZHRoKSlcblx0XHRcdFx0Lm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuXHRcdFx0XHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3QgcGFyc2VkVmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuXG5cdFx0XHRcdFx0XHRpZiAocGFyc2VkVmFsdWUgPj0gMTAwICYmICghaXNOYU4ocGFyc2VkVmFsdWUpICYmIHBhcnNlZFZhbHVlID09PSBwYXJzZUZsb2F0KHZhbHVlKSkpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3dpZHRoID0gcGFyc2VkVmFsdWU7XG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHRcdHRleHQuc2V0VmFsdWUoU3RyaW5nKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl93aWR0aCA/PyBERUZBVUxUX1NFVFRJTkdTLkFQQl93aWR0aCkpO1xuXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdFx0bmV3IE5vdGljZSgnUGxlYXNlIGVudGVyIGEgdmFsdWUgMTAwIG9yIGFib3ZlLicpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0sIDEwMDApO1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQuaW5wdXRFbC5jbGFzc0xpc3QuYWRkKCdjdXN0b20tdGV4dGJveCcpXG5cdFx0XHQpXG5cdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdyb3RhdGUtY2N3Jykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gZGVmYXVsdCcpXG5cdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfd2lkdGggPSBERUZBVUxUX1NFVFRJTkdTLkFQQl93aWR0aCBhcyBudW1iZXI7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHR9XG5cblx0LyoqKioqKioqKioqKiBIZWlnaHQgKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ0hlaWdodCcpXG5cdFx0LnNldERlc2MoJ1NldCB0aGUgaGVpZ2h0IG9mIHRoZSBwcm9ncmVzcyBiYXIgaW4gcGl4ZWxzLiAgKFNlZSBkZW1vbnN0cmF0aW9uIHByb2dyZXNzIGJhciBhYm92ZSknKVxuXHRcdC5hZGRTbGlkZXIoKHNsaWRlcikgPT4ge1xuXHRcdFx0dmFyIF9hO1xuXHRcdFx0c2xpZGVyXG5cdFx0XHRcdC5zZXRMaW1pdHMoMSwgMTUsIDEpXG5cdFx0XHRcdC5zZXREeW5hbWljVG9vbHRpcCgpXHRcdFx0XHRcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9oZWlnaHQgPz8gREVGQVVMVF9TRVRUSU5HUy5BUEJfaGVpZ2h0KVxuXHRcdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiAge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9oZWlnaHQgPSB2YWx1ZTtcblx0XHRcdFx0XHRzZXRFbmRDYXBzKHByb2dyZXNzQmFyQmFja2dyb3VuZCwgcHJvZ3Jlc3NiYXIsIHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9lbmRjYXBUb2dnbGUpOyBcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcHJvZ3Jlc3NCYXJDaGFuZ2UgPSB0cnVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1x0XHRcdFx0XG5cdFx0XHRcdH0pXG5cdFx0XHR9KVxuXHRcdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2hlaWdodCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2hlaWdodCBhcyBudW1iZXI7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyQ2hhbmdlID0gdHJ1ZTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcdFx0XHRcdFx0XG5cdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHRcdFx0XG5cdC8qKioqKioqKioqKiogRW5kIENhcHMgKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ1JvdW5kIGVuZCBjYXBzJylcblx0XHQuc2V0RGVzYygnV2hlbiB0b2dnbGVkLCB0aGUgcHJvZ3Jlc3MgYmFyIHdpbGwgaGF2ZSBlaXRoZXIgYSByb3VuZCBvciBzcXVhcmUgZW5kIGNhcC4gIChTZWUgZGVtb25zdHJhdGlvbiBwcm9ncmVzcyBiYXIgYWJvdmUpJylcblx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZW5kY2FwVG9nZ2xlKVxuXHRcdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2VuZGNhcFRvZ2dsZSA9IHZhbHVlO1xuXHRcdFx0XHRcdHNldEVuZENhcHMocHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kLCBwcm9ncmVzc2JhciwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2VuZGNhcFRvZ2dsZSk7IFxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZW5kY2FwVG9nZ2xlID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfZW5kY2FwVG9nZ2xlIGFzIGJvb2xlYW47XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIFNFQ1RJT04gTWFya3MgU2V0dGluZ3MgKioqKioqKioqKioqKi9cblx0Y29udGFpbmVyRWwuY3JlYXRlRWwoJ2g0JywgeyB0ZXh0OiAnU2VjdGlvbiBNYXJrcycgfSk7XG5cblx0LyoqKioqKioqKioqKiBCYXIgU2VjdGlvbiBNYXJrcyAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnU2VjdGlvbiBtYXJrcycpXG5cdFx0LnNldERlc2MoY3JlYXRlRnJhZ21lbnQoKGZyYWcpID0+IHtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnV2hlbiB0b2dnbGVkIG9uLCB0aGUgcHJvZ3Jlc3MgYmFyIHdpbGwgaGF2ZSB2ZXJ0aWNhbCBzZWN0aW9uIG1hcmtzIGVxdWFsbHkgc3BhY2VkIGFsb25nIGl0cyBsZW5ndGguICBUaGUgbnVtYmVyIGFuZCBzcGFjaW5nIG9mIHRoZXNlIHdpbGwgY2hhbmdlIGRlcGVuZGluZyBvbiBob3cgbWFueSBjb2xvcnMgeW91ciBwcm9ncmVzcyBiYXIgdXNlcyAoc2VlICcpO1xuICAgICAgICAgICAgZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAnTnVtYmVyIG9mIGNvbG9ycycsXG5cdFx0XHRcdGNsczogJ2hpZ2hsaWdodC10ZXh0J1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJyBzZXR0aW5nIGJlbG93KS4gTm90ZTogaWYgdGhlIGJhciByZWFjaGVzIDEwMCUgb3IgdGhlIGJhciBoYXMgb25seSBvbmUgY29sb3IsIG5vIG1hcmtzIHdpbGwgbm90IGJlIGRpc3BsYXllZC4gIChTZWUgZGVtb25zdHJhdGlvbiBwcm9ncmVzcyBiYXIgYWJvdmUpJyk7XG4gICAgICAgIH0pKVxuXHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc1RvZ2dsZSlcblx0XHRcdFx0Lm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc1RvZ2dsZSA9IHZhbHVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1x0XHRcdFx0XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc1RvZ2dsZSA9IERFRkFVTFRfU0VUVElOR1MuQVBCX21hcmtzVG9nZ2xlIGFzIGJvb2xlYW47XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIFNlY3Rpb24gTWFyayBDb2xvciAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0LnNldE5hbWUoJ1NlY3Rpb24gTWFyayBjb2xvcicpXG5cdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG5cdFx0ZnJhZy5hcHBlbmRUZXh0KCdTZWxlY3QgdGhlIGNvbG9yIG9mIHRoZSBzZWN0aW9uICcpO1xuXHRcdGZyYWcuY3JlYXRlRWwoJ3NwYW4nLCB7XG5cdFx0XHR0ZXh0OiAnTWFya3MnLFxuXHRcdFx0Y2xzOiAnaGlnaGxpZ2h0LXRleHQnXG5cdFx0fSk7XG5cdFx0ZnJhZy5hcHBlbmRUZXh0KCcuIE5vdGU6IFRoZSBjb2xvciB3aWxsIGJlIHNldCB0byA1MCUgdHJhbnNwYXJlbmN5LCBhbGxvd2luZyB0aGUgcHJvZ3Jlc3MgYmFyXFwncyBjb2xvciB0byBibGVuZCBhbmQgaW5mbHVlbmNlIHRoZSBmaW5hbCBhcHBlYXJhbmNlLicpO1xuXHR9KSlcblx0LmFkZENvbG9yUGlja2VyKChQQmNvbG9ycGlja2VyMCkgPT5cdFBCY29sb3JwaWNrZXIwXG5cdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc0NvbG9yKS5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc0NvbG9yID0gdmFsdWU7XG5cdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdH0pKVxuXHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX21hcmtzQ29sb3IgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9tYXJrc0xpZ2h0Q29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc0NvbG9yID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfbWFya3NDb2xvciBhcyBzdHJpbmc7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIEJhciBTZWN0aW9uIE1hcmsgV2lkdGggKioqKioqKioqKioqKi9cblx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc1RvZ2dsZSkge1xuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdTZWN0aW9uIG1hcmsgd2lkdGgnKVxuXHRcdC5zZXREZXNjKCdTZXQgdGhlIHdpZHRoIG9mIHRoZSBzZWN0aW9uIG1hcmsgbGluZXMgb24gdGhlIHByb2dyZXNzIGJhciBmcm9tIGEgcmFuZ2Ugb2YgMSB0byA1IHBpeGVscy4gIChTZWUgZGVtb25zdHJhdGlvbiBwcm9ncmVzcyBiYXIgYWJvdmUpJylcblx0XHQuYWRkU2xpZGVyKChzbGlkZXIpID0+IHtcblx0XHRcdHZhciBfYTtcblx0XHRcdHNsaWRlclxuXHRcdFx0XHQuc2V0TGltaXRzKDEsIDUsIDEpXG5cdFx0XHRcdC5zZXREeW5hbWljVG9vbHRpcCgpXHRcdFx0XHRcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9tYXJrc1dpZHRoID8/IERFRkFVTFRfU0VUVElOR1MuQVBCX21hcmtzV2lkdGgpXG5cdFx0XHRcdC5vbkNoYW5nZSgodmFsdWUpID0+ICB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX21hcmtzV2lkdGggPSB2YWx1ZTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcdFx0XHRcdFx0XHRcdFxuXHRcdFx0XHR9KVxuXHRcdFx0fSlcdFx0XHRcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0YnV0dG9uLnNldEljb24oJ3JvdGF0ZS1jY3cnKS5zZXRUb29sdGlwKCdSZXNldCB0byBkZWZhdWx0Jylcblx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1x0XHRcdFx0XHRcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfbWFya3NXaWR0aCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX21hcmtzV2lkdGggYXMgbnVtYmVyO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0XHR9XG5cblx0LyoqKioqKioqKioqKiBTRUNUSU9OIFRleHQgU2V0dGluZ3MgKioqKioqKioqKioqKi9cblx0Y29udGFpbmVyRWwuY3JlYXRlRWwoJ2g0JywgeyB0ZXh0OiAnVGV4dCcgfSk7XG5cblx0LyoqKioqKioqKioqKiBTaG93IFRpdGxlICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdTaG93IHRpdGxlIHRleHQnKVxuXHRcdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJ1doZW4gdG9nZ2xlZCBvbiwgdGhlICcpO1xuICAgICAgICAgICAgZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAnVGl0bGUnLFxuXHRcdFx0XHRjbHM6ICdoaWdobGlnaHQtdGV4dCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCcgdGV4dCB3aWxsIGJlIGRpc3BsYXllZCBhYm92ZSB0aGUgcHJvZ3Jlc3MgYmFyLiAgKFNlZSBkZW1vbnN0cmF0aW9uIHByb2dyZXNzIGJhciBhYm92ZSknKTtcbiAgICAgICAgfSkpXG5cdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RpdGxlVG9nZ2xlKVxuXHRcdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RpdGxlVG9nZ2xlID0gdmFsdWU7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdH0pKVxuXHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdGJ1dHRvbi5zZXRJY29uKCdyb3RhdGUtY2N3Jykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZVRvZ2dsZSA9IERFRkFVTFRfU0VUVElOR1MuQVBCX3RpdGxlVG9nZ2xlIGFzIGJvb2xlYW47XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIFRpdGxlIENvbG9yICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdUaXRsZSB0ZXh0IGNvbG9yJylcblx0XHQuc2V0RGVzYyhjcmVhdGVGcmFnbWVudCgoZnJhZykgPT4ge1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCdTZWxlY3QgdGhlIGNvbG9yIG9mIHRoZSAnKTtcbiAgICAgICAgICAgIGZyYWcuY3JlYXRlRWwoJ3NwYW4nLCB7XG4gICAgICAgICAgICAgICAgdGV4dDogJ1RpdGxlJyxcblx0XHRcdFx0Y2xzOiAnaGlnaGxpZ2h0LXRleHQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnIHRleHQuJyk7XG4gICAgICAgIH0pKVxuXHRcdC5hZGRDb2xvclBpY2tlcigoUEJjb2xvcnBpY2tlcjApID0+XHRQQmNvbG9ycGlja2VyMFxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZUNvbG9yKS5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3RpdGxlQ29sb3IgPSB2YWx1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZUNvbG9yID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfdGl0bGVMaWdodENvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0fSkpXG5cdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdtb29uJykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gRGFyayBkZWZhdWx0Jylcblx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl90aXRsZUNvbG9yID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfdGl0bGVDb2xvciBhcyBzdHJpbmc7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogU2hvdyBQZXJjZW50YWdlICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdTaG93IHBlcmNlbnRhZ2UgdGV4dCcpXG5cdFx0LnNldERlc2MoY3JlYXRlRnJhZ21lbnQoKGZyYWcpID0+IHtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnV2hlbiB0b2dnbGVkIG9uLCB0aGUgJyk7XG4gICAgICAgICAgICBmcmFnLmNyZWF0ZUVsKCdzcGFuJywge1xuICAgICAgICAgICAgICAgIHRleHQ6ICdQZXJjZW50YWdlJyxcblx0XHRcdFx0Y2xzOiAnaGlnaGxpZ2h0LXRleHQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnIHRleHQgd2lsbCBiZSBkaXNwbGF5ZWQgYWJvdmUgdGhlIHByb2dyZXNzIGJhci4gIChTZWUgZGVtb25zdHJhdGlvbiBwcm9ncmVzcyBiYXIgYWJvdmUpJyk7XG4gICAgICAgIH0pKVxuXHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cblx0XHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wZXJjZW50YWdlVG9nZ2xlKVxuXHRcdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VUb2dnbGUgPSB2YWx1ZTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0fSkpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ3JvdGF0ZS1jY3cnKS5zZXRUb29sdGlwKCdSZXNldCB0byBkZWZhdWx0Jylcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VUb2dnbGUgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9wZXJjZW50YWdlVG9nZ2xlIGFzIGJvb2xlYW47XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIFBlcmNlbnRhZ2UgQ29sb3IgKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ1BlcmNlbnRhZ2UgdGV4dCBjb2xvcicpXG5cdFx0LnNldERlc2MoY3JlYXRlRnJhZ21lbnQoKGZyYWcpID0+IHtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnU2VsZWN0IHRoZSBjb2xvciBvZiB0aGUgJyk7XG4gICAgICAgICAgICBmcmFnLmNyZWF0ZUVsKCdzcGFuJywge1xuICAgICAgICAgICAgICAgIHRleHQ6ICdQZXJjZW50YWdlJyxcblx0XHRcdFx0Y2xzOiAnaGlnaGxpZ2h0LXRleHQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnIHRleHQuJyk7XG4gICAgICAgIH0pKVxuXHRcdC5hZGRDb2xvclBpY2tlcigoUEJjb2xvcnBpY2tlcjApID0+XHRQQmNvbG9ycGlja2VyMFxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9wZXJjZW50YWdlQ29sb3IpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcGVyY2VudGFnZUNvbG9yID0gdmFsdWU7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pKVxuXHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3BlcmNlbnRhZ2VDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX3BlcmNlbnRhZ2VMaWdodENvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ21vb24nKS5zZXRUb29sdGlwKCdSZXNldCB0byBEYXJrIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcGVyY2VudGFnZUNvbG9yID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfcGVyY2VudGFnZUNvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogU2hvdyBGcmFjdGlvbiAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnU2hvdyBmcmFjdGlvbiB0ZXh0IChWYWx1ZS9Ub3RhbCknKVxuXHRcdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJ1doZW4gdG9nZ2xlZCBvbiwgdGhlIGZyYWN0aW9uIHRleHQgJyk7XG4gICAgICAgICAgICBmcmFnLmNyZWF0ZUVsKCdzcGFuJywge1xuICAgICAgICAgICAgICAgIHRleHQ6ICcoVmFsdWUvVG90YWwpJyxcblx0XHRcdFx0Y2xzOiAnaGlnaGxpZ2h0LXRleHQnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZyYWcuYXBwZW5kVGV4dCgnIHdpbGwgYmUgZGlzcGxheWVkIGFib3ZlIHRoZSBwcm9ncmVzcyBiYXIuICAoU2VlIGRlbW9uc3RyYXRpb24gcHJvZ3Jlc3MgYmFyIGFib3ZlKScpO1xuICAgICAgICB9KSlcblx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZnJhY3Rpb25Ub2dnbGUpXG5cdFx0XHRcdC5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZnJhY3Rpb25Ub2dnbGUgPSB2YWx1ZTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0fSkpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ3JvdGF0ZS1jY3cnKS5zZXRUb29sdGlwKCdSZXNldCB0byBkZWZhdWx0Jylcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2ZyYWN0aW9uVG9nZ2xlID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfZnJhY3Rpb25Ub2dnbGUgYXMgYm9vbGVhbjtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogRnJhY3Rpb24gQ29sb3IgKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0LnNldE5hbWUoJ0ZyYWN0aW9uIHRleHQgY29sb3InKVxuXHRcdC5zZXREZXNjKGNyZWF0ZUZyYWdtZW50KChmcmFnKSA9PiB7XG4gICAgICAgICAgICBmcmFnLmFwcGVuZFRleHQoJ1NlbGVjdCB0aGUgY29sb3Igb2YgdGhlICcpO1xuICAgICAgICAgICAgZnJhZy5jcmVhdGVFbCgnc3BhbicsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiAnRnJhY3Rpb24nLFxuXHRcdFx0XHRjbHM6ICdoaWdobGlnaHQtdGV4dCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZnJhZy5hcHBlbmRUZXh0KCcgdGV4dC4nKTtcbiAgICAgICAgfSkpXG5cdFx0LmFkZENvbG9yUGlja2VyKChQQmNvbG9ycGlja2VyMCkgPT5cdFBCY29sb3JwaWNrZXIwXG5cdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2ZyYWN0aW9uQ29sb3IpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfZnJhY3Rpb25Db2xvciA9IHZhbHVlO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0YnV0dG9uLnNldEljb24oJ3N1bicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIExpZ2h0IGRlZmF1bHQnKVxuXHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2ZyYWN0aW9uQ29sb3IgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9mcmFjdGlvbkxpZ2h0Q29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KSlcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0YnV0dG9uLnNldEljb24oJ21vb24nKS5zZXRUb29sdGlwKCdSZXNldCB0byBEYXJrIGRlZmF1bHQnKVxuXHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2ZyYWN0aW9uQ29sb3IgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9mcmFjdGlvbkNvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0LyoqKioqKioqKioqKiBTaG93IENvbXBsZXRlZCAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0LnNldE5hbWUoJ1Nob3cgY29tcGxldGVkIHRleHQnKVxuXHQuc2V0RGVzYygnV2hlbiB0b2dnbGVkIG9uLCB0aGUgd29yZCBDT01QTEVURUQgd2lsbCBiZSBkaXNwbGF5ZWQgb24gdGhlIHByb2dyZXNzIGJhciB3aGVuIGl0IHJlYWNoZXMgMTAwJS4gIChTZWUgZGVtb25zdHJhdGlvbiBwcm9ncmVzcyBiYXIgYWJvdmUpJylcblx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxuXHRcdFx0dG9nZ2xlLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRUb2dnbGUpXG5cdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRUb2dnbGUgPSB2YWx1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRUb2dnbGUgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb21wbGV0ZWRUb2dnbGUgYXMgYm9vbGVhbjtcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0fSlcblx0KTtcblxuXHQvKioqKioqKioqKioqIENvbXBsZXRlZCBDb2xvciAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0LnNldE5hbWUoJ0NvbXBsZXRlZCB0ZXh0IGNvbG9yJylcblx0LnNldERlc2MoY3JlYXRlRnJhZ21lbnQoKGZyYWcpID0+IHtcblx0XHRmcmFnLmFwcGVuZFRleHQoJ1NlbGVjdCB0aGUgY29sb3Igb2YgdGhlICcpO1xuXHRcdGZyYWcuY3JlYXRlRWwoJ3NwYW4nLCB7XG5cdFx0XHR0ZXh0OiAnQ29tcGxldGVkJyxcblx0XHRcdGNsczogJ2hpZ2hsaWdodC10ZXh0J1xuXHRcdH0pO1xuXHRcdGZyYWcuYXBwZW5kVGV4dCgnIHRleHQuJyk7XG5cdH0pKVxuXHQuYWRkQ29sb3JQaWNrZXIoKFBCY29sb3JwaWNrZXIwKSA9Plx0UEJjb2xvcnBpY2tlcjBcblx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbXBsZXRlZENvbG9yKS5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRDb2xvciA9IHZhbHVlO1xuXHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignc3VuJykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gTGlnaHQgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbXBsZXRlZExpZ2h0Q29sb3IgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb21wbGV0ZWRDb2xvciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbXBsZXRlZENvbG9yIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cblx0LyoqKioqKioqKioqKiBTRUNUSU9OIEJvcmRlciAmIEJhY2tncm91bmQgKioqKioqKioqKioqKi9cdFxuXHRjb250YWluZXJFbC5jcmVhdGVFbCgnaDQnLCB7IHRleHQ6ICdQcm9ncmVzcyBCYXIgQ29udGFpbmVyJyB9KTtcblxuXHQvKioqKioqKioqKioqIEJvcmRlciAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnQm9yZGVyJylcblx0XHQuc2V0RGVzYygnV2hlbiB0b2dnbGVkIG9uLCBhIGJvcmRlciB3aWxsIGJlIGRpc3BsYXllZCBhcm91bmQgdGhlIHByb2dyZXNzIGJhciBjb250YWluZXIuJylcblx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XG5cdFx0XHRcdHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfYm9yZGVyVG9nZ2xlKVxuXHRcdFx0XHQub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2JvcmRlclRvZ2dsZSA9IHZhbHVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfYm9yZGVyVG9nZ2xlID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfYm9yZGVyVG9nZ2xlIGFzIGJvb2xlYW47XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHQvKioqKioqKioqKioqIEJvcmRlciBDb2xvciAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnQm9yZGVyIGNvbG9yJylcblx0XHQuc2V0RGVzYygnU2VsZWN0IHRoZSBjb2xvciBvZiB0aGUgYm9yZGVyIGFyb3VuZCB0aGUgcHJvZ3Jlc3MgYmFyIGNvbnRhaW5lci4nKVxuXHRcdC5hZGRDb2xvclBpY2tlcigoUEJjb2xvcnBpY2tlcjApID0+XHRQQmNvbG9ycGlja2VyMFxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJvcmRlcikub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJvcmRlciA9IHZhbHVlO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignc3VuJykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gTGlnaHQgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJvcmRlciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yTGlnaHRCb3JkZXIgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJvcmRlciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yQm9yZGVyIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogQmFja2dyb3VuZCAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnQmFja2dyb3VuZCcpXG5cdFx0LnNldERlc2MoJ1doZW4gdG9nZ2xlZCBvbiwgdGhlIGJhY2tncm91bmQgb2YgdGhlIHByb2dyZXNzIGJhciBjb250YWluZXIgd2lsbCBzaG93LicpXG5cdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxuXHRcdFx0XHR0b2dnbGUuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2JhY2tncm91bmRUb2dnbGUpXG5cdFx0XHRcdC5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfYmFja2dyb3VuZFRvZ2dsZSA9IHZhbHVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbigncm90YXRlLWNjdycpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfYmFja2dyb3VuZFRvZ2dsZSA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2JhY2tncm91bmRUb2dnbGUgYXMgYm9vbGVhbjtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogQmFja2dyb3VuZCBDb2xvciAqKioqKioqKioqKioqL1xuXHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnQmFja2dyb3VuZCBjb2xvcicpXG5cdFx0LnNldERlc2MoJ1NlbGVjdCB0aGUgYmFja2dyb3VuZCBjb2xvciBvZiB0aGUgcHJvZ3Jlc3MgYmFyIGNvbnRhaW5lci4nKVxuXHRcdC5hZGRDb2xvclBpY2tlcigoUEJjb2xvcnBpY2tlcjApID0+XHRQQmNvbG9ycGlja2VyMFxuXHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhY2tncm91bmQpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYWNrZ3JvdW5kID0gdmFsdWU7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdH0pKVxuXHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yQmFja2dyb3VuZCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yTGlnaHRCYWNrZ3JvdW5kIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ21vb24nKS5zZXRUb29sdGlwKCdSZXNldCB0byBEYXJrIGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYWNrZ3JvdW5kID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3JCYWNrZ3JvdW5kIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXHRcdFxuXHQvKioqKioqKioqKioqIFNFQ1RJT04gUHJvZ3Jlc3MgQmFyIENvbG9yIE9wdGlvbnMgKioqKioqKioqKioqKi9cblx0Y29udGFpbmVyRWwuY3JlYXRlRWwoJ2g0JywgeyB0ZXh0OiAnUHJvZ3Jlc3MgQmFyIENvbG9yJyB9KTtcblxuXHQvKioqKioqKioqKioqIE51bWJlciBvZiBDb2xvcnMgRHJvcGRvd24gKioqKioqKioqKioqKi9cblx0bmV3IFNldHRpbmcodGhpcy5jb250YWluZXJFbClcblx0XHQuc2V0TmFtZSgnTnVtYmVyIG9mIGNvbG9ycycpXG5cdFx0LnNldERlc2MoJ1NlbGVjdCBob3cgbWFueSBkaWZmZXJlbnQgY29sb3JzIHlvdSB3YW50IHRoZSBwcm9ncmVzcyBiYXIgdG8gdXNlLiAgRWFjaCBjb2xvciB3aWxsIGJlIHVzZWQgZm9yIHRoZSBlbnRpcmUgYmFyIGRlcGVuZGluZyBvbiBpdHMgcGVyY2VudGFnZSBjb21wbGV0ZWQuICAoU2VlIGRlbW9uc3RyYXRpb24gcHJvZ3Jlc3MgYmFyIGFib3ZlKScpXG5cdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xuXHRcdFx0ZHJvcGRvd25cblx0XHRcdFx0LmFkZE9wdGlvbnMoe1xuXHRcdFx0XHRcdG9wdGlvbjE6ICcxIGNvbG9yJyxcblx0XHRcdFx0XHRvcHRpb24yOiAnMiBjb2xvcnMnLFxuXHRcdFx0XHRcdG9wdGlvbjM6ICczIGNvbG9ycycsXG5cdFx0XHRcdFx0b3B0aW9uNDogJzQgY29sb3JzJyxcblx0XHRcdFx0XHRvcHRpb241OiAnNSBjb2xvcnMnXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JudW1iZXIpXG5cdFx0XHRcdC5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JudW1iZXIgPSB2YWx1ZTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfcHJvZ3Jlc3NCYXJDaGFuZ2UgPSB0cnVlO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KTtcblx0XHR9KVxuXHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdGJ1dHRvbi5zZXRJY29uKCdyb3RhdGUtY2N3Jykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcm51bWJlciA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9ybnVtYmVyIGFzIHN0cmluZztcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX3Byb2dyZXNzQmFyQ2hhbmdlID0gdHJ1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXG5cdC8qKioqKioqKioqKiogMXN0IENvbG9yICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCcxc3QgY29sb3InKVxuXHRcdC5zZXREZXNjKCdUaGlzIGNvbG9yIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGVudGlyZSBwcm9ncmVlcyBiYXIgaWYgdGhlIHBlcmNlbnRhZ2UgaXMgd2l0aGluIHRoZSBmaXJzdCBzZWN0aW9uLicpXG5cdFx0LmFkZENvbG9yUGlja2VyKChQQmNvbG9ycGlja2VyMSkgPT5cdFBCY29sb3JwaWNrZXIxXG5cdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yMSkub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjEgPSB2YWx1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSlcblx0XHQpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ3N1bicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIExpZ2h0IGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3IxID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3IxTGlnaHQgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjEgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjEgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KVxuXHRcdCk7XG5cblx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcm51bWJlciAhPT0gJ29wdGlvbjEnKSB7XG5cdFx0LyoqKioqKioqKioqKiAybmQgQ29sb3IgKioqKioqKioqKioqKi9cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCcybmQgY29sb3InKVxuXHRcdFx0LnNldERlc2MoJ1RoaXMgY29sb3Igd2lsbCBiZSB1c2VkIGZvciB0aGUgZW50aXJlIHByb2dyZWVzIGJhciBpZiB0aGUgcGVyY2VudGFnZSBpcyB3aXRoaW4gdGhlIHNlY29uZCBzZWN0aW9uLicpXG5cdFx0XHQuYWRkQ29sb3JQaWNrZXIoKFBCY29sb3JwaWNrZXIyKSA9Plx0UEJjb2xvcnBpY2tlcjJcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjIpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjIgPSB2YWx1ZTtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0fSkpXG5cdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjIgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjJMaWdodCBhcyBzdHJpbmc7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdH0pKVxuXHRcdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3IyID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3IyIGFzIHN0cmluZztcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9ybnVtYmVyICE9PSAnb3B0aW9uMicpIHtcblx0XHRcdC8qKioqKioqKioqKiogM3JkIENvbG9yICoqKioqKioqKioqKiovXG5cdFx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdFx0LnNldE5hbWUoJzNyZCBjb2xvcicpXG5cdFx0XHRcdC5zZXREZXNjKCdUaGlzIGNvbG9yIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGVudGlyZSBwcm9ncmVlcyBiYXIgaWYgdGhlIHBlcmNlbnRhZ2UgaXMgd2l0aGluIHRoZSB0aGlyZCBzZWN0aW9uLicpXG5cdFx0XHRcdC5hZGRDb2xvclBpY2tlcigoUEJjb2xvcnBpY2tlcjMpID0+XHRQQmNvbG9ycGlja2VyM1xuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3IzKS5vbkNoYW5nZSgodmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjMgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdFx0fSkpXG5cdFx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0XHRidXR0b24uc2V0SWNvbignc3VuJykuc2V0VG9vbHRpcCgnUmVzZXQgdG8gTGlnaHQgZGVmYXVsdCcpXG5cdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yMyA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yM0xpZ2h0IGFzIHN0cmluZztcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdFx0fSkpXG5cdFx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yMyA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yMyBhcyBzdHJpbmc7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdCk7XG5cdFxuXHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcm51bWJlciAhPT0gJ29wdGlvbjMnKSB7XG5cdFx0XHRcdC8qKioqKioqKioqKiogNHRoIENvbG9yICoqKioqKioqKioqKiovXG5cdFx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHRcdC5zZXROYW1lKCc0dGggY29sb3InKVxuXHRcdFx0XHRcdC5zZXREZXNjKCdUaGlzIGNvbG9yIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGVudGlyZSBwcm9ncmVlcyBiYXIgaWYgdGhlIHBlcmNlbnRhZ2UgaXMgd2l0aGluIHRoZSBmb3VydGggc2VjdGlvbi4nKVxuXHRcdFx0XHRcdC5hZGRDb2xvclBpY2tlcigoUEJjb2xvcnBpY2tlcjQpID0+XHRQQmNvbG9ycGlja2VyNFxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjQpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3I0ID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdH0pKVxuXHRcdFx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yNCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yNExpZ2h0IGFzIHN0cmluZztcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdFx0fSkpXG5cdFx0XHRcdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0XHRcdFx0YnV0dG9uLnNldEljb24oJ21vb24nKS5zZXRUb29sdGlwKCdSZXNldCB0byBEYXJrIGRlZmF1bHQnKVxuXHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3I0ID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3I0IGFzIHN0cmluZztcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JudW1iZXIgIT09ICdvcHRpb240Jykge1xuXHRcdFx0XHRcdC8qKioqKioqKioqKiogNXRoIENvbG9yICoqKioqKioqKioqKiovXG5cdFx0XHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHRcdFx0XHQuc2V0TmFtZSgnNXRoIGNvbG9yJylcblx0XHRcdFx0XHRcdC5zZXREZXNjKCdUaGlzIGNvbG9yIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGVudGlyZSBwcm9ncmVlcyBiYXIgaWYgdGhlIHBlcmNlbnRhZ2UgaXMgd2l0aGluIHRoZSBmaWZ0aCBzZWN0aW9uLicpXG5cdFx0XHRcdFx0XHQuYWRkQ29sb3JQaWNrZXIoKFBCY29sb3JwaWNrZXI1KSA9Plx0UEJjb2xvcnBpY2tlcjVcblx0XHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjUpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjUgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdFx0fSkpXG5cdFx0XHRcdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRcdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvcjUgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvcjVMaWdodCBhcyBzdHJpbmc7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHRcdFx0XHRcdH0pKVxuXHRcdFx0XHRcdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0XHRcdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3I1ID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3I1IGFzIHN0cmluZztcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdC8qKioqKioqKioqKiogQ29tcGxldGVkIENvbG9yICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdDb21wbGV0ZWQgY29sb3InKVxuXHRcdC5zZXREZXNjKCdTZWxlY3QgdGhlIGNvbG9yIHRoZSBlbnRpcmUgcHJvZ3Jlc3MgYmFyIHdpbGwgdXNlIHdoZW4gaXQgcmVhY2hlcyAxMDAlIGNvbXBsZXRpb24uJylcblx0XHQuYWRkQ29sb3JQaWNrZXIoKFBCY29sb3JwaWNrZXIwKSA9Plx0UEJjb2xvcnBpY2tlcjBcblx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYXJDb21wbGV0ZWQpLm9uQ2hhbmdlKCh2YWx1ZSkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYXJDb21wbGV0ZWQgPSB2YWx1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdFx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRcdGJ1dHRvbi5zZXRJY29uKCdzdW4nKS5zZXRUb29sdGlwKCdSZXNldCB0byBMaWdodCBkZWZhdWx0Jylcblx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhckNvbXBsZXRlZCA9IERFRkFVTFRfU0VUVElOR1MuQVBCX2NvbG9yTGlnaHRCYXJDb21wbGV0ZWQgYXMgc3RyaW5nO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KSlcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cblx0XHRcdFx0YnV0dG9uLnNldEljb24oJ21vb24nKS5zZXRUb29sdGlwKCdSZXNldCB0byBEYXJrIGRlZmF1bHQnKVxuXHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yQmFyQ29tcGxldGVkID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3JCYXJDb21wbGV0ZWQgYXMgc3RyaW5nO1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHQvKioqKioqKioqKioqIEJhciBCYWNrZ3JvdW5kIENvbG9yICoqKioqKioqKioqKiovXG5cdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdC5zZXROYW1lKCdCYXIgYmFja2dyb3VuZCBjb2xvcicpXG5cdFx0LnNldERlc2MoJ1RoaXMgY29sb3Igd2lsbCBiZSB1c2VkIGZvciB0aGUgcHJvZ3Jlc3MgYmFyXFwncyBiYWNrZ3JvdW5kLCByZXByZXNlbnRpbmcgdGhlIHJlbWFpbmluZyBwZXJjZW50YWdlLicpXG5cdFx0LmFkZENvbG9yUGlja2VyKChQQmNvbG9ycGlja2VyMCkgPT5cdFBCY29sb3JwaWNrZXIwXG5cdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuQVBCX2NvbG9yQmFyQmFja2dyb3VuZCkub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhckJhY2tncm91bmQgPSB2YWx1ZTtcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xuXHRcdFx0fSkpXG5cdFx0LmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuXHRcdFx0YnV0dG9uLnNldEljb24oJ3N1bicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIExpZ2h0IGRlZmF1bHQnKVxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5BUEJfY29sb3JCYXJCYWNrZ3JvdW5kID0gREVGQVVMVF9TRVRUSU5HUy5BUEJfY29sb3JMaWdodEJhckJhY2tncm91bmQgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KSlcblx0XHQuYWRkQnV0dG9uKChidXR0b24pID0+XG5cdFx0XHRidXR0b24uc2V0SWNvbignbW9vbicpLnNldFRvb2x0aXAoJ1Jlc2V0IHRvIERhcmsgZGVmYXVsdCcpXG5cdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLkFQQl9jb2xvckJhckJhY2tncm91bmQgPSBERUZBVUxUX1NFVFRJTkdTLkFQQl9jb2xvckJhckJhY2tncm91bmQgYXMgc3RyaW5nO1xuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XG5cdFx0XHR9KVxuXHRcdCk7XG4gICAgfVxufVxuXG4vKioqKioqKioqKioqIHNldEVuZENhcHMgRnVuY3Rpb24gKioqKioqKioqKioqKi9cbmZ1bmN0aW9uIHNldEVuZENhcHMocHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kOiBIVE1MRWxlbWVudCB8IG51bGwsIHByb2dyZXNzYmFyOiBIVE1MRWxlbWVudCB8IG51bGwsIGVuZENhcDogYm9vbGVhbikge1xuXHRpZiAocHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kICYmIHByb2dyZXNzYmFyKSB7XG5cdFx0aWYgKGVuZENhcCkge1xuXHRcdFx0cHJvZ3Jlc3NCYXJCYWNrZ3JvdW5kLnN0eWxlLmJvcmRlclJhZGl1cyA9ICc3cHgnO1xuXHRcdFx0cHJvZ3Jlc3NiYXIuc3R5bGUuYm9yZGVyUmFkaXVzID0gJzdweCc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHByb2dyZXNzQmFyQmFja2dyb3VuZC5zdHlsZS5ib3JkZXJSYWRpdXMgPSAnMHB4Jztcblx0XHRcdHByb2dyZXNzYmFyLnN0eWxlLmJvcmRlclJhZGl1cyA9ICcwcHgnO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRjb25zb2xlLmVycm9yKCdFbGVtZW50cyBhcmUgbm90IGRlZmluZWQnKTtcblx0fVxufVxuXG5mdW5jdGlvbiBoZXhUb1JnYmEoaGV4OiBzdHJpbmcsIGFscGhhOiBudW1iZXIgPSAxKTogc3RyaW5nIHtcbiAgICBoZXggPSBoZXgucmVwbGFjZSgnIycsICcnKTtcblxuICAgIC8vIElmIGhleCBpcyAzIGNoYXJhY3RlcnMsIGV4cGFuZCB0byA2IChlLmcuLCAjRjAwID0+ICNGRjAwMDApXG4gICAgaWYgKGhleC5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgaGV4ID0gaGV4LnNwbGl0KCcnKS5tYXAoY2hhciA9PiBjaGFyICsgY2hhcikuam9pbignJyk7XG4gICAgfVxuXG4gICAgLy8gQ29udmVydCBoZXggdG8gUkdCIHZhbHVlc1xuICAgIGNvbnN0IHIgPSBwYXJzZUludChoZXguc2xpY2UoMCwgMiksIDE2KTtcbiAgICBjb25zdCBnID0gcGFyc2VJbnQoaGV4LnNsaWNlKDIsIDQpLCAxNik7XG4gICAgY29uc3QgYiA9IHBhcnNlSW50KGhleC5zbGljZSg0LCA2KSwgMTYpO1xuXG4gICAgLy8gUmV0dXJuIHRoZSBSR0JBIHN0cmluZ1xuICAgIHJldHVybiBgcmdiYSgke3J9LCAke2d9LCAke2J9LCAke2FscGhhfSlgO1xufSJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxzQkFBaUU7QUF3RGpFLElBQU0sbUJBQTBEO0FBQUE7QUFBQSxFQUUvRCxXQUFXO0FBQUEsRUFDWCxpQkFBaUI7QUFBQSxFQUNqQixXQUFXO0FBQUEsRUFDWCxZQUFZO0FBQUEsRUFDWiwyQkFBMkI7QUFBQSxFQUMzQixXQUFXO0FBQUEsRUFDWCxrQkFBa0I7QUFBQSxFQUNsQixpQkFBaUI7QUFBQSxFQUNqQixnQkFBZ0I7QUFBQSxFQUNoQixxQkFBcUI7QUFBQSxFQUNyQixnQkFBZ0I7QUFBQTtBQUFBLEVBRWhCLGlCQUFpQjtBQUFBLEVBQ2pCLGdCQUFnQjtBQUFBLEVBQ2hCLHFCQUFxQjtBQUFBLEVBQ3JC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QUNkLENBQUMsQ0FBQyxFQUNGO0FBQUEsTUFBVSxDQUFDLFdBQ1gsT0FBTyxRQUFRLE1BQU0sRUFBRSxXQUFXLHVCQUF1QixFQUN4RCxRQUFRLE1BQU07QUFDZCxhQUFLLE9BQU8sU0FBUyx5QkFBeUIsaUJBQWlCO0FBQy9ELGFBQUssT0FBTyxhQUFhO0FBQ3pCLGFBQUssUUFBUTtBQUFBLE1BQ2QsQ0FBQztBQUFBLElBQ0Y7QUFBQSxFQUNFO0FBQ0o7QUFHQSxTQUFTLFdBQVcsdUJBQTJDLGFBQWlDLFFBQWlCO0FBQ2hILE1BQUkseUJBQXlCLGFBQWE7QUFDekMsUUFBSSxRQUFRO0FBQ1gsNEJBQXNCLE1BQU0sZUFBZTtBQUMzQyxrQkFBWSxNQUFNLGVBQWU7QUFBQSxJQUNsQyxPQUFPO0FBQ04sNEJBQXNCLE1BQU0sZUFBZTtBQUMzQyxrQkFBWSxNQUFNLGVBQWU7QUFBQSxJQUNsQztBQUFBLEVBQ0QsT0FBTztBQUNOLFlBQVEsTUFBTSwwQkFBMEI7QUFBQSxFQUN6QztBQUNEO0FBRUEsU0FBUyxVQUFVLEtBQWEsUUFBZ0IsR0FBVztBQUN2RCxRQUFNLElBQUksUUFBUSxLQUFLLEVBQUU7QUFHekIsTUFBSSxJQUFJLFdBQVcsR0FBRztBQUNsQixVQUFNLElBQUksTUFBTSxFQUFFLEVBQUUsSUFBSSxVQUFRLE9BQU8sSUFBSSxFQUFFLEtBQUssRUFBRTtBQUFBLEVBQ3hEO0FBR0EsUUFBTSxJQUFJLFNBQVMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEVBQUU7QUFDdEMsUUFBTSxJQUFJLFNBQVMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEVBQUU7QUFDdEMsUUFBTSxJQUFJLFNBQVMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxHQUFHLEVBQUU7QUFHdEMsU0FBTyxRQUFRLE1BQU0sTUFBTSxNQUFNO0FBQ3JDOyIsCiAgIm5hbWVzIjogWyJ2YWx1ZUZyb21QZXJjZW50YWdlT2ZUb3RhbCIsICJjb250YWluZXIiLCAicHJvZ3Jlc3NCYXJQZXJjZW50YWdlIiwgIl9hIiwgInRpbWVvdXRJZCJdCn0K diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..d36b8d3 --- /dev/null +++ b/manifest.json @@ -0,0 +1,17 @@ +{ + "id": "obsidian-advanced-progress-bars", + "name": "Advanced Progress Bars", + "version": "1.0.1", + "minAppVersion": "0.15.0", + "description": "Progress bars that can change color depending on completion value - fully customizable.", + "author": "cactuzhead", + "authorUrl": "https://cactuzhead.com", + "fundingUrl": "https://ko-fi.com/cactuzhead", + "isDesktopOnly": false, + "commands": [ + { + "id": "paste-code-block", + "name": "Paste Code Block" + } + ] +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..2139fef --- /dev/null +++ b/styles.css @@ -0,0 +1,154 @@ +:root { + color-scheme: light dark; +} + +h3, .markdown-rendered h3 { + color: #a3be8c; +} + +h4, .markdown-rendered h4 { + color: #689DED; +} + +.highlight-text { + color: light-dark(#ec7e83, #71d1c4); +} + +.custom-textbox { + width: 60px; +} + +.custom-container { + align-Items: center; + border-Radius: 7px; + border: 1px solid #689ded; + display: flex; + justify-Content: space-between; + margin: 0px; +} + +.custom-container img { + padding-right: 1em; +} + +.custom-container p { + color: #8fa0ba; + flex: 1 1 auto; + min-width: 10px; + overflow: hidden; + padding-left: 1em; + white-space: wrap; + width: 160px; +} + +.progressBar-container { + border-radius: 7px; + display: flex; + flex-flow: row wrap; + margin-top: 7px; + overflow: hidden; + padding: 5px; + position: relative; + width: 100%; +} + +.progressBar-text-container { + align-items: center; + box-sizing: border-box; + display: flex; + flex-flow: row nowrap; + font-family: Arial, Helvetica, sans-serif; + font-size: 0.75rem; + justify-content: space-between; + overflow: hidden; + padding: 0 0 0.3em 0; + width: 100%; +} + +.progressBar-title { + color: #8fa0ba; + flex: 1 1 0; + min-width: 10px; + overflow: hidden; + padding: 0 0.3em; + text-overflow: ellipsis; + white-space: nowrap; + width: 10px; +} + +.progressBar-percentage { + color: #c1d7f9; + flex: 0 0 auto; + padding: 0 0 0 0.3em; + text-align: right; +} + +.progressBar-value { + color: #8fa0ba; + flex: 0 0 auto; + padding: 0 0.3em; + text-align: right; +} + +.progressBar-completed { + color: #c1d7f9; + font-size: 0.75em; + font-weight: 500; + overflow: hidden; + padding: 0 0 0 0.3em; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; +} + +.progressBar-background { + display: flex; + flex-flow: row nowrap; + position: relative; +} + +.progressBar { + display: flex; + justify-Content: space-between; + margin: 0px; + align-Items: center; +} + +.marks { + height: 100%; + left: 0; + pointer-events: none; + position: absolute; + top: 0; + width: 100%; + } + +.mark { + height: 100%; + position: absolute; + top: 0; + z-index: 1; + } + +.error-container { + background:#912f3c; + border-radius: 7px; + display: flex; + flex-flow: row wrap; + overflow: hidden; + padding: 5px; + position: relative; +} + +.error-text-container { + align-items: center; + color:#ffffff; + display: flex; + flex-flow: row nowrap; + font-family: Arial, Helvetica, sans-serif; + font-size: 0.75rem; + justify-content: space-between; + padding: 0.3em; + width: 100%; +} \ No newline at end of file