From 8c84faecd39f526a2c49c1029868b0904addcb45 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Tue, 1 Aug 2023 21:42:33 +0200 Subject: [PATCH 1/2] Create main.js --- main.js | 4250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4250 insertions(+) create mode 100644 main.js diff --git a/main.js b/main.js new file mode 100644 index 0000000..9d02e2e --- /dev/null +++ b/main.js @@ -0,0 +1,4250 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js +var require_Api = __commonJS({ + "node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } +}); + +// node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js +var require_EventDispatcher = __commonJS({ + "node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } +}); + +// node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js +var require_Resolver = __commonJS({ + "node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } +}); + +// node_modules/front-matter-plugin-api-provider/lib/index.js +var require_lib = __commonJS({ + "node_modules/front-matter-plugin-api-provider/lib/index.js"(exports) { + "use strict"; + var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + o[k2] = m[k]; + }); + var __exportStar = exports && exports.__exportStar || function(m, exports2) { + for (var p in m) + if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) + __createBinding(exports2, m, p); + }; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.getApiSafe = exports.getDefer = exports.isPluginEnabled = exports.PluginNotEnabledError = exports.pluginId = void 0; + __exportStar(require_Api(), exports); + __exportStar(require_EventDispatcher(), exports); + __exportStar(require_Resolver(), exports); + exports.pluginId = "obsidian-front-matter-title-plugin"; + var PluginNotEnabledError = class extends Error { + }; + exports.PluginNotEnabledError = PluginNotEnabledError; + function isPluginEnabled(app2) { + var _a, _b, _c; + return (_c = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.enabledPlugins) === null || _b === void 0 ? void 0 : _b.has(exports.pluginId)) !== null && _c !== void 0 ? _c : false; + } + exports.isPluginEnabled = isPluginEnabled; + function getDefer2(app2) { + var _a, _b, _c, _d; + const plugin = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin(exports.pluginId)) !== null && _b !== void 0 ? _b : null; + const defer = (_d = (_c = plugin === null || plugin === void 0 ? void 0 : plugin.getDefer) === null || _c === void 0 ? void 0 : _c.call(plugin)) !== null && _d !== void 0 ? _d : null; + if (defer === null) { + throw new PluginNotEnabledError(`Plugin ${exports.pluginId} is not enabled or old version`); + } + return defer; + } + exports.getDefer = getDefer2; + function getApiSafe(app2) { + return new ApiWrapper(null, app2); + } + exports.getApiSafe = getApiSafe; + var ApiWrapper = class { + constructor(api, app2) { + this.api = api; + this.app = app2; + } + before() { + if (this.api !== null) { + return; + } + const defer = this.getDeffer(); + if (defer === null) { + return; + } + const api = defer.getApi(); + if (api === null) { + return defer.awaitPlugin().then(() => { + this.api = defer.getApi(); + }); + } else { + this.api = api; + } + } + getDeffer() { + try { + return getDefer2(this.app); + } catch (e) { + if (e instanceof PluginNotEnabledError) { + return null; + } + throw e; + } + } + getResolverFactory() { + var _a, _b; + this.before(); + return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getResolverFactory()) !== null && _b !== void 0 ? _b : null; + } + getEventDispatcher() { + var _a, _b; + this.before(); + return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEventDispatcher()) !== null && _b !== void 0 ? _b : null; + } + getEnabledFeatures() { + var _a, _b; + this.before(); + return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEnabledFeatures()) !== null && _b !== void 0 ? _b : []; + } + }; + } +}); + +// src/main.ts +var main_exports = {}; +__export(main_exports, { + default: () => FolderNotesPlugin +}); +module.exports = __toCommonJS(main_exports); +var import_obsidian19 = require("obsidian"); + +// src/settings.ts +var import_obsidian12 = require("obsidian"); + +// src/suggesters/templateSuggester.ts +var import_obsidian3 = require("obsidian"); + +// src/suggesters/suggest.ts +var import_obsidian = require("obsidian"); + +// node_modules/@popperjs/core/lib/enums.js +var top = "top"; +var bottom = "bottom"; +var right = "right"; +var left = "left"; +var auto = "auto"; +var basePlacements = [top, bottom, right, left]; +var start = "start"; +var end = "end"; +var clippingParents = "clippingParents"; +var viewport = "viewport"; +var popper = "popper"; +var reference = "reference"; +var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) { + return acc.concat([placement + "-" + start, placement + "-" + end]); +}, []); +var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) { + return acc.concat([placement, placement + "-" + start, placement + "-" + end]); +}, []); +var beforeRead = "beforeRead"; +var read = "read"; +var afterRead = "afterRead"; +var beforeMain = "beforeMain"; +var main = "main"; +var afterMain = "afterMain"; +var beforeWrite = "beforeWrite"; +var write = "write"; +var afterWrite = "afterWrite"; +var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; + +// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js +function getNodeName(element) { + return element ? (element.nodeName || "").toLowerCase() : null; +} + +// node_modules/@popperjs/core/lib/dom-utils/getWindow.js +function getWindow(node) { + if (node == null) { + return window; + } + if (node.toString() !== "[object Window]") { + var ownerDocument = node.ownerDocument; + return ownerDocument ? ownerDocument.defaultView || window : window; + } + return node; +} + +// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js +function isElement(node) { + var OwnElement = getWindow(node).Element; + return node instanceof OwnElement || node instanceof Element; +} +function isHTMLElement(node) { + var OwnElement = getWindow(node).HTMLElement; + return node instanceof OwnElement || node instanceof HTMLElement; +} +function isShadowRoot(node) { + if (typeof ShadowRoot === "undefined") { + return false; + } + var OwnElement = getWindow(node).ShadowRoot; + return node instanceof OwnElement || node instanceof ShadowRoot; +} + +// node_modules/@popperjs/core/lib/modifiers/applyStyles.js +function applyStyles(_ref) { + var state = _ref.state; + Object.keys(state.elements).forEach(function(name) { + var style = state.styles[name] || {}; + var attributes = state.attributes[name] || {}; + var element = state.elements[name]; + if (!isHTMLElement(element) || !getNodeName(element)) { + return; + } + Object.assign(element.style, style); + Object.keys(attributes).forEach(function(name2) { + var value = attributes[name2]; + if (value === false) { + element.removeAttribute(name2); + } else { + element.setAttribute(name2, value === true ? "" : value); + } + }); + }); +} +function effect(_ref2) { + var state = _ref2.state; + var initialStyles = { + popper: { + position: state.options.strategy, + left: "0", + top: "0", + margin: "0" + }, + arrow: { + position: "absolute" + }, + reference: {} + }; + Object.assign(state.elements.popper.style, initialStyles.popper); + state.styles = initialStyles; + if (state.elements.arrow) { + Object.assign(state.elements.arrow.style, initialStyles.arrow); + } + return function() { + Object.keys(state.elements).forEach(function(name) { + var element = state.elements[name]; + var attributes = state.attributes[name] || {}; + var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); + var style = styleProperties.reduce(function(style2, property) { + style2[property] = ""; + return style2; + }, {}); + if (!isHTMLElement(element) || !getNodeName(element)) { + return; + } + Object.assign(element.style, style); + Object.keys(attributes).forEach(function(attribute) { + element.removeAttribute(attribute); + }); + }); + }; +} +var applyStyles_default = { + name: "applyStyles", + enabled: true, + phase: "write", + fn: applyStyles, + effect, + requires: ["computeStyles"] +}; + +// node_modules/@popperjs/core/lib/utils/getBasePlacement.js +function getBasePlacement(placement) { + return placement.split("-")[0]; +} + +// node_modules/@popperjs/core/lib/utils/math.js +var max = Math.max; +var min = Math.min; +var round = Math.round; + +// node_modules/@popperjs/core/lib/utils/userAgent.js +function getUAString() { + var uaData = navigator.userAgentData; + if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { + return uaData.brands.map(function(item) { + return item.brand + "/" + item.version; + }).join(" "); + } + return navigator.userAgent; +} + +// node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js +function isLayoutViewport() { + return !/^((?!chrome|android).)*safari/i.test(getUAString()); +} + +// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js +function getBoundingClientRect(element, includeScale, isFixedStrategy) { + if (includeScale === void 0) { + includeScale = false; + } + if (isFixedStrategy === void 0) { + isFixedStrategy = false; + } + var clientRect = element.getBoundingClientRect(); + var scaleX = 1; + var scaleY = 1; + if (includeScale && isHTMLElement(element)) { + scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; + scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; + } + var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport; + var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; + var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; + var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; + var width = clientRect.width / scaleX; + var height = clientRect.height / scaleY; + return { + width, + height, + top: y, + right: x + width, + bottom: y + height, + left: x, + x, + y + }; +} + +// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js +function getLayoutRect(element) { + var clientRect = getBoundingClientRect(element); + var width = element.offsetWidth; + var height = element.offsetHeight; + if (Math.abs(clientRect.width - width) <= 1) { + width = clientRect.width; + } + if (Math.abs(clientRect.height - height) <= 1) { + height = clientRect.height; + } + return { + x: element.offsetLeft, + y: element.offsetTop, + width, + height + }; +} + +// node_modules/@popperjs/core/lib/dom-utils/contains.js +function contains(parent, child) { + var rootNode = child.getRootNode && child.getRootNode(); + if (parent.contains(child)) { + return true; + } else if (rootNode && isShadowRoot(rootNode)) { + var next = child; + do { + if (next && parent.isSameNode(next)) { + return true; + } + next = next.parentNode || next.host; + } while (next); + } + return false; +} + +// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js +function getComputedStyle(element) { + return getWindow(element).getComputedStyle(element); +} + +// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js +function isTableElement(element) { + return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0; +} + +// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js +function getDocumentElement(element) { + return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement; +} + +// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js +function getParentNode(element) { + if (getNodeName(element) === "html") { + return element; + } + return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element); +} + +// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js +function getTrueOffsetParent(element) { + if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") { + return null; + } + return element.offsetParent; +} +function getContainingBlock(element) { + var isFirefox = /firefox/i.test(getUAString()); + var isIE = /Trident/i.test(getUAString()); + if (isIE && isHTMLElement(element)) { + var elementCss = getComputedStyle(element); + if (elementCss.position === "fixed") { + return null; + } + } + var currentNode = getParentNode(element); + if (isShadowRoot(currentNode)) { + currentNode = currentNode.host; + } + while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) { + var css = getComputedStyle(currentNode); + if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { + return currentNode; + } else { + currentNode = currentNode.parentNode; + } + } + return null; +} +function getOffsetParent(element) { + var window2 = getWindow(element); + var offsetParent = getTrueOffsetParent(element); + while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") { + offsetParent = getTrueOffsetParent(offsetParent); + } + if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) { + return window2; + } + return offsetParent || getContainingBlock(element) || window2; +} + +// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js +function getMainAxisFromPlacement(placement) { + return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y"; +} + +// node_modules/@popperjs/core/lib/utils/within.js +function within(min2, value, max2) { + return max(min2, min(value, max2)); +} +function withinMaxClamp(min2, value, max2) { + var v = within(min2, value, max2); + return v > max2 ? max2 : v; +} + +// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js +function getFreshSideObject() { + return { + top: 0, + right: 0, + bottom: 0, + left: 0 + }; +} + +// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js +function mergePaddingObject(paddingObject) { + return Object.assign({}, getFreshSideObject(), paddingObject); +} + +// node_modules/@popperjs/core/lib/utils/expandToHashMap.js +function expandToHashMap(value, keys) { + return keys.reduce(function(hashMap, key) { + hashMap[key] = value; + return hashMap; + }, {}); +} + +// node_modules/@popperjs/core/lib/modifiers/arrow.js +var toPaddingObject = function toPaddingObject2(padding, state) { + padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { + placement: state.placement + })) : padding; + return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); +}; +function arrow(_ref) { + var _state$modifiersData$; + var state = _ref.state, name = _ref.name, options = _ref.options; + var arrowElement = state.elements.arrow; + var popperOffsets2 = state.modifiersData.popperOffsets; + var basePlacement = getBasePlacement(state.placement); + var axis = getMainAxisFromPlacement(basePlacement); + var isVertical = [left, right].indexOf(basePlacement) >= 0; + var len = isVertical ? "height" : "width"; + if (!arrowElement || !popperOffsets2) { + return; + } + var paddingObject = toPaddingObject(options.padding, state); + var arrowRect = getLayoutRect(arrowElement); + var minProp = axis === "y" ? top : left; + var maxProp = axis === "y" ? bottom : right; + var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len]; + var startDiff = popperOffsets2[axis] - state.rects.reference[axis]; + var arrowOffsetParent = getOffsetParent(arrowElement); + var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; + var centerToReference = endDiff / 2 - startDiff / 2; + var min2 = paddingObject[minProp]; + var max2 = clientSize - arrowRect[len] - paddingObject[maxProp]; + var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; + var offset2 = within(min2, center, max2); + var axisProp = axis; + state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$); +} +function effect2(_ref2) { + var state = _ref2.state, options = _ref2.options; + var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; + if (arrowElement == null) { + return; + } + if (typeof arrowElement === "string") { + arrowElement = state.elements.popper.querySelector(arrowElement); + if (!arrowElement) { + return; + } + } + if (!contains(state.elements.popper, arrowElement)) { + return; + } + state.elements.arrow = arrowElement; +} +var arrow_default = { + name: "arrow", + enabled: true, + phase: "main", + fn: arrow, + effect: effect2, + requires: ["popperOffsets"], + requiresIfExists: ["preventOverflow"] +}; + +// node_modules/@popperjs/core/lib/utils/getVariation.js +function getVariation(placement) { + return placement.split("-")[1]; +} + +// node_modules/@popperjs/core/lib/modifiers/computeStyles.js +var unsetSides = { + top: "auto", + right: "auto", + bottom: "auto", + left: "auto" +}; +function roundOffsetsByDPR(_ref, win) { + var x = _ref.x, y = _ref.y; + var dpr = win.devicePixelRatio || 1; + return { + x: round(x * dpr) / dpr || 0, + y: round(y * dpr) / dpr || 0 + }; +} +function mapToStyles(_ref2) { + var _Object$assign2; + var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; + var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; + var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ + x, + y + }) : { + x, + y + }; + x = _ref3.x; + y = _ref3.y; + var hasX = offsets.hasOwnProperty("x"); + var hasY = offsets.hasOwnProperty("y"); + var sideX = left; + var sideY = top; + var win = window; + if (adaptive) { + var offsetParent = getOffsetParent(popper2); + var heightProp = "clientHeight"; + var widthProp = "clientWidth"; + if (offsetParent === getWindow(popper2)) { + offsetParent = getDocumentElement(popper2); + if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") { + heightProp = "scrollHeight"; + widthProp = "scrollWidth"; + } + } + offsetParent = offsetParent; + if (placement === top || (placement === left || placement === right) && variation === end) { + sideY = bottom; + var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp]; + y -= offsetY - popperRect.height; + y *= gpuAcceleration ? 1 : -1; + } + if (placement === left || (placement === top || placement === bottom) && variation === end) { + sideX = right; + var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp]; + x -= offsetX - popperRect.width; + x *= gpuAcceleration ? 1 : -1; + } + } + var commonStyles = Object.assign({ + position + }, adaptive && unsetSides); + var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ + x, + y + }, getWindow(popper2)) : { + x, + y + }; + x = _ref4.x; + y = _ref4.y; + if (gpuAcceleration) { + var _Object$assign; + return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); + } + return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); +} +function computeStyles(_ref5) { + var state = _ref5.state, options = _ref5.options; + var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; + var commonStyles = { + placement: getBasePlacement(state.placement), + variation: getVariation(state.placement), + popper: state.elements.popper, + popperRect: state.rects.popper, + gpuAcceleration, + isFixed: state.options.strategy === "fixed" + }; + if (state.modifiersData.popperOffsets != null) { + state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { + offsets: state.modifiersData.popperOffsets, + position: state.options.strategy, + adaptive, + roundOffsets + }))); + } + if (state.modifiersData.arrow != null) { + state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { + offsets: state.modifiersData.arrow, + position: "absolute", + adaptive: false, + roundOffsets + }))); + } + state.attributes.popper = Object.assign({}, state.attributes.popper, { + "data-popper-placement": state.placement + }); +} +var computeStyles_default = { + name: "computeStyles", + enabled: true, + phase: "beforeWrite", + fn: computeStyles, + data: {} +}; + +// node_modules/@popperjs/core/lib/modifiers/eventListeners.js +var passive = { + passive: true +}; +function effect3(_ref) { + var state = _ref.state, instance = _ref.instance, options = _ref.options; + var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize; + var window2 = getWindow(state.elements.popper); + var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); + if (scroll) { + scrollParents.forEach(function(scrollParent) { + scrollParent.addEventListener("scroll", instance.update, passive); + }); + } + if (resize) { + window2.addEventListener("resize", instance.update, passive); + } + return function() { + if (scroll) { + scrollParents.forEach(function(scrollParent) { + scrollParent.removeEventListener("scroll", instance.update, passive); + }); + } + if (resize) { + window2.removeEventListener("resize", instance.update, passive); + } + }; +} +var eventListeners_default = { + name: "eventListeners", + enabled: true, + phase: "write", + fn: function fn() { + }, + effect: effect3, + data: {} +}; + +// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js +var hash = { + left: "right", + right: "left", + bottom: "top", + top: "bottom" +}; +function getOppositePlacement(placement) { + return placement.replace(/left|right|bottom|top/g, function(matched) { + return hash[matched]; + }); +} + +// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js +var hash2 = { + start: "end", + end: "start" +}; +function getOppositeVariationPlacement(placement) { + return placement.replace(/start|end/g, function(matched) { + return hash2[matched]; + }); +} + +// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js +function getWindowScroll(node) { + var win = getWindow(node); + var scrollLeft = win.pageXOffset; + var scrollTop = win.pageYOffset; + return { + scrollLeft, + scrollTop + }; +} + +// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js +function getWindowScrollBarX(element) { + return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; +} + +// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js +function getViewportRect(element, strategy) { + var win = getWindow(element); + var html = getDocumentElement(element); + var visualViewport = win.visualViewport; + var width = html.clientWidth; + var height = html.clientHeight; + var x = 0; + var y = 0; + if (visualViewport) { + width = visualViewport.width; + height = visualViewport.height; + var layoutViewport = isLayoutViewport(); + if (layoutViewport || !layoutViewport && strategy === "fixed") { + x = visualViewport.offsetLeft; + y = visualViewport.offsetTop; + } + } + return { + width, + height, + x: x + getWindowScrollBarX(element), + y + }; +} + +// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js +function getDocumentRect(element) { + var _element$ownerDocumen; + var html = getDocumentElement(element); + var winScroll = getWindowScroll(element); + var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; + var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); + var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); + var x = -winScroll.scrollLeft + getWindowScrollBarX(element); + var y = -winScroll.scrollTop; + if (getComputedStyle(body || html).direction === "rtl") { + x += max(html.clientWidth, body ? body.clientWidth : 0) - width; + } + return { + width, + height, + x, + y + }; +} + +// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js +function isScrollParent(element) { + var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; + return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); +} + +// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js +function getScrollParent(node) { + if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) { + return node.ownerDocument.body; + } + if (isHTMLElement(node) && isScrollParent(node)) { + return node; + } + return getScrollParent(getParentNode(node)); +} + +// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js +function listScrollParents(element, list) { + var _element$ownerDocumen; + if (list === void 0) { + list = []; + } + var scrollParent = getScrollParent(element); + var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); + var win = getWindow(scrollParent); + var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; + var updatedList = list.concat(target); + return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target))); +} + +// node_modules/@popperjs/core/lib/utils/rectToClientRect.js +function rectToClientRect(rect) { + return Object.assign({}, rect, { + left: rect.x, + top: rect.y, + right: rect.x + rect.width, + bottom: rect.y + rect.height + }); +} + +// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js +function getInnerBoundingClientRect(element, strategy) { + var rect = getBoundingClientRect(element, false, strategy === "fixed"); + rect.top = rect.top + element.clientTop; + rect.left = rect.left + element.clientLeft; + rect.bottom = rect.top + element.clientHeight; + rect.right = rect.left + element.clientWidth; + rect.width = element.clientWidth; + rect.height = element.clientHeight; + rect.x = rect.left; + rect.y = rect.top; + return rect; +} +function getClientRectFromMixedType(element, clippingParent, strategy) { + return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); +} +function getClippingParents(element) { + var clippingParents2 = listScrollParents(getParentNode(element)); + var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0; + var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; + if (!isElement(clipperElement)) { + return []; + } + return clippingParents2.filter(function(clippingParent) { + return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body"; + }); +} +function getClippingRect(element, boundary, rootBoundary, strategy) { + var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); + var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]); + var firstClippingParent = clippingParents2[0]; + var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) { + var rect = getClientRectFromMixedType(element, clippingParent, strategy); + accRect.top = max(rect.top, accRect.top); + accRect.right = min(rect.right, accRect.right); + accRect.bottom = min(rect.bottom, accRect.bottom); + accRect.left = max(rect.left, accRect.left); + return accRect; + }, getClientRectFromMixedType(element, firstClippingParent, strategy)); + clippingRect.width = clippingRect.right - clippingRect.left; + clippingRect.height = clippingRect.bottom - clippingRect.top; + clippingRect.x = clippingRect.left; + clippingRect.y = clippingRect.top; + return clippingRect; +} + +// node_modules/@popperjs/core/lib/utils/computeOffsets.js +function computeOffsets(_ref) { + var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement; + var basePlacement = placement ? getBasePlacement(placement) : null; + var variation = placement ? getVariation(placement) : null; + var commonX = reference2.x + reference2.width / 2 - element.width / 2; + var commonY = reference2.y + reference2.height / 2 - element.height / 2; + var offsets; + switch (basePlacement) { + case top: + offsets = { + x: commonX, + y: reference2.y - element.height + }; + break; + case bottom: + offsets = { + x: commonX, + y: reference2.y + reference2.height + }; + break; + case right: + offsets = { + x: reference2.x + reference2.width, + y: commonY + }; + break; + case left: + offsets = { + x: reference2.x - element.width, + y: commonY + }; + break; + default: + offsets = { + x: reference2.x, + y: reference2.y + }; + } + var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; + if (mainAxis != null) { + var len = mainAxis === "y" ? "height" : "width"; + switch (variation) { + case start: + offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2); + break; + case end: + offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2); + break; + default: + } + } + return offsets; +} + +// node_modules/@popperjs/core/lib/utils/detectOverflow.js +function detectOverflow(state, options) { + if (options === void 0) { + options = {}; + } + var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; + var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); + var altContext = elementContext === popper ? reference : popper; + var popperRect = state.rects.popper; + var element = state.elements[altBoundary ? altContext : elementContext]; + var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); + var referenceClientRect = getBoundingClientRect(state.elements.reference); + var popperOffsets2 = computeOffsets({ + reference: referenceClientRect, + element: popperRect, + strategy: "absolute", + placement + }); + var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2)); + var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; + var overflowOffsets = { + top: clippingClientRect.top - elementClientRect.top + paddingObject.top, + bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, + left: clippingClientRect.left - elementClientRect.left + paddingObject.left, + right: elementClientRect.right - clippingClientRect.right + paddingObject.right + }; + var offsetData = state.modifiersData.offset; + if (elementContext === popper && offsetData) { + var offset2 = offsetData[placement]; + Object.keys(overflowOffsets).forEach(function(key) { + var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; + var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x"; + overflowOffsets[key] += offset2[axis] * multiply; + }); + } + return overflowOffsets; +} + +// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js +function computeAutoPlacement(state, options) { + if (options === void 0) { + options = {}; + } + var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; + var variation = getVariation(placement); + var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) { + return getVariation(placement2) === variation; + }) : basePlacements; + var allowedPlacements = placements2.filter(function(placement2) { + return allowedAutoPlacements.indexOf(placement2) >= 0; + }); + if (allowedPlacements.length === 0) { + allowedPlacements = placements2; + } + var overflows = allowedPlacements.reduce(function(acc, placement2) { + acc[placement2] = detectOverflow(state, { + placement: placement2, + boundary, + rootBoundary, + padding + })[getBasePlacement(placement2)]; + return acc; + }, {}); + return Object.keys(overflows).sort(function(a, b) { + return overflows[a] - overflows[b]; + }); +} + +// node_modules/@popperjs/core/lib/modifiers/flip.js +function getExpandedFallbackPlacements(placement) { + if (getBasePlacement(placement) === auto) { + return []; + } + var oppositePlacement = getOppositePlacement(placement); + return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; +} +function flip(_ref) { + var state = _ref.state, options = _ref.options, name = _ref.name; + if (state.modifiersData[name]._skip) { + return; + } + var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements; + var preferredPlacement = state.options.placement; + var basePlacement = getBasePlacement(preferredPlacement); + var isBasePlacement = basePlacement === preferredPlacement; + var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); + var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) { + return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, { + placement: placement2, + boundary, + rootBoundary, + padding, + flipVariations, + allowedAutoPlacements + }) : placement2); + }, []); + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var checksMap = /* @__PURE__ */ new Map(); + var makeFallbackChecks = true; + var firstFittingPlacement = placements2[0]; + for (var i = 0; i < placements2.length; i++) { + var placement = placements2[i]; + var _basePlacement = getBasePlacement(placement); + var isStartVariation = getVariation(placement) === start; + var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; + var len = isVertical ? "width" : "height"; + var overflow = detectOverflow(state, { + placement, + boundary, + rootBoundary, + altBoundary, + padding + }); + var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; + if (referenceRect[len] > popperRect[len]) { + mainVariationSide = getOppositePlacement(mainVariationSide); + } + var altVariationSide = getOppositePlacement(mainVariationSide); + var checks = []; + if (checkMainAxis) { + checks.push(overflow[_basePlacement] <= 0); + } + if (checkAltAxis) { + checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); + } + if (checks.every(function(check) { + return check; + })) { + firstFittingPlacement = placement; + makeFallbackChecks = false; + break; + } + checksMap.set(placement, checks); + } + if (makeFallbackChecks) { + var numberOfChecks = flipVariations ? 3 : 1; + var _loop = function _loop2(_i2) { + var fittingPlacement = placements2.find(function(placement2) { + var checks2 = checksMap.get(placement2); + if (checks2) { + return checks2.slice(0, _i2).every(function(check) { + return check; + }); + } + }); + if (fittingPlacement) { + firstFittingPlacement = fittingPlacement; + return "break"; + } + }; + for (var _i = numberOfChecks; _i > 0; _i--) { + var _ret = _loop(_i); + if (_ret === "break") + break; + } + } + if (state.placement !== firstFittingPlacement) { + state.modifiersData[name]._skip = true; + state.placement = firstFittingPlacement; + state.reset = true; + } +} +var flip_default = { + name: "flip", + enabled: true, + phase: "main", + fn: flip, + requiresIfExists: ["offset"], + data: { + _skip: false + } +}; + +// node_modules/@popperjs/core/lib/modifiers/hide.js +function getSideOffsets(overflow, rect, preventedOffsets) { + if (preventedOffsets === void 0) { + preventedOffsets = { + x: 0, + y: 0 + }; + } + return { + top: overflow.top - rect.height - preventedOffsets.y, + right: overflow.right - rect.width + preventedOffsets.x, + bottom: overflow.bottom - rect.height + preventedOffsets.y, + left: overflow.left - rect.width - preventedOffsets.x + }; +} +function isAnySideFullyClipped(overflow) { + return [top, right, bottom, left].some(function(side) { + return overflow[side] >= 0; + }); +} +function hide(_ref) { + var state = _ref.state, name = _ref.name; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var preventedOffsets = state.modifiersData.preventOverflow; + var referenceOverflow = detectOverflow(state, { + elementContext: "reference" + }); + var popperAltOverflow = detectOverflow(state, { + altBoundary: true + }); + var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); + var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); + var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); + var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); + state.modifiersData[name] = { + referenceClippingOffsets, + popperEscapeOffsets, + isReferenceHidden, + hasPopperEscaped + }; + state.attributes.popper = Object.assign({}, state.attributes.popper, { + "data-popper-reference-hidden": isReferenceHidden, + "data-popper-escaped": hasPopperEscaped + }); +} +var hide_default = { + name: "hide", + enabled: true, + phase: "main", + requiresIfExists: ["preventOverflow"], + fn: hide +}; + +// node_modules/@popperjs/core/lib/modifiers/offset.js +function distanceAndSkiddingToXY(placement, rects, offset2) { + var basePlacement = getBasePlacement(placement); + var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; + var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, { + placement + })) : offset2, skidding = _ref[0], distance = _ref[1]; + skidding = skidding || 0; + distance = (distance || 0) * invertDistance; + return [left, right].indexOf(basePlacement) >= 0 ? { + x: distance, + y: skidding + } : { + x: skidding, + y: distance + }; +} +function offset(_ref2) { + var state = _ref2.state, options = _ref2.options, name = _ref2.name; + var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset; + var data = placements.reduce(function(acc, placement) { + acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2); + return acc; + }, {}); + var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; + if (state.modifiersData.popperOffsets != null) { + state.modifiersData.popperOffsets.x += x; + state.modifiersData.popperOffsets.y += y; + } + state.modifiersData[name] = data; +} +var offset_default = { + name: "offset", + enabled: true, + phase: "main", + requires: ["popperOffsets"], + fn: offset +}; + +// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js +function popperOffsets(_ref) { + var state = _ref.state, name = _ref.name; + state.modifiersData[name] = computeOffsets({ + reference: state.rects.reference, + element: state.rects.popper, + strategy: "absolute", + placement: state.placement + }); +} +var popperOffsets_default = { + name: "popperOffsets", + enabled: true, + phase: "read", + fn: popperOffsets, + data: {} +}; + +// node_modules/@popperjs/core/lib/utils/getAltAxis.js +function getAltAxis(axis) { + return axis === "x" ? "y" : "x"; +} + +// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js +function preventOverflow(_ref) { + var state = _ref.state, options = _ref.options, name = _ref.name; + var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; + var overflow = detectOverflow(state, { + boundary, + rootBoundary, + padding, + altBoundary + }); + var basePlacement = getBasePlacement(state.placement); + var variation = getVariation(state.placement); + var isBasePlacement = !variation; + var mainAxis = getMainAxisFromPlacement(basePlacement); + var altAxis = getAltAxis(mainAxis); + var popperOffsets2 = state.modifiersData.popperOffsets; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { + placement: state.placement + })) : tetherOffset; + var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { + mainAxis: tetherOffsetValue, + altAxis: tetherOffsetValue + } : Object.assign({ + mainAxis: 0, + altAxis: 0 + }, tetherOffsetValue); + var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; + var data = { + x: 0, + y: 0 + }; + if (!popperOffsets2) { + return; + } + if (checkMainAxis) { + var _offsetModifierState$; + var mainSide = mainAxis === "y" ? top : left; + var altSide = mainAxis === "y" ? bottom : right; + var len = mainAxis === "y" ? "height" : "width"; + var offset2 = popperOffsets2[mainAxis]; + var min2 = offset2 + overflow[mainSide]; + var max2 = offset2 - overflow[altSide]; + var additive = tether ? -popperRect[len] / 2 : 0; + var minLen = variation === start ? referenceRect[len] : popperRect[len]; + var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; + var arrowElement = state.elements.arrow; + var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { + width: 0, + height: 0 + }; + var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); + var arrowPaddingMin = arrowPaddingObject[mainSide]; + var arrowPaddingMax = arrowPaddingObject[altSide]; + var arrowLen = within(0, referenceRect[len], arrowRect[len]); + var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; + var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; + var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); + var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; + var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; + var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset; + var tetherMax = offset2 + maxOffset - offsetModifierValue; + var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2); + popperOffsets2[mainAxis] = preventedOffset; + data[mainAxis] = preventedOffset - offset2; + } + if (checkAltAxis) { + var _offsetModifierState$2; + var _mainSide = mainAxis === "x" ? top : left; + var _altSide = mainAxis === "x" ? bottom : right; + var _offset = popperOffsets2[altAxis]; + var _len = altAxis === "y" ? "height" : "width"; + var _min = _offset + overflow[_mainSide]; + var _max = _offset - overflow[_altSide]; + var isOriginSide = [top, left].indexOf(basePlacement) !== -1; + var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; + var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; + var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; + var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); + popperOffsets2[altAxis] = _preventedOffset; + data[altAxis] = _preventedOffset - _offset; + } + state.modifiersData[name] = data; +} +var preventOverflow_default = { + name: "preventOverflow", + enabled: true, + phase: "main", + fn: preventOverflow, + requiresIfExists: ["offset"] +}; + +// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js +function getHTMLElementScroll(element) { + return { + scrollLeft: element.scrollLeft, + scrollTop: element.scrollTop + }; +} + +// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js +function getNodeScroll(node) { + if (node === getWindow(node) || !isHTMLElement(node)) { + return getWindowScroll(node); + } else { + return getHTMLElementScroll(node); + } +} + +// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js +function isElementScaled(element) { + var rect = element.getBoundingClientRect(); + var scaleX = round(rect.width) / element.offsetWidth || 1; + var scaleY = round(rect.height) / element.offsetHeight || 1; + return scaleX !== 1 || scaleY !== 1; +} +function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { + if (isFixed === void 0) { + isFixed = false; + } + var isOffsetParentAnElement = isHTMLElement(offsetParent); + var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); + var documentElement = getDocumentElement(offsetParent); + var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); + var scroll = { + scrollLeft: 0, + scrollTop: 0 + }; + var offsets = { + x: 0, + y: 0 + }; + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { + if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) { + scroll = getNodeScroll(offsetParent); + } + if (isHTMLElement(offsetParent)) { + offsets = getBoundingClientRect(offsetParent, true); + offsets.x += offsetParent.clientLeft; + offsets.y += offsetParent.clientTop; + } else if (documentElement) { + offsets.x = getWindowScrollBarX(documentElement); + } + } + return { + x: rect.left + scroll.scrollLeft - offsets.x, + y: rect.top + scroll.scrollTop - offsets.y, + width: rect.width, + height: rect.height + }; +} + +// node_modules/@popperjs/core/lib/utils/orderModifiers.js +function order(modifiers) { + var map = /* @__PURE__ */ new Map(); + var visited = /* @__PURE__ */ new Set(); + var result = []; + modifiers.forEach(function(modifier) { + map.set(modifier.name, modifier); + }); + function sort(modifier) { + visited.add(modifier.name); + var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); + requires.forEach(function(dep) { + if (!visited.has(dep)) { + var depModifier = map.get(dep); + if (depModifier) { + sort(depModifier); + } + } + }); + result.push(modifier); + } + modifiers.forEach(function(modifier) { + if (!visited.has(modifier.name)) { + sort(modifier); + } + }); + return result; +} +function orderModifiers(modifiers) { + var orderedModifiers = order(modifiers); + return modifierPhases.reduce(function(acc, phase) { + return acc.concat(orderedModifiers.filter(function(modifier) { + return modifier.phase === phase; + })); + }, []); +} + +// node_modules/@popperjs/core/lib/utils/debounce.js +function debounce(fn2) { + var pending; + return function() { + if (!pending) { + pending = new Promise(function(resolve) { + Promise.resolve().then(function() { + pending = void 0; + resolve(fn2()); + }); + }); + } + return pending; + }; +} + +// node_modules/@popperjs/core/lib/utils/mergeByName.js +function mergeByName(modifiers) { + var merged = modifiers.reduce(function(merged2, current) { + var existing = merged2[current.name]; + merged2[current.name] = existing ? Object.assign({}, existing, current, { + options: Object.assign({}, existing.options, current.options), + data: Object.assign({}, existing.data, current.data) + }) : current; + return merged2; + }, {}); + return Object.keys(merged).map(function(key) { + return merged[key]; + }); +} + +// node_modules/@popperjs/core/lib/createPopper.js +var DEFAULT_OPTIONS = { + placement: "bottom", + modifiers: [], + strategy: "absolute" +}; +function areValidElements() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + return !args.some(function(element) { + return !(element && typeof element.getBoundingClientRect === "function"); + }); +} +function popperGenerator(generatorOptions) { + if (generatorOptions === void 0) { + generatorOptions = {}; + } + var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; + return function createPopper2(reference2, popper2, options) { + if (options === void 0) { + options = defaultOptions; + } + var state = { + placement: "bottom", + orderedModifiers: [], + options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), + modifiersData: {}, + elements: { + reference: reference2, + popper: popper2 + }, + attributes: {}, + styles: {} + }; + var effectCleanupFns = []; + var isDestroyed = false; + var instance = { + state, + setOptions: function setOptions(setOptionsAction) { + var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; + cleanupModifierEffects(); + state.options = Object.assign({}, defaultOptions, state.options, options2); + state.scrollParents = { + reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [], + popper: listScrollParents(popper2) + }; + var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers))); + state.orderedModifiers = orderedModifiers.filter(function(m) { + return m.enabled; + }); + runModifierEffects(); + return instance.update(); + }, + forceUpdate: function forceUpdate() { + if (isDestroyed) { + return; + } + var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper; + if (!areValidElements(reference3, popper3)) { + return; + } + state.rects = { + reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"), + popper: getLayoutRect(popper3) + }; + state.reset = false; + state.placement = state.options.placement; + state.orderedModifiers.forEach(function(modifier) { + return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); + }); + for (var index = 0; index < state.orderedModifiers.length; index++) { + if (state.reset === true) { + state.reset = false; + index = -1; + continue; + } + var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; + if (typeof fn2 === "function") { + state = fn2({ + state, + options: _options, + name, + instance + }) || state; + } + } + }, + update: debounce(function() { + return new Promise(function(resolve) { + instance.forceUpdate(); + resolve(state); + }); + }), + destroy: function destroy() { + cleanupModifierEffects(); + isDestroyed = true; + } + }; + if (!areValidElements(reference2, popper2)) { + return instance; + } + instance.setOptions(options).then(function(state2) { + if (!isDestroyed && options.onFirstUpdate) { + options.onFirstUpdate(state2); + } + }); + function runModifierEffects() { + state.orderedModifiers.forEach(function(_ref) { + var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect4 = _ref.effect; + if (typeof effect4 === "function") { + var cleanupFn = effect4({ + state, + name, + instance, + options: options2 + }); + var noopFn = function noopFn2() { + }; + effectCleanupFns.push(cleanupFn || noopFn); + } + }); + } + function cleanupModifierEffects() { + effectCleanupFns.forEach(function(fn2) { + return fn2(); + }); + effectCleanupFns = []; + } + return instance; + }; +} + +// node_modules/@popperjs/core/lib/popper.js +var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default]; +var createPopper = /* @__PURE__ */ popperGenerator({ + defaultModifiers +}); + +// src/suggesters/suggest.ts +var wrapAround = (value, size) => { + return (value % size + size) % size; +}; +var Suggest = class { + constructor(owner, containerEl, scope) { + this.owner = owner; + this.containerEl = containerEl; + containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this)); + containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this)); + scope.register([], "ArrowUp", (event) => { + if (!event.isComposing) { + this.setSelectedItem(this.selectedItem - 1, true); + return false; + } + }); + scope.register([], "ArrowDown", (event) => { + if (!event.isComposing) { + this.setSelectedItem(this.selectedItem + 1, true); + return false; + } + }); + scope.register([], "Enter", (event) => { + if (!event.isComposing) { + this.useSelectedItem(event); + return false; + } + }); + } + onSuggestionClick(event, el) { + event.preventDefault(); + const item = this.suggestions.indexOf(el); + this.setSelectedItem(item, false); + this.useSelectedItem(event); + } + onSuggestionMouseover(_event, el) { + const item = this.suggestions.indexOf(el); + this.setSelectedItem(item, false); + } + setSuggestions(values) { + this.containerEl.empty(); + const suggestionEls = []; + values.forEach((value) => { + const suggestionEl = this.containerEl.createDiv("suggestion-item"); + this.owner.renderSuggestion(value, suggestionEl); + suggestionEls.push(suggestionEl); + }); + this.values = values; + this.suggestions = suggestionEls; + this.setSelectedItem(0, false); + } + useSelectedItem(event) { + const currentValue = this.values[this.selectedItem]; + if (currentValue) { + this.owner.selectSuggestion(currentValue, event); + } + } + setSelectedItem(selectedIndex, scrollIntoView) { + const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length); + const prevSelectedSuggestion = this.suggestions[this.selectedItem]; + const selectedSuggestion = this.suggestions[normalizedIndex]; + prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected"); + selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected"); + this.selectedItem = normalizedIndex; + if (scrollIntoView) { + selectedSuggestion.scrollIntoView(false); + } + } +}; +var TextInputSuggest = class { + constructor(inputEl) { + this.inputEl = inputEl; + this.scope = new import_obsidian.Scope(); + this.suggestEl = createDiv("suggestion-container"); + const suggestion = this.suggestEl.createDiv("suggestion"); + this.suggest = new Suggest(this, suggestion, this.scope); + this.scope.register([], "Escape", this.close.bind(this)); + this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); + this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); + this.inputEl.addEventListener("blur", this.close.bind(this)); + this.suggestEl.on("mousedown", ".suggestion-container", (event) => { + event.preventDefault(); + }); + } + onInputChanged() { + const inputStr = this.inputEl.value; + const suggestions = this.getSuggestions(inputStr); + if (!suggestions) { + this.close(); + return; + } + if (suggestions.length > 0) { + this.suggest.setSuggestions(suggestions); + this.open(app.dom.appContainerEl, this.inputEl); + } else { + this.close(); + } + } + open(container, inputEl) { + app.keymap.pushScope(this.scope); + container.appendChild(this.suggestEl); + this.popper = createPopper(inputEl, this.suggestEl, { + placement: "bottom-start", + modifiers: [ + { + name: "sameWidth", + enabled: true, + fn: ({ state, instance }) => { + const targetWidth = `${state.rects.reference.width}px`; + if (state.styles.popper.width === targetWidth) { + return; + } + state.styles.popper.width = targetWidth; + instance.update(); + }, + phase: "beforeWrite", + requires: ["computeStyles"] + } + ] + }); + } + close() { + app.keymap.popScope(this.scope); + this.suggest.setSuggestions([]); + if (this.popper) + this.popper.destroy(); + this.suggestEl.detach(); + } +}; + +// src/template.ts +var import_obsidian2 = require("obsidian"); +async function applyTemplate(plugin, file, templatePath) { + const templateFile = templatePath ? plugin.app.vault.getAbstractFileByPath(templatePath) : null; + if (templateFile && templateFile instanceof import_obsidian2.TFile) { + try { + const { + templatesEnabled, + templaterEnabled, + templatesPlugin, + templaterPlugin + } = getTemplatePlugins(plugin.app); + const templateContent = await plugin.app.vault.read(templateFile); + if (templatesEnabled && templaterEnabled) { + if (/<%/.test(templateContent)) { + return await templaterPlugin.write_template_to_file(templateFile, file); + } + return await templatesPlugin.instance.insertTemplate(templateFile); + } + if (templatesEnabled) { + return await templatesPlugin.instance.insertTemplate(templateFile); + } + if (templaterEnabled) { + return await templaterPlugin.write_template_to_file(templateFile, file); + } + } catch (e) { + console.error(e); + } + } +} +function getTemplatePlugins(app2) { + var _a; + const templatesPlugin = app2.internalPlugins.plugins.templates; + const templatesEnabled = templatesPlugin.enabled; + const templaterPlugin = app2.plugins.plugins["templater-obsidian"]; + const templaterEnabled = app2.plugins.enabledPlugins.has("templater-obsidian"); + const templaterEmptyFileTemplate = templaterPlugin && ((_a = this.app.plugins.plugins["templater-obsidian"].settings) == null ? void 0 : _a.empty_file_template); + const templateFolder = templatesEnabled ? templatesPlugin.instance.options.folder : templaterPlugin ? templaterPlugin.settings.template_folder : void 0; + return { + templatesPlugin, + templatesEnabled, + templaterPlugin: templaterPlugin == null ? void 0 : templaterPlugin.templater, + templaterEnabled, + templaterEmptyFileTemplate, + templateFolder + }; +} + +// src/suggesters/templateSuggester.ts +var TemplateSuggest = class extends TextInputSuggest { + constructor(inputEl, plugin) { + super(inputEl); + this.inputEl = inputEl; + this.plugin = plugin; + } + get_error_msg(mode) { + switch (mode) { + case 0 /* TemplateFiles */: + return "Templates folder doesn't exist"; + case 1 /* ScriptFiles */: + return "User Scripts folder doesn't exist"; + } + } + getSuggestions(input_str) { + var _a, _b; + const { templateFolder, templaterPlugin } = getTemplatePlugins(this.plugin.app); + if ((!templateFolder || (templateFolder == null ? void 0 : templateFolder.trim()) === "") && !templaterPlugin) { + this.plugin.settings.templatePath = ""; + this.plugin.saveSettings(); + return []; + } + let folder; + if (templaterPlugin) { + folder = this.plugin.app.vault.getAbstractFileByPath((_b = (_a = templaterPlugin.plugin) == null ? void 0 : _a.settings) == null ? void 0 : _b.templates_folder); + } else { + folder = this.plugin.app.vault.getAbstractFileByPath(templateFolder); + } + const files = []; + const lower_input_str = input_str.toLowerCase(); + import_obsidian3.Vault.recurseChildren(folder, (file) => { + if (file instanceof import_obsidian3.TFile && file.path.toLowerCase().contains(lower_input_str)) { + files.push(file); + } + }); + return files; + } + renderSuggestion(file, el) { + el.setText(file.name.replace(".md", "")); + } + selectSuggestion(file) { + this.inputEl.value = file.name.replace(".md", ""); + this.inputEl.trigger("input"); + this.plugin.settings.templatePath = file.path; + this.plugin.saveSettings(); + this.close(); + } +}; + +// src/modals/existingNote.ts +var import_obsidian4 = require("obsidian"); +var ExistingFolderNoteModal = class extends import_obsidian4.Modal { + constructor(app2, plugin, file, folder, folderNote) { + super(app2); + this.plugin = plugin; + this.app = app2; + this.file = file; + this.folder = folder; + this.folderNote = folderNote; + } + onOpen() { + var _a; + const { contentEl } = this; + contentEl.createEl("h2", { text: "A folder note for this folder already exists" }); + const setting = new import_obsidian4.Setting(contentEl); + setting.infoEl.createEl("p", { text: "Are you sure you want to turn the note into a folder note and rename the existing folder note?" }); + (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal"); + const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" }); + if (import_obsidian4.Platform.isMobileApp) { + const confirmButton = buttonContainer.createEl("button", { text: "Rename and don't ask again" }); + confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button"); + confirmButton.addEventListener("click", async () => { + this.plugin.settings.showRenameConfirmation = false; + this.plugin.saveSettings(); + this.close(); + turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true); + }); + } else { + const checkbox = buttonContainer.createEl("input", { type: "checkbox" }); + checkbox.addEventListener("change", (e) => { + const target = e.target; + if (target.checked) { + this.plugin.settings.showRenameConfirmation = false; + } else { + this.plugin.settings.showRenameConfirmation = true; + } + }); + const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" }); + checkBoxText.addEventListener("click", () => { + checkbox.click(); + }); + } + const button = buttonContainer.createEl("button", { text: "Rename" }); + button.classList.add("mod-warning", "fn-confirmation-modal-button"); + button.addEventListener("click", async () => { + this.plugin.saveSettings(); + this.close(); + turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true); + }); + button.focus(); + const cancelButton = buttonContainer.createEl("button", { text: "Cancel" }); + cancelButton.addEventListener("click", async () => { + this.close(); + }); + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +}; + +// src/functions/folderNoteFunctions.ts +var import_obsidian10 = require("obsidian"); + +// src/modals/deleteConfirmation.ts +var import_obsidian5 = require("obsidian"); +var DeleteConfirmationModal = class extends import_obsidian5.Modal { + constructor(app2, plugin, file) { + super(app2); + this.plugin = plugin; + this.app = app2; + this.file = file; + } + onOpen() { + var _a; + const { contentEl } = this; + contentEl.createEl("h2", { text: "Delete folder note" }); + const setting = new import_obsidian5.Setting(contentEl); + setting.infoEl.createEl("p", { text: `Are you sure you want to delete the folder note "${this.file.name}" ?` }); + setting.infoEl.createEl("p", { text: "It will be moved to your system trash." }); + (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal"); + const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" }); + if (import_obsidian5.Platform.isMobileApp) { + const confirmButton = buttonContainer.createEl("button", { text: "Delete and don't ask again" }); + confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button"); + confirmButton.addEventListener("click", async () => { + this.plugin.settings.showDeleteConfirmation = false; + this.plugin.saveSettings(); + this.close(); + const folder = getFolder(this.plugin, this.file); + if (!folder) + return; + this.plugin.removeCSSClassFromEL(folder == null ? void 0 : folder.path, "has-folder-note"); + this.app.vault.delete(this.file); + }); + } else { + const checkbox = buttonContainer.createEl("input", { type: "checkbox" }); + checkbox.addEventListener("change", (e) => { + const target = e.target; + if (target.checked) { + this.plugin.settings.showDeleteConfirmation = false; + } else { + this.plugin.settings.showDeleteConfirmation = true; + } + this.plugin.saveSettings(); + }); + const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" }); + checkBoxText.addEventListener("click", () => { + checkbox.click(); + }); + } + const button = buttonContainer.createEl("button", { text: "Delete" }); + button.classList.add("mod-warning", "fn-confirmation-modal-button"); + button.addEventListener("click", async () => { + this.close(); + const folder = getFolder(this.plugin, this.file); + if (!folder) + return; + this.plugin.removeCSSClassFromEL(folder.path, "has-folder-note"); + this.app.vault.delete(this.file); + }); + button.focus(); + const cancelButton = buttonContainer.createEl("button", { text: "Cancel" }); + cancelButton.addEventListener("click", async () => { + this.close(); + }); + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +}; + +// src/excludedFolder.ts +var import_obsidian9 = require("obsidian"); + +// src/modals/excludeFolderSettings.ts +var import_obsidian6 = require("obsidian"); +var ExcludedFolderSettings = class extends import_obsidian6.Modal { + constructor(app2, plugin, excludedFolder) { + super(app2); + this.plugin = plugin; + this.app = app2; + this.excludedFolder = excludedFolder; + } + onOpen() { + this.display(); + } + display() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Excluded folder settings" }); + new import_obsidian6.Setting(contentEl).setName("Include subfolders").setDesc("Choose if the subfolders of the folder should also be excluded").addToggle((toggle) => toggle.setValue(this.excludedFolder.subFolders).onChange(async (value) => { + this.excludedFolder.subFolders = value; + await this.plugin.saveSettings(); + })); + new import_obsidian6.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder note should be renamed when the folder name is changed").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableSync).onChange(async (value) => { + this.excludedFolder.disableSync = value; + await this.plugin.saveSettings(); + })); + new import_obsidian6.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableAutoCreate).onChange(async (value) => { + this.excludedFolder.disableAutoCreate = value; + await this.plugin.saveSettings(); + })); + new import_obsidian6.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableFolderNote).onChange(async (value) => { + this.excludedFolder.disableFolderNote = value; + await this.plugin.saveSettings(); + this.display(); + })); + if (!this.excludedFolder.disableFolderNote) { + new import_obsidian6.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.enableCollapsing).onChange(async (value) => { + this.excludedFolder.enableCollapsing = value; + await this.plugin.saveSettings(); + })); + } + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +}; + +// src/suggesters/FolderSuggester.ts +var import_obsidian7 = require("obsidian"); +var FolderSuggest = class extends TextInputSuggest { + constructor(inputEl, plugin) { + super(inputEl); + this.inputEl = inputEl; + this.plugin = plugin; + } + get_error_msg(mode) { + switch (mode) { + case 0 /* TemplateFiles */: + return "Templates folder doesn't exist"; + case 1 /* ScriptFiles */: + return "User Scripts folder doesn't exist"; + } + } + getSuggestions(input_str) { + const folders = []; + const lower_input_str = input_str.toLowerCase(); + this.plugin.app.vault.getAllLoadedFiles().forEach((folder) => { + if (folder instanceof import_obsidian7.TFolder && folder.path.toLowerCase().contains(lower_input_str) && !this.plugin.settings.excludeFolders.find((f) => f.path === folder.path)) { + folders.push(folder); + } + }); + return folders; + } + renderSuggestion(folder, el) { + el.setText(folder.path); + } + selectSuggestion(folder) { + this.inputEl.value = folder.path; + this.inputEl.trigger("input"); + this.close(); + } +}; + +// src/modals/patternSettings.ts +var import_obsidian8 = require("obsidian"); +var PatternSettings = class extends import_obsidian8.Modal { + constructor(app2, plugin, pattern) { + super(app2); + this.plugin = plugin; + this.app = app2; + this.pattern = pattern; + } + onOpen() { + this.display(); + } + display() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Pattern settings" }); + new import_obsidian8.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder name should be renamed when the file name has been changed").addToggle((toggle) => toggle.setValue(this.pattern.disableSync).onChange(async (value) => { + this.pattern.disableSync = value; + await this.plugin.saveSettings(); + })); + new import_obsidian8.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created that matches this pattern").addToggle((toggle) => toggle.setValue(this.pattern.disableAutoCreate).onChange(async (value) => { + this.pattern.disableAutoCreate = value; + await this.plugin.saveSettings(); + })); + new import_obsidian8.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.pattern.disableFolderNote).onChange(async (value) => { + this.pattern.disableFolderNote = value; + await this.plugin.saveSettings(); + this.display(); + })); + if (!this.pattern.disableFolderNote) { + new import_obsidian8.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.pattern.enableCollapsing).onChange(async (value) => { + this.pattern.enableCollapsing = value; + await this.plugin.saveSettings(); + })); + } + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +}; + +// src/excludedFolder.ts +var ExcludedFolder = class { + constructor(path, position) { + this.type = "folder"; + this.path = path; + this.subFolders = true; + this.disableSync = true; + this.disableAutoCreate = true; + this.disableFolderNote = false; + this.enableCollapsing = false; + this.position = position; + this.string = ""; + } +}; +var ExcludePattern = class { + constructor(pattern, position) { + this.type = "pattern"; + this.string = pattern; + this.position = position; + this.subFolders = false; + this.disableSync = true; + this.disableAutoCreate = true; + this.disableFolderNote = false; + this.enableCollapsing = false; + this.path = ""; + } +}; +function getExcludedFolder(plugin, path) { + const folderName = plugin.getFolderNameFromPathString(path); + const matchedPattern = getExcludedFolderByPattern(plugin, folderName); + if (matchedPattern) { + return matchedPattern; + } + const excludedFolder = getExcludedFolderByPath(plugin, path); + return excludedFolder; +} +function getExcludedFolderByPattern(plugin, folderName) { + return plugin.settings.excludeFolders.filter((s) => s.path === "").find((pattern) => { + if (!pattern.string) { + return false; + } + if (pattern.string.toLocaleLowerCase().startsWith("{regex}") && pattern.string.slice(7).trim() !== "") { + const match = new RegExp(pattern.string.slice(7).trim()).exec(folderName); + if (match) { + return true; + } + } else if (pattern.string.startsWith("*") && pattern.string.endsWith("*")) { + if (folderName.includes(pattern.string.slice(1, -1))) { + return true; + } + } else if (pattern.string.startsWith("*")) { + if (folderName.endsWith(pattern.string.slice(1))) { + return true; + } + } else if (pattern.string.endsWith("*")) { + if (folderName.startsWith(pattern.string.slice(0, -1))) { + return true; + } + } + }); +} +function getExcludedFolderByPath(plugin, path) { + return plugin.settings.excludeFolders.find((excludedFolder) => { + if (excludedFolder.path === path) { + return true; + } + if (!excludedFolder.subFolders) { + return false; + } + return plugin.getFolderPathFromString(path).startsWith(excludedFolder.path); + }); +} +function addExcludedFolder(plugin, excludedFolder) { + plugin.settings.excludeFolders.push(excludedFolder); + plugin.saveSettings(); +} +function deleteExcludedFolder(plugin, excludedFolder) { + plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path || folder.type === "pattern"); + plugin.saveSettings(); + resyncArray(plugin); +} +function deletePattern(plugin, pattern) { + plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string || folder.type === "folder"); + plugin.saveSettings(); + resyncArray(plugin); +} +function updateExcludedFolder(plugin, excludedFolder, newExcludeFolder) { + plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path); + addExcludedFolder(plugin, newExcludeFolder); +} +function updatePattern(plugin, pattern, newPattern) { + plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string); + addExcludedFolder(plugin, newPattern); +} +function resyncArray(plugin) { + plugin.settings.excludeFolders = plugin.settings.excludeFolders.sort((a, b) => a.position - b.position); + plugin.settings.excludeFolders.forEach((folder, index) => { + folder.position = index; + }); + plugin.saveSettings(); +} +function addExcludePatternListItem(settings, containerEl, pattern) { + const plugin = settings.plugin; + const setting = new import_obsidian9.Setting(containerEl); + setting.setClass("fn-exclude-folder-list"); + setting.addSearch((cb) => { + cb.containerEl.addClass("fn-exclude-folder-path"); + cb.setPlaceholder("Pattern"); + cb.setValue(pattern.string); + cb.onChange((value) => { + if (plugin.settings.excludeFolders.find((folder) => folder.string === value)) { + return; + } + pattern.string = value; + updatePattern(plugin, pattern, pattern); + }); + }); + setting.addButton((cb) => { + cb.setIcon("edit"); + cb.setTooltip("Edit pattern"); + cb.onClick(() => { + new PatternSettings(plugin.app, plugin, pattern).open(); + }); + }); + setting.addButton((cb) => { + cb.setIcon("up-chevron-glyph"); + cb.setTooltip("Move up"); + cb.onClick(() => { + if (pattern.position === 0) { + return; + } + pattern.position -= 1; + updatePattern(plugin, pattern, pattern); + const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position); + if (oldPattern) { + oldPattern.position += 1; + if (oldPattern.type === "pattern") { + updatePattern(plugin, oldPattern, oldPattern); + } else { + updateExcludedFolder(plugin, oldPattern, oldPattern); + } + } + settings.display(); + }); + }); + setting.addButton((cb) => { + cb.setIcon("down-chevron-glyph"); + cb.setTooltip("Move down"); + cb.onClick(() => { + if (pattern.position === plugin.settings.excludeFolders.length - 1) { + return; + } + pattern.position += 1; + updatePattern(plugin, pattern, pattern); + const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position); + if (oldPattern) { + oldPattern.position -= 1; + if (oldPattern.type === "pattern") { + updatePattern(plugin, oldPattern, oldPattern); + } else { + updateExcludedFolder(plugin, oldPattern, oldPattern); + } + } + settings.display(); + }); + }); + setting.addButton((cb) => { + cb.setIcon("trash-2"); + cb.setTooltip("Delete pattern"); + cb.onClick(() => { + deletePattern(plugin, pattern); + setting.clear(); + setting.settingEl.remove(); + }); + }); +} +function addExcludeFolderListItem(settings, containerEl, excludedFolder) { + const plugin = settings.plugin; + const setting = new import_obsidian9.Setting(containerEl); + setting.setClass("fn-exclude-folder-list"); + setting.addSearch((cb) => { + new FolderSuggest(cb.inputEl, plugin); + cb.containerEl.addClass("fn-exclude-folder-path"); + cb.setPlaceholder("Folder path"); + cb.setValue(excludedFolder.path); + cb.onChange((value) => { + if (value.startsWith("{regex}") || value.includes("*")) { + deleteExcludedFolder(plugin, excludedFolder); + const pattern = new ExcludePattern(value, plugin.settings.excludeFolders.length); + addExcludedFolder(plugin, pattern); + addExcludePatternListItem(settings, containerEl, pattern); + setting.clear(); + setting.settingEl.remove(); + } + if (!plugin.app.vault.getAbstractFileByPath(value)) + return; + excludedFolder.path = value; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + }); + }); + setting.addButton((cb) => { + cb.setIcon("edit"); + cb.setTooltip("Edit folder note"); + cb.onClick(() => { + new ExcludedFolderSettings(plugin.app, plugin, excludedFolder).open(); + }); + }); + setting.addButton((cb) => { + cb.setIcon("up-chevron-glyph"); + cb.setTooltip("Move up"); + cb.onClick(() => { + if (excludedFolder.position === 0) { + return; + } + excludedFolder.position -= 1; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position); + if (oldExcludedFolder) { + oldExcludedFolder.position += 1; + if (oldExcludedFolder.type === "pattern") { + updatePattern(plugin, oldExcludedFolder, oldExcludedFolder); + } else { + updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder); + } + } + settings.display(); + }); + }); + setting.addButton((cb) => { + cb.setIcon("down-chevron-glyph"); + cb.setTooltip("Move down"); + cb.onClick(() => { + if (excludedFolder.position === plugin.settings.excludeFolders.length - 1) { + return; + } + excludedFolder.position += 1; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position); + if (oldExcludedFolder) { + oldExcludedFolder.position -= 1; + if (oldExcludedFolder.type === "pattern") { + updatePattern(plugin, oldExcludedFolder, oldExcludedFolder); + } else { + updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder); + } + } + settings.display(); + }); + }); + setting.addButton((cb) => { + cb.setIcon("trash-2"); + cb.setTooltip("Delete excluded folder"); + cb.onClick(() => { + deleteExcludedFolder(plugin, excludedFolder); + setting.clear(); + setting.settingEl.remove(); + }); + }); +} + +// src/functions/folderNoteFunctions.ts +async function createFolderNote(plugin, folderPath, openFile, useModal, existingNote) { + const leaf = plugin.app.workspace.getLeaf(false); + const folderName = plugin.getFolderNameFromPathString(folderPath); + const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName); + let path = ""; + if (plugin.settings.storageLocation === "parentFolder") { + const parentFolderPath = plugin.getFolderPathFromString(folderPath); + if (parentFolderPath.trim() === "") { + path = `${fileName}${plugin.settings.folderNoteType}`; + } else { + path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`; + } + } else if (plugin.settings.storageLocation === "vaultFolder") { + path = `${fileName}${plugin.settings.folderNoteType}`; + } else { + path = `${folderPath}/${fileName}${plugin.settings.folderNoteType}`; + } + let file; + if (!existingNote) { + file = await plugin.app.vault.create(path, ""); + } else { + file = existingNote; + plugin.app.vault.rename(existingNote, path); + } + if (openFile) { + await leaf.openFile(file); + } + if (file && !existingNote) { + applyTemplate(this, file, plugin.settings.templatePath); + } + const folder = plugin.app.vault.getAbstractFileByPath(folderPath); + if (!(folder instanceof import_obsidian10.TFolder)) + return; + plugin.addCSSClassToTitleEL(path, "is-folder-note", true); + plugin.addCSSClassToTitleEL(folder.path, "has-folder-note"); +} +async function turnIntoFolderNote(plugin, file, folder, folderNote, skipConfirmation) { + var _a; + if (folderNote) { + if (plugin.settings.showRenameConfirmation && !skipConfirmation) { + return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open(); + } + plugin.removeCSSClassFromEL(folderNote.path, "is-folder-note"); + let excludedFolder = getExcludedFolder(plugin, folder.path); + let excludedFolderExisted = true; + let disabledSync = false; + if (!excludedFolder) { + excludedFolderExisted = false; + excludedFolder = new ExcludedFolder(folder.path, plugin.settings.excludeFolders.length); + addExcludedFolder(plugin, excludedFolder); + } else if (!excludedFolder.disableSync) { + disabledSync = false; + excludedFolder.disableSync = true; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + } + const newPath = `${folder.path}/${folder.name} (${file.stat.ctime.toString().slice(10) + Math.floor(Math.random() * 1e3)})${plugin.settings.folderNoteType}`; + plugin.app.vault.rename(folderNote, newPath).then(() => { + if (!excludedFolder) { + return; + } + if (!excludedFolderExisted) { + deleteExcludedFolder(plugin, excludedFolder); + } else if (!disabledSync) { + excludedFolder.disableSync = false; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + } + }); + } + const folderName = folder.name; + const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName); + let path = `${folder.path}/${fileName}${plugin.settings.folderNoteType}`; + if (plugin.settings.storageLocation === "parentFolder") { + const parentFolderPath = (_a = folder.parent) == null ? void 0 : _a.path; + if (!parentFolderPath) + return; + if (parentFolderPath.trim() === "") { + path = `${fileName}${plugin.settings.folderNoteType}`; + } else { + path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`; + } + } + await plugin.app.vault.rename(file, path); + plugin.addCSSClassToTitleEL(path, "is-folder-note", true); + plugin.addCSSClassToTitleEL(folder.path, "has-folder-note"); +} +async function openFolderNote(plugin, file, evt) { + var _a; + const path = file.path; + if (((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path) === path) { + return; + } + const leaf = plugin.app.workspace.getLeaf(import_obsidian10.Keymap.isModEvent(evt) || plugin.settings.openInNewTab); + if (file instanceof import_obsidian10.TFile) { + await leaf.openFile(file); + } +} +async function deleteFolderNote(plugin, file) { + if (plugin.settings.showDeleteConfirmation) { + return new DeleteConfirmationModal(plugin.app, plugin, file).open(); + } + const folder = getFolder(plugin, file); + if (!folder) + return; + plugin.removeCSSClassFromEL(folder.path, "has-folder-note"); + await plugin.app.vault.delete(file); +} +function extractFolderName(template, changedFileName) { + const [prefix, suffix] = template.split("{{folder_name}}"); + if (prefix.trim() === "" && suffix.trim() === "") { + return changedFileName; + } + if (!changedFileName.startsWith(prefix) || !changedFileName.endsWith(suffix)) { + return null; + } + if (changedFileName.startsWith(prefix) && prefix.trim() !== "") { + return changedFileName.slice(prefix.length).replace(suffix, ""); + } else if (changedFileName.endsWith(suffix) && suffix.trim() !== "") { + return changedFileName.slice(0, -suffix.length); + } + return null; +} +function getFolderNote(plugin, folderPath, storageLocation, file) { + if (!folderPath) + return null; + const folder = { + path: folderPath, + name: plugin.getFolderNameFromPathString(folderPath) + }; + let fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folder.name); + if (file) { + fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.basename); + } + if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") { + folder.path = plugin.getFolderPathFromString(folderPath); + } + let path = `${folder.path}/${fileName}`; + if (folder.path.trim() === "") { + folder.path = fileName; + path = `${fileName}`; + } + let folderNote = plugin.app.vault.getAbstractFileByPath(path + plugin.settings.folderNoteType); + if (folderNote instanceof import_obsidian10.TFile) { + return folderNote; + } else { + if (plugin.settings.folderNoteType === ".canvas") { + folderNote = plugin.app.vault.getAbstractFileByPath(path + ".md"); + } else { + folderNote = plugin.app.vault.getAbstractFileByPath(path + ".canvas"); + } + return folderNote; + } +} +function getFolder(plugin, file, storageLocation) { + if (!file) + return null; + const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename); + if (!folderName) + return null; + let folderPath = plugin.getFolderPathFromString(file.path); + let folder = null; + if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") { + if (folderPath.trim() === "") { + folderPath = folderName; + } else { + folderPath = `${folderPath}/${folderName}`; + } + folder = plugin.app.vault.getAbstractFileByPath(folderPath); + } else { + folder = plugin.app.vault.getAbstractFileByPath(folderPath); + } + if (!folder) { + return null; + } + return folder; +} +function getFolderNoteFolder(plugin, folderNote, fileName) { + if (!folderNote) + return null; + let filePath = ""; + if (typeof folderNote === "string") { + filePath = folderNote; + } else { + fileName = folderNote.basename; + filePath = folderNote.path; + } + const folderName = extractFolderName(plugin.settings.folderNoteName, fileName); + if (!folderName) + return null; + let folderPath = plugin.getFolderPathFromString(filePath); + if (plugin.settings.storageLocation === "parentFolder") { + if (folderPath.trim() === "") { + folderPath = folderName; + } else { + folderPath = `${folderPath}/${folderName}`; + } + } else { + folderPath = plugin.getFolderPathFromString(filePath); + } + const folder = plugin.app.vault.getAbstractFileByPath(folderPath); + if (!folder) { + return null; + } + return folder; +} + +// src/events/frontMatterTitle.ts +var import_front_matter_plugin_api_provider = __toESM(require_lib()); +var import_obsidian11 = require("obsidian"); +var FrontMatterTitlePluginHandler = class { + constructor(plugin) { + this.api = null; + this.deffer = null; + this.modifiedFolders = /* @__PURE__ */ new Map(); + this.plugin = plugin; + this.app = plugin.app; + (async () => { + var _a; + this.deffer = (0, import_front_matter_plugin_api_provider.getDefer)(this.app); + if (this.deffer.isPluginReady()) { + this.api = this.deffer.getApi(); + } else { + await this.deffer.awaitPlugin(); + this.api = this.deffer.getApi(); + if (!this.deffer.isFeaturesReady()) { + await this.deffer.awaitFeatures(); + } + } + const dispatcher = (_a = this.api) == null ? void 0 : _a.getEventDispatcher(); + if (dispatcher) { + this.dispatcher = dispatcher; + } + const event = { + name: "manager:update", + cb: (data) => { + this.handleRename(data, true); + } + }; + const ref = dispatcher == null ? void 0 : dispatcher.addListener(event); + if (ref) { + this.eventRef = ref; + } + this.plugin.app.vault.getFiles().forEach((file) => { + this.handleRename({ id: "", result: false, path: file.path }, false); + }); + this.plugin.updateBreadcrumbs(); + })(); + } + deleteEvent() { + if (this.eventRef) { + this.dispatcher.removeListener(this.eventRef); + } + } + async handleRename(data, isEvent) { + var _a, _b, _c; + if (data.data) + data = data.data; + const file = this.app.vault.getAbstractFileByPath(data.path); + if (!(file instanceof import_obsidian11.TFile)) { + return; + } + const resolver = (_b = (_a = this.api) == null ? void 0 : _a.getResolverFactory()) == null ? void 0 : _b.createResolver("#feature-id#"); + const newName = resolver == null ? void 0 : resolver.resolve((_c = file == null ? void 0 : file.path) != null ? _c : ""); + const folder = getFolder(this.plugin, file); + if ((extractFolderName(this.plugin.settings.folderNoteName, file.basename) || file.basename) !== (folder == null ? void 0 : folder.name)) { + return; + } + if (!(folder instanceof import_obsidian11.TFolder)) { + return; + } + if (isEvent) { + this.plugin.changeName(folder, newName, true); + } else { + this.plugin.changeName(folder, newName, false); + } + if (newName) { + folder.newName = newName; + this.modifiedFolders.set(folder.path, folder); + } else { + folder.newName = null; + this.modifiedFolders.delete(folder.path); + } + } +}; + +// src/settings.ts +var DEFAULT_SETTINGS = { + syncFolderName: true, + ctrlKey: true, + altKey: false, + hideFolderNote: true, + templatePath: "", + autoCreate: false, + enableCollapsing: false, + excludeFolders: [], + showDeleteConfirmation: true, + underlineFolder: true, + allowWhitespaceCollapsing: false, + underlineFolderInPath: true, + openFolderNoteOnClickInPath: true, + openInNewTab: false, + folderNoteName: "{{folder_name}}", + folderNoteType: ".md", + disableFolderHighlighting: false, + newFolderNoteName: "{{folder_name}}", + storageLocation: "insideFolder", + syncDelete: false, + showRenameConfirmation: true, + defaultOverview: { + title: "{{folderName}} overview", + disableTitle: false, + depth: 3, + includeTypes: ["folder", "markdown"], + style: "list", + disableFileTag: false + }, + useSubmenus: true, + syncMove: true, + frontMatterTitle: { + enabled: false, + explorer: true, + path: true + } +}; +var SettingsTab = class extends import_obsidian12.PluginSettingTab { + constructor(app2, plugin) { + super(app2, plugin); + } + display() { + const { containerEl } = this; + containerEl.empty(); + containerEl.createEl("h2", { text: "Folder notes settings" }); + const nameSetting = new import_obsidian12.Setting(containerEl).setName("Folder note name").setDesc("{{folder_name}} will be replaced with the name of the folder").addText((text) => text.setValue(this.plugin.settings.newFolderNoteName).onChange(async (value) => { + if (value.trim() === "") { + return; + } + this.plugin.settings.newFolderNoteName = value; + await this.plugin.saveSettings(); + })).addButton((button) => button.setButtonText("Rename existing folder notes").setCta().onClick(async () => { + this.updateFolderNotes(this.plugin.settings.folderNoteName, this.plugin.settings.newFolderNoteName); + })); + nameSetting.infoEl.appendText("Make sure to back up your vault before renaming all folder notes and restart Obsidian after renaming them"); + nameSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + new import_obsidian12.Setting(containerEl).setName("Folder note type").setDesc("Choose the file type for creating new folder notes (markdown or canvas) old folder notes will not be changed and you can also create canvas/markdown files and change the name manually to the custom folder note name or to the name of the folder.").addDropdown((dropdown) => dropdown.addOption(".md", "markdown").addOption(".canvas", "canvas").setValue(this.plugin.settings.folderNoteType).onChange(async (value) => { + this.plugin.settings.folderNoteType = value; + await this.plugin.saveSettings(); + })); + const setting = new import_obsidian12.Setting(containerEl); + const desc = document.createDocumentFragment(); + desc.append("After setting the template path, restart Obsidian if the template folder path (from templater/templates) had been changed beforehand.", desc.createEl("br"), "Obsidian should also be restarted if the template path was removed."); + setting.setName("Template path"); + setting.setDesc(desc).descEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + setting.addSearch((cb) => { + var _a; + new TemplateSuggest(cb.inputEl, this.plugin); + cb.setPlaceholder("Template path"); + cb.setValue(((_a = this.plugin.app.vault.getAbstractFileByPath(this.plugin.settings.templatePath)) == null ? void 0 : _a.name.replace(".md", "")) || ""); + cb.onChange(async (value) => { + if (value.trim() === "") { + this.plugin.settings.templatePath = ""; + await this.plugin.saveSettings(); + this.display(); + return; + } + }); + }); + const storageLocation = new import_obsidian12.Setting(containerEl).setName("Storage location").setDesc("Choose where to store the folder notes").addDropdown((dropdown) => dropdown.addOption("insideFolder", "Inside the folder").addOption("parentFolder", "In the parent folder").setValue(this.plugin.settings.storageLocation).onChange(async (value) => { + this.plugin.settings.storageLocation = value; + await this.plugin.saveSettings(); + this.display(); + this.plugin.loadFileClasses(); + })); + storageLocation.infoEl.appendText("Requires a restart to take effect"); + storageLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + const switchLocation = new import_obsidian12.Setting(containerEl).setName("Switch to new storage location").setDesc("Move all folder notes to the new storage location").addButton((button) => button.setButtonText("Switch").setCta().onClick(async () => { + let oldStorageLocation = this.plugin.settings.storageLocation; + if (this.plugin.settings.storageLocation === "parentFolder") { + oldStorageLocation = "insideFolder"; + } else if (this.plugin.settings.storageLocation === "insideFolder") { + oldStorageLocation = "parentFolder"; + } + this.switchStorageLocation(oldStorageLocation); + })); + switchLocation.infoEl.appendText("Requires a restart to take effect"); + switchLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + if (this.plugin.settings.storageLocation === "parentFolder") { + new import_obsidian12.Setting(containerEl).setName("Delete folder notes when deleting the folder").setDesc("Delete the folder note when deleting the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncDelete).onChange(async (value) => { + this.plugin.settings.syncDelete = value; + await this.plugin.saveSettings(); + })); + new import_obsidian12.Setting(containerEl).setName("Move folder notes when moving the folder").setDesc("Move the folder note when moving the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncMove).onChange(async (value) => { + this.plugin.settings.syncMove = value; + await this.plugin.saveSettings(); + })); + } + const disableSetting = new import_obsidian12.Setting(containerEl); + disableSetting.setName("Disable folder collapsing"); + disableSetting.setDesc("Disable the ability to collapse folders by clicking exactly on the folder name"); + disableSetting.addToggle((toggle) => toggle.setValue(!this.plugin.settings.enableCollapsing).onChange(async (value) => { + this.plugin.settings.enableCollapsing = !value; + await this.plugin.saveSettings(); + })); + disableSetting.infoEl.appendText("Requires a restart to take effect"); + disableSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + if (import_obsidian12.Platform.isDesktopApp) { + new import_obsidian12.Setting(containerEl).setName("Key for creating folder note").setDesc("The key combination to create a folder note").addDropdown((dropdown) => { + if (!import_obsidian12.Platform.isMacOS) { + dropdown.addOption("ctrl", "Ctrl + Click"); + } else { + dropdown.addOption("ctrl", "Cmd + Click"); + } + dropdown.addOption("alt", "Alt + Click"); + dropdown.setValue(this.plugin.settings.ctrlKey ? "ctrl" : "alt"); + dropdown.onChange(async (value) => { + this.plugin.settings.ctrlKey = value === "ctrl"; + this.plugin.settings.altKey = value === "alt"; + await this.plugin.saveSettings(); + this.display(); + }); + }); + } + new import_obsidian12.Setting(containerEl).setName("Only open folder notes through the name").setDesc("Only open folder notes in the file explorer by clicking on the folder name").addToggle((toggle) => toggle.setValue(this.plugin.settings.allowWhitespaceCollapsing).onChange(async (value) => { + if (!value) { + document.body.classList.add("fn-whitespace-stop-collapsing"); + } else { + document.body.classList.remove("fn-whitespace-stop-collapsing"); + } + this.plugin.settings.allowWhitespaceCollapsing = value; + await this.plugin.saveSettings(); + })); + new import_obsidian12.Setting(containerEl).setName("Hide folder note").setDesc("Hide the folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.hideFolderNote).onChange(async (value) => { + this.plugin.settings.hideFolderNote = value; + await this.plugin.saveSettings(); + if (value) { + document.body.classList.add("hide-folder-note"); + } else { + document.body.classList.remove("hide-folder-note"); + } + this.display(); + })); + new import_obsidian12.Setting(containerEl).setName("Sync folder name").setDesc("Automatically rename the folder note when the folder name is changed").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncFolderName).onChange(async (value) => { + this.plugin.settings.syncFolderName = value; + await this.plugin.saveSettings(); + this.display(); + })); + if (import_obsidian12.Platform.isDesktop) { + const setting3 = new import_obsidian12.Setting(containerEl); + setting3.setName("Open folder note in a new tab by default"); + setting3.setDesc("Always open folder notes in a new tab (except when you try to open the same note) instead of having to use ctrl/cmd + click to open in a new tab"); + setting3.addToggle((toggle) => toggle.setValue(this.plugin.settings.openInNewTab).onChange(async (value) => { + this.plugin.settings.openInNewTab = value; + await this.plugin.saveSettings(); + this.display(); + })); + setting3.infoEl.appendText("Requires a restart to take effect"); + setting3.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + } + new import_obsidian12.Setting(containerEl).setName("Automatically create folder notes").setDesc("Automatically create a folder note when a new folder is created").addToggle((toggle) => toggle.setValue(this.plugin.settings.autoCreate).onChange(async (value) => { + this.plugin.settings.autoCreate = value; + await this.plugin.saveSettings(); + this.display(); + })); + new import_obsidian12.Setting(containerEl).setName("Use submenus").setDesc("Use submenus for file/folder commands").addToggle((toggle) => toggle.setValue(this.plugin.settings.useSubmenus).onChange(async (value) => { + this.plugin.settings.useSubmenus = value; + await this.plugin.saveSettings(); + this.display(); + })); + new import_obsidian12.Setting(containerEl).setName("Add underline to folders with folder notes").setDesc("Add an underline to folders that have a folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolder).onChange(async (value) => { + this.plugin.settings.underlineFolder = value; + if (value) { + document.body.classList.add("folder-note-underline"); + } else { + document.body.classList.remove("folder-note-underline"); + } + await this.plugin.saveSettings(); + })); + new import_obsidian12.Setting(containerEl).setName("Open folder note through path").setDesc("Open a folder note when clicking on a folder name in the path if it is a folder note").addToggle((toggle) => toggle.setValue(this.plugin.settings.openFolderNoteOnClickInPath).onChange(async (value) => { + this.plugin.settings.openFolderNoteOnClickInPath = value; + await this.plugin.saveSettings(); + this.display(); + })); + if (this.plugin.settings.openFolderNoteOnClickInPath) { + new import_obsidian12.Setting(containerEl).setName("Underline folders in the path").setDesc("Add an underline to folders that have a folder note in the path above a note").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolderInPath).onChange(async (value) => { + this.plugin.settings.underlineFolderInPath = value; + if (value) { + document.body.classList.add("folder-note-underline-path"); + } else { + document.body.classList.remove("folder-note-underline-path"); + } + await this.plugin.saveSettings(); + })); + } + new import_obsidian12.Setting(containerEl).setName("Enable front matter title plugin integration").setDesc("Automatically rename a folder name when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.enabled).onChange(async (value) => { + var _a; + this.plugin.settings.frontMatterTitle.enabled = value; + await this.plugin.saveSettings(); + if (value) { + this.plugin.fmtpHandler = new FrontMatterTitlePluginHandler(this.plugin); + } else { + if (this.plugin.fmtpHandler) { + this.plugin.updateBreadcrumbs(true); + } + this.plugin.app.vault.getFiles().forEach((file) => { + var _a2; + (_a2 = this.plugin.fmtpHandler) == null ? void 0 : _a2.handleRename({ id: "", result: false, path: file.path }, false); + }); + (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.deleteEvent(); + this.plugin.fmtpHandler = null; + } + this.display(); + })); + if (this.plugin.settings.frontMatterTitle.enabled) { + new import_obsidian12.Setting(containerEl).setName("Include file explorer").setDesc("Automatically rename a folder name in the file explorer when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.explorer).onChange(async (value) => { + this.plugin.settings.frontMatterTitle.explorer = value; + await this.plugin.saveSettings(); + this.plugin.app.vault.getFiles().forEach((file) => { + var _a; + (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.handleRename({ id: "", result: false, path: file.path }, false); + }); + })); + new import_obsidian12.Setting(containerEl).setName("Include path above note").setDesc("Automatically rename a folder name in the path above a note when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.path).onChange(async (value) => { + this.plugin.settings.frontMatterTitle.path = value; + await this.plugin.saveSettings(); + if (value) { + this.plugin.updateBreadcrumbs(); + } else { + this.plugin.updateBreadcrumbs(true); + } + })); + } + const manageExcluded = new import_obsidian12.Setting(containerEl).setHeading().setClass("fn-excluded-folder-heading").setName("Manage excluded folders"); + const desc3 = document.createDocumentFragment(); + desc3.append("Add {regex} at the beginning of the folder name to use a regex pattern.", desc.createEl("br"), "Use * before and after to exclude folders that include the name between the *s.", desc.createEl("br"), "Use * before the folder name to exclude folders that end with the folder name.", desc.createEl("br"), "Use * after the folder name to exclude folders that start with the folder name."); + manageExcluded.setDesc(desc3); + manageExcluded.infoEl.appendText("The regexes and wildcards are only for the folder name, not the path."); + manageExcluded.infoEl.createEl("br"); + manageExcluded.infoEl.appendText("If you want to switch to a folder path delete the pattern first."); + manageExcluded.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; + new import_obsidian12.Setting(containerEl).setName("Add excluded folder").setClass("add-exclude-folder-item").addButton((cb) => { + cb.setIcon("plus"); + cb.setClass("add-exclude-folder"); + cb.setTooltip("Add excluded folder"); + cb.onClick(() => { + const excludedFolder = new ExcludedFolder("", this.plugin.settings.excludeFolders.length); + addExcludeFolderListItem(this, containerEl, excludedFolder); + addExcludedFolder(this.plugin, excludedFolder); + this.display(); + }); + }); + this.plugin.settings.excludeFolders.sort((a, b) => a.position - b.position).forEach((excludedFolder) => { + var _a, _b; + if (((_a = excludedFolder.string) == null ? void 0 : _a.trim()) !== "" && ((_b = excludedFolder.path) == null ? void 0 : _b.trim()) === "") { + addExcludePatternListItem(this, containerEl, excludedFolder); + } else { + addExcludeFolderListItem(this, containerEl, excludedFolder); + } + }); + } + updateFolderNotes(oldTemplate, newTemplate) { + this.plugin.settings.folderNoteName = newTemplate; + this.plugin.saveSettings(); + new import_obsidian12.Notice("Starting to update folder notes..."); + this.app.vault.getFiles().forEach((file) => { + if (file instanceof import_obsidian12.TFile) { + const folderPath = this.plugin.getFolderPathFromString(file.path); + let folder = this.app.vault.getAbstractFileByPath(folderPath); + let folderName = file.name.slice(0, -file.extension.length - 1); + folderName = extractFolderName(oldTemplate, folderName) || ""; + if (!(folder instanceof import_obsidian12.TFolder) || folderName !== (folder == null ? void 0 : folder.name)) { + if (folderPath.trim() === "") { + folder = this.app.vault.getAbstractFileByPath(folderName); + } else { + folder = this.app.vault.getAbstractFileByPath(folderPath + "/" + folderName); + } + } + if (!(folder instanceof import_obsidian12.TFolder)) { + return; + } + if (folderName === (folder == null ? void 0 : folder.name)) { + const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", folderName)}.${file.extension}`; + this.app.vault.rename(file, newPath); + } else if ((folder == null ? void 0 : folder.name) === file.name.slice(0, -file.extension.length - 1) || "") { + const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", file.name.slice(0, -file.extension.length - 1) || "")}.${file.extension}`; + this.app.vault.rename(file, newPath); + } + } + }); + new import_obsidian12.Notice("Finished updating folder notes"); + } + switchStorageLocation(oldMethod) { + new import_obsidian12.Notice("Starting to switch storage location..."); + this.app.vault.getAllLoadedFiles().forEach((file) => { + if (file instanceof import_obsidian12.TFolder) { + const folderNote = getFolderNote(this.plugin, file.path, oldMethod); + if (folderNote instanceof import_obsidian12.TFile) { + if (this.plugin.settings.storageLocation === "parentFolder") { + let newPath = ""; + if (this.plugin.getFolderPathFromString(file.path).trim() === "") { + newPath = `${folderNote.name}`; + } else { + newPath = `${this.plugin.getFolderPathFromString(file.path)}/${folderNote.name}`; + } + this.app.vault.rename(folderNote, newPath); + } else if (this.plugin.settings.storageLocation === "insideFolder") { + if (this.plugin.getFolderPathFromString(folderNote.path) === file.path) { + return; + } else { + const newPath = `${file.path}/${folderNote.name}`; + this.app.vault.rename(folderNote, newPath); + } + } + } + } + }); + new import_obsidian12.Notice("Finished switching storage location"); + } +}; + +// src/commands.ts +var import_obsidian13 = require("obsidian"); +var Commands = class { + constructor(app2, plugin) { + this.plugin = plugin; + this.app = app2; + } + registerCommands() { + this.plugin.registerEvent(this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => { + const text = editor.getSelection().trim(); + menu.addItem((item) => { + item.setTitle("Create folder overview").setIcon("edit").onClick(() => { + editor.replaceSelection("```folder-overview\n```\n"); + }); + }); + if (!text || text.trim() === "") + return; + menu.addItem((item) => { + item.setTitle("Create folder note").setIcon("edit").onClick(() => { + const file = view.file; + if (!(file instanceof import_obsidian13.TFile)) + return; + const blacklist = ["*", "\\", '"', "/", "<", ">", "?", "|", ":"]; + for (const char of blacklist) { + if (text.includes(char)) { + new import_obsidian13.Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?'); + return; + } + } + if (text.endsWith(".")) { + new import_obsidian13.Notice("File name cannot end with a dot"); + return; + } + let folder; + const folderPath = this.plugin.getFolderPathFromString(file.path); + if (folderPath === "") { + folder = this.plugin.app.vault.getAbstractFileByPath(text); + if (folder instanceof import_obsidian13.TFolder) { + return new import_obsidian13.Notice("Folder note already exists"); + } else { + this.plugin.app.vault.createFolder(text); + createFolderNote(this.plugin, text, false); + } + } else { + folder = this.plugin.app.vault.getAbstractFileByPath(folderPath + "/" + text); + if (folder instanceof import_obsidian13.TFolder) { + return new import_obsidian13.Notice("Folder note already exists"); + } + if (this.plugin.settings.storageLocation === "parentFolder") { + if (this.app.vault.getAbstractFileByPath(folderPath + "/" + text + this.plugin.settings.folderNoteType)) { + return new import_obsidian13.Notice("File already exists"); + } + } + this.plugin.app.vault.createFolder(folderPath + "/" + text); + createFolderNote(this.plugin, folderPath + "/" + text, false); + } + const fileName = this.plugin.settings.folderNoteName.replace("{{folder_name}}", text); + if (fileName === text) { + editor.replaceSelection(`[[${fileName}]]`); + } else { + editor.replaceSelection(`[[${fileName}|${text}]]`); + } + }); + }); + })); + this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => { + var _a, _b, _c; + let folder = file.parent; + if (file instanceof import_obsidian13.TFile) { + if (this.plugin.settings.storageLocation === "insideFolder") { + folder = file.parent; + } else { + const fileName = extractFolderName(this.plugin.settings.folderNoteName, file.basename); + if (fileName) { + if (((_a = file.parent) == null ? void 0 : _a.path) === "" || ((_b = file.parent) == null ? void 0 : _b.path) === "/") { + folder = this.plugin.app.vault.getAbstractFileByPath(fileName); + } else { + folder = this.plugin.app.vault.getAbstractFileByPath(((_c = file.parent) == null ? void 0 : _c.path) + "/" + fileName); + } + } + } + if (folder instanceof import_obsidian13.TFolder) { + const folderNote = getFolderNote(this.plugin, folder.path); + if ((folderNote == null ? void 0 : folderNote.path) === file.path) { + return; + } + } else if (file.parent instanceof import_obsidian13.TFolder) { + folder = file.parent; + } + } + menu.addItem((item) => { + if (import_obsidian13.Platform.isDesktop && !import_obsidian13.Platform.isTablet && this.plugin.settings.useSubmenus) { + item.setTitle("Folder Note Commands").setIcon("folder-edit"); + } + let subMenu; + if (!import_obsidian13.Platform.isDesktopApp || !import_obsidian13.Platform.isDesktop || import_obsidian13.Platform.isTablet || !this.plugin.settings.useSubmenus) { + subMenu = menu; + item.setDisabled(true); + } else { + subMenu = item.setSubmenu(); + } + if (file instanceof import_obsidian13.TFile) { + subMenu.addItem((item2) => { + item2.setTitle("Create folder note").setIcon("edit").onClick(async () => { + if (!folder) + return; + let newPath = folder.path + "/" + file.basename; + if (folder.path === "" || folder.path === "/") { + newPath = file.basename; + } + if (this.plugin.app.vault.getAbstractFileByPath(newPath)) { + return new import_obsidian13.Notice("Folder already exists"); + } + await this.plugin.app.vault.createFolder(newPath); + const newFolder = this.plugin.app.vault.getAbstractFileByPath(newPath); + if (!(newFolder instanceof import_obsidian13.TFolder)) + return; + createFolderNote(this.plugin, newFolder.path, true, false, file); + }); + }); + if (this.plugin.getFolderPathFromString(file.path) === "") + return; + if (!(folder instanceof import_obsidian13.TFolder)) + return; + subMenu.addItem((item2) => { + item2.setTitle("Turn into folder note").setIcon("edit").onClick(() => { + if (!folder || !(folder instanceof import_obsidian13.TFolder)) + return; + const folderNote2 = getFolderNote(this.plugin, folder.path); + turnIntoFolderNote(this.plugin, file, folder, folderNote2); + }); + }); + } + if (!(file instanceof import_obsidian13.TFolder)) + return; + if (this.plugin.settings.excludeFolders.find((folder2) => folder2.path === file.path)) { + subMenu.addItem((item2) => { + item2.setTitle("Remove folder from excluded folders").setIcon("trash").onClick(() => { + this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder2) => folder2.path !== file.path); + this.plugin.saveSettings(); + new import_obsidian13.Notice("Successfully removed folder from excluded folders"); + }); + }); + return; + } + subMenu.addItem((item2) => { + item2.setTitle("Exclude folder from folder notes").setIcon("x-circle").onClick(() => { + const excludedFolder = new ExcludedFolder(file.path, this.plugin.settings.excludeFolders.length); + this.plugin.settings.excludeFolders.push(excludedFolder); + this.plugin.saveSettings(); + new import_obsidian13.Notice("Successfully excluded folder from folder notes"); + }); + }); + if (!(file instanceof import_obsidian13.TFolder)) + return; + const folderNote = getFolderNote(this.plugin, file.path); + if (folderNote instanceof import_obsidian13.TFile) { + subMenu.addItem((item2) => { + item2.setTitle("Delete folder note").setIcon("trash").onClick(() => { + deleteFolderNote(this.plugin, folderNote); + }); + }); + subMenu.addItem((item2) => { + item2.setTitle("Open folder note").setIcon("chevron-right-square").onClick(() => { + openFolderNote(this.plugin, folderNote); + }); + }); + } else { + subMenu.addItem((item2) => { + item2.setTitle("Create folder note").setIcon("edit").onClick(() => { + createFolderNote(this.plugin, file.path, true); + }); + }); + } + }); + })); + } +}; + +// src/events/handleClick.ts +var import_obsidian14 = require("obsidian"); +async function handleViewHeaderClick(event, plugin) { + if (!(event.target instanceof HTMLElement)) + return; + if (!plugin.settings.openFolderNoteOnClickInPath) + return; + const folderPath = event.target.getAttribute("data-path"); + if (!folderPath) { + return; + } + const excludedFolder = getExcludedFolder(plugin, folderPath); + if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) { + event.target.onclick = null; + event.target.click(); + return; + } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) { + event.target.onclick = null; + event.target.click(); + } + const folderNote = getFolderNote(plugin, folderPath); + if (folderNote) { + return openFolderNote(plugin, folderNote, event); + } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") { + if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") { + await createFolderNote(plugin, folderPath, true, true); + plugin.addCSSClassToTitleEL(folderPath, "has-folder-note"); + plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note"); + return; + } + } + event.target.onclick = null; + event.target.click(); +} +async function handleFolderClick(event, plugin) { + var _a; + if (!(event.target instanceof HTMLElement)) + return; + event.stopImmediatePropagation(); + const folderPath = (_a = event.target.parentElement) == null ? void 0 : _a.getAttribute("data-path"); + if (!folderPath) { + return; + } + const excludedFolder = getExcludedFolder(plugin, folderPath); + if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) { + event.target.onclick = null; + event.target.click(); + return; + } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) { + event.target.onclick = null; + event.target.click(); + } + const folderNote = getFolderNote(plugin, folderPath); + if (folderNote) { + return openFolderNote(plugin, folderNote, event); + } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") { + if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") { + await createFolderNote(plugin, folderPath, true, true); + plugin.addCSSClassToTitleEL(folderPath, "has-folder-note"); + plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note"); + return; + } + } + event.target.onclick = null; + event.target.click(); +} + +// src/events/handleRename.ts +var import_obsidian15 = require("obsidian"); +function handleFolderRename(file, oldPath, plugin) { + const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.name); + const folder = plugin.app.vault.getAbstractFileByPath(file.path); + const folderNote = getFolderNote(plugin, oldPath); + if (!(folderNote instanceof import_obsidian15.TFile)) + return; + if (!(folder instanceof import_obsidian15.TFolder)) + return; + const excludedFolders = plugin.settings.excludeFolders.filter((excludedFolder2) => excludedFolder2.path.includes(oldPath)); + excludedFolders.forEach((excludedFolder2) => { + if (excludedFolder2.path === oldPath) { + excludedFolder2.path = folder.path; + return; + } + const folders = excludedFolder2.path.split("/"); + if (folders.length < 1) { + folders.push(excludedFolder2.path); + } + folders[folders.indexOf(folder.name)] = folder.name; + excludedFolder2.path = folders.join("/"); + }); + plugin.saveSettings(); + const excludedFolder = getExcludedFolder(plugin, file.path); + if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && !folderNote) { + return plugin.removeCSSClassFromEL(file.path, "has-folder-note"); + } + let newPath = ""; + if (plugin.settings.storageLocation === "parentFolder") { + const parentFolderPath = plugin.getFolderPathFromString(file.path); + const oldParentFolderPath = plugin.getFolderPathFromString(oldPath); + if (parentFolderPath !== oldParentFolderPath) { + if (!plugin.settings.syncMove) { + return; + } + newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`; + } else if (parentFolderPath.trim() === "") { + folderNote.path = `${folderNote.name}`; + newPath = `${fileName}.${folderNote.extension}`; + } else { + folderNote.path = `${parentFolderPath}/${folderNote.name}`; + newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`; + } + } else { + folderNote.path = `${file.path}/${folderNote.name}`; + newPath = `${file.path}/${fileName}.${folderNote.extension}`; + } + plugin.app.vault.rename(folderNote, newPath); +} +function handleFileRename(file, oldPath, plugin) { + const oldFileName = plugin.removeExtension(plugin.getFileNameFromPathString(oldPath)); + const oldFolder = getFolderNoteFolder(plugin, oldPath, oldFileName); + const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename) || file.basename; + const oldFolderName = extractFolderName(plugin.settings.folderNoteName, oldFileName) || oldFileName; + const newFolder = getFolderNoteFolder(plugin, file, file.basename); + let excludedFolder = getExcludedFolder(plugin, (newFolder == null ? void 0 : newFolder.path) || ""); + const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file); + if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && folderName === (newFolder == null ? void 0 : newFolder.name)) { + plugin.addCSSClassToTitleEL(file.path, "is-folder-note"); + plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note"); + return; + } else if (excludedFolder == null ? void 0 : excludedFolder.disableSync) { + plugin.removeCSSClassFromEL(file.path, "is-folder-note"); + plugin.removeCSSClassFromEL((newFolder == null ? void 0 : newFolder.path) || "", "has-folder-note"); + return; + } + if (folderName === (newFolder == null ? void 0 : newFolder.name) && folderNote) { + new import_obsidian15.Notice("Folder with same name already exists!"); + let excludedFolderExisted = true; + let disabledSync = false; + if (!excludedFolder) { + excludedFolderExisted = false; + excludedFolder = new ExcludedFolder((oldFolder == null ? void 0 : oldFolder.path) || "", plugin.settings.excludeFolders.length); + addExcludedFolder(plugin, excludedFolder); + } else if (!excludedFolder.disableSync) { + disabledSync = false; + excludedFolder.disableSync = true; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + } + return plugin.app.vault.rename(file, oldPath).then(() => { + if (!excludedFolder) { + return; + } + if (!excludedFolderExisted) { + deleteExcludedFolder(plugin, excludedFolder); + } else if (!disabledSync) { + excludedFolder.disableSync = false; + updateExcludedFolder(plugin, excludedFolder, excludedFolder); + } + }); + } + if (folderName === (newFolder == null ? void 0 : newFolder.name)) { + plugin.addCSSClassToTitleEL(file.path, "is-folder-note"); + plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note"); + plugin.removeCSSClassFromEL(oldFolder == null ? void 0 : oldFolder.path, "has-folder-note"); + return; + } + if (!oldFolder) + return; + if (oldFolderName === oldFolder.name && (newFolder == null ? void 0 : newFolder.path) === oldFolder.path) { + return renameFolderOnFileRename(file, oldPath, oldFolder, plugin); + } else if (folderNote && oldFolderName === oldFolder.name) { + return renameFolderOnFileRename(file, oldPath, oldFolder, plugin); + } + if (oldFolder.name === oldFileName && (newFolder == null ? void 0 : newFolder.path) !== oldFolder.path) { + plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note"); + plugin.removeCSSClassFromEL(file.path, "is-folder-note"); + plugin.removeCSSClassFromEL(oldPath, "is-folder-note"); + } +} +async function renameFolderOnFileRename(file, oldPath, oldFolder, plugin) { + var _a; + const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename); + if (!newFolderName) { + plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note"); + plugin.removeCSSClassFromEL(file.path, "is-folder-note"); + return; + } else if (newFolderName === oldFolder.name) { + plugin.addCSSClassToTitleEL(oldFolder.path, "has-folder-note"); + plugin.addCSSClassToTitleEL(file.path, "is-folder-note"); + return; + } + let newFolderPath = ""; + if (plugin.settings.storageLocation === "insideFolder") { + newFolderPath = ((_a = oldFolder.parent) == null ? void 0 : _a.path) + "/" + newFolderName; + } else { + const parentFolderPath = plugin.getFolderPathFromString(file.path); + if (parentFolderPath.trim() === "") { + newFolderPath = `${newFolderName}`; + } else { + newFolderPath = `${parentFolderPath}/${newFolderName}`; + } + } + if (plugin.app.vault.getAbstractFileByPath(newFolderPath) || plugin.app.vault.getAbstractFileByPath(newFolderName || "")) { + await plugin.app.vault.rename(file, oldPath); + return new import_obsidian15.Notice("A folder with the same name already exists"); + } + await plugin.app.vault.rename(oldFolder, newFolderPath); +} + +// src/folderOverview.ts +var import_obsidian16 = require("obsidian"); +function createOverview(plugin, source, el, ctx) { + let yaml = (0, import_obsidian16.parseYaml)(source); + if (!yaml) { + yaml = { + title: plugin.settings.defaultOverview.title, + disableTitle: plugin.settings.defaultOverview.disableTitle, + depth: plugin.settings.defaultOverview.depth, + type: plugin.settings.defaultOverview.type, + includeTypes: plugin.settings.defaultOverview.includeTypes, + style: plugin.settings.defaultOverview.style, + disableFileTag: plugin.settings.defaultOverview.disableFileTag, + sortBy: plugin.settings.defaultOverview.sortBy, + showEmptyFolders: plugin.settings.defaultOverview.showEmptyFolders, + onlyIncludeSubfolders: plugin.settings.defaultOverview.onlyIncludeSubfolders + }; + } + const depth = (yaml == null ? void 0 : yaml.depth) || 1; + let title = (yaml == null ? void 0 : yaml.title) || plugin.settings.defaultOverview.title || "{{folderName}} overview"; + const folderName = extractFolderName(plugin.settings.folderNoteName, plugin.removeExtension(plugin.getFolderNameFromPathString(ctx.sourcePath))); + title = title.replaceAll("{{folderName}}", folderName || ""); + const disableTitle = (yaml == null ? void 0 : yaml.disableTitle) || plugin.settings.defaultOverview.disableTitle || false; + let includeTypes = (yaml == null ? void 0 : yaml.includeTypes) || plugin.settings.defaultOverview.includeTypes || ["folder", "markdown"]; + includeTypes = includeTypes.map((type) => type.toLowerCase()); + const style = (yaml == null ? void 0 : yaml.style) || "list"; + const disableFileTag = (yaml == null ? void 0 : yaml.disableFileTag) || plugin.settings.defaultOverview.disableFileTag || false; + const showEmptyFolders = (yaml == null ? void 0 : yaml.showEmptyFolders) || plugin.settings.defaultOverview.showEmptyFolders || false; + const root = el.createEl("div", { cls: "folder-overview" }); + const titleEl = root.createEl("h1", { cls: "folder-overview-title" }); + const ul = root.createEl("ul", { cls: "folder-overview-list" }); + if (!disableTitle) { + titleEl.innerText = title; + } + if (includeTypes.length === 0) { + return; + } + let files = []; + const sourceFile = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath); + if (!sourceFile) + return; + const sourceFolderPath = plugin.getFolderPathFromString(ctx.sourcePath); + let sourceFolder; + if (sourceFile.parent instanceof import_obsidian16.TFolder) { + sourceFolder = sourceFile.parent; + } else { + sourceFolder = plugin.app.vault.getAbstractFileByPath(plugin.getFolderPathFromString(ctx.sourcePath)); + } + files = sourceFolder.children; + files = files.filter((file) => { + const folderPath = plugin.getFolderPathFromString(file.path); + if (!folderPath.startsWith(sourceFolderPath)) { + return false; + } + if (file.path === ctx.sourcePath) { + return false; + } + if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) { + return true; + } + }); + if (!includeTypes.includes("folder")) { + files = getAllFiles(files, sourceFolderPath, depth); + } + files = sortFiles(files, yaml, plugin); + if (style === "grid") { + const grid = root.createEl("div", { cls: "folder-overview-grid" }); + files.forEach(async (file) => { + const gridItem = grid.createEl("div", { cls: "folder-overview-grid-item" }); + const gridArticle = gridItem.createEl("article", { cls: "folder-overview-grid-item-article" }); + if (file instanceof import_obsidian16.TFile) { + const fileContent = await plugin.app.vault.read(file); + const descriptionEl = gridArticle.createEl("p", { cls: "folder-overview-grid-item-description" }); + let description = fileContent.split("\n")[0]; + if (description.length > 64) { + description = description.slice(0, 64) + "..."; + } + descriptionEl.innerText = description; + const link = gridArticle.createEl("a", { cls: "folder-overview-grid-item-link internal-link" }); + const title2 = link.createEl("h1", { cls: "folder-overview-grid-item-link-title" }); + title2.innerText = file.name.replace(".md", "").replace(".canvas", ""); + link.href = file.path; + } else if (file instanceof import_obsidian16.TFolder) { + const folderItem = gridArticle.createEl("div", { cls: "folder-overview-grid-item-folder" }); + const folderName2 = folderItem.createEl("h1", { cls: "folder-overview-grid-item-folder-name" }); + folderName2.innerText = file.name; + } + }); + } else if (style === "list") { + const pathBlacklist = []; + files.forEach((file) => { + if (file instanceof import_obsidian16.TFolder) { + const folderItem = addFolderList(plugin, ul, pathBlacklist, file); + goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag); + } else if (file instanceof import_obsidian16.TFile) { + addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag); + } + }); + } else if (style === "explorer") { + } + if (includeTypes.length > 1 && style !== "grid" && (!showEmptyFolders || yaml.onlyIncludeSubfolders)) { + removeEmptyFolders(ul, 1, yaml); + } +} +function goThroughFolders(plugin, list, folder, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag) { + if (sourceFolderPath === "") { + depth--; + } + let files = folder.children.filter((file) => { + const folderPath = plugin.getFolderPathFromString(file.path); + if (!folderPath.startsWith(sourceFolderPath)) { + return false; + } + if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) { + return true; + } + }); + files = sortFiles(files, yaml, plugin); + const ul = list.createEl("ul", { cls: "folder-overview-list" }); + files.forEach((file) => { + if (file instanceof import_obsidian16.TFolder) { + const folderItem = addFolderList(plugin, ul, pathBlacklist, file); + goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag); + } else if (file instanceof import_obsidian16.TFile) { + addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag); + } + }); +} +function sortFiles(files, yaml, plugin) { + if (!(yaml == null ? void 0 : yaml.sortBy)) { + yaml.sortBy = plugin.settings.defaultOverview.sortBy || "name"; + } + return files.sort((a, b) => { + if (a instanceof import_obsidian16.TFolder && !(b instanceof import_obsidian16.TFolder)) { + return -1; + } + if (!(a instanceof import_obsidian16.TFolder) && b instanceof import_obsidian16.TFolder) { + return 1; + } + if (!(a instanceof import_obsidian16.TFile) || !(b instanceof import_obsidian16.TFile)) { + return -1; + } + if (yaml.sortBy === "created") { + if (a.stat.ctime > b.stat.ctime) { + return -1; + } else if (a.stat.ctime < b.stat.ctime) { + return 1; + } + } else if (yaml.sortBy === "createdAsc") { + if (a.stat.ctime < b.stat.ctime) { + return -1; + } else if (a.stat.ctime > b.stat.ctime) { + return 1; + } + } else if (yaml.sortBy === "modified") { + if (a.stat.mtime > b.stat.mtime) { + return -1; + } else if (a.stat.mtime < b.stat.mtime) { + return 1; + } + } else if (yaml.sortBy === "modifiedAsc") { + if (a.stat.mtime < b.stat.mtime) { + return -1; + } else if (a.stat.mtime > b.stat.mtime) { + return 1; + } + } + if (a.name < b.name && yaml.sortBy === "name") { + return -1; + } else if (a.name > b.name && yaml.sortBy === "nameAsc") { + return -1; + } + if (a.name > b.name && yaml.sortBy === "name") { + return 1; + } else if (a.name < b.name && yaml.sortBy === "nameAsc") { + return 1; + } + return 0; + }); +} +function removeEmptyFolders(ul, depth, yaml) { + const childrensToRemove = []; + ul.childNodes.forEach((el) => { + const childrens = el.querySelector("ul"); + if (!childrens || childrens === null) { + return; + } + if (childrens && !(childrens == null ? void 0 : childrens.hasChildNodes()) && !(el instanceof HTMLUListElement)) { + childrensToRemove.push(el); + } else if (el instanceof HTMLUListElement || el instanceof HTMLLIElement) { + removeEmptyFolders(el, depth + 1, yaml); + } + }); + childrensToRemove.forEach((el) => { + if (yaml.onlyIncludeSubfolders && depth === 1) { + return; + } + el.remove(); + }); +} +function addFolderList(plugin, list, pathBlacklist, folder) { + const folderItem = list.createEl("li", { cls: "folder-overview-list folder-list" }); + const folderNote = getFolderNote(plugin, folder.path); + if (folderNote instanceof import_obsidian16.TFile) { + const folderNoteLink = folderItem.createEl("a", { cls: "folder-overview-list-item folder-name-item internal-link", href: folderNote.path }); + folderNoteLink.innerText = folder.name; + pathBlacklist.push(folderNote.path); + } else { + const folderName = folderItem.createEl("span", { cls: "folder-overview-list-item folder-name-item" }); + folderName.innerText = folder.name; + } + return folderItem; +} +function addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag) { + if (includeTypes.length > 0 && !includeTypes.includes("all")) { + if (file.extension === "md" && !includeTypes.includes("markdown")) + return; + if (file.extension === "canvas" && !includeTypes.includes("canvas")) + return; + if (file.extension === "pdf" && !includeTypes.includes("pdf")) + return; + const imageTypes = ["jpg", "jpeg", "png", "gif", "svg", "webp"]; + if (imageTypes.includes(file.extension) && !includeTypes.includes("image")) + return; + const videoTypes = ["mp4", "webm", "ogv", "mov", "mkv"]; + if (videoTypes.includes(file.extension) && !includeTypes.includes("video")) + return; + const audioTypes = ["mp3", "wav", "m4a", "3gp", "flac", "ogg", "oga", "opus"]; + if (audioTypes.includes(file.extension) && includeTypes.includes("audio")) + return; + const allTypes = ["md", "canvas", "pdf", ...imageTypes, ...videoTypes, ...audioTypes]; + if (!allTypes.includes(file.extension) && !includeTypes.includes("other")) + return; + } + if (pathBlacklist.includes(file.path)) + return; + const listItem = list.createEl("li", { cls: "folder-overview-list file-link" }); + const nameItem = listItem.createEl("div", { cls: "folder-overview-list-item" }); + const link = nameItem.createEl("a", { cls: "internal-link", href: file.path }); + link.innerText = file.basename; + if (file.extension !== "md" && !disableFileTag) { + nameItem.createDiv({ cls: "nav-file-tag" }).innerText = file.extension; + } +} +function getAllFiles(files, sourceFolderPath, depth) { + const allFiles = []; + files.forEach((file) => { + if (file instanceof import_obsidian16.TFolder) { + if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth - 1) { + allFiles.push(...getAllFiles(file.children, sourceFolderPath, depth)); + } + } else { + allFiles.push(file); + } + }); + return allFiles; +} + +// src/modals/folderOverview.ts +var import_obsidian17 = require("obsidian"); +var FolderOverviewSettings = class extends import_obsidian17.Modal { + constructor(app2, plugin, yaml, ctx, el) { + super(app2); + this.plugin = plugin; + this.app = app2; + this.yaml = yaml; + this.ctx = ctx; + this.el = el; + if (!this.yaml) { + this.yaml = { + title: this.plugin.settings.defaultOverview.title, + disableTitle: this.plugin.settings.defaultOverview.disableTitle, + depth: this.plugin.settings.defaultOverview.depth, + type: this.plugin.settings.defaultOverview.type, + includeTypes: this.plugin.settings.defaultOverview.includeTypes, + style: this.plugin.settings.defaultOverview.style, + disableFileTag: this.plugin.settings.defaultOverview.disableFileTag, + sortBy: this.plugin.settings.defaultOverview.sortBy, + showEmptyFolders: this.plugin.settings.defaultOverview.showEmptyFolders, + onlyIncludeSubfolders: this.plugin.settings.defaultOverview.onlyIncludeSubfolders + }; + } + } + onOpen() { + this.display(); + } + display() { + var _a, _b, _c, _d; + const { contentEl } = this; + contentEl.empty(); + contentEl.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + this.close(); + } + }); + contentEl.createEl("h2", { text: "Folder overview settings" }); + new import_obsidian17.Setting(contentEl).setName("Disable the title").setDesc("Choose if the title should be shown").addToggle((toggle) => toggle.setValue(this.yaml.disableTitle || false).onChange(async (value) => { + this.yaml.disableTitle = value; + this.display(); + await this.updateYaml(); + })); + if (!this.yaml.disableTitle) { + new import_obsidian17.Setting(contentEl).setName("Title").setDesc("Choose the title of the folder overview").addText((text) => { + var _a2; + return text.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.title) || "{{folderName}} overview").onChange(async (value) => { + this.yaml.title = value; + await this.updateYaml(); + }); + }); + } + const setting = new import_obsidian17.Setting(contentEl); + setting.setName("Include types"); + const list = setting.createList((list2) => { + var _a2; + return list2.addModal(this).setValues(((_a2 = this.yaml) == null ? void 0 : _a2.includeTypes) || this.plugin.settings.defaultOverview.includeTypes || []).addResetButton(); + }); + if ((((_b = (_a = this.yaml) == null ? void 0 : _a.includeTypes) == null ? void 0 : _b.length) || 0) < 8 && !((_c = this.yaml.includeTypes) == null ? void 0 : _c.includes("all"))) { + setting.addDropdown((dropdown) => { + if (!this.yaml.includeTypes) + this.yaml.includeTypes = this.plugin.settings.defaultOverview.includeTypes || []; + this.yaml.includeTypes = this.yaml.includeTypes.map((type) => type.toLowerCase()); + const options = [ + { value: "markdown", label: "Markdown" }, + { value: "folder", label: "Folder" }, + { value: "canvas", label: "Canvas" }, + { value: "pdf", label: "PDF" }, + { value: "image", label: "Image" }, + { value: "audio", label: "Audio" }, + { value: "video", label: "Video" }, + { value: "other", label: "All other file types" }, + { value: "all", label: "All file types" } + ]; + options.forEach((option) => { + var _a2; + if (!((_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.includes(option.value))) { + dropdown.addOption(option.value, option.label); + } + }); + dropdown.addOption("+", "+"); + dropdown.setValue("+"); + dropdown.onChange(async (value) => { + var _a2; + if (value === "all") { + this.yaml.includeTypes = (_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.filter((type) => type === "folder"); + list.setValues(this.yaml.includeTypes); + } + await list.addValue(value.toLowerCase()); + await this.updateYaml(); + this.display(); + }); + }); + } + let disableFileTag; + (_d = this.yaml.includeTypes) == null ? void 0 : _d.forEach((type) => { + type === "folder" || type === "markdown" ? disableFileTag = true : null; + }); + if (disableFileTag) { + new import_obsidian17.Setting(contentEl).setName("Disable file tag").setDesc("Choose if the file tag should be shown after the file name").addToggle((toggle) => { + toggle.setValue(this.yaml.disableFileTag || this.plugin.settings.defaultOverview.disableFileTag || false).onChange(async (value) => { + this.yaml.disableFileTag = value; + await this.updateYaml(); + }); + }); + } + new import_obsidian17.Setting(contentEl).setName("File depth").setDesc("File & folder = +1 depth").addSlider((slider) => { + var _a2; + return slider.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.depth) || 2).setLimits(1, 10, 1).onChange(async (value) => { + this.yaml.depth = value; + await this.updateYaml(); + }); + }); + new import_obsidian17.Setting(contentEl).setName("Overview style").setDesc("Choose the style of the overview (grid style soon)").addDropdown((dropdown) => { + var _a2; + return dropdown.addOption("list", "List").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.style) || "list").onChange(async (value) => { + this.yaml.style = value; + await this.updateYaml(); + }); + }); + new import_obsidian17.Setting(contentEl).setName("Sort files by").setDesc("Choose how the files should be sorted").addDropdown((dropdown) => { + var _a2; + return dropdown.addOption("name", "Name descending").addOption("created", "Created descending").addOption("modified", "Modified descending").addOption("nameAsc", "Name ascending").addOption("createdAsc", "Created ascending").addOption("modifiedAsc", "Modified ascending").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.sortBy) || "name").onChange(async (value) => { + this.yaml.sortBy = value; + await this.updateYaml(); + }); + }); + new import_obsidian17.Setting(contentEl).setName("Show folder names of empty folders").setDesc("That includes subfolders of the current folder when you are on file depth 1").addToggle((toggle) => { + toggle.setValue(this.yaml.showEmptyFolders || this.plugin.settings.defaultOverview.showEmptyFolders || false).onChange(async (value) => { + this.yaml.showEmptyFolders = value; + this.yaml.onlyIncludeSubfolders = false; + this.display(); + await this.updateYaml(); + }); + }); + if (this.yaml.showEmptyFolders) { + new import_obsidian17.Setting(contentEl).setName("Only show first empty subfolders of current folder").addToggle((toggle) => { + toggle.setValue(this.yaml.onlyIncludeSubfolders || this.plugin.settings.defaultOverview.onlyIncludeSubfolders || false).onChange(async (value) => { + this.yaml.onlyIncludeSubfolders = value; + await this.updateYaml(); + }); + }); + } + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } + async updateYaml() { + const file = this.plugin.app.vault.getAbstractFileByPath(this.ctx.sourcePath); + if (!(file instanceof import_obsidian17.TFile)) + return; + let stringYaml = (0, import_obsidian17.stringifyYaml)(this.yaml); + await this.plugin.app.vault.process(file, (text) => { + const info = this.ctx.getSectionInfo(this.el); + if (stringYaml[stringYaml.length - 1] !== "\n") { + stringYaml += "\n"; + } + if (info) { + const { lineStart } = info; + const lineEnd = this.getCodeBlockEndLine(text, lineStart); + if (lineEnd === -1 || !lineEnd) + return text; + const lineLength = lineEnd - lineStart; + const lines = text.split("\n"); + lines.splice(lineStart, lineLength + 1, `\`\`\`folder-overview +${stringYaml}\`\`\``); + return lines.join("\n"); + } + return `\`\`\`folder-overview +${stringYaml}\`\`\``; + }); + } + getCodeBlockEndLine(text, startLine, count = 1) { + let line = startLine + 1; + const lines = text.split("\n"); + while (line < lines.length) { + if (count > 20) { + return -1; + } + if (lines[line].startsWith("```")) { + return line; + } + line++; + count++; + } + return line; + } +}; + +// src/functions/ListComponent.ts +var import_obsidian18 = require("obsidian"); +var ListComponent = class { + constructor(containerEl) { + this.containerEl = containerEl; + this.controlEl = containerEl.querySelector(".setting-item-control") || containerEl; + this.listEl = this.controlEl.createDiv("setting-command-hotkeys"); + } + addModal(modal) { + this.modal = modal; + this.values = modal.yaml.includeTypes || []; + return this; + } + setValues(values) { + this.listEl.empty(); + this.values = values; + this.modal.yaml.includeTypes = values; + if (values.length !== 0) { + values.forEach((value) => { + this.addElement(value); + }); + } + this.modal.updateYaml(); + return this; + } + addElement(value) { + this.listEl.createSpan("setting-hotkey", (span) => { + span.innerText = value; + const removeSpan = span.createEl("span", { cls: "ofn-list-item-remove setting-hotkey-icon" }); + const svg = ''; + const svgElement = removeSpan.createEl("span", { cls: "ofn-list-item-remove-icon" }); + svgElement.innerHTML = svg; + removeSpan.onClickEvent((e) => { + this.removeValue(value); + span.remove(); + }); + }); + } + async addValue(value) { + this.values.push(value); + this.addElement(value); + this.modal.yaml.includeTypes = this.values; + return this; + } + addResetButton() { + const resetButton = this.controlEl.createEl("span", { cls: "clickable-icon setting-restore-hotkey-button" }); + const svg = ''; + resetButton.innerHTML = svg; + resetButton.onClickEvent((e) => { + this.modal.plugin.loadSettings(); + this.setValues(this.modal.plugin.settings.defaultOverview.includeTypes || []); + this.modal.display(); + }); + return this; + } + removeValue(value) { + this.values = this.values.filter((v) => v !== value); + this.setValues(this.values); + this.modal.display(); + } +}; +function createList(cb) { + const list = new ListComponent(this.settingEl); + cb(list); + return list; +} +import_obsidian18.Setting.prototype.createList = createList; + +// src/main.ts +var FolderNotesPlugin = class extends import_obsidian19.Plugin { + constructor() { + super(...arguments); + this.fmtpHandler = null; + } + async onload() { + console.log("loading folder notes plugin"); + await this.loadSettings(); + this.settingsTab = new SettingsTab(this.app, this); + this.addSettingTab(this.settingsTab); + this.saveSettings(); + document.body.classList.add("folder-notes-plugin"); + if (this.settings.hideFolderNote) { + document.body.classList.add("hide-folder-note"); + } + if (this.settings.underlineFolder) { + document.body.classList.add("folder-note-underline"); + } + if (this.settings.underlineFolderInPath) { + document.body.classList.add("folder-note-underline-path"); + } + if (!this.settings.allowWhitespaceCollapsing) { + document.body.classList.add("fn-whitespace-stop-collapsing"); + } + new Commands(this.app, this).registerCommands(); + this.app.workspace.onLayoutReady(() => { + if (this.settings.frontMatterTitle.enabled) { + this.fmtpHandler = new FrontMatterTitlePluginHandler(this); + } + }); + this.observer = new MutationObserver((mutations) => { + mutations.forEach((rec) => { + if (rec.type === "childList") { + rec.target.querySelectorAll("div.nav-folder-title-content").forEach((element) => { + if (element.onclick) + return; + element.onclick = (event) => handleFolderClick(event, this); + }); + if (!this.settings.openFolderNoteOnClickInPath) { + return; + } + rec.target.querySelectorAll("span.view-header-breadcrumb").forEach((element) => { + var _a, _b; + const breadcrumbs = (_a = element.parentElement) == null ? void 0 : _a.querySelectorAll("span.view-header-breadcrumb"); + if (!breadcrumbs) + return; + let path = ""; + breadcrumbs.forEach((breadcrumb) => { + var _a2; + if (breadcrumb.hasAttribute("old-name")) { + path += breadcrumb.getAttribute("old-name") + "/"; + } else { + path += breadcrumb.innerText.trim() + "/"; + } + const folderPath = path.slice(0, -1); + breadcrumb.setAttribute("data-path", folderPath); + const folder = (_a2 = this.fmtpHandler) == null ? void 0 : _a2.modifiedFolders.get(folderPath); + if (folder && this.settings.frontMatterTitle.path && this.settings.frontMatterTitle.enabled) { + breadcrumb.setAttribute("old-name", folder.name || ""); + breadcrumb.innerText = folder.newName || ""; + } + const folderNote = getFolderNote(this, folderPath); + if (folderNote) { + breadcrumb.classList.add("has-folder-note"); + } + }); + (_b = element.parentElement) == null ? void 0 : _b.setAttribute("data-path", path.slice(0, -1)); + if (breadcrumbs.length > 0) { + breadcrumbs.forEach((breadcrumb) => { + if (breadcrumb.onclick) + return; + breadcrumb.onclick = (event) => handleViewHeaderClick(event, this); + }); + } + }); + } + }); + }); + this.observer.observe(document.body, { + childList: true, + subtree: true + }); + this.registerEvent(this.app.workspace.on("layout-change", () => { + this.loadFileClasses(); + })); + this.registerEvent(this.app.vault.on("delete", (file) => { + if (!(file instanceof import_obsidian19.TFile)) { + return; + } + const parentPath = this.getFolderPathFromString(file.path); + const parentName = this.getFileNameFromPathString(parentPath); + if (parentName !== file.basename) { + return; + } + this.removeCSSClassFromEL(parentPath, "has-folder-note"); + })); + this.registerEvent(this.app.vault.on("create", (file) => { + if (file instanceof import_obsidian19.TFile) { + const folderName = extractFolderName(this.settings.folderNoteName, file.basename); + const folder = getFolder(this, file); + if (!folder) { + return; + } + if (folderName !== folder.name) { + return; + } + this.addCSSClassToTitleEL(folder.path, "has-folder-note"); + this.addCSSClassToTitleEL(file.path, "is-folder-note"); + } + if (!this.app.workspace.layoutReady) + return; + if (!this.settings.autoCreate) + return; + if (!(file instanceof import_obsidian19.TFolder)) + return; + const excludedFolder = getExcludedFolder(this, file.path); + if (excludedFolder == null ? void 0 : excludedFolder.disableAutoCreate) + return; + const folderNote = getFolderNote(this, file.path); + if (folderNote) + return; + createFolderNote(this, file.path, true, true); + this.addCSSClassToTitleEL(file.path, "has-folder-note"); + })); + this.registerEvent(this.app.workspace.on("file-open", (openFile) => { + if (this.activeFolderDom) { + this.activeFolderDom.removeClass("is-active"); + this.activeFolderDom = null; + } + if (!openFile || !openFile.basename) { + return; + } + const folder = getFolder(this, openFile); + if (!folder) { + return; + } + if (extractFolderName(this.settings.folderNoteName, openFile.basename) !== folder.name) { + return; + } + this.activeFolderDom = this.getEL(folder.path); + if (this.activeFolderDom) + this.activeFolderDom.addClass("is-active"); + })); + this.registerEvent(this.app.vault.on("rename", (file, oldPath) => { + if (!this.settings.syncFolderName) { + this.removeCSSClassFromEL(file.path, "has-folder-note"); + this.removeCSSClassFromEL(file.path, "is-folder-note"); + return; + } + if (file instanceof import_obsidian19.TFolder) { + return handleFolderRename(file, oldPath, this); + } else if (file instanceof import_obsidian19.TFile) { + return handleFileRename(file, oldPath, this); + } + })); + this.registerEvent(this.app.vault.on("delete", (file) => { + if (file instanceof import_obsidian19.TFile) { + const folder = getFolder(this, file); + if (!folder) { + return; + } + this.removeCSSClassFromEL(folder.path, "has-folder-note"); + } + if (!(file instanceof import_obsidian19.TFolder)) { + return; + } + const folderNote = getFolderNote(this, file.path); + if (!folderNote) { + return; + } + this.removeCSSClassFromEL(folderNote.path, "is-folder-note"); + if (!this.settings.syncDelete) { + return; + } + this.app.vault.delete(folderNote); + })); + this.registerMarkdownCodeBlockProcessor("folder-overview", (source, el, ctx) => { + const observer = new MutationObserver(() => { + var _a; + const editButton = (_a = el.parentElement) == null ? void 0 : _a.childNodes.item(1); + if (editButton) { + editButton.addEventListener("click", (e) => { + e.stopImmediatePropagation(); + e.preventDefault(); + e.stopPropagation(); + new FolderOverviewSettings(this.app, this, (0, import_obsidian19.parseYaml)(source), ctx, el).open(); + }, { capture: true }); + } + }); + observer.observe(el, { + childList: true, + subtree: true + }); + createOverview(this, source, el, ctx); + }); + if (this.app.workspace.layoutReady) { + this.loadFileClasses(); + } else { + this.app.workspace.onLayoutReady(async () => this.loadFileClasses()); + } + } + getFileNameFromPathString(path) { + return path.substring(path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") + 1 : 0); + } + getFolderNameFromPathString(path) { + if (path.endsWith(".md") || path.endsWith(".canvas")) { + return path.split("/").slice(-2)[0]; + } else { + return path.split("/").slice(-1)[0]; + } + } + removeExtension(name) { + return name.replace(/\.[^/.]+$/, ""); + } + getExtensionFromPathString(path) { + return path.slice(path.lastIndexOf(".") >= 0 ? path.lastIndexOf(".") : 0); + } + getFolderPathFromString(path) { + const subString = path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") : 0; + return path.substring(0, subString); + } + getParentFolderPath(path) { + return this.getFolderPathFromString(this.getFolderPathFromString(path)); + } + getFileExplorer() { + return this.app.workspace.getLeavesOfType("file-explorer")[0]; + } + getFileExplorerView() { + return this.getFileExplorer().view; + } + async addCSSClassToTitleEL(path, cssClass, waitForCreate = false, count = 0) { + const fileExplorerItem = this.getEL(path); + if (!fileExplorerItem) { + if (waitForCreate && count < 5) { + await new Promise((r) => setTimeout(r, 500)); + this.addCSSClassToTitleEL(path, cssClass, waitForCreate, count + 1); + return; + } + return; + } + fileExplorerItem.addClass(cssClass); + const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`); + viewHeaderItems.forEach((item) => { + item.addClass(cssClass); + }); + } + async changeName(folder, name, replacePath, waitForCreate = false, count = 0) { + if (!name) + name = folder.name; + let fileExplorerItem = this.getEL(folder.path); + if (!fileExplorerItem) { + if (waitForCreate && count < 5) { + await new Promise((r) => setTimeout(r, 500)); + this.changeName(folder, name, replacePath, waitForCreate, count + 1); + return; + } + return; + } + fileExplorerItem = fileExplorerItem.querySelector("div.nav-folder-title-content"); + if (!fileExplorerItem) { + return; + } + if (this.settings.frontMatterTitle.explorer && this.settings.frontMatterTitle.enabled) { + fileExplorerItem.innerText = name; + fileExplorerItem.setAttribute("old-name", folder.name); + } else { + fileExplorerItem.innerText = folder.name; + fileExplorerItem.removeAttribute("old-name"); + } + if (replacePath) { + this.updateBreadcrumbs(); + } + } + updateBreadcrumbs(remove) { + if (!this.settings.frontMatterTitle.path && !remove) { + return; + } + const viewHeaderItems = document.querySelectorAll("span.view-header-breadcrumb"); + const files = this.app.vault.getAllLoadedFiles().filter((file) => file instanceof import_obsidian19.TFolder); + viewHeaderItems.forEach((item) => { + if (!item.hasAttribute("data-path")) { + return; + } + const path = item.getAttribute("data-path"); + const folder = files.find((file) => file.path === path); + if (!(folder instanceof import_obsidian19.TFolder)) { + return; + } + if (remove) { + item.textContent = folder.name; + item.removeAttribute("old-name"); + } else { + item.textContent = folder.newName || folder.name; + item.setAttribute("old-name", folder.name); + item.setAttribute("data-path", folder.path); + } + }); + } + removeCSSClassFromEL(path, cssClass) { + if (!path) + return; + const fileExplorerItem = this.getEL(path); + const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`); + viewHeaderItems.forEach((item) => { + item.removeClass(cssClass); + }); + if (!fileExplorerItem) { + return; + } + fileExplorerItem.removeClass(cssClass); + } + getEL(path) { + const fileExplorer = this.getFileExplorer(); + if (!fileExplorer) { + return null; + } + const fileExplorerItem = fileExplorer.view.fileItems[path]; + if (!fileExplorerItem) { + return null; + } + if (fileExplorerItem.selfEl) + return fileExplorerItem.selfEl; + return fileExplorerItem.titleEl; + } + loadFileClasses(forceReload = false) { + if (this.activeFileExplorer === this.getFileExplorer() && !forceReload) { + return; + } + this.activeFileExplorer = this.getFileExplorer(); + this.app.vault.getAllLoadedFiles().forEach((file) => { + if (!(file instanceof import_obsidian19.TFolder)) { + return; + } + const folderNote = getFolderNote(this, file.path); + if (!folderNote) { + this.removeCSSClassFromEL(file == null ? void 0 : file.path, "has-folder-note"); + return; + } + const excludedFolder = getExcludedFolder(this, file.path); + if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) { + this.removeCSSClassFromEL(folderNote.path, "is-folder-note"); + this.removeCSSClassFromEL(file.path, "has-folder-note"); + } else { + this.addCSSClassToTitleEL(folderNote.path, "is-folder-note"); + this.addCSSClassToTitleEL(file.path, "has-folder-note"); + } + }); + } + reloadHandlers() { + document.querySelectorAll("div.nav-folder-title-content").forEach((element) => { + if (element.onclick) + return; + element.onclick = (event) => handleFolderClick(event, this); + }); + } + onunload() { + console.log("unloading folder notes plugin"); + this.observer.disconnect(); + document.body.classList.remove("folder-notes-plugin"); + document.body.classList.remove("folder-note-underline"); + document.body.classList.remove("hide-folder-note"); + document.body.classList.remove("fn-whitespace-stop-collapsing"); + if (this.activeFolderDom) { + this.activeFolderDom.removeClass("is-active"); + } + if (this.fmtpHandler) { + this.fmtpHandler.deleteEvent(); + } + } + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } + async saveSettings() { + await this.saveData(this.settings); + this.loadFileClasses(true); + } +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzL2Zyb250LW1hdHRlci1wbHVnaW4tYXBpLXByb3ZpZGVyL2xpYi9jb250cmFjdHMvQXBpLmpzIiwgIm5vZGVfbW9kdWxlcy9mcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlci9saWIvY29udHJhY3RzL0V2ZW50RGlzcGF0Y2hlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2NvbnRyYWN0cy9SZXNvbHZlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2luZGV4LmpzIiwgInNyYy9tYWluLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlci50cyIsICJzcmMvc3VnZ2VzdGVycy9zdWdnZXN0LnRzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZW51bXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZU5hbWUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2luc3RhbmNlT2YuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvYXBwbHlTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWF0aC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3VzZXJBZ2VudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc0xheW91dFZpZXdwb3J0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2NvbnRhaW5zLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNUYWJsZUVsZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFBhcmVudE5vZGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvd2l0aGluLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0RnJlc2hTaWRlT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZXhwYW5kVG9IYXNoTWFwLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2Fycm93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0VmFyaWF0aW9uLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2NvbXB1dGVTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRPcHBvc2l0ZVBsYWNlbWVudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvd1Njcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFZpZXdwb3J0UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXREb2N1bWVudFJlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNTY3JvbGxQYXJlbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0U2Nyb2xsUGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvcmVjdFRvQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9jb21wdXRlT2Zmc2V0cy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvY29tcHV0ZUF1dG9QbGFjZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZmxpcC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9oaWRlLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL29mZnNldC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0QWx0QXhpcy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wcmV2ZW50T3ZlcmZsb3cuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZVNjcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvb3JkZXJNb2RpZmllcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9kZWJvdW5jZS5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21lcmdlQnlOYW1lLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvY3JlYXRlUG9wcGVyLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvcG9wcGVyLmpzIiwgInNyYy90ZW1wbGF0ZS50cyIsICJzcmMvbW9kYWxzL2V4aXN0aW5nTm90ZS50cyIsICJzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMudHMiLCAic3JjL21vZGFscy9kZWxldGVDb25maXJtYXRpb24udHMiLCAic3JjL2V4Y2x1ZGVkRm9sZGVyLnRzIiwgInNyYy9tb2RhbHMvZXhjbHVkZUZvbGRlclNldHRpbmdzLnRzIiwgInNyYy9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlci50cyIsICJzcmMvbW9kYWxzL3BhdHRlcm5TZXR0aW5ncy50cyIsICJzcmMvZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUudHMiLCAic3JjL2NvbW1hbmRzLnRzIiwgInNyYy9ldmVudHMvaGFuZGxlQ2xpY2sudHMiLCAic3JjL2V2ZW50cy9oYW5kbGVSZW5hbWUudHMiLCAic3JjL2ZvbGRlck92ZXJ2aWV3LnRzIiwgInNyYy9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcudHMiLCAic3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAodGhpcyAmJiB0aGlzLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19leHBvcnRTdGFyID0gKHRoaXMgJiYgdGhpcy5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRBcGlTYWZlID0gZXhwb3J0cy5nZXREZWZlciA9IGV4cG9ydHMuaXNQbHVnaW5FbmFibGVkID0gZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBleHBvcnRzLnBsdWdpbklkID0gdm9pZCAwO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9BcGlcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9FdmVudERpc3BhdGNoZXJcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9SZXNvbHZlclwiKSwgZXhwb3J0cyk7XG5leHBvcnRzLnBsdWdpbklkID0gJ29ic2lkaWFuLWZyb250LW1hdHRlci10aXRsZS1wbHVnaW4nO1xuY2xhc3MgUGx1Z2luTm90RW5hYmxlZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBQbHVnaW5Ob3RFbmFibGVkRXJyb3I7XG4vKipcbiAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgb2JzaWRpYW4tZnJvbnQtbWF0dGVyLXRpdGxlLXBsdWdpbiBpcyBlbmFibGVkXG4gKiBAcGFyYW0gYXBwXG4gKi9cbmZ1bmN0aW9uIGlzUGx1Z2luRW5hYmxlZChhcHApIHtcbiAgICB2YXIgX2EsIF9iLCBfYztcbiAgICAvL0B0cy1pZ25vcmVcbiAgICByZXR1cm4gKF9jID0gKF9iID0gKF9hID0gYXBwID09PSBudWxsIHx8IGFwcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogYXBwLnBsdWdpbnMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5lbmFibGVkUGx1Z2lucykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmhhcyhleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2MgIT09IHZvaWQgMCA/IF9jIDogZmFsc2U7XG59XG5leHBvcnRzLmlzUGx1Z2luRW5hYmxlZCA9IGlzUGx1Z2luRW5hYmxlZDtcbi8qKlxuICpcbiAqIEB0aHJvd3MgUGx1Z2luTm90RW5hYmxlZEVycm9yXG4gKi9cbmZ1bmN0aW9uIGdldERlZmVyKGFwcCkge1xuICAgIHZhciBfYSwgX2IsIF9jLCBfZDtcbiAgICAvL0B0cy1pZ25vcmVcbiAgICBjb25zdCBwbHVnaW4gPSAoX2IgPSAoX2EgPSBhcHAgPT09IG51bGwgfHwgYXBwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhcHAucGx1Z2lucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFBsdWdpbihleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogbnVsbDtcbiAgICBjb25zdCBkZWZlciA9IChfZCA9IChfYyA9IHBsdWdpbiA9PT0gbnVsbCB8fCBwbHVnaW4gPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBsdWdpbi5nZXREZWZlcikgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jLmNhbGwocGx1Z2luKSkgIT09IG51bGwgJiYgX2QgIT09IHZvaWQgMCA/IF9kIDogbnVsbDtcbiAgICBpZiAoZGVmZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBsdWdpbk5vdEVuYWJsZWRFcnJvcihgUGx1Z2luICR7ZXhwb3J0cy5wbHVnaW5JZH0gaXMgbm90IGVuYWJsZWQgb3Igb2xkIHZlcnNpb25gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmVyO1xufVxuZXhwb3J0cy5nZXREZWZlciA9IGdldERlZmVyO1xuLyoqXG4gKiBXcmFwcGVyIGZvciBvYmplY3QuIEl0IHdpbGwgY2hlY2sgaXRzZWxmIGlmIHBsdWdpbiBpcyBlbmFibGVkIGFuZCByZWFkeVxuICogQHBhcmFtIGFwcFxuICovXG5mdW5jdGlvbiBnZXRBcGlTYWZlKGFwcCkge1xuICAgIHJldHVybiBuZXcgQXBpV3JhcHBlcihudWxsLCBhcHApO1xufVxuZXhwb3J0cy5nZXRBcGlTYWZlID0gZ2V0QXBpU2FmZTtcbmNsYXNzIEFwaVdyYXBwZXIge1xuICAgIGNvbnN0cnVjdG9yKGFwaSwgYXBwKSB7XG4gICAgICAgIHRoaXMuYXBpID0gYXBpO1xuICAgICAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICB9XG4gICAgYmVmb3JlKCkge1xuICAgICAgICBpZiAodGhpcy5hcGkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWZlciA9IHRoaXMuZ2V0RGVmZmVyKCk7XG4gICAgICAgIGlmIChkZWZlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICBpZiAoYXBpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmZXIuYXdhaXRQbHVnaW4oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXREZWZmZXIoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RGVmZXIodGhpcy5hcHApO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFBsdWdpbk5vdEVuYWJsZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRSZXNvbHZlckZhY3RvcnkoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFJlc29sdmVyRmFjdG9yeSgpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFdmVudERpc3BhdGNoZXIoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEV2ZW50RGlzcGF0Y2hlcigpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFbmFibGVkRmVhdHVyZXMoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEVuYWJsZWRGZWF0dXJlcygpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBbXTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBGb2xkZXJOb3Rlc1NldHRpbmdzLCBTZXR0aW5nc1RhYiB9IGZyb20gJy4vc2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBDb21tYW5kcyB9IGZyb20gJy4vY29tbWFuZHMnO1xyXG5pbXBvcnQgeyBGaWxlRXhwbG9yZXJXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnLi9nbG9iYWxzJztcclxuaW1wb3J0IHsgaGFuZGxlVmlld0hlYWRlckNsaWNrLCBoYW5kbGVGb2xkZXJDbGljayB9IGZyb20gJy4vZXZlbnRzL2hhbmRsZUNsaWNrJztcclxuaW1wb3J0IHsgaGFuZGxlRmlsZVJlbmFtZSwgaGFuZGxlRm9sZGVyUmVuYW1lIH0gZnJvbSAnLi9ldmVudHMvaGFuZGxlUmVuYW1lJztcclxuaW1wb3J0IHsgY3JlYXRlRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUsIGdldEZvbGRlciB9IGZyb20gJy4vZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBnZXRFeGNsdWRlZEZvbGRlciB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG5pbXBvcnQgeyBjcmVhdGVPdmVydmlldyBhcyBjcmVhdGVGb2xkZXJPdmVydmlldyB9IGZyb20gJy4vZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgJy4vZnVuY3Rpb25zL0xpc3RDb21wb25lbnQnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGb2xkZXJOb3Rlc1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0b2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XHJcblx0c2V0dGluZ3M6IEZvbGRlck5vdGVzU2V0dGluZ3M7XHJcblx0c2V0dGluZ3NUYWI6IFNldHRpbmdzVGFiO1xyXG5cdGFjdGl2ZUZvbGRlckRvbTogSFRNTEVsZW1lbnQgfCBudWxsO1xyXG5cdGFjdGl2ZUZpbGVFeHBsb3JlcjogRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHRmbXRwSGFuZGxlcjogRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIgfCBudWxsID0gbnVsbDtcclxuXHRhc3luYyBvbmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygnbG9hZGluZyBmb2xkZXIgbm90ZXMgcGx1Z2luJyk7XHJcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5zZXR0aW5nc1RhYiA9IG5ldyBTZXR0aW5nc1RhYih0aGlzLmFwcCwgdGhpcyk7XHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIodGhpcy5zZXR0aW5nc1RhYik7XHJcblx0XHR0aGlzLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIEFkZCBDU1MgQ2xhc3Nlc1xyXG5cdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZXMtcGx1Z2luJyk7XHJcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2hpZGUtZm9sZGVyLW5vdGUnKTsgfVxyXG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLnVuZGVybGluZUZvbGRlckluUGF0aCkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7IH1cclxuXHRcdGlmICghdGhpcy5zZXR0aW5ncy5hbGxvd1doaXRlc3BhY2VDb2xsYXBzaW5nKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTsgfVxyXG5cclxuXHRcdG5ldyBDb21tYW5kcyh0aGlzLmFwcCwgdGhpcykucmVnaXN0ZXJDb21tYW5kcygpO1xyXG5cclxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHtcclxuXHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdFx0dGhpcy5mbXRwSGFuZGxlciA9IG5ldyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlcih0aGlzKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnM6IE11dGF0aW9uUmVjb3JkW10pID0+IHtcclxuXHRcdFx0bXV0YXRpb25zLmZvckVhY2goKHJlYykgPT4ge1xyXG5cdFx0XHRcdGlmIChyZWMudHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcclxuXHRcdFx0XHRcdCg8RWxlbWVudD5yZWMudGFyZ2V0KS5xdWVyeVNlbGVjdG9yQWxsKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGVsZW1lbnQub25jbGljaykgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQub25jbGljayA9IChldmVudDogTW91c2VFdmVudCkgPT4gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0XHQoPEVsZW1lbnQ+cmVjLnRhcmdldCkucXVlcnlTZWxlY3RvckFsbCgnc3Bhbi52aWV3LWhlYWRlci1icmVhZGNydW1iJylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgYnJlYWRjcnVtYnMgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NwYW4udmlldy1oZWFkZXItYnJlYWRjcnVtYicpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICghYnJlYWRjcnVtYnMpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRsZXQgcGF0aCA9ICcnO1xyXG5cdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoYnJlYWRjcnVtYi5oYXNBdHRyaWJ1dGUoJ29sZC1uYW1lJykpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cGF0aCArPSBicmVhZGNydW1iLmdldEF0dHJpYnV0ZSgnb2xkLW5hbWUnKSArICcvJztcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHBhdGggKz0gYnJlYWRjcnVtYi5pbm5lclRleHQudHJpbSgpICsgJy8nO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcsIGZvbGRlclBhdGgpO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyID0gdGhpcy5mbXRwSGFuZGxlcj8ubW9kaWZpZWRGb2xkZXJzLmdldChmb2xkZXJQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLnBhdGggJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUgfHwgJycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmlubmVyVGV4dCA9IGZvbGRlci5uZXdOYW1lIHx8ICcnO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmNsYXNzTGlzdC5hZGQoJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQucGFyZW50RWxlbWVudD8uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBwYXRoLnNsaWNlKDAsIC0xKSk7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGJyZWFkY3J1bWJzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChicmVhZGNydW1iLm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5vbmNsaWNrID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiBoYW5kbGVWaWV3SGVhZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHksIHtcclxuXHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRzdWJ0cmVlOiB0cnVlLFxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdsYXlvdXQtY2hhbmdlJywgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmxvYWRGaWxlQ2xhc3NlcygpO1xyXG5cdFx0fSkpO1xyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdkZWxldGUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cdFx0XHQvLyBwYXJlbnQgaXMgbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIHBhcmVudCBleGlzdHNcclxuXHRcdFx0Ly8gbm90IGVudGlyZWx5IHN1cmUgd2h5XHJcblx0XHRcdGNvbnN0IHBhcmVudFBhdGggPSB0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0XHRcdGNvbnN0IHBhcmVudE5hbWUgPSB0aGlzLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGFyZW50UGF0aCk7XHJcblx0XHRcdGlmIChwYXJlbnROYW1lICE9PSBmaWxlLmJhc2VuYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKHBhcmVudFBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignY3JlYXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcywgZmlsZSk7XHJcblx0XHRcdFx0aWYgKCFmb2xkZXIpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0aWYgKGZvbGRlck5hbWUgIT09IGZvbGRlci5uYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCF0aGlzLmFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHkpIHJldHVybjtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmF1dG9DcmVhdGUpIHJldHVybjtcclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gZ2V0RXhjbHVkZWRGb2xkZXIodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlQXV0b0NyZWF0ZSkgcmV0dXJuO1xyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoZm9sZGVyTm90ZSkgcmV0dXJuO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMsIGZpbGUucGF0aCwgdHJ1ZSwgdHJ1ZSk7XHJcblx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblxyXG5cdFx0fSkpO1xyXG5cclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2ZpbGUtb3BlbicsIChvcGVuRmlsZTogVEZpbGUgfCBudWxsKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkge1xyXG5cdFx0XHRcdHRoaXMuYWN0aXZlRm9sZGVyRG9tLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHRcdFx0XHR0aGlzLmFjdGl2ZUZvbGRlckRvbSA9IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCFvcGVuRmlsZSB8fCAhb3BlbkZpbGUuYmFzZW5hbWUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBvcGVuRmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSB7IHJldHVybjsgfVxyXG5cdFx0XHRpZiAoZXh0cmFjdEZvbGRlck5hbWUodGhpcy5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgb3BlbkZpbGUuYmFzZW5hbWUpICE9PSBmb2xkZXIubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdFx0dGhpcy5hY3RpdmVGb2xkZXJEb20gPSB0aGlzLmdldEVMKGZvbGRlci5wYXRoKTtcclxuXHRcdFx0aWYgKHRoaXMuYWN0aXZlRm9sZGVyRG9tKSB0aGlzLmFjdGl2ZUZvbGRlckRvbS5hZGRDbGFzcygnaXMtYWN0aXZlJyk7XHJcblx0XHR9KSk7XHJcblxyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdyZW5hbWUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSwgb2xkUGF0aDogc3RyaW5nKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSkge1xyXG5cdFx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdHJldHVybiBoYW5kbGVGb2xkZXJSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0cmV0dXJuIGhhbmRsZUZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH1cclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignZGVsZXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBmaWxlKTtcclxuXHRcdFx0XHRpZiAoIWZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoIWZvbGRlck5vdGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLnN5bmNEZWxldGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZShmb2xkZXJOb3RlKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93bkNvZGVCbG9ja1Byb2Nlc3NvcignZm9sZGVyLW92ZXJ2aWV3JywgKHNvdXJjZTogc3RyaW5nLCBlbDogSFRNTEVsZW1lbnQsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCkgPT4ge1xyXG5cdFx0XHRjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBlZGl0QnV0dG9uID0gZWwucGFyZW50RWxlbWVudD8uY2hpbGROb2Rlcy5pdGVtKDEpO1xyXG5cdFx0XHRcdGlmIChlZGl0QnV0dG9uKSB7XHJcblx0XHRcdFx0XHRlZGl0QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHRuZXcgRm9sZGVyT3ZlcnZpZXdTZXR0aW5ncyh0aGlzLmFwcCwgdGhpcywgcGFyc2VZYW1sKHNvdXJjZSksIGN0eCwgZWwpLm9wZW4oKTtcclxuXHRcdFx0XHRcdH0sIHsgY2FwdHVyZTogdHJ1ZSB9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRvYnNlcnZlci5vYnNlcnZlKGVsLCB7XHJcblx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdHN1YnRyZWU6IHRydWUsXHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJPdmVydmlldyh0aGlzLCBzb3VyY2UsIGVsLCBjdHgpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAodGhpcy5hcHAud29ya3NwYWNlLmxheW91dFJlYWR5KSB7XHJcblx0XHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeShhc3luYyAoKSA9PiB0aGlzLmxvYWRGaWxlQ2xhc3NlcygpKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBwYXRoLnN1YnN0cmluZyhwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpICsgMSA6IDApO1xyXG5cdH1cclxuXHJcblx0Z2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRpZiAocGF0aC5lbmRzV2l0aCgnLm1kJykgfHwgcGF0aC5lbmRzV2l0aCgnLmNhbnZhcycpKSB7XHJcblx0XHRcdHJldHVybiBwYXRoLnNwbGl0KCcvJykuc2xpY2UoLTIpWzBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIHBhdGguc3BsaXQoJy8nKS5zbGljZSgtMSlbMF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZW1vdmVFeHRlbnNpb24obmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBuYW1lLnJlcGxhY2UoL1xcLlteLy5dKyQvLCAnJyk7XHJcblx0fVxyXG5cclxuXHRnZXRFeHRlbnNpb25Gcm9tUGF0aFN0cmluZyhwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIHBhdGguc2xpY2UocGF0aC5sYXN0SW5kZXhPZignLicpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcuJykgOiAwKTtcclxuXHR9XHJcblxyXG5cdGdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRjb25zdCBzdWJTdHJpbmcgPSBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJykgOiAwO1xyXG5cdFx0cmV0dXJuIHBhdGguc3Vic3RyaW5nKDAsIHN1YlN0cmluZyk7XHJcblx0fVxyXG5cclxuXHRnZXRQYXJlbnRGb2xkZXJQYXRoKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyh0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpKTtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlcigpIHtcclxuXHRcdHJldHVybiB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKCdmaWxlLWV4cGxvcmVyJylbMF0gYXMgRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlclZpZXcoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGaWxlRXhwbG9yZXIoKS52aWV3O1xyXG5cdH1cclxuXHJcblx0YXN5bmMgYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aDogc3RyaW5nLCBjc3NDbGFzczogc3RyaW5nLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0Y29uc3QgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwocGF0aCk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHtcclxuXHRcdFx0aWYgKHdhaXRGb3JDcmVhdGUgJiYgY291bnQgPCA1KSB7XHJcblx0XHRcdFx0Ly8gc2xlZXAgZm9yIGEgc2Vjb25kIGZvciB0aGUgZmlsZS1leHBsb3JlciBldmVudCB0byBjYXRjaCB1cFxyXG5cdFx0XHRcdC8vIHRoaXMgaXMgYW5ub3lpbmcgYXMgaW4gbW9zdCBzY2FuYXJpb3Mgb3VyIHBsdWdpbiByZWNpZXZlcyB0aGUgZXZlbnQgYmVmb3JlIGZpbGUgZXhwbG9yZXJcclxuXHRcdFx0XHQvLyBJZiB3ZSBjb3VsZCBndWFycmFudGVlIGxvYWQgb3JkZXIgaXQgd291bGRuJ3QgYmUgYW4gaXNzdWUgYnV0IHdlIGNhbid0XHJcblx0XHRcdFx0Ly8gcmVhbGlzZSB0aGlzIGlzIHJhY2V5IGFuZCBuZWVkcyB0byBiZSBmaXhlZC5cclxuXHRcdFx0XHRhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCA1MDApKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKHBhdGgsIGNzc0NsYXNzLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdGNvbnN0IHZpZXdIZWFkZXJJdGVtcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLXBhdGg9XCIke3BhdGh9XCJdYCk7XHJcblx0XHR2aWV3SGVhZGVySXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG5cdFx0XHRpdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgY2hhbmdlTmFtZShmb2xkZXI6IFRGb2xkZXIsIG5hbWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIHJlcGxhY2VQYXRoOiBib29sZWFuLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0aWYgKCFuYW1lKSBuYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0XHRsZXQgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwoZm9sZGVyLnBhdGgpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXJJdGVtKSB7XHJcblx0XHRcdGlmICh3YWl0Rm9yQ3JlYXRlICYmIGNvdW50IDwgNSkge1xyXG5cdFx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwMCkpO1xyXG5cdFx0XHRcdHRoaXMuY2hhbmdlTmFtZShmb2xkZXIsIG5hbWUsIHJlcGxhY2VQYXRoLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtID0gZmlsZUV4cGxvcmVySXRlbS5xdWVyeVNlbGVjdG9yKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdGlmICghZmlsZUV4cGxvcmVySXRlbSkgeyByZXR1cm47IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0ZmlsZUV4cGxvcmVySXRlbS5pbm5lclRleHQgPSBuYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnNldEF0dHJpYnV0ZSgnb2xkLW5hbWUnLCBmb2xkZXIubmFtZSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLmlubmVyVGV4dCA9IGZvbGRlci5uYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdH1cclxuXHRcdGlmIChyZXBsYWNlUGF0aCkge1xyXG5cdFx0XHR0aGlzLnVwZGF0ZUJyZWFkY3J1bWJzKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHR1cGRhdGVCcmVhZGNydW1icyhyZW1vdmU/OiBib29sZWFuKSB7XHJcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5wYXRoICYmICFyZW1vdmUpIHsgcmV0dXJuOyB9XHJcblx0XHRjb25zdCB2aWV3SGVhZGVySXRlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuLnZpZXctaGVhZGVyLWJyZWFkY3J1bWInKTtcclxuXHRcdGNvbnN0IGZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5maWx0ZXIoKGZpbGUpID0+IGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGlmICghaXRlbS5oYXNBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBwYXRoID0gaXRlbS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBmaWxlcy5maW5kKChmaWxlKSA9PiBmaWxlLnBhdGggPT09IHBhdGgpO1xyXG5cdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKHJlbW92ZSkge1xyXG5cdFx0XHRcdGl0ZW0udGV4dENvbnRlbnQgPSBmb2xkZXIubmFtZTtcclxuXHRcdFx0XHRpdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpdGVtLnRleHRDb250ZW50ID0gZm9sZGVyLm5ld05hbWUgfHwgZm9sZGVyLm5hbWU7XHJcblx0XHRcdFx0aXRlbS5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUpO1xyXG5cdFx0XHRcdGl0ZW0uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0cmVtb3ZlQ1NTQ2xhc3NGcm9tRUwocGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLCBjc3NDbGFzczogc3RyaW5nKSB7XHJcblx0XHRpZiAoIXBhdGgpIHJldHVybjtcclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSB0aGlzLmdldEVMKHBhdGgpO1xyXG5cdFx0Y29uc3Qgdmlld0hlYWRlckl0ZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtcGF0aD1cIiR7cGF0aH1cIl1gKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGl0ZW0ucmVtb3ZlQ2xhc3MoY3NzQ2xhc3MpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuOyB9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUNsYXNzKGNzc0NsYXNzKTtcclxuXHR9XHJcblxyXG5cdGdldEVMKHBhdGg6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XHJcblx0XHRjb25zdCBmaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXIpIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSBmaWxlRXhwbG9yZXIudmlldy5maWxlSXRlbXNbcGF0aF07XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGlmIChmaWxlRXhwbG9yZXJJdGVtLnNlbGZFbCkgcmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0uc2VsZkVsO1xyXG5cdFx0cmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0udGl0bGVFbDtcclxuXHR9XHJcblxyXG5cdGxvYWRGaWxlQ2xhc3Nlcyhmb3JjZVJlbG9hZCA9IGZhbHNlKSB7XHJcblx0XHRpZiAodGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPT09IHRoaXMuZ2V0RmlsZUV4cGxvcmVyKCkgJiYgIWZvcmNlUmVsb2FkKSB7IHJldHVybjsgfVxyXG5cdFx0dGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0dGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKCFmb2xkZXJOb3RlKSB7XHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHRoaXMsIGZpbGUucGF0aCk7XHJcblx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdC8vIEluY2FzZSBzZXR0aW5ncyBoYXZlIGNoYW5nZWRcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJlbG9hZEhhbmRsZXJzKCkge1xyXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZGl2Lm5hdi1mb2xkZXItdGl0bGUtY29udGVudCcpXHJcblx0XHRcdC5mb3JFYWNoKChlbGVtZW50OiBIVE1MRWxlbWVudCkgPT4ge1xyXG5cdFx0XHRcdGlmIChlbGVtZW50Lm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRlbGVtZW50Lm9uY2xpY2sgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IGhhbmRsZUZvbGRlckNsaWNrKGV2ZW50LCB0aGlzKTtcclxuXHRcdFx0fSk7XHJcblx0fVxyXG5cclxuXHRvbnVubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKCd1bmxvYWRpbmcgZm9sZGVyIG5vdGVzIHBsdWdpbicpO1xyXG5cdFx0dGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3Rlcy1wbHVnaW4nKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkgeyB0aGlzLmFjdGl2ZUZvbGRlckRvbS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJyk7IH1cclxuXHRcdGlmICh0aGlzLmZtdHBIYW5kbGVyKSB7XHJcblx0XHRcdHRoaXMuZm10cEhhbmRsZXIuZGVsZXRlRXZlbnQoKTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0XHQvLyBjbGVhbnVwIGFueSBjc3MgaWYgd2UgbmVlZCB0b29cclxuXHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKHRydWUpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFBsYXRmb3JtLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBURmlsZSwgVEZvbGRlciB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmltcG9ydCB7IFRlbXBsYXRlU3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnLi9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7IGFkZEV4Y2x1ZGVGb2xkZXJMaXN0SXRlbSwgRXhjbHVkZWRGb2xkZXIsIGFkZEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlUGF0dGVybiwgYWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbSB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG4vLyBpbXBvcnQgQ29uZmlybWF0aW9uTW9kYWwgZnJvbSBcIi4vbW9kYWxzL2NvbmZpcm1DcmVhdGlvblwiO1xyXG5pbXBvcnQgeyB5YW1sU2V0dGluZ3MgfSBmcm9tICcuL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJOb3Rlc1NldHRpbmdzIHtcclxuXHRzeW5jRm9sZGVyTmFtZTogYm9vbGVhbjtcclxuXHRjdHJsS2V5OiBib29sZWFuO1xyXG5cdGFsdEtleTogYm9vbGVhbjtcclxuXHRoaWRlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHR0ZW1wbGF0ZVBhdGg6IHN0cmluZztcclxuXHRhdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0ZXhjbHVkZUZvbGRlcnM6IChFeGNsdWRlUGF0dGVybiB8IEV4Y2x1ZGVkRm9sZGVyKVtdO1xyXG5cdHNob3dEZWxldGVDb25maXJtYXRpb246IGJvb2xlYW47XHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXI6IGJvb2xlYW47XHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXJJblBhdGg6IGJvb2xlYW47XHJcblx0b3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoOiBib29sZWFuO1xyXG5cdG9wZW5Jbk5ld1RhYjogYm9vbGVhbjtcclxuXHRmb2xkZXJOb3RlTmFtZTogc3RyaW5nO1xyXG5cdG5ld0ZvbGRlck5vdGVOYW1lOiBzdHJpbmc7XHJcblx0Zm9sZGVyTm90ZVR5cGU6ICcubWQnIHwgJy5jYW52YXMnO1xyXG5cdGRpc2FibGVGb2xkZXJIaWdobGlnaHRpbmc6IGJvb2xlYW47XHJcblx0c3RvcmFnZUxvY2F0aW9uOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJztcclxuXHRzeW5jRGVsZXRlOiBib29sZWFuO1xyXG5cdGRlZmF1bHRPdmVydmlldzogeWFtbFNldHRpbmdzO1xyXG5cdHVzZVN1Ym1lbnVzOiBib29sZWFuO1xyXG5cdHN5bmNNb3ZlOiBib29sZWFuO1xyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGJvb2xlYW47XHJcblx0XHRleHBsb3JlcjogYm9vbGVhbjtcclxuXHRcdHBhdGg6IGJvb2xlYW47XHJcblx0fVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogRm9sZGVyTm90ZXNTZXR0aW5ncyA9IHtcclxuXHRzeW5jRm9sZGVyTmFtZTogdHJ1ZSxcclxuXHRjdHJsS2V5OiB0cnVlLFxyXG5cdGFsdEtleTogZmFsc2UsXHJcblx0aGlkZUZvbGRlck5vdGU6IHRydWUsXHJcblx0dGVtcGxhdGVQYXRoOiAnJyxcclxuXHRhdXRvQ3JlYXRlOiBmYWxzZSxcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBmYWxzZSxcclxuXHRleGNsdWRlRm9sZGVyczogW10sXHJcblx0c2hvd0RlbGV0ZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHR1bmRlcmxpbmVGb2xkZXI6IHRydWUsXHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogZmFsc2UsXHJcblx0dW5kZXJsaW5lRm9sZGVySW5QYXRoOiB0cnVlLFxyXG5cdG9wZW5Gb2xkZXJOb3RlT25DbGlja0luUGF0aDogdHJ1ZSxcclxuXHRvcGVuSW5OZXdUYWI6IGZhbHNlLFxyXG5cdGZvbGRlck5vdGVOYW1lOiAne3tmb2xkZXJfbmFtZX19JyxcclxuXHRmb2xkZXJOb3RlVHlwZTogJy5tZCcsXHJcblx0ZGlzYWJsZUZvbGRlckhpZ2hsaWdodGluZzogZmFsc2UsXHJcblx0bmV3Rm9sZGVyTm90ZU5hbWU6ICd7e2ZvbGRlcl9uYW1lfX0nLFxyXG5cdHN0b3JhZ2VMb2NhdGlvbjogJ2luc2lkZUZvbGRlcicsXHJcblx0c3luY0RlbGV0ZTogZmFsc2UsXHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHRkZWZhdWx0T3ZlcnZpZXc6IHtcclxuXHRcdHRpdGxlOiAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnLFxyXG5cdFx0ZGlzYWJsZVRpdGxlOiBmYWxzZSxcclxuXHRcdGRlcHRoOiAzLFxyXG5cdFx0aW5jbHVkZVR5cGVzOiBbJ2ZvbGRlcicsICdtYXJrZG93biddLFxyXG5cdFx0c3R5bGU6ICdsaXN0JyxcclxuXHRcdGRpc2FibGVGaWxlVGFnOiBmYWxzZSxcclxuXHR9LFxyXG5cdHVzZVN1Ym1lbnVzOiB0cnVlLFxyXG5cdHN5bmNNb3ZlOiB0cnVlLFxyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGZhbHNlLFxyXG5cdFx0ZXhwbG9yZXI6IHRydWUsXHJcblx0XHRwYXRoOiB0cnVlLFxyXG5cdH1cclxufTtcclxuZXhwb3J0IGNsYXNzIFNldHRpbmdzVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHRleGNsdWRlRm9sZGVyczogRXhjbHVkZWRGb2xkZXJbXTtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xyXG5cdH1cclxuXHRkaXNwbGF5KCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcclxuXHJcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xyXG5cclxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0ZvbGRlciBub3RlcyBzZXR0aW5ncycgfSk7XHJcblxyXG5cdFx0Y29uc3QgbmFtZVNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZvbGRlciBub3RlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygne3tmb2xkZXJfbmFtZX19IHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgbmFtZSBvZiB0aGUgZm9sZGVyJylcclxuXHRcdFx0LmFkZFRleHQoKHRleHQpID0+XHJcblx0XHRcdFx0dGV4dFxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld0ZvbGRlck5vdGVOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykgeyByZXR1cm47IH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3Rm9sZGVyTm90ZU5hbWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdSZW5hbWUgZXhpc3RpbmcgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdC5zZXRDdGEoKVxyXG5cdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUZvbGRlck5vdGVzKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdGb2xkZXJOb3RlTmFtZSk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLmFwcGVuZFRleHQoJ01ha2Ugc3VyZSB0byBiYWNrIHVwIHlvdXIgdmF1bHQgYmVmb3JlIHJlbmFtaW5nIGFsbCBmb2xkZXIgbm90ZXMgYW5kIHJlc3RhcnQgT2JzaWRpYW4gYWZ0ZXIgcmVuYW1pbmcgdGhlbScpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdGb2xkZXIgbm90ZSB0eXBlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSB0aGUgZmlsZSB0eXBlIGZvciBjcmVhdGluZyBuZXcgZm9sZGVyIG5vdGVzIChtYXJrZG93biBvciBjYW52YXMpIG9sZCBmb2xkZXIgbm90ZXMgd2lsbCBub3QgYmUgY2hhbmdlZCBhbmQgeW91IGNhbiBhbHNvIGNyZWF0ZSBjYW52YXMvbWFya2Rvd24gZmlsZXMgYW5kIGNoYW5nZSB0aGUgbmFtZSBtYW51YWxseSB0byB0aGUgY3VzdG9tIGZvbGRlciBub3RlIG5hbWUgb3IgdG8gdGhlIG5hbWUgb2YgdGhlIGZvbGRlci4nKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCcubWQnLCAnbWFya2Rvd24nKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignLmNhbnZhcycsICdjYW52YXMnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJy5tZCcgfCAnLmNhbnZhcycpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0XHRjb25zdCBkZXNjID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xyXG5cdFx0ZGVzYy5hcHBlbmQoXHJcblx0XHRcdCdBZnRlciBzZXR0aW5nIHRoZSB0ZW1wbGF0ZSBwYXRoLCByZXN0YXJ0IE9ic2lkaWFuIGlmIHRoZSB0ZW1wbGF0ZSBmb2xkZXIgcGF0aCAoZnJvbSB0ZW1wbGF0ZXIvdGVtcGxhdGVzKSBoYWQgYmVlbiBjaGFuZ2VkIGJlZm9yZWhhbmQuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J09ic2lkaWFuIHNob3VsZCBhbHNvIGJlIHJlc3RhcnRlZCBpZiB0aGUgdGVtcGxhdGUgcGF0aCB3YXMgcmVtb3ZlZC4nXHJcblx0XHQpO1xyXG5cdFx0c2V0dGluZy5zZXROYW1lKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRzZXR0aW5nLnNldERlc2MoZGVzYykuZGVzY0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblx0XHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdFx0bmV3IFRlbXBsYXRlU3VnZ2VzdChjYi5pbnB1dEVsLCB0aGlzLnBsdWdpbik7XHJcblx0XHRcdGNiLnNldFBsYWNlaG9sZGVyKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRcdGNiLnNldFZhbHVlKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoKT8ubmFtZS5yZXBsYWNlKCcubWQnLCAnJykgfHwgJycpO1xyXG5cdFx0XHRjYi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRjb25zdCBzdG9yYWdlTG9jYXRpb24gPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ1N0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHdoZXJlIHRvIHN0b3JlIHRoZSBmb2xkZXIgbm90ZXMnKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdpbnNpZGVGb2xkZXInLCAnSW5zaWRlIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbigncGFyZW50Rm9sZGVyJywgJ0luIHRoZSBwYXJlbnQgZm9sZGVyJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24pXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5sb2FkRmlsZUNsYXNzZXMoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblx0XHRzdG9yYWdlTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3RvcmFnZUxvY2F0aW9uLmluZm9FbC5zdHlsZS5jb2xvciA9IHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZygnYWNjZW50Q29sb3InKSBhcyBzdHJpbmcgfHwgJyM3ZDViZWQnO1xyXG5cclxuXHRcdGNvbnN0IHN3aXRjaExvY2F0aW9uID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTd2l0Y2ggdG8gbmV3IHN0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnTW92ZSBhbGwgZm9sZGVyIG5vdGVzIHRvIHRoZSBuZXcgc3RvcmFnZSBsb2NhdGlvbicpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdTd2l0Y2gnKVxyXG5cdFx0XHRcdFx0LnNldEN0YSgpXHJcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGxldCBvbGRTdG9yYWdlTG9jYXRpb24gPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb247XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0b2xkU3RvcmFnZUxvY2F0aW9uID0gJ2luc2lkZUZvbGRlcic7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAnaW5zaWRlRm9sZGVyJykge1xyXG5cdFx0XHRcdFx0XHRcdG9sZFN0b3JhZ2VMb2NhdGlvbiA9ICdwYXJlbnRGb2xkZXInO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuc3dpdGNoU3RvcmFnZUxvY2F0aW9uKG9sZFN0b3JhZ2VMb2NhdGlvbik7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0RlbGV0ZSBmb2xkZXIgbm90ZXMgd2hlbiBkZWxldGluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuc2V0RGVzYygnRGVsZXRlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIGRlbGV0aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY0RlbGV0ZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNEZWxldGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ01vdmUgZm9sZGVyIG5vdGVzIHdoZW4gbW92aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdNb3ZlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIG1vdmluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNNb3ZlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY01vdmUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBkaXNhYmxlU2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIGNvbGxhcHNpbmcnKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldERlc2MoJ0Rpc2FibGUgdGhlIGFiaWxpdHkgdG8gY29sbGFwc2UgZm9sZGVycyBieSBjbGlja2luZyBleGFjdGx5IG9uIHRoZSBmb2xkZXIgbmFtZScpO1xyXG5cdFx0ZGlzYWJsZVNldHRpbmcuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdC5zZXRWYWx1ZSghdGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVDb2xsYXBzaW5nID0gIXZhbHVlO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0fSlcclxuXHRcdCk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuYXBwZW5kVGV4dCgnUmVxdWlyZXMgYSByZXN0YXJ0IHRvIHRha2UgZWZmZWN0Jyk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdLZXkgZm9yIGNyZWF0aW5nIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnVGhlIGtleSBjb21iaW5hdGlvbiB0byBjcmVhdGUgYSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdFx0aWYgKCFQbGF0Zm9ybS5pc01hY09TKSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDdHJsICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDbWQgKyBDbGljaycpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKCdhbHQnLCAnQWx0ICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdGRyb3Bkb3duLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmN0cmxLZXkgPyAnY3RybCcgOiAnYWx0Jyk7XHJcblx0XHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY3RybEtleSA9IHZhbHVlID09PSAnY3RybCc7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmFsdEtleSA9IHZhbHVlID09PSAnYWx0JztcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPbmx5IG9wZW4gZm9sZGVyIG5vdGVzIHRocm91Z2ggdGhlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygnT25seSBvcGVuIGZvbGRlciBub3RlcyBpbiB0aGUgZmlsZSBleHBsb3JlciBieSBjbGlja2luZyBvbiB0aGUgZm9sZGVyIG5hbWUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0aWYgKCF2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZuLXdoaXRlc3BhY2Utc3RvcC1jb2xsYXBzaW5nJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdIaWRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0LnNldERlc2MoJ0hpZGUgdGhlIGZvbGRlciBub3RlIGluIHRoZSBmaWxlIGV4cGxvcmVyJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTeW5jIGZvbGRlciBuYW1lJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIHRoZSBmb2xkZXIgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbmFtZSBpcyBjaGFuZ2VkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNGb2xkZXJOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0aWYgKFBsYXRmb3JtLmlzRGVza3RvcCkge1xyXG5cdFx0XHRjb25zdCBzZXR0aW5nMyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdFx0c2V0dGluZzMuc2V0TmFtZSgnT3BlbiBmb2xkZXIgbm90ZSBpbiBhIG5ldyB0YWIgYnkgZGVmYXVsdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5zZXREZXNjKCdBbHdheXMgb3BlbiBmb2xkZXIgbm90ZXMgaW4gYSBuZXcgdGFiIChleGNlcHQgd2hlbiB5b3UgdHJ5IHRvIG9wZW4gdGhlIHNhbWUgbm90ZSkgaW5zdGVhZCBvZiBoYXZpbmcgdG8gdXNlIGN0cmwvY21kICsgY2xpY2sgdG8gb3BlbiBpbiBhIG5ldyB0YWInKTtcclxuXHRcdFx0c2V0dGluZzMuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkluTmV3VGFiKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuSW5OZXdUYWIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdFx0c2V0dGluZzMuaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHRcdH1cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnQXV0b21hdGljYWxseSBjcmVhdGUgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgY3JlYXRlIGEgZm9sZGVyIG5vdGUgd2hlbiBhIG5ldyBmb2xkZXIgaXMgY3JlYXRlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdVc2Ugc3VibWVudXMnKVxyXG5cdFx0XHQuc2V0RGVzYygnVXNlIHN1Ym1lbnVzIGZvciBmaWxlL2ZvbGRlciBjb21tYW5kcycpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlU3VibWVudXMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCB1bmRlcmxpbmUgdG8gZm9sZGVycyB3aXRoIGZvbGRlciBub3RlcycpXHJcblx0XHRcdC5zZXREZXNjKCdBZGQgYW4gdW5kZXJsaW5lIHRvIGZvbGRlcnMgdGhhdCBoYXZlIGEgZm9sZGVyIG5vdGUgaW4gdGhlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy51bmRlcmxpbmVGb2xkZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZS11bmRlcmxpbmUnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3RlLXVuZGVybGluZScpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPcGVuIGZvbGRlciBub3RlIHRocm91Z2ggcGF0aCcpXHJcblx0XHRcdC5zZXREZXNjKCdPcGVuIGEgZm9sZGVyIG5vdGUgd2hlbiBjbGlja2luZyBvbiBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGlmIGl0IGlzIGEgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGggPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdVbmRlcmxpbmUgZm9sZGVycyBpbiB0aGUgcGF0aCcpXHJcblx0XHRcdFx0LnNldERlc2MoJ0FkZCBhbiB1bmRlcmxpbmUgdG8gZm9sZGVycyB0aGF0IGhhdmUgYSBmb2xkZXIgbm90ZSBpbiB0aGUgcGF0aCBhYm92ZSBhIG5vdGUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lLXBhdGgnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0VuYWJsZSBmcm9udCBtYXR0ZXIgdGl0bGUgcGx1Z2luIGludGVncmF0aW9uJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIGEgZm9sZGVyIG5hbWUgd2hlbiB0aGUgZm9sZGVyIG5vdGUgaXMgcmVuYW1lZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZW5hYmxlZCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBuZXcgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIodGhpcy5wbHVnaW4pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmZtdHBIYW5kbGVyPy5oYW5kbGVSZW5hbWUoeyBpZDogJycsIHJlc3VsdDogZmFsc2UsIHBhdGg6IGZpbGUucGF0aCB9LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXI/LmRlbGV0ZUV2ZW50KCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBudWxsO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBmaWxlIGV4cGxvcmVyIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIHJlbmFtZWQnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5leHBsb3JlcilcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0RmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcj8uaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnSW5jbHVkZSBwYXRoIGFib3ZlIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGFib3ZlIGEgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbm90ZSBpcyByZW5hbWVkJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aClcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICh2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRHVlIHRvIGFuIGlzc3VlIHdpdGggdGVtcGxhdGVyIGl0IGhhcyBiZWVuIGRpc2FibGVkIGZvciBub3dcclxuXHRcdC8vIElmIHlvdSB3YW50IHRvIHRyeSBpdCB5b3Vyc2VsZiBtYWtlIGEgcHJcclxuXHRcdC8vIFRoZSBpc3N1ZSB3YXMgdGhhdCBpdCBvbmx5IHVzZWQgdGhlIGZpcnN0IGZvbGRlciBmb3IgYWxsIG9mIHRoZSBvdGhlciBmb2xkZXIgbm90ZXNcclxuXHRcdC8qXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdC5zZXROYW1lKCdDcmVhdGUgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlcicpXHJcblx0XHQuc2V0RGVzYygnQ3JlYXRlIGEgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlciBpbiB0aGUgdmF1bHQnKVxyXG5cdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0Y2Iuc2V0SWNvbigncGx1cycpO1xyXG5cdFx0XHRjYi5zZXRUb29sdGlwKCdDcmVhdGUgZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdGNiLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdG5ldyBDb25maXJtYXRpb25Nb2RhbCh0aGlzLmFwcCwgdGhpcy5wbHVnaW4pLm9wZW4oKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHRcdCovXHJcblxyXG5cclxuXHRcdGNvbnN0IG1hbmFnZUV4Y2x1ZGVkID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXRIZWFkaW5nKClcclxuXHRcdFx0LnNldENsYXNzKCdmbi1leGNsdWRlZC1mb2xkZXItaGVhZGluZycpXHJcblx0XHRcdC5zZXROYW1lKCdNYW5hZ2UgZXhjbHVkZWQgZm9sZGVycycpO1xyXG5cdFx0Y29uc3QgZGVzYzMgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XHJcblx0XHRkZXNjMy5hcHBlbmQoXHJcblx0XHRcdCdBZGQge3JlZ2V4fSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmb2xkZXIgbmFtZSB0byB1c2UgYSByZWdleCBwYXR0ZXJuLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBiZWZvcmUgYW5kIGFmdGVyIHRvIGV4Y2x1ZGUgZm9sZGVycyB0aGF0IGluY2x1ZGUgdGhlIG5hbWUgYmV0d2VlbiB0aGUgKnMuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J1VzZSAqIGJlZm9yZSB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgZW5kIHdpdGggdGhlIGZvbGRlciBuYW1lLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBhZnRlciB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgc3RhcnQgd2l0aCB0aGUgZm9sZGVyIG5hbWUuJyxcclxuXHRcdCk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5zZXREZXNjKGRlc2MzKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdUaGUgcmVnZXhlcyBhbmQgd2lsZGNhcmRzIGFyZSBvbmx5IGZvciB0aGUgZm9sZGVyIG5hbWUsIG5vdCB0aGUgcGF0aC4nKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5jcmVhdGVFbCgnYnInKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdJZiB5b3Ugd2FudCB0byBzd2l0Y2ggdG8gYSBmb2xkZXIgcGF0aCBkZWxldGUgdGhlIHBhdHRlcm4gZmlyc3QuJyk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCBleGNsdWRlZCBmb2xkZXInKVxyXG5cdFx0XHQuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlci1pdGVtJylcclxuXHRcdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0XHRjYi5zZXRJY29uKCdwbHVzJyk7XHJcblx0XHRcdFx0Y2Iuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlcicpO1xyXG5cdFx0XHRcdGNiLnNldFRvb2x0aXAoJ0FkZCBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdFx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKCcnLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdFx0YWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHRoaXMsIGNvbnRhaW5lckVsLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0XHRhZGRFeGNsdWRlZEZvbGRlcih0aGlzLnBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuc29ydCgoYSwgYikgPT4gYS5wb3NpdGlvbiAtIGIucG9zaXRpb24pLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRcdGlmIChleGNsdWRlZEZvbGRlci5zdHJpbmc/LnRyaW0oKSAhPT0gJycgJiYgZXhjbHVkZWRGb2xkZXIucGF0aD8udHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRhZGRFeGNsdWRlRm9sZGVyTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHR1cGRhdGVGb2xkZXJOb3RlcyhvbGRUZW1wbGF0ZTogc3RyaW5nLCBuZXdUZW1wbGF0ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSA9IG5ld1RlbXBsYXRlO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRuZXcgTm90aWNlKCdTdGFydGluZyB0byB1cGRhdGUgZm9sZGVyIG5vdGVzLi4uJyk7XHJcblx0XHR0aGlzLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlclBhdGggPSB0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGxldCBmb2xkZXIgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0bGV0IGZvbGRlck5hbWUgPSBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpO1xyXG5cdFx0XHRcdGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShvbGRUZW1wbGF0ZSwgZm9sZGVyTmFtZSkgfHwgJyc7XHJcblx0XHRcdFx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikgfHwgZm9sZGVyTmFtZSAhPT0gZm9sZGVyPy5uYW1lKSB7XHJcblx0XHRcdFx0XHRpZiAoZm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJOYW1lKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoICsgJy8nICsgZm9sZGVyTmFtZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdGlmIChmb2xkZXJOYW1lID09PSBmb2xkZXI/Lm5hbWUpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXI/LnBhdGh9LyR7dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSl9LiR7ZmlsZS5leHRlbnNpb259YDtcclxuXHRcdFx0XHRcdHRoaXMuYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBuZXdQYXRoKTtcclxuXHRcdFx0XHR9IGVsc2UgaWYgKGZvbGRlcj8ubmFtZSA9PT0gZmlsZS5uYW1lLnNsaWNlKDAsIC1maWxlLmV4dGVuc2lvbi5sZW5ndGggLSAxKSB8fCAnJykge1xyXG5cdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZvbGRlcj8ucGF0aH0vJHt0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpIHx8ICcnKX0uJHtmaWxlLmV4dGVuc2lvbn1gO1xyXG5cdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZpbGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRuZXcgTm90aWNlKCdGaW5pc2hlZCB1cGRhdGluZyBmb2xkZXIgbm90ZXMnKTtcclxuXHR9XHJcblxyXG5cdHN3aXRjaFN0b3JhZ2VMb2NhdGlvbihvbGRNZXRob2Q6IHN0cmluZykge1xyXG5cdFx0bmV3IE5vdGljZSgnU3RhcnRpbmcgdG8gc3dpdGNoIHN0b3JhZ2UgbG9jYXRpb24uLi4nKTtcclxuXHRcdHRoaXMuYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCBvbGRNZXRob2QpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXdQYXRoID0gYCR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0bmV3UGF0aCA9IGAke3RoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCl9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZvbGRlck5vdGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJOb3RlLnBhdGgpID09PSBmaWxlLnBhdGgpIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0bmV3IE5vdGljZSgnRmluaXNoZWQgc3dpdGNoaW5nIHN0b3JhZ2UgbG9jYXRpb24nKTtcclxuXHR9XHJcblxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGaWxlLCBURm9sZGVyLCBWYXVsdCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgVGV4dElucHV0U3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdCc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0VGVtcGxhdGVQbHVnaW5zIH0gZnJvbSAnc3JjL3RlbXBsYXRlJztcclxuZXhwb3J0IGVudW0gRmlsZVN1Z2dlc3RNb2RlIHtcclxuICAgIFRlbXBsYXRlRmlsZXMsXHJcbiAgICBTY3JpcHRGaWxlcyxcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlU3VnZ2VzdCBleHRlbmRzIFRleHRJbnB1dFN1Z2dlc3Q8VEZpbGU+IHtcclxuXHRjb25zdHJ1Y3RvcihcclxuICAgICAgICBwdWJsaWMgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCxcclxuICAgICAgICBwcml2YXRlIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW5cclxuXHQpIHtcclxuXHRcdHN1cGVyKGlucHV0RWwpO1xyXG5cdH1cclxuXHJcblxyXG5cdGdldF9lcnJvcl9tc2cobW9kZTogRmlsZVN1Z2dlc3RNb2RlKTogc3RyaW5nIHtcclxuXHRcdHN3aXRjaCAobW9kZSkge1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5UZW1wbGF0ZUZpbGVzOlxyXG5cdFx0XHRcdHJldHVybiAnVGVtcGxhdGVzIGZvbGRlciBkb2VzblxcJ3QgZXhpc3QnO1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5TY3JpcHRGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1VzZXIgU2NyaXB0cyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldFN1Z2dlc3Rpb25zKGlucHV0X3N0cjogc3RyaW5nKTogVEZpbGVbXSB7XHJcblx0XHRjb25zdCB7IHRlbXBsYXRlRm9sZGVyLCB0ZW1wbGF0ZXJQbHVnaW4gfSA9IGdldFRlbXBsYXRlUGx1Z2lucyh0aGlzLnBsdWdpbi5hcHApO1xyXG5cdFx0aWYgKCghdGVtcGxhdGVGb2xkZXIgfHwgdGVtcGxhdGVGb2xkZXI/LnRyaW0oKSA9PT0gJycpICYmICF0ZW1wbGF0ZXJQbHVnaW4pIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRyZXR1cm4gW107XHJcblx0XHR9XHJcblx0XHRsZXQgZm9sZGVyOiBURm9sZGVyO1xyXG5cdFx0aWYgKHRlbXBsYXRlclBsdWdpbikge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlclBsdWdpbi5wbHVnaW4/LnNldHRpbmdzPy50ZW1wbGF0ZXNfZm9sZGVyIGFzIHN0cmluZykgYXMgVEZvbGRlcjtcclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlRm9sZGVyKSBhcyBURm9sZGVyO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGZpbGVzOiBURmlsZVtdID0gW107XHJcblx0XHRjb25zdCBsb3dlcl9pbnB1dF9zdHIgPSBpbnB1dF9zdHIudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0XHRWYXVsdC5yZWN1cnNlQ2hpbGRyZW4oZm9sZGVyLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlICYmXHJcbiAgICAgICAgICAgICAgICBmaWxlLnBhdGgudG9Mb3dlckNhc2UoKS5jb250YWlucyhsb3dlcl9pbnB1dF9zdHIpXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdGZpbGVzLnB1c2goZmlsZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiBmaWxlcztcclxuXHR9XHJcblxyXG5cdHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZpbGUsIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZWwuc2V0VGV4dChmaWxlLm5hbWUucmVwbGFjZSgnLm1kJywgJycpKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZmlsZTogVEZpbGUpOiB2b2lkIHtcclxuXHRcdHRoaXMuaW5wdXRFbC52YWx1ZSA9IGZpbGUubmFtZS5yZXBsYWNlKCcubWQnLCAnJyk7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlUGF0aCA9IGZpbGUucGF0aDtcclxuXHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiLy8gQ3JlZGl0cyBnbyB0byBMaWFtJ3MgUGVyaW9kaWMgTm90ZXMgUGx1Z2luOiBodHRwczovL2dpdGh1Yi5jb20vbGlhbWNhaW4vb2JzaWRpYW4tcGVyaW9kaWMtbm90ZXMgYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9TaWxlbnRWb2lkMTMvVGVtcGxhdGVyXHJcblxyXG5cclxuaW1wb3J0IHsgSVN1Z2dlc3RPd25lciwgU2NvcGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGNyZWF0ZVBvcHBlciwgSW5zdGFuY2UgYXMgUG9wcGVySW5zdGFuY2UgfSBmcm9tICdAcG9wcGVyanMvY29yZSc7XHJcblxyXG5jb25zdCB3cmFwQXJvdW5kID0gKHZhbHVlOiBudW1iZXIsIHNpemU6IG51bWJlcik6IG51bWJlciA9PiB7XHJcblx0cmV0dXJuICgodmFsdWUgJSBzaXplKSArIHNpemUpICUgc2l6ZTtcclxufTtcclxuXHJcbmNsYXNzIFN1Z2dlc3Q8VD4ge1xyXG5cdHByaXZhdGUgb3duZXI6IElTdWdnZXN0T3duZXI8VD47XHJcblx0cHJpdmF0ZSB2YWx1ZXM6IFRbXTtcclxuXHRwcml2YXRlIHN1Z2dlc3Rpb25zOiBIVE1MRGl2RWxlbWVudFtdO1xyXG5cdHByaXZhdGUgc2VsZWN0ZWRJdGVtOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBjb250YWluZXJFbDogSFRNTEVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKFxyXG5cdFx0b3duZXI6IElTdWdnZXN0T3duZXI8VD4sXHJcblx0XHRjb250YWluZXJFbDogSFRNTEVsZW1lbnQsXHJcblx0XHRzY29wZTogU2NvcGVcclxuXHQpIHtcclxuXHRcdHRoaXMub3duZXIgPSBvd25lcjtcclxuXHRcdHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcclxuXHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J2NsaWNrJyxcclxuXHRcdFx0Jy5zdWdnZXN0aW9uLWl0ZW0nLFxyXG5cdFx0XHR0aGlzLm9uU3VnZ2VzdGlvbkNsaWNrLmJpbmQodGhpcylcclxuXHRcdCk7XHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J21vdXNlbW92ZScsXHJcblx0XHRcdCcuc3VnZ2VzdGlvbi1pdGVtJyxcclxuXHRcdFx0dGhpcy5vblN1Z2dlc3Rpb25Nb3VzZW92ZXIuYmluZCh0aGlzKVxyXG5cdFx0KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93VXAnLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKHRoaXMuc2VsZWN0ZWRJdGVtIC0gMSwgdHJ1ZSk7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93RG93bicsIChldmVudCkgPT4ge1xyXG5cdFx0XHRpZiAoIWV2ZW50LmlzQ29tcG9zaW5nKSB7XHJcblx0XHRcdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0odGhpcy5zZWxlY3RlZEl0ZW0gKyAxLCB0cnVlKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHNjb3BlLnJlZ2lzdGVyKFtdLCAnRW50ZXInLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0b25TdWdnZXN0aW9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHRjb25zdCBpdGVtID0gdGhpcy5zdWdnZXN0aW9ucy5pbmRleE9mKGVsKTtcclxuXHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKGl0ZW0sIGZhbHNlKTtcclxuXHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHR9XHJcblxyXG5cdG9uU3VnZ2VzdGlvbk1vdXNlb3ZlcihfZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaXRlbSA9IHRoaXMuc3VnZ2VzdGlvbnMuaW5kZXhPZihlbCk7XHJcblx0XHR0aGlzLnNldFNlbGVjdGVkSXRlbShpdGVtLCBmYWxzZSk7XHJcblx0fVxyXG5cclxuXHRzZXRTdWdnZXN0aW9ucyh2YWx1ZXM6IFRbXSkge1xyXG5cdFx0dGhpcy5jb250YWluZXJFbC5lbXB0eSgpO1xyXG5cdFx0Y29uc3Qgc3VnZ2VzdGlvbkVsczogSFRNTERpdkVsZW1lbnRbXSA9IFtdO1xyXG5cclxuXHRcdHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBzdWdnZXN0aW9uRWwgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZURpdignc3VnZ2VzdGlvbi1pdGVtJyk7XHJcblx0XHRcdHRoaXMub3duZXIucmVuZGVyU3VnZ2VzdGlvbih2YWx1ZSwgc3VnZ2VzdGlvbkVsKTtcclxuXHRcdFx0c3VnZ2VzdGlvbkVscy5wdXNoKHN1Z2dlc3Rpb25FbCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLnZhbHVlcyA9IHZhbHVlcztcclxuXHRcdHRoaXMuc3VnZ2VzdGlvbnMgPSBzdWdnZXN0aW9uRWxzO1xyXG5cdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0oMCwgZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0dXNlU2VsZWN0ZWRJdGVtKGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCkge1xyXG5cdFx0Y29uc3QgY3VycmVudFZhbHVlID0gdGhpcy52YWx1ZXNbdGhpcy5zZWxlY3RlZEl0ZW1dO1xyXG5cdFx0aWYgKGN1cnJlbnRWYWx1ZSkge1xyXG5cdFx0XHR0aGlzLm93bmVyLnNlbGVjdFN1Z2dlc3Rpb24oY3VycmVudFZhbHVlLCBldmVudCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRzZXRTZWxlY3RlZEl0ZW0oc2VsZWN0ZWRJbmRleDogbnVtYmVyLCBzY3JvbGxJbnRvVmlldzogYm9vbGVhbikge1xyXG5cdFx0Y29uc3Qgbm9ybWFsaXplZEluZGV4ID0gd3JhcEFyb3VuZChcclxuXHRcdFx0c2VsZWN0ZWRJbmRleCxcclxuXHRcdFx0dGhpcy5zdWdnZXN0aW9ucy5sZW5ndGhcclxuXHRcdCk7XHJcblx0XHRjb25zdCBwcmV2U2VsZWN0ZWRTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uc1t0aGlzLnNlbGVjdGVkSXRlbV07XHJcblx0XHRjb25zdCBzZWxlY3RlZFN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3Rpb25zW25vcm1hbGl6ZWRJbmRleF07XHJcblxyXG5cdFx0cHJldlNlbGVjdGVkU3VnZ2VzdGlvbj8ucmVtb3ZlQ2xhc3MoJ2lzLXNlbGVjdGVkJyk7XHJcblx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24/LmFkZENsYXNzKCdpcy1zZWxlY3RlZCcpO1xyXG5cclxuXHRcdHRoaXMuc2VsZWN0ZWRJdGVtID0gbm9ybWFsaXplZEluZGV4O1xyXG5cclxuXHRcdGlmIChzY3JvbGxJbnRvVmlldykge1xyXG5cdFx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24uc2Nyb2xsSW50b1ZpZXcoZmFsc2UpO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRleHRJbnB1dFN1Z2dlc3Q8VD4gaW1wbGVtZW50cyBJU3VnZ2VzdE93bmVyPFQ+IHtcclxuXHRwcm90ZWN0ZWQgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQ7XHJcblxyXG5cdHByaXZhdGUgcG9wcGVyOiBQb3BwZXJJbnN0YW5jZTtcclxuXHRwcml2YXRlIHNjb3BlOiBTY29wZTtcclxuXHRwcml2YXRlIHN1Z2dlc3RFbDogSFRNTEVsZW1lbnQ7XHJcblx0cHJpdmF0ZSBzdWdnZXN0OiBTdWdnZXN0PFQ+O1xyXG5cclxuXHRjb25zdHJ1Y3RvcihpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudCkge1xyXG5cdFx0dGhpcy5pbnB1dEVsID0gaW5wdXRFbDtcclxuXHRcdHRoaXMuc2NvcGUgPSBuZXcgU2NvcGUoKTtcclxuXHJcblx0XHR0aGlzLnN1Z2dlc3RFbCA9IGNyZWF0ZURpdignc3VnZ2VzdGlvbi1jb250YWluZXInKTtcclxuXHRcdGNvbnN0IHN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3RFbC5jcmVhdGVEaXYoJ3N1Z2dlc3Rpb24nKTtcclxuXHRcdHRoaXMuc3VnZ2VzdCA9IG5ldyBTdWdnZXN0KHRoaXMsIHN1Z2dlc3Rpb24sIHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc2NvcGUucmVnaXN0ZXIoW10sICdFc2NhcGUnLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cclxuXHRcdHRoaXMuaW5wdXRFbC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMub25JbnB1dENoYW5nZWQuYmluZCh0aGlzKSk7XHJcblx0XHR0aGlzLmlucHV0RWwuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLm9uSW5wdXRDaGFuZ2VkLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5pbnB1dEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5zdWdnZXN0RWwub24oXHJcblx0XHRcdCdtb3VzZWRvd24nLFxyXG5cdFx0XHQnLnN1Z2dlc3Rpb24tY29udGFpbmVyJyxcclxuXHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0fVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdG9uSW5wdXRDaGFuZ2VkKCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaW5wdXRTdHIgPSB0aGlzLmlucHV0RWwudmFsdWU7XHJcblx0XHRjb25zdCBzdWdnZXN0aW9ucyA9IHRoaXMuZ2V0U3VnZ2VzdGlvbnMoaW5wdXRTdHIpO1xyXG5cclxuXHRcdGlmICghc3VnZ2VzdGlvbnMpIHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0dGhpcy5zdWdnZXN0LnNldFN1Z2dlc3Rpb25zKHN1Z2dlc3Rpb25zKTtcclxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxyXG5cdFx0XHR0aGlzLm9wZW4oYXBwLmRvbS5hcHBDb250YWluZXJFbCwgdGhpcy5pbnB1dEVsKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdG9wZW4oY29udGFpbmVyOiBIVE1MRWxlbWVudCwgaW5wdXRFbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XHJcblx0XHRhcHAua2V5bWFwLnB1c2hTY29wZSh0aGlzLnNjb3BlKTtcclxuXHJcblx0XHRjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5zdWdnZXN0RWwpO1xyXG5cdFx0dGhpcy5wb3BwZXIgPSBjcmVhdGVQb3BwZXIoaW5wdXRFbCwgdGhpcy5zdWdnZXN0RWwsIHtcclxuXHRcdFx0cGxhY2VtZW50OiAnYm90dG9tLXN0YXJ0JyxcclxuXHRcdFx0bW9kaWZpZXJzOiBbXHJcblx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0bmFtZTogJ3NhbWVXaWR0aCcsXHJcblx0XHRcdFx0XHRlbmFibGVkOiB0cnVlLFxyXG5cdFx0XHRcdFx0Zm46ICh7IHN0YXRlLCBpbnN0YW5jZSB9KSA9PiB7XHJcblx0XHRcdFx0XHRcdC8vIE5vdGU6IHBvc2l0aW9uaW5nIG5lZWRzIHRvIGJlIGNhbGN1bGF0ZWQgdHdpY2UgLVxyXG5cdFx0XHRcdFx0XHQvLyBmaXJzdCBwYXNzIC0gcG9zaXRpb25pbmcgaXQgYWNjb3JkaW5nIHRvIHRoZSB3aWR0aCBvZiB0aGUgcG9wcGVyXHJcblx0XHRcdFx0XHRcdC8vIHNlY29uZCBwYXNzIC0gcG9zaXRpb24gaXQgd2l0aCB0aGUgd2lkdGggYm91bmQgdG8gdGhlIHJlZmVyZW5jZSBlbGVtZW50XHJcblx0XHRcdFx0XHRcdC8vIHdlIG5lZWQgdG8gZWFybHkgZXhpdCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wXHJcblx0XHRcdFx0XHRcdGNvbnN0IHRhcmdldFdpZHRoID0gYCR7c3RhdGUucmVjdHMucmVmZXJlbmNlLndpZHRofXB4YDtcclxuXHRcdFx0XHRcdFx0aWYgKHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPT09IHRhcmdldFdpZHRoKSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPSB0YXJnZXRXaWR0aDtcclxuXHRcdFx0XHRcdFx0aW5zdGFuY2UudXBkYXRlKCk7XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0cGhhc2U6ICdiZWZvcmVXcml0ZScsXHJcblx0XHRcdFx0XHRyZXF1aXJlczogWydjb21wdXRlU3R5bGVzJ10sXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y2xvc2UoKTogdm9pZCB7XHJcblx0XHRhcHAua2V5bWFwLnBvcFNjb3BlKHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc3VnZ2VzdC5zZXRTdWdnZXN0aW9ucyhbXSk7XHJcblx0XHRpZiAodGhpcy5wb3BwZXIpIHRoaXMucG9wcGVyLmRlc3Ryb3koKTtcclxuXHRcdHRoaXMuc3VnZ2VzdEVsLmRldGFjaCgpO1xyXG5cdH1cclxuXHJcbiAgICBhYnN0cmFjdCBnZXRTdWdnZXN0aW9ucyhpbnB1dFN0cjogc3RyaW5nKTogVFtdO1xyXG4gICAgYWJzdHJhY3QgcmVuZGVyU3VnZ2VzdGlvbihpdGVtOiBULCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkO1xyXG4gICAgYWJzdHJhY3Qgc2VsZWN0U3VnZ2VzdGlvbihpdGVtOiBUKTogdm9pZDtcclxufVxyXG4iLCAiZXhwb3J0IHZhciB0b3AgPSAndG9wJztcbmV4cG9ydCB2YXIgYm90dG9tID0gJ2JvdHRvbSc7XG5leHBvcnQgdmFyIHJpZ2h0ID0gJ3JpZ2h0JztcbmV4cG9ydCB2YXIgbGVmdCA9ICdsZWZ0JztcbmV4cG9ydCB2YXIgYXV0byA9ICdhdXRvJztcbmV4cG9ydCB2YXIgYmFzZVBsYWNlbWVudHMgPSBbdG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0XTtcbmV4cG9ydCB2YXIgc3RhcnQgPSAnc3RhcnQnO1xuZXhwb3J0IHZhciBlbmQgPSAnZW5kJztcbmV4cG9ydCB2YXIgY2xpcHBpbmdQYXJlbnRzID0gJ2NsaXBwaW5nUGFyZW50cyc7XG5leHBvcnQgdmFyIHZpZXdwb3J0ID0gJ3ZpZXdwb3J0JztcbmV4cG9ydCB2YXIgcG9wcGVyID0gJ3BvcHBlcic7XG5leHBvcnQgdmFyIHJlZmVyZW5jZSA9ICdyZWZlcmVuY2UnO1xuZXhwb3J0IHZhciB2YXJpYXRpb25QbGFjZW1lbnRzID0gLyojX19QVVJFX18qL2Jhc2VQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCArIFwiLVwiICsgc3RhcnQsIHBsYWNlbWVudCArIFwiLVwiICsgZW5kXSk7XG59LCBbXSk7XG5leHBvcnQgdmFyIHBsYWNlbWVudHMgPSAvKiNfX1BVUkVfXyovW10uY29uY2F0KGJhc2VQbGFjZW1lbnRzLCBbYXV0b10pLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCwgcGxhY2VtZW50ICsgXCItXCIgKyBzdGFydCwgcGxhY2VtZW50ICsgXCItXCIgKyBlbmRdKTtcbn0sIFtdKTsgLy8gbW9kaWZpZXJzIHRoYXQgbmVlZCB0byByZWFkIHRoZSBET01cblxuZXhwb3J0IHZhciBiZWZvcmVSZWFkID0gJ2JlZm9yZVJlYWQnO1xuZXhwb3J0IHZhciByZWFkID0gJ3JlYWQnO1xuZXhwb3J0IHZhciBhZnRlclJlYWQgPSAnYWZ0ZXJSZWFkJzsgLy8gcHVyZS1sb2dpYyBtb2RpZmllcnNcblxuZXhwb3J0IHZhciBiZWZvcmVNYWluID0gJ2JlZm9yZU1haW4nO1xuZXhwb3J0IHZhciBtYWluID0gJ21haW4nO1xuZXhwb3J0IHZhciBhZnRlck1haW4gPSAnYWZ0ZXJNYWluJzsgLy8gbW9kaWZpZXIgd2l0aCB0aGUgcHVycG9zZSB0byB3cml0ZSB0byB0aGUgRE9NIChvciB3cml0ZSBpbnRvIGEgZnJhbWV3b3JrIHN0YXRlKVxuXG5leHBvcnQgdmFyIGJlZm9yZVdyaXRlID0gJ2JlZm9yZVdyaXRlJztcbmV4cG9ydCB2YXIgd3JpdGUgPSAnd3JpdGUnO1xuZXhwb3J0IHZhciBhZnRlcldyaXRlID0gJ2FmdGVyV3JpdGUnO1xuZXhwb3J0IHZhciBtb2RpZmllclBoYXNlcyA9IFtiZWZvcmVSZWFkLCByZWFkLCBhZnRlclJlYWQsIGJlZm9yZU1haW4sIG1haW4sIGFmdGVyTWFpbiwgYmVmb3JlV3JpdGUsIHdyaXRlLCBhZnRlcldyaXRlXTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Tm9kZU5hbWUoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCA/IChlbGVtZW50Lm5vZGVOYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpIDogbnVsbDtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICBpZiAobm9kZS50b1N0cmluZygpICE9PSAnW29iamVjdCBXaW5kb3ddJykge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBvd25lckRvY3VtZW50ID8gb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3cgOiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuRWxlbWVudDtcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBPd25FbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBpc0hUTUxFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuSFRNTEVsZW1lbnQ7XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgT3duRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzU2hhZG93Um9vdChub2RlKSB7XG4gIC8vIElFIDExIGhhcyBubyBTaGFkb3dSb290XG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5TaGFkb3dSb290O1xuICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE93bkVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIFNoYWRvd1Jvb3Q7XG59XG5cbmV4cG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCwgaXNTaGFkb3dSb290IH07IiwgImltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4uL2RvbS11dGlscy9pbnN0YW5jZU9mLmpzXCI7IC8vIFRoaXMgbW9kaWZpZXIgdGFrZXMgdGhlIHN0eWxlcyBwcmVwYXJlZCBieSB0aGUgYGNvbXB1dGVTdHlsZXNgIG1vZGlmaWVyXG4vLyBhbmQgYXBwbGllcyB0aGVtIHRvIHRoZSBIVE1MRWxlbWVudHMgc3VjaCBhcyBwb3BwZXIgYW5kIGFycm93XG5cbmZ1bmN0aW9uIGFwcGx5U3R5bGVzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZTtcbiAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgc3R5bGUgPSBzdGF0ZS5zdHlsZXNbbmFtZV0gfHwge307XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBzdGF0ZS5hdHRyaWJ1dGVzW25hbWVdIHx8IHt9O1xuICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07IC8vIGFycm93IGlzIG9wdGlvbmFsICsgdmlydHVhbCBlbGVtZW50c1xuXG4gICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gRmxvdyBkb2Vzbid0IHN1cHBvcnQgdG8gZXh0ZW5kIHRoaXMgcHJvcGVydHksIGJ1dCBpdCdzIHRoZSBtb3N0XG4gICAgLy8gZWZmZWN0aXZlIHdheSB0byBhcHBseSBzdHlsZXMgdG8gYW4gSFRNTEVsZW1lbnRcbiAgICAvLyAkRmxvd0ZpeE1lW2Nhbm5vdC13cml0ZV1cblxuXG4gICAgT2JqZWN0LmFzc2lnbihlbGVtZW50LnN0eWxlLCBzdHlsZSk7XG4gICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cmlidXRlc1tuYW1lXTtcblxuICAgICAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlID09PSB0cnVlID8gJycgOiB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGU7XG4gIHZhciBpbml0aWFsU3R5bGVzID0ge1xuICAgIHBvcHBlcjoge1xuICAgICAgcG9zaXRpb246IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBsZWZ0OiAnMCcsXG4gICAgICB0b3A6ICcwJyxcbiAgICAgIG1hcmdpbjogJzAnXG4gICAgfSxcbiAgICBhcnJvdzoge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICB9LFxuICAgIHJlZmVyZW5jZToge31cbiAgfTtcbiAgT2JqZWN0LmFzc2lnbihzdGF0ZS5lbGVtZW50cy5wb3BwZXIuc3R5bGUsIGluaXRpYWxTdHlsZXMucG9wcGVyKTtcbiAgc3RhdGUuc3R5bGVzID0gaW5pdGlhbFN0eWxlcztcblxuICBpZiAoc3RhdGUuZWxlbWVudHMuYXJyb3cpIHtcbiAgICBPYmplY3QuYXNzaWduKHN0YXRlLmVsZW1lbnRzLmFycm93LnN0eWxlLCBpbml0aWFsU3R5bGVzLmFycm93KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07XG4gICAgICB2YXIgYXR0cmlidXRlcyA9IHN0YXRlLmF0dHJpYnV0ZXNbbmFtZV0gfHwge307XG4gICAgICB2YXIgc3R5bGVQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoc3RhdGUuc3R5bGVzLmhhc093blByb3BlcnR5KG5hbWUpID8gc3RhdGUuc3R5bGVzW25hbWVdIDogaW5pdGlhbFN0eWxlc1tuYW1lXSk7IC8vIFNldCBhbGwgdmFsdWVzIHRvIGFuIGVtcHR5IHN0cmluZyB0byB1bnNldCB0aGVtXG5cbiAgICAgIHZhciBzdHlsZSA9IHN0eWxlUHJvcGVydGllcy5yZWR1Y2UoZnVuY3Rpb24gKHN0eWxlLCBwcm9wZXJ0eSkge1xuICAgICAgICBzdHlsZVtwcm9wZXJ0eV0gPSAnJztcbiAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgICAgfSwge30pOyAvLyBhcnJvdyBpcyBvcHRpb25hbCArIHZpcnR1YWwgZWxlbWVudHNcblxuICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgc3R5bGUpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2FwcGx5U3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBhcHBseVN0eWxlcyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ2NvbXB1dGVTdHlsZXMnXVxufTsiLCAiaW1wb3J0IHsgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xufSIsICJleHBvcnQgdmFyIG1heCA9IE1hdGgubWF4O1xuZXhwb3J0IHZhciBtaW4gPSBNYXRoLm1pbjtcbmV4cG9ydCB2YXIgcm91bmQgPSBNYXRoLnJvdW5kOyIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRVQVN0cmluZygpIHtcbiAgdmFyIHVhRGF0YSA9IG5hdmlnYXRvci51c2VyQWdlbnREYXRhO1xuXG4gIGlmICh1YURhdGEgIT0gbnVsbCAmJiB1YURhdGEuYnJhbmRzICYmIEFycmF5LmlzQXJyYXkodWFEYXRhLmJyYW5kcykpIHtcbiAgICByZXR1cm4gdWFEYXRhLmJyYW5kcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBpdGVtLmJyYW5kICsgXCIvXCIgKyBpdGVtLnZlcnNpb247XG4gICAgfSkuam9pbignICcpO1xuICB9XG5cbiAgcmV0dXJuIG5hdmlnYXRvci51c2VyQWdlbnQ7XG59IiwgImltcG9ydCBnZXRVQVN0cmluZyBmcm9tIFwiLi4vdXRpbHMvdXNlckFnZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0xheW91dFZpZXdwb3J0KCkge1xuICByZXR1cm4gIS9eKCg/IWNocm9tZXxhbmRyb2lkKS4pKnNhZmFyaS9pLnRlc3QoZ2V0VUFTdHJpbmcoKSk7XG59IiwgImltcG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcbmltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCwgaW5jbHVkZVNjYWxlLCBpc0ZpeGVkU3RyYXRlZ3kpIHtcbiAgaWYgKGluY2x1ZGVTY2FsZSA9PT0gdm9pZCAwKSB7XG4gICAgaW5jbHVkZVNjYWxlID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaXNGaXhlZFN0cmF0ZWd5ID09PSB2b2lkIDApIHtcbiAgICBpc0ZpeGVkU3RyYXRlZ3kgPSBmYWxzZTtcbiAgfVxuXG4gIHZhciBjbGllbnRSZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgdmFyIHNjYWxlWCA9IDE7XG4gIHZhciBzY2FsZVkgPSAxO1xuXG4gIGlmIChpbmNsdWRlU2NhbGUgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSkge1xuICAgIHNjYWxlWCA9IGVsZW1lbnQub2Zmc2V0V2lkdGggPiAwID8gcm91bmQoY2xpZW50UmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDEgOiAxO1xuICAgIHNjYWxlWSA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0ID4gMCA/IHJvdW5kKGNsaWVudFJlY3QuaGVpZ2h0KSAvIGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDEgOiAxO1xuICB9XG5cbiAgdmFyIF9yZWYgPSBpc0VsZW1lbnQoZWxlbWVudCkgPyBnZXRXaW5kb3coZWxlbWVudCkgOiB3aW5kb3csXG4gICAgICB2aXN1YWxWaWV3cG9ydCA9IF9yZWYudmlzdWFsVmlld3BvcnQ7XG5cbiAgdmFyIGFkZFZpc3VhbE9mZnNldHMgPSAhaXNMYXlvdXRWaWV3cG9ydCgpICYmIGlzRml4ZWRTdHJhdGVneTtcbiAgdmFyIHggPSAoY2xpZW50UmVjdC5sZWZ0ICsgKGFkZFZpc3VhbE9mZnNldHMgJiYgdmlzdWFsVmlld3BvcnQgPyB2aXN1YWxWaWV3cG9ydC5vZmZzZXRMZWZ0IDogMCkpIC8gc2NhbGVYO1xuICB2YXIgeSA9IChjbGllbnRSZWN0LnRvcCArIChhZGRWaXN1YWxPZmZzZXRzICYmIHZpc3VhbFZpZXdwb3J0ID8gdmlzdWFsVmlld3BvcnQub2Zmc2V0VG9wIDogMCkpIC8gc2NhbGVZO1xuICB2YXIgd2lkdGggPSBjbGllbnRSZWN0LndpZHRoIC8gc2NhbGVYO1xuICB2YXIgaGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQgLyBzY2FsZVk7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHRvcDogeSxcbiAgICByaWdodDogeCArIHdpZHRoLFxuICAgIGJvdHRvbTogeSArIGhlaWdodCxcbiAgICBsZWZ0OiB4LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiOyAvLyBSZXR1cm5zIHRoZSBsYXlvdXQgcmVjdCBvZiBhbiBlbGVtZW50IHJlbGF0aXZlIHRvIGl0cyBvZmZzZXRQYXJlbnQuIExheW91dFxuLy8gbWVhbnMgaXQgZG9lc24ndCB0YWtlIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zLlxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRMYXlvdXRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIGNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCk7IC8vIFVzZSB0aGUgY2xpZW50UmVjdCBzaXplcyBpZiBpdCdzIG5vdCBiZWVuIHRyYW5zZm9ybWVkLlxuICAvLyBGaXhlcyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEyMjNcblxuICB2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG5cbiAgaWYgKE1hdGguYWJzKGNsaWVudFJlY3Qud2lkdGggLSB3aWR0aCkgPD0gMSkge1xuICAgIHdpZHRoID0gY2xpZW50UmVjdC53aWR0aDtcbiAgfVxuXG4gIGlmIChNYXRoLmFicyhjbGllbnRSZWN0LmhlaWdodCAtIGhlaWdodCkgPD0gMSkge1xuICAgIGhlaWdodCA9IGNsaWVudFJlY3QuaGVpZ2h0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBlbGVtZW50Lm9mZnNldExlZnQsXG4gICAgeTogZWxlbWVudC5vZmZzZXRUb3AsXG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRhaW5zKHBhcmVudCwgY2hpbGQpIHtcbiAgdmFyIHJvb3ROb2RlID0gY2hpbGQuZ2V0Um9vdE5vZGUgJiYgY2hpbGQuZ2V0Um9vdE5vZGUoKTsgLy8gRmlyc3QsIGF0dGVtcHQgd2l0aCBmYXN0ZXIgbmF0aXZlIG1ldGhvZFxuXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gLy8gdGhlbiBmYWxsYmFjayB0byBjdXN0b20gaW1wbGVtZW50YXRpb24gd2l0aCBTaGFkb3cgRE9NIHN1cHBvcnRcbiAgZWxzZSBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgICAgdmFyIG5leHQgPSBjaGlsZDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAobmV4dCAmJiBwYXJlbnQuaXNTYW1lTm9kZShuZXh0KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXTogbmVlZCBhIGJldHRlciB3YXkgdG8gaGFuZGxlIHRoaXMuLi5cblxuXG4gICAgICAgIG5leHQgPSBuZXh0LnBhcmVudE5vZGUgfHwgbmV4dC5ob3N0O1xuICAgICAgfSB3aGlsZSAobmV4dCk7XG4gICAgfSAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG5cblxuICByZXR1cm4gZmFsc2U7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFdpbmRvdyhlbGVtZW50KS5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xufSIsICJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGlzVGFibGVFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIFsndGFibGUnLCAndGQnLCAndGgnXS5pbmRleE9mKGdldE5vZGVOYW1lKGVsZW1lbnQpKSA+PSAwO1xufSIsICJpbXBvcnQgeyBpc0VsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkge1xuICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gIHJldHVybiAoKGlzRWxlbWVudChlbGVtZW50KSA/IGVsZW1lbnQub3duZXJEb2N1bWVudCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICBlbGVtZW50LmRvY3VtZW50KSB8fCB3aW5kb3cuZG9jdW1lbnQpLmRvY3VtZW50RWxlbWVudDtcbn0iLCAiaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IHsgaXNTaGFkb3dSb290IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0UGFyZW50Tm9kZShlbGVtZW50KSB7XG4gIGlmIChnZXROb2RlTmFtZShlbGVtZW50KSA9PT0gJ2h0bWwnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gKC8vIHRoaXMgaXMgYSBxdWlja2VyIChidXQgbGVzcyB0eXBlIHNhZmUpIHdheSB0byBzYXZlIHF1aXRlIHNvbWUgYnl0ZXMgZnJvbSB0aGUgYnVuZGxlXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXVxuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgIGVsZW1lbnQuYXNzaWduZWRTbG90IHx8IC8vIHN0ZXAgaW50byB0aGUgc2hhZG93IERPTSBvZiB0aGUgcGFyZW50IG9mIGEgc2xvdHRlZCBub2RlXG4gICAgZWxlbWVudC5wYXJlbnROb2RlIHx8ICggLy8gRE9NIEVsZW1lbnQgZGV0ZWN0ZWRcbiAgICBpc1NoYWRvd1Jvb3QoZWxlbWVudCkgPyBlbGVtZW50Lmhvc3QgOiBudWxsKSB8fCAvLyBTaGFkb3dSb290IGRldGVjdGVkXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IEhUTUxFbGVtZW50IGlzIGEgTm9kZVxuICAgIGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KSAvLyBmYWxsYmFja1xuXG4gICk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQsIGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBpc1RhYmxlRWxlbWVudCBmcm9tIFwiLi9pc1RhYmxlRWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGdldFVBU3RyaW5nIGZyb20gXCIuLi91dGlscy91c2VyQWdlbnQuanNcIjtcblxuZnVuY3Rpb24gZ2V0VHJ1ZU9mZnNldFBhcmVudChlbGVtZW50KSB7XG4gIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzgzN1xuICBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG59IC8vIGAub2Zmc2V0UGFyZW50YCByZXBvcnRzIGBudWxsYCBmb3IgZml4ZWQgZWxlbWVudHMsIHdoaWxlIGFic29sdXRlIGVsZW1lbnRzXG4vLyByZXR1cm4gdGhlIGNvbnRhaW5pbmcgYmxvY2tcblxuXG5mdW5jdGlvbiBnZXRDb250YWluaW5nQmxvY2soZWxlbWVudCkge1xuICB2YXIgaXNGaXJlZm94ID0gL2ZpcmVmb3gvaS50ZXN0KGdldFVBU3RyaW5nKCkpO1xuICB2YXIgaXNJRSA9IC9UcmlkZW50L2kudGVzdChnZXRVQVN0cmluZygpKTtcblxuICBpZiAoaXNJRSAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgLy8gSW4gSUUgOSwgMTAgYW5kIDExIGZpeGVkIGVsZW1lbnRzIGNvbnRhaW5pbmcgYmxvY2sgaXMgYWx3YXlzIGVzdGFibGlzaGVkIGJ5IHRoZSB2aWV3cG9ydFxuICAgIHZhciBlbGVtZW50Q3NzID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50Q3NzLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICB2YXIgY3VycmVudE5vZGUgPSBnZXRQYXJlbnROb2RlKGVsZW1lbnQpO1xuXG4gIGlmIChpc1NoYWRvd1Jvb3QoY3VycmVudE5vZGUpKSB7XG4gICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5ob3N0O1xuICB9XG5cbiAgd2hpbGUgKGlzSFRNTEVsZW1lbnQoY3VycmVudE5vZGUpICYmIFsnaHRtbCcsICdib2R5J10uaW5kZXhPZihnZXROb2RlTmFtZShjdXJyZW50Tm9kZSkpIDwgMCkge1xuICAgIHZhciBjc3MgPSBnZXRDb21wdXRlZFN0eWxlKGN1cnJlbnROb2RlKTsgLy8gVGhpcyBpcyBub24tZXhoYXVzdGl2ZSBidXQgY292ZXJzIHRoZSBtb3N0IGNvbW1vbiBDU1MgcHJvcGVydGllcyB0aGF0XG4gICAgLy8gY3JlYXRlIGEgY29udGFpbmluZyBibG9jay5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ29udGFpbmluZ19ibG9jayNpZGVudGlmeWluZ190aGVfY29udGFpbmluZ19ibG9ja1xuXG4gICAgaWYgKGNzcy50cmFuc2Zvcm0gIT09ICdub25lJyB8fCBjc3MucGVyc3BlY3RpdmUgIT09ICdub25lJyB8fCBjc3MuY29udGFpbiA9PT0gJ3BhaW50JyB8fCBbJ3RyYW5zZm9ybScsICdwZXJzcGVjdGl2ZSddLmluZGV4T2YoY3NzLndpbGxDaGFuZ2UpICE9PSAtMSB8fCBpc0ZpcmVmb3ggJiYgY3NzLndpbGxDaGFuZ2UgPT09ICdmaWx0ZXInIHx8IGlzRmlyZWZveCAmJiBjc3MuZmlsdGVyICYmIGNzcy5maWx0ZXIgIT09ICdub25lJykge1xuICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59IC8vIEdldHMgdGhlIGNsb3Nlc3QgYW5jZXN0b3IgcG9zaXRpb25lZCBlbGVtZW50LiBIYW5kbGVzIHNvbWUgZWRnZSBjYXNlcyxcbi8vIHN1Y2ggYXMgdGFibGUgYW5jZXN0b3JzIGFuZCBjcm9zcyBicm93c2VyIGJ1Z3MuXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIHtcbiAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIG9mZnNldFBhcmVudCA9IGdldFRydWVPZmZzZXRQYXJlbnQoZWxlbWVudCk7XG5cbiAgd2hpbGUgKG9mZnNldFBhcmVudCAmJiBpc1RhYmxlRWxlbWVudChvZmZzZXRQYXJlbnQpICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpIHtcbiAgICBvZmZzZXRQYXJlbnQgPSBnZXRUcnVlT2Zmc2V0UGFyZW50KG9mZnNldFBhcmVudCk7XG4gIH1cblxuICBpZiAob2Zmc2V0UGFyZW50ICYmIChnZXROb2RlTmFtZShvZmZzZXRQYXJlbnQpID09PSAnaHRtbCcgfHwgZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSA9PT0gJ2JvZHknICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpKSB7XG4gICAgcmV0dXJuIHdpbmRvdztcbiAgfVxuXG4gIHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZ2V0Q29udGFpbmluZ0Jsb2NrKGVsZW1lbnQpIHx8IHdpbmRvdztcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gWyd0b3AnLCAnYm90dG9tJ10uaW5kZXhPZihwbGFjZW1lbnQpID49IDAgPyAneCcgOiAneSc7XG59IiwgImltcG9ydCB7IG1heCBhcyBtYXRoTWF4LCBtaW4gYXMgbWF0aE1pbiB9IGZyb20gXCIuL21hdGguanNcIjtcbmV4cG9ydCBmdW5jdGlvbiB3aXRoaW4obWluLCB2YWx1ZSwgbWF4KSB7XG4gIHJldHVybiBtYXRoTWF4KG1pbiwgbWF0aE1pbih2YWx1ZSwgbWF4KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gd2l0aGluTWF4Q2xhbXAobWluLCB2YWx1ZSwgbWF4KSB7XG4gIHZhciB2ID0gd2l0aGluKG1pbiwgdmFsdWUsIG1heCk7XG4gIHJldHVybiB2ID4gbWF4ID8gbWF4IDogdjtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RnJlc2hTaWRlT2JqZWN0KCkge1xuICByZXR1cm4ge1xuICAgIHRvcDogMCxcbiAgICByaWdodDogMCxcbiAgICBib3R0b206IDAsXG4gICAgbGVmdDogMFxuICB9O1xufSIsICJpbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbWVyZ2VQYWRkaW5nT2JqZWN0KHBhZGRpbmdPYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGdldEZyZXNoU2lkZU9iamVjdCgpLCBwYWRkaW5nT2JqZWN0KTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZXhwYW5kVG9IYXNoTWFwKHZhbHVlLCBrZXlzKSB7XG4gIHJldHVybiBrZXlzLnJlZHVjZShmdW5jdGlvbiAoaGFzaE1hcCwga2V5KSB7XG4gICAgaGFzaE1hcFtrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIGhhc2hNYXA7XG4gIH0sIHt9KTtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuLi9kb20tdXRpbHMvY29udGFpbnMuanNcIjtcbmltcG9ydCBnZXRPZmZzZXRQYXJlbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgd2l0aGluIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGhpbi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi4vdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzXCI7XG5pbXBvcnQgZXhwYW5kVG9IYXNoTWFwIGZyb20gXCIuLi91dGlscy9leHBhbmRUb0hhc2hNYXAuanNcIjtcbmltcG9ydCB7IGxlZnQsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdG9wLCBib3R0b20gfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdG9QYWRkaW5nT2JqZWN0ID0gZnVuY3Rpb24gdG9QYWRkaW5nT2JqZWN0KHBhZGRpbmcsIHN0YXRlKSB7XG4gIHBhZGRpbmcgPSB0eXBlb2YgcGFkZGluZyA9PT0gJ2Z1bmN0aW9uJyA/IHBhZGRpbmcoT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KSkgOiBwYWRkaW5nO1xuICByZXR1cm4gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbn07XG5cbmZ1bmN0aW9uIGFycm93KF9yZWYpIHtcbiAgdmFyIF9zdGF0ZSRtb2RpZmllcnNEYXRhJDtcblxuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XG4gIHZhciBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdztcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHM7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgYXhpcyA9IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChiYXNlUGxhY2VtZW50KTtcbiAgdmFyIGlzVmVydGljYWwgPSBbbGVmdCwgcmlnaHRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgPj0gMDtcbiAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgaWYgKCFhcnJvd0VsZW1lbnQgfHwgIXBvcHBlck9mZnNldHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFkZGluZ09iamVjdCA9IHRvUGFkZGluZ09iamVjdChvcHRpb25zLnBhZGRpbmcsIHN0YXRlKTtcbiAgdmFyIGFycm93UmVjdCA9IGdldExheW91dFJlY3QoYXJyb3dFbGVtZW50KTtcbiAgdmFyIG1pblByb3AgPSBheGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICB2YXIgbWF4UHJvcCA9IGF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICB2YXIgZW5kRGlmZiA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtsZW5dICsgc3RhdGUucmVjdHMucmVmZXJlbmNlW2F4aXNdIC0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnBvcHBlcltsZW5dO1xuICB2YXIgc3RhcnREaWZmID0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtheGlzXTtcbiAgdmFyIGFycm93T2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KGFycm93RWxlbWVudCk7XG4gIHZhciBjbGllbnRTaXplID0gYXJyb3dPZmZzZXRQYXJlbnQgPyBheGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRIZWlnaHQgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudFdpZHRoIHx8IDAgOiAwO1xuICB2YXIgY2VudGVyVG9SZWZlcmVuY2UgPSBlbmREaWZmIC8gMiAtIHN0YXJ0RGlmZiAvIDI7IC8vIE1ha2Ugc3VyZSB0aGUgYXJyb3cgZG9lc24ndCBvdmVyZmxvdyB0aGUgcG9wcGVyIGlmIHRoZSBjZW50ZXIgcG9pbnQgaXNcbiAgLy8gb3V0c2lkZSBvZiB0aGUgcG9wcGVyIGJvdW5kc1xuXG4gIHZhciBtaW4gPSBwYWRkaW5nT2JqZWN0W21pblByb3BdO1xuICB2YXIgbWF4ID0gY2xpZW50U2l6ZSAtIGFycm93UmVjdFtsZW5dIC0gcGFkZGluZ09iamVjdFttYXhQcm9wXTtcbiAgdmFyIGNlbnRlciA9IGNsaWVudFNpemUgLyAyIC0gYXJyb3dSZWN0W2xlbl0gLyAyICsgY2VudGVyVG9SZWZlcmVuY2U7XG4gIHZhciBvZmZzZXQgPSB3aXRoaW4obWluLCBjZW50ZXIsIG1heCk7IC8vIFByZXZlbnRzIGJyZWFraW5nIHN5bnRheCBoaWdobGlnaHRpbmcuLi5cblxuICB2YXIgYXhpc1Byb3AgPSBheGlzO1xuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gKF9zdGF0ZSRtb2RpZmllcnNEYXRhJCA9IHt9LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSRbYXhpc1Byb3BdID0gb2Zmc2V0LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQuY2VudGVyT2Zmc2V0ID0gb2Zmc2V0IC0gY2VudGVyLCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQpO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJGVsZW1lbnQgPSBvcHRpb25zLmVsZW1lbnQsXG4gICAgICBhcnJvd0VsZW1lbnQgPSBfb3B0aW9ucyRlbGVtZW50ID09PSB2b2lkIDAgPyAnW2RhdGEtcG9wcGVyLWFycm93XScgOiBfb3B0aW9ucyRlbGVtZW50O1xuXG4gIGlmIChhcnJvd0VsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfSAvLyBDU1Mgc2VsZWN0b3JcblxuXG4gIGlmICh0eXBlb2YgYXJyb3dFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgIGFycm93RWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzLnBvcHBlci5xdWVyeVNlbGVjdG9yKGFycm93RWxlbWVudCk7XG5cbiAgICBpZiAoIWFycm93RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmICghY29udGFpbnMoc3RhdGUuZWxlbWVudHMucG9wcGVyLCBhcnJvd0VsZW1lbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3RhdGUuZWxlbWVudHMuYXJyb3cgPSBhcnJvd0VsZW1lbnQ7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcnJvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBhcnJvdyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydwcmV2ZW50T3ZlcmZsb3cnXVxufTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnNwbGl0KCctJylbMV07XG59IiwgImltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgZW5kIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdW5zZXRTaWRlcyA9IHtcbiAgdG9wOiAnYXV0bycsXG4gIHJpZ2h0OiAnYXV0bycsXG4gIGJvdHRvbTogJ2F1dG8nLFxuICBsZWZ0OiAnYXV0bydcbn07IC8vIFJvdW5kIHRoZSBvZmZzZXRzIHRvIHRoZSBuZWFyZXN0IHN1aXRhYmxlIHN1YnBpeGVsIGJhc2VkIG9uIHRoZSBEUFIuXG4vLyBab29taW5nIGNhbiBjaGFuZ2UgdGhlIERQUiwgYnV0IGl0IHNlZW1zIHRvIHJlcG9ydCBhIHZhbHVlIHRoYXQgd2lsbFxuLy8gY2xlYW5seSBkaXZpZGUgdGhlIHZhbHVlcyBpbnRvIHRoZSBhcHByb3ByaWF0ZSBzdWJwaXhlbHMuXG5cbmZ1bmN0aW9uIHJvdW5kT2Zmc2V0c0J5RFBSKF9yZWYsIHdpbikge1xuICB2YXIgeCA9IF9yZWYueCxcbiAgICAgIHkgPSBfcmVmLnk7XG4gIHZhciBkcHIgPSB3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICByZXR1cm4ge1xuICAgIHg6IHJvdW5kKHggKiBkcHIpIC8gZHByIHx8IDAsXG4gICAgeTogcm91bmQoeSAqIGRwcikgLyBkcHIgfHwgMFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFwVG9TdHlsZXMoX3JlZjIpIHtcbiAgdmFyIF9PYmplY3QkYXNzaWduMjtcblxuICB2YXIgcG9wcGVyID0gX3JlZjIucG9wcGVyLFxuICAgICAgcG9wcGVyUmVjdCA9IF9yZWYyLnBvcHBlclJlY3QsXG4gICAgICBwbGFjZW1lbnQgPSBfcmVmMi5wbGFjZW1lbnQsXG4gICAgICB2YXJpYXRpb24gPSBfcmVmMi52YXJpYXRpb24sXG4gICAgICBvZmZzZXRzID0gX3JlZjIub2Zmc2V0cyxcbiAgICAgIHBvc2l0aW9uID0gX3JlZjIucG9zaXRpb24sXG4gICAgICBncHVBY2NlbGVyYXRpb24gPSBfcmVmMi5ncHVBY2NlbGVyYXRpb24sXG4gICAgICBhZGFwdGl2ZSA9IF9yZWYyLmFkYXB0aXZlLFxuICAgICAgcm91bmRPZmZzZXRzID0gX3JlZjIucm91bmRPZmZzZXRzLFxuICAgICAgaXNGaXhlZCA9IF9yZWYyLmlzRml4ZWQ7XG4gIHZhciBfb2Zmc2V0cyR4ID0gb2Zmc2V0cy54LFxuICAgICAgeCA9IF9vZmZzZXRzJHggPT09IHZvaWQgMCA/IDAgOiBfb2Zmc2V0cyR4LFxuICAgICAgX29mZnNldHMkeSA9IG9mZnNldHMueSxcbiAgICAgIHkgPSBfb2Zmc2V0cyR5ID09PSB2b2lkIDAgPyAwIDogX29mZnNldHMkeTtcblxuICB2YXIgX3JlZjMgPSB0eXBlb2Ygcm91bmRPZmZzZXRzID09PSAnZnVuY3Rpb24nID8gcm91bmRPZmZzZXRzKHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWYzLng7XG4gIHkgPSBfcmVmMy55O1xuICB2YXIgaGFzWCA9IG9mZnNldHMuaGFzT3duUHJvcGVydHkoJ3gnKTtcbiAgdmFyIGhhc1kgPSBvZmZzZXRzLmhhc093blByb3BlcnR5KCd5Jyk7XG4gIHZhciBzaWRlWCA9IGxlZnQ7XG4gIHZhciBzaWRlWSA9IHRvcDtcbiAgdmFyIHdpbiA9IHdpbmRvdztcblxuICBpZiAoYWRhcHRpdmUpIHtcbiAgICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KHBvcHBlcik7XG4gICAgdmFyIGhlaWdodFByb3AgPSAnY2xpZW50SGVpZ2h0JztcbiAgICB2YXIgd2lkdGhQcm9wID0gJ2NsaWVudFdpZHRoJztcblxuICAgIGlmIChvZmZzZXRQYXJlbnQgPT09IGdldFdpbmRvdyhwb3BwZXIpKSB7XG4gICAgICBvZmZzZXRQYXJlbnQgPSBnZXREb2N1bWVudEVsZW1lbnQocG9wcGVyKTtcblxuICAgICAgaWYgKGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiAhPT0gJ3N0YXRpYycgJiYgcG9zaXRpb24gPT09ICdhYnNvbHV0ZScpIHtcbiAgICAgICAgaGVpZ2h0UHJvcCA9ICdzY3JvbGxIZWlnaHQnO1xuICAgICAgICB3aWR0aFByb3AgPSAnc2Nyb2xsV2lkdGgnO1xuICAgICAgfVxuICAgIH0gLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FzdF06IGZvcmNlIHR5cGUgcmVmaW5lbWVudCwgd2UgY29tcGFyZSBvZmZzZXRQYXJlbnQgd2l0aCB3aW5kb3cgYWJvdmUsIGJ1dCBGbG93IGRvZXNuJ3QgZGV0ZWN0IGl0XG5cblxuICAgIG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudDtcblxuICAgIGlmIChwbGFjZW1lbnQgPT09IHRvcCB8fCAocGxhY2VtZW50ID09PSBsZWZ0IHx8IHBsYWNlbWVudCA9PT0gcmlnaHQpICYmIHZhcmlhdGlvbiA9PT0gZW5kKSB7XG4gICAgICBzaWRlWSA9IGJvdHRvbTtcbiAgICAgIHZhciBvZmZzZXRZID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQuaGVpZ2h0IDogLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICBvZmZzZXRQYXJlbnRbaGVpZ2h0UHJvcF07XG4gICAgICB5IC09IG9mZnNldFkgLSBwb3BwZXJSZWN0LmhlaWdodDtcbiAgICAgIHkgKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cblxuICAgIGlmIChwbGFjZW1lbnQgPT09IGxlZnQgfHwgKHBsYWNlbWVudCA9PT0gdG9wIHx8IHBsYWNlbWVudCA9PT0gYm90dG9tKSAmJiB2YXJpYXRpb24gPT09IGVuZCkge1xuICAgICAgc2lkZVggPSByaWdodDtcbiAgICAgIHZhciBvZmZzZXRYID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQud2lkdGggOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgIG9mZnNldFBhcmVudFt3aWR0aFByb3BdO1xuICAgICAgeCAtPSBvZmZzZXRYIC0gcG9wcGVyUmVjdC53aWR0aDtcbiAgICAgIHggKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjb21tb25TdHlsZXMgPSBPYmplY3QuYXNzaWduKHtcbiAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgfSwgYWRhcHRpdmUgJiYgdW5zZXRTaWRlcyk7XG5cbiAgdmFyIF9yZWY0ID0gcm91bmRPZmZzZXRzID09PSB0cnVlID8gcm91bmRPZmZzZXRzQnlEUFIoe1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9LCBnZXRXaW5kb3cocG9wcGVyKSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWY0Lng7XG4gIHkgPSBfcmVmNC55O1xuXG4gIGlmIChncHVBY2NlbGVyYXRpb24pIHtcbiAgICB2YXIgX09iamVjdCRhc3NpZ247XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCAoX09iamVjdCRhc3NpZ24gPSB7fSwgX09iamVjdCRhc3NpZ25bc2lkZVldID0gaGFzWSA/ICcwJyA6ICcnLCBfT2JqZWN0JGFzc2lnbltzaWRlWF0gPSBoYXNYID8gJzAnIDogJycsIF9PYmplY3QkYXNzaWduLnRyYW5zZm9ybSA9ICh3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxKSA8PSAxID8gXCJ0cmFuc2xhdGUoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweClcIiA6IFwidHJhbnNsYXRlM2QoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweCwgMClcIiwgX09iamVjdCRhc3NpZ24pKTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIChfT2JqZWN0JGFzc2lnbjIgPSB7fSwgX09iamVjdCRhc3NpZ24yW3NpZGVZXSA9IGhhc1kgPyB5ICsgXCJweFwiIDogJycsIF9PYmplY3QkYXNzaWduMltzaWRlWF0gPSBoYXNYID8geCArIFwicHhcIiA6ICcnLCBfT2JqZWN0JGFzc2lnbjIudHJhbnNmb3JtID0gJycsIF9PYmplY3QkYXNzaWduMikpO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlU3R5bGVzKF9yZWY1KSB7XG4gIHZhciBzdGF0ZSA9IF9yZWY1LnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWY1Lm9wdGlvbnM7XG4gIHZhciBfb3B0aW9ucyRncHVBY2NlbGVyYXQgPSBvcHRpb25zLmdwdUFjY2VsZXJhdGlvbixcbiAgICAgIGdwdUFjY2VsZXJhdGlvbiA9IF9vcHRpb25zJGdwdUFjY2VsZXJhdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGdwdUFjY2VsZXJhdCxcbiAgICAgIF9vcHRpb25zJGFkYXB0aXZlID0gb3B0aW9ucy5hZGFwdGl2ZSxcbiAgICAgIGFkYXB0aXZlID0gX29wdGlvbnMkYWRhcHRpdmUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRhZGFwdGl2ZSxcbiAgICAgIF9vcHRpb25zJHJvdW5kT2Zmc2V0cyA9IG9wdGlvbnMucm91bmRPZmZzZXRzLFxuICAgICAgcm91bmRPZmZzZXRzID0gX29wdGlvbnMkcm91bmRPZmZzZXRzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkcm91bmRPZmZzZXRzO1xuICB2YXIgY29tbW9uU3R5bGVzID0ge1xuICAgIHBsYWNlbWVudDogZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpLFxuICAgIHZhcmlhdGlvbjogZ2V0VmFyaWF0aW9uKHN0YXRlLnBsYWNlbWVudCksXG4gICAgcG9wcGVyOiBzdGF0ZS5lbGVtZW50cy5wb3BwZXIsXG4gICAgcG9wcGVyUmVjdDogc3RhdGUucmVjdHMucG9wcGVyLFxuICAgIGdwdUFjY2VsZXJhdGlvbjogZ3B1QWNjZWxlcmF0aW9uLFxuICAgIGlzRml4ZWQ6IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3kgPT09ICdmaXhlZCdcbiAgfTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuc3R5bGVzLnBvcHBlciwgbWFwVG9TdHlsZXMoT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCB7XG4gICAgICBvZmZzZXRzOiBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMsXG4gICAgICBwb3NpdGlvbjogc3RhdGUub3B0aW9ucy5zdHJhdGVneSxcbiAgICAgIGFkYXB0aXZlOiBhZGFwdGl2ZSxcbiAgICAgIHJvdW5kT2Zmc2V0czogcm91bmRPZmZzZXRzXG4gICAgfSkpKTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLmFycm93ICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMuYXJyb3cgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5zdHlsZXMuYXJyb3csIG1hcFRvU3R5bGVzKE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywge1xuICAgICAgb2Zmc2V0czogc3RhdGUubW9kaWZpZXJzRGF0YS5hcnJvdyxcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgYWRhcHRpdmU6IGZhbHNlLFxuICAgICAgcm91bmRPZmZzZXRzOiByb3VuZE9mZnNldHNcbiAgICB9KSkpO1xuICB9XG5cbiAgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5hdHRyaWJ1dGVzLnBvcHBlciwge1xuICAgICdkYXRhLXBvcHBlci1wbGFjZW1lbnQnOiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSk7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdjb21wdXRlU3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdiZWZvcmVXcml0ZScsXG4gIGZuOiBjb21wdXRlU3R5bGVzLFxuICBkYXRhOiB7fVxufTsiLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldFdpbmRvdy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciBwYXNzaXZlID0ge1xuICBwYXNzaXZlOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgaW5zdGFuY2UgPSBfcmVmLmluc3RhbmNlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJHNjcm9sbCA9IG9wdGlvbnMuc2Nyb2xsLFxuICAgICAgc2Nyb2xsID0gX29wdGlvbnMkc2Nyb2xsID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc2Nyb2xsLFxuICAgICAgX29wdGlvbnMkcmVzaXplID0gb3B0aW9ucy5yZXNpemUsXG4gICAgICByZXNpemUgPSBfb3B0aW9ucyRyZXNpemUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRyZXNpemU7XG4gIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coc3RhdGUuZWxlbWVudHMucG9wcGVyKTtcbiAgdmFyIHNjcm9sbFBhcmVudHMgPSBbXS5jb25jYXQoc3RhdGUuc2Nyb2xsUGFyZW50cy5yZWZlcmVuY2UsIHN0YXRlLnNjcm9sbFBhcmVudHMucG9wcGVyKTtcblxuICBpZiAoc2Nyb2xsKSB7XG4gICAgc2Nyb2xsUGFyZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzY3JvbGxQYXJlbnQpIHtcbiAgICAgIHNjcm9sbFBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJlc2l6ZSkge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2Nyb2xsKSB7XG4gICAgICBzY3JvbGxQYXJlbnRzLmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbFBhcmVudCkge1xuICAgICAgICBzY3JvbGxQYXJlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyZXNpemUpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH1cbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2V2ZW50TGlzdGVuZXJzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBmdW5jdGlvbiBmbigpIHt9LFxuICBlZmZlY3Q6IGVmZmVjdCxcbiAgZGF0YToge31cbn07IiwgInZhciBoYXNoID0ge1xuICBsZWZ0OiAncmlnaHQnLFxuICByaWdodDogJ2xlZnQnLFxuICBib3R0b206ICd0b3AnLFxuICB0b3A6ICdib3R0b20nXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvbGVmdHxyaWdodHxib3R0b218dG9wL2csIGZ1bmN0aW9uIChtYXRjaGVkKSB7XG4gICAgcmV0dXJuIGhhc2hbbWF0Y2hlZF07XG4gIH0pO1xufSIsICJ2YXIgaGFzaCA9IHtcbiAgc3RhcnQ6ICdlbmQnLFxuICBlbmQ6ICdzdGFydCdcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5yZXBsYWNlKC9zdGFydHxlbmQvZywgZnVuY3Rpb24gKG1hdGNoZWQpIHtcbiAgICByZXR1cm4gaGFzaFttYXRjaGVkXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRXaW5kb3dTY3JvbGwobm9kZSkge1xuICB2YXIgd2luID0gZ2V0V2luZG93KG5vZGUpO1xuICB2YXIgc2Nyb2xsTGVmdCA9IHdpbi5wYWdlWE9mZnNldDtcbiAgdmFyIHNjcm9sbFRvcCA9IHdpbi5wYWdlWU9mZnNldDtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBzY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogc2Nyb2xsVG9wXG4gIH07XG59IiwgImltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCkge1xuICAvLyBJZiA8aHRtbD4gaGFzIGEgQ1NTIHdpZHRoIGdyZWF0ZXIgdGhhbiB0aGUgdmlld3BvcnQsIHRoZW4gdGhpcyB3aWxsIGJlXG4gIC8vIGluY29ycmVjdCBmb3IgUlRMLlxuICAvLyBQb3BwZXIgMSBpcyBicm9rZW4gaW4gdGhpcyBjYXNlIGFuZCBuZXZlciBoYWQgYSBidWcgcmVwb3J0IHNvIGxldCdzIGFzc3VtZVxuICAvLyBpdCdzIG5vdCBhbiBpc3N1ZS4gSSBkb24ndCB0aGluayBhbnlvbmUgZXZlciBzcGVjaWZpZXMgd2lkdGggb24gPGh0bWw+XG4gIC8vIGFueXdheS5cbiAgLy8gQnJvd3NlcnMgd2hlcmUgdGhlIGxlZnQgc2Nyb2xsYmFyIGRvZXNuJ3QgY2F1c2UgYW4gaXNzdWUgcmVwb3J0IGAwYCBmb3JcbiAgLy8gdGhpcyAoZS5nLiBFZGdlIDIwMTksIElFMTEsIFNhZmFyaSlcbiAgcmV0dXJuIGdldEJvdW5kaW5nQ2xpZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpLmxlZnQgKyBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCkuc2Nyb2xsTGVmdDtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93U2Nyb2xsQmFyWCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpIHtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB2aXN1YWxWaWV3cG9ydCA9IHdpbi52aXN1YWxWaWV3cG9ydDtcbiAgdmFyIHdpZHRoID0gaHRtbC5jbGllbnRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IGh0bWwuY2xpZW50SGVpZ2h0O1xuICB2YXIgeCA9IDA7XG4gIHZhciB5ID0gMDtcblxuICBpZiAodmlzdWFsVmlld3BvcnQpIHtcbiAgICB3aWR0aCA9IHZpc3VhbFZpZXdwb3J0LndpZHRoO1xuICAgIGhlaWdodCA9IHZpc3VhbFZpZXdwb3J0LmhlaWdodDtcbiAgICB2YXIgbGF5b3V0Vmlld3BvcnQgPSBpc0xheW91dFZpZXdwb3J0KCk7XG5cbiAgICBpZiAobGF5b3V0Vmlld3BvcnQgfHwgIWxheW91dFZpZXdwb3J0ICYmIHN0cmF0ZWd5ID09PSAnZml4ZWQnKSB7XG4gICAgICB4ID0gdmlzdWFsVmlld3BvcnQub2Zmc2V0TGVmdDtcbiAgICAgIHkgPSB2aXN1YWxWaWV3cG9ydC5vZmZzZXRUb3A7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgeDogeCArIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCksXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldENvbXB1dGVkU3R5bGUgZnJvbSBcIi4vZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmltcG9ydCB7IG1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7IC8vIEdldHMgdGhlIGVudGlyZSBzaXplIG9mIHRoZSBzY3JvbGxhYmxlIGRvY3VtZW50IGFyZWEsIGV2ZW4gZXh0ZW5kaW5nIG91dHNpZGVcbi8vIG9mIHRoZSBgPGh0bWw+YCBhbmQgYDxib2R5PmAgcmVjdCBib3VuZHMgaWYgaG9yaXpvbnRhbGx5IHNjcm9sbGFibGVcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RG9jdW1lbnRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIF9lbGVtZW50JG93bmVyRG9jdW1lbjtcblxuICB2YXIgaHRtbCA9IGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KTtcbiAgdmFyIHdpblNjcm9sbCA9IGdldFdpbmRvd1Njcm9sbChlbGVtZW50KTtcbiAgdmFyIGJvZHkgPSAoX2VsZW1lbnQkb3duZXJEb2N1bWVuID0gZWxlbWVudC5vd25lckRvY3VtZW50KSA9PSBudWxsID8gdm9pZCAwIDogX2VsZW1lbnQkb3duZXJEb2N1bWVuLmJvZHk7XG4gIHZhciB3aWR0aCA9IG1heChodG1sLnNjcm9sbFdpZHRoLCBodG1sLmNsaWVudFdpZHRoLCBib2R5ID8gYm9keS5zY3JvbGxXaWR0aCA6IDAsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCk7XG4gIHZhciBoZWlnaHQgPSBtYXgoaHRtbC5zY3JvbGxIZWlnaHQsIGh0bWwuY2xpZW50SGVpZ2h0LCBib2R5ID8gYm9keS5zY3JvbGxIZWlnaHQgOiAwLCBib2R5ID8gYm9keS5jbGllbnRIZWlnaHQgOiAwKTtcbiAgdmFyIHggPSAtd2luU2Nyb2xsLnNjcm9sbExlZnQgKyBnZXRXaW5kb3dTY3JvbGxCYXJYKGVsZW1lbnQpO1xuICB2YXIgeSA9IC13aW5TY3JvbGwuc2Nyb2xsVG9wO1xuXG4gIGlmIChnZXRDb21wdXRlZFN0eWxlKGJvZHkgfHwgaHRtbCkuZGlyZWN0aW9uID09PSAncnRsJykge1xuICAgIHggKz0gbWF4KGh0bWwuY2xpZW50V2lkdGgsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCkgLSB3aWR0aDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1Njcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIC8vIEZpcmVmb3ggd2FudHMgdXMgdG8gY2hlY2sgYC14YCBhbmQgYC15YCB2YXJpYXRpb25zIGFzIHdlbGxcbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcbiAgICAgIG92ZXJmbG93ID0gX2dldENvbXB1dGVkU3R5bGUub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1gsXG4gICAgICBvdmVyZmxvd1kgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1k7XG5cbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbi8udGVzdChvdmVyZmxvdyArIG92ZXJmbG93WSArIG92ZXJmbG93WCk7XG59IiwgImltcG9ydCBnZXRQYXJlbnROb2RlIGZyb20gXCIuL2dldFBhcmVudE5vZGUuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0U2Nyb2xsUGFyZW50KG5vZGUpIHtcbiAgaWYgKFsnaHRtbCcsICdib2R5JywgJyNkb2N1bWVudCddLmluZGV4T2YoZ2V0Tm9kZU5hbWUobm9kZSkpID49IDApIHtcbiAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gICAgcmV0dXJuIG5vZGUub3duZXJEb2N1bWVudC5ib2R5O1xuICB9XG5cbiAgaWYgKGlzSFRNTEVsZW1lbnQobm9kZSkgJiYgaXNTY3JvbGxQYXJlbnQobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHJldHVybiBnZXRTY3JvbGxQYXJlbnQoZ2V0UGFyZW50Tm9kZShub2RlKSk7XG59IiwgImltcG9ydCBnZXRTY3JvbGxQYXJlbnQgZnJvbSBcIi4vZ2V0U2Nyb2xsUGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0UGFyZW50Tm9kZSBmcm9tIFwiLi9nZXRQYXJlbnROb2RlLmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGlzU2Nyb2xsUGFyZW50IGZyb20gXCIuL2lzU2Nyb2xsUGFyZW50LmpzXCI7XG4vKlxuZ2l2ZW4gYSBET00gZWxlbWVudCwgcmV0dXJuIHRoZSBsaXN0IG9mIGFsbCBzY3JvbGwgcGFyZW50cywgdXAgdGhlIGxpc3Qgb2YgYW5jZXNvcnNcbnVudGlsIHdlIGdldCB0byB0aGUgdG9wIHdpbmRvdyBvYmplY3QuIFRoaXMgbGlzdCBpcyB3aGF0IHdlIGF0dGFjaCBzY3JvbGwgbGlzdGVuZXJzXG50bywgYmVjYXVzZSBpZiBhbnkgb2YgdGhlc2UgcGFyZW50IGVsZW1lbnRzIHNjcm9sbCwgd2UnbGwgbmVlZCB0byByZS1jYWxjdWxhdGUgdGhlXG5yZWZlcmVuY2UgZWxlbWVudCdzIHBvc2l0aW9uLlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGlzdFNjcm9sbFBhcmVudHMoZWxlbWVudCwgbGlzdCkge1xuICB2YXIgX2VsZW1lbnQkb3duZXJEb2N1bWVuO1xuXG4gIGlmIChsaXN0ID09PSB2b2lkIDApIHtcbiAgICBsaXN0ID0gW107XG4gIH1cblxuICB2YXIgc2Nyb2xsUGFyZW50ID0gZ2V0U2Nyb2xsUGFyZW50KGVsZW1lbnQpO1xuICB2YXIgaXNCb2R5ID0gc2Nyb2xsUGFyZW50ID09PSAoKF9lbGVtZW50JG93bmVyRG9jdW1lbiA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50JG93bmVyRG9jdW1lbi5ib2R5KTtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhzY3JvbGxQYXJlbnQpO1xuICB2YXIgdGFyZ2V0ID0gaXNCb2R5ID8gW3dpbl0uY29uY2F0KHdpbi52aXN1YWxWaWV3cG9ydCB8fCBbXSwgaXNTY3JvbGxQYXJlbnQoc2Nyb2xsUGFyZW50KSA/IHNjcm9sbFBhcmVudCA6IFtdKSA6IHNjcm9sbFBhcmVudDtcbiAgdmFyIHVwZGF0ZWRMaXN0ID0gbGlzdC5jb25jYXQodGFyZ2V0KTtcbiAgcmV0dXJuIGlzQm9keSA/IHVwZGF0ZWRMaXN0IDogLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IGlzQm9keSB0ZWxscyB1cyB0YXJnZXQgd2lsbCBiZSBhbiBIVE1MRWxlbWVudCBoZXJlXG4gIHVwZGF0ZWRMaXN0LmNvbmNhdChsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKHRhcmdldCkpKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZWN0LCB7XG4gICAgbGVmdDogcmVjdC54LFxuICAgIHRvcDogcmVjdC55LFxuICAgIHJpZ2h0OiByZWN0LnggKyByZWN0LndpZHRoLFxuICAgIGJvdHRvbTogcmVjdC55ICsgcmVjdC5oZWlnaHRcbiAgfSk7XG59IiwgImltcG9ydCB7IHZpZXdwb3J0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0Vmlld3BvcnRSZWN0IGZyb20gXCIuL2dldFZpZXdwb3J0UmVjdC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50UmVjdCBmcm9tIFwiLi9nZXREb2N1bWVudFJlY3QuanNcIjtcbmltcG9ydCBsaXN0U2Nyb2xsUGFyZW50cyBmcm9tIFwiLi9saXN0U2Nyb2xsUGFyZW50cy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5pbXBvcnQgeyBpc0VsZW1lbnQsIGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuL2NvbnRhaW5zLmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCByZWN0VG9DbGllbnRSZWN0IGZyb20gXCIuLi91dGlscy9yZWN0VG9DbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgeyBtYXgsIG1pbiB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIGdldElubmVyQm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIHN0cmF0ZWd5KSB7XG4gIHZhciByZWN0ID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIGZhbHNlLCBzdHJhdGVneSA9PT0gJ2ZpeGVkJyk7XG4gIHJlY3QudG9wID0gcmVjdC50b3AgKyBlbGVtZW50LmNsaWVudFRvcDtcbiAgcmVjdC5sZWZ0ID0gcmVjdC5sZWZ0ICsgZWxlbWVudC5jbGllbnRMZWZ0O1xuICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgZWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gIHJlY3QucmlnaHQgPSByZWN0LmxlZnQgKyBlbGVtZW50LmNsaWVudFdpZHRoO1xuICByZWN0LndpZHRoID0gZWxlbWVudC5jbGllbnRXaWR0aDtcbiAgcmVjdC5oZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgcmVjdC54ID0gcmVjdC5sZWZ0O1xuICByZWN0LnkgPSByZWN0LnRvcDtcbiAgcmV0dXJuIHJlY3Q7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGNsaXBwaW5nUGFyZW50LCBzdHJhdGVneSkge1xuICByZXR1cm4gY2xpcHBpbmdQYXJlbnQgPT09IHZpZXdwb3J0ID8gcmVjdFRvQ2xpZW50UmVjdChnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpKSA6IGlzRWxlbWVudChjbGlwcGluZ1BhcmVudCkgPyBnZXRJbm5lckJvdW5kaW5nQ2xpZW50UmVjdChjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpIDogcmVjdFRvQ2xpZW50UmVjdChnZXREb2N1bWVudFJlY3QoZ2V0RG9jdW1lbnRFbGVtZW50KGVsZW1lbnQpKSk7XG59IC8vIEEgXCJjbGlwcGluZyBwYXJlbnRcIiBpcyBhbiBvdmVyZmxvd2FibGUgY29udGFpbmVyIHdpdGggdGhlIGNoYXJhY3RlcmlzdGljIG9mXG4vLyBjbGlwcGluZyAob3IgaGlkaW5nKSBvdmVyZmxvd2luZyBlbGVtZW50cyB3aXRoIGEgcG9zaXRpb24gZGlmZmVyZW50IGZyb21cbi8vIGBpbml0aWFsYFxuXG5cbmZ1bmN0aW9uIGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSB7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKGVsZW1lbnQpKTtcbiAgdmFyIGNhbkVzY2FwZUNsaXBwaW5nID0gWydhYnNvbHV0ZScsICdmaXhlZCddLmluZGV4T2YoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbikgPj0gMDtcbiAgdmFyIGNsaXBwZXJFbGVtZW50ID0gY2FuRXNjYXBlQ2xpcHBpbmcgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSA/IGdldE9mZnNldFBhcmVudChlbGVtZW50KSA6IGVsZW1lbnQ7XG5cbiAgaWYgKCFpc0VsZW1lbnQoY2xpcHBlckVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXJldHVybl06IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8xNDE0XG5cblxuICByZXR1cm4gY2xpcHBpbmdQYXJlbnRzLmZpbHRlcihmdW5jdGlvbiAoY2xpcHBpbmdQYXJlbnQpIHtcbiAgICByZXR1cm4gaXNFbGVtZW50KGNsaXBwaW5nUGFyZW50KSAmJiBjb250YWlucyhjbGlwcGluZ1BhcmVudCwgY2xpcHBlckVsZW1lbnQpICYmIGdldE5vZGVOYW1lKGNsaXBwaW5nUGFyZW50KSAhPT0gJ2JvZHknO1xuICB9KTtcbn0gLy8gR2V0cyB0aGUgbWF4aW11bSBhcmVhIHRoYXQgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBpbiBkdWUgdG8gYW55IG51bWJlciBvZlxuLy8gY2xpcHBpbmcgcGFyZW50c1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENsaXBwaW5nUmVjdChlbGVtZW50LCBib3VuZGFyeSwgcm9vdEJvdW5kYXJ5LCBzdHJhdGVneSkge1xuICB2YXIgbWFpbkNsaXBwaW5nUGFyZW50cyA9IGJvdW5kYXJ5ID09PSAnY2xpcHBpbmdQYXJlbnRzJyA/IGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSA6IFtdLmNvbmNhdChib3VuZGFyeSk7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBbXS5jb25jYXQobWFpbkNsaXBwaW5nUGFyZW50cywgW3Jvb3RCb3VuZGFyeV0pO1xuICB2YXIgZmlyc3RDbGlwcGluZ1BhcmVudCA9IGNsaXBwaW5nUGFyZW50c1swXTtcbiAgdmFyIGNsaXBwaW5nUmVjdCA9IGNsaXBwaW5nUGFyZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjY1JlY3QsIGNsaXBwaW5nUGFyZW50KSB7XG4gICAgdmFyIHJlY3QgPSBnZXRDbGllbnRSZWN0RnJvbU1peGVkVHlwZShlbGVtZW50LCBjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpO1xuICAgIGFjY1JlY3QudG9wID0gbWF4KHJlY3QudG9wLCBhY2NSZWN0LnRvcCk7XG4gICAgYWNjUmVjdC5yaWdodCA9IG1pbihyZWN0LnJpZ2h0LCBhY2NSZWN0LnJpZ2h0KTtcbiAgICBhY2NSZWN0LmJvdHRvbSA9IG1pbihyZWN0LmJvdHRvbSwgYWNjUmVjdC5ib3R0b20pO1xuICAgIGFjY1JlY3QubGVmdCA9IG1heChyZWN0LmxlZnQsIGFjY1JlY3QubGVmdCk7XG4gICAgcmV0dXJuIGFjY1JlY3Q7XG4gIH0sIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGZpcnN0Q2xpcHBpbmdQYXJlbnQsIHN0cmF0ZWd5KSk7XG4gIGNsaXBwaW5nUmVjdC53aWR0aCA9IGNsaXBwaW5nUmVjdC5yaWdodCAtIGNsaXBwaW5nUmVjdC5sZWZ0O1xuICBjbGlwcGluZ1JlY3QuaGVpZ2h0ID0gY2xpcHBpbmdSZWN0LmJvdHRvbSAtIGNsaXBwaW5nUmVjdC50b3A7XG4gIGNsaXBwaW5nUmVjdC54ID0gY2xpcHBpbmdSZWN0LmxlZnQ7XG4gIGNsaXBwaW5nUmVjdC55ID0gY2xpcHBpbmdSZWN0LnRvcDtcbiAgcmV0dXJuIGNsaXBwaW5nUmVjdDtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4vZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQsIHN0YXJ0LCBlbmQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbXB1dGVPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHJlZmVyZW5jZSA9IF9yZWYucmVmZXJlbmNlLFxuICAgICAgZWxlbWVudCA9IF9yZWYuZWxlbWVudCxcbiAgICAgIHBsYWNlbWVudCA9IF9yZWYucGxhY2VtZW50O1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IHBsYWNlbWVudCA/IGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciB2YXJpYXRpb24gPSBwbGFjZW1lbnQgPyBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciBjb21tb25YID0gcmVmZXJlbmNlLnggKyByZWZlcmVuY2Uud2lkdGggLyAyIC0gZWxlbWVudC53aWR0aCAvIDI7XG4gIHZhciBjb21tb25ZID0gcmVmZXJlbmNlLnkgKyByZWZlcmVuY2UuaGVpZ2h0IC8gMiAtIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgdmFyIG9mZnNldHM7XG5cbiAgc3dpdGNoIChiYXNlUGxhY2VtZW50KSB7XG4gICAgY2FzZSB0b3A6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiBjb21tb25YLFxuICAgICAgICB5OiByZWZlcmVuY2UueSAtIGVsZW1lbnQuaGVpZ2h0XG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGJvdHRvbTpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IGNvbW1vblgsXG4gICAgICAgIHk6IHJlZmVyZW5jZS55ICsgcmVmZXJlbmNlLmhlaWdodFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSByaWdodDpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IHJlZmVyZW5jZS54ICsgcmVmZXJlbmNlLndpZHRoLFxuICAgICAgICB5OiBjb21tb25ZXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGxlZnQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCAtIGVsZW1lbnQud2lkdGgsXG4gICAgICAgIHk6IGNvbW1vbllcbiAgICAgIH07XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCxcbiAgICAgICAgeTogcmVmZXJlbmNlLnlcbiAgICAgIH07XG4gIH1cblxuICB2YXIgbWFpbkF4aXMgPSBiYXNlUGxhY2VtZW50ID8gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpIDogbnVsbDtcblxuICBpZiAobWFpbkF4aXMgIT0gbnVsbCkge1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuXG4gICAgc3dpdGNoICh2YXJpYXRpb24pIHtcbiAgICAgIGNhc2Ugc3RhcnQ6XG4gICAgICAgIG9mZnNldHNbbWFpbkF4aXNdID0gb2Zmc2V0c1ttYWluQXhpc10gLSAocmVmZXJlbmNlW2xlbl0gLyAyIC0gZWxlbWVudFtsZW5dIC8gMik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIGVuZDpcbiAgICAgICAgb2Zmc2V0c1ttYWluQXhpc10gPSBvZmZzZXRzW21haW5BeGlzXSArIChyZWZlcmVuY2VbbGVuXSAvIDIgLSBlbGVtZW50W2xlbl0gLyAyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9mZnNldHM7XG59IiwgImltcG9ydCBnZXRDbGlwcGluZ1JlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4vcmVjdFRvQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IHsgY2xpcHBpbmdQYXJlbnRzLCByZWZlcmVuY2UsIHBvcHBlciwgYm90dG9tLCB0b3AsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4vZXhwYW5kVG9IYXNoTWFwLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBfb3B0aW9ucyRwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/IHN0YXRlLnBsYWNlbWVudCA6IF9vcHRpb25zJHBsYWNlbWVudCxcbiAgICAgIF9vcHRpb25zJHN0cmF0ZWd5ID0gX29wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBzdHJhdGVneSA9IF9vcHRpb25zJHN0cmF0ZWd5ID09PSB2b2lkIDAgPyBzdGF0ZS5zdHJhdGVneSA6IF9vcHRpb25zJHN0cmF0ZWd5LFxuICAgICAgX29wdGlvbnMkYm91bmRhcnkgPSBfb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMkYm91bmRhcnkgPT09IHZvaWQgMCA/IGNsaXBwaW5nUGFyZW50cyA6IF9vcHRpb25zJGJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyB2aWV3cG9ydCA6IF9vcHRpb25zJHJvb3RCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGVsZW1lbnRDb250ZSA9IF9vcHRpb25zLmVsZW1lbnRDb250ZXh0LFxuICAgICAgZWxlbWVudENvbnRleHQgPSBfb3B0aW9ucyRlbGVtZW50Q29udGUgPT09IHZvaWQgMCA/IHBvcHBlciA6IF9vcHRpb25zJGVsZW1lbnRDb250ZSxcbiAgICAgIF9vcHRpb25zJGFsdEJvdW5kYXJ5ID0gX29wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IF9vcHRpb25zJGFsdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyBmYWxzZSA6IF9vcHRpb25zJGFsdEJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMkcGFkZGluZyA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHBhZGRpbmc7XG4gIHZhciBwYWRkaW5nT2JqZWN0ID0gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbiAgdmFyIGFsdENvbnRleHQgPSBlbGVtZW50Q29udGV4dCA9PT0gcG9wcGVyID8gcmVmZXJlbmNlIDogcG9wcGVyO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGVsZW1lbnQgPSBzdGF0ZS5lbGVtZW50c1thbHRCb3VuZGFyeSA/IGFsdENvbnRleHQgOiBlbGVtZW50Q29udGV4dF07XG4gIHZhciBjbGlwcGluZ0NsaWVudFJlY3QgPSBnZXRDbGlwcGluZ1JlY3QoaXNFbGVtZW50KGVsZW1lbnQpID8gZWxlbWVudCA6IGVsZW1lbnQuY29udGV4dEVsZW1lbnQgfHwgZ2V0RG9jdW1lbnRFbGVtZW50KHN0YXRlLmVsZW1lbnRzLnBvcHBlciksIGJvdW5kYXJ5LCByb290Qm91bmRhcnksIHN0cmF0ZWd5KTtcbiAgdmFyIHJlZmVyZW5jZUNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qoc3RhdGUuZWxlbWVudHMucmVmZXJlbmNlKTtcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyh7XG4gICAgcmVmZXJlbmNlOiByZWZlcmVuY2VDbGllbnRSZWN0LFxuICAgIGVsZW1lbnQ6IHBvcHBlclJlY3QsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSk7XG4gIHZhciBwb3BwZXJDbGllbnRSZWN0ID0gcmVjdFRvQ2xpZW50UmVjdChPYmplY3QuYXNzaWduKHt9LCBwb3BwZXJSZWN0LCBwb3BwZXJPZmZzZXRzKSk7XG4gIHZhciBlbGVtZW50Q2xpZW50UmVjdCA9IGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgPyBwb3BwZXJDbGllbnRSZWN0IDogcmVmZXJlbmNlQ2xpZW50UmVjdDsgLy8gcG9zaXRpdmUgPSBvdmVyZmxvd2luZyB0aGUgY2xpcHBpbmcgcmVjdFxuICAvLyAwIG9yIG5lZ2F0aXZlID0gd2l0aGluIHRoZSBjbGlwcGluZyByZWN0XG5cbiAgdmFyIG92ZXJmbG93T2Zmc2V0cyA9IHtcbiAgICB0b3A6IGNsaXBwaW5nQ2xpZW50UmVjdC50b3AgLSBlbGVtZW50Q2xpZW50UmVjdC50b3AgKyBwYWRkaW5nT2JqZWN0LnRvcCxcbiAgICBib3R0b206IGVsZW1lbnRDbGllbnRSZWN0LmJvdHRvbSAtIGNsaXBwaW5nQ2xpZW50UmVjdC5ib3R0b20gKyBwYWRkaW5nT2JqZWN0LmJvdHRvbSxcbiAgICBsZWZ0OiBjbGlwcGluZ0NsaWVudFJlY3QubGVmdCAtIGVsZW1lbnRDbGllbnRSZWN0LmxlZnQgKyBwYWRkaW5nT2JqZWN0LmxlZnQsXG4gICAgcmlnaHQ6IGVsZW1lbnRDbGllbnRSZWN0LnJpZ2h0IC0gY2xpcHBpbmdDbGllbnRSZWN0LnJpZ2h0ICsgcGFkZGluZ09iamVjdC5yaWdodFxuICB9O1xuICB2YXIgb2Zmc2V0RGF0YSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0OyAvLyBPZmZzZXRzIGNhbiBiZSBhcHBsaWVkIG9ubHkgdG8gdGhlIHBvcHBlciBlbGVtZW50XG5cbiAgaWYgKGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgJiYgb2Zmc2V0RGF0YSkge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXREYXRhW3BsYWNlbWVudF07XG4gICAgT2JqZWN0LmtleXMob3ZlcmZsb3dPZmZzZXRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciBtdWx0aXBseSA9IFtyaWdodCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/IDEgOiAtMTtcbiAgICAgIHZhciBheGlzID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/ICd5JyA6ICd4JztcbiAgICAgIG92ZXJmbG93T2Zmc2V0c1trZXldICs9IG9mZnNldFtheGlzXSAqIG11bHRpcGx5O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG92ZXJmbG93T2Zmc2V0cztcbn0iLCAiaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHZhcmlhdGlvblBsYWNlbWVudHMsIGJhc2VQbGFjZW1lbnRzLCBwbGFjZW1lbnRzIGFzIGFsbFBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29tcHV0ZUF1dG9QbGFjZW1lbnQoc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBib3VuZGFyeSA9IF9vcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zLmZsaXBWYXJpYXRpb25zLFxuICAgICAgX29wdGlvbnMkYWxsb3dlZEF1dG9QID0gX29wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzLFxuICAgICAgYWxsb3dlZEF1dG9QbGFjZW1lbnRzID0gX29wdGlvbnMkYWxsb3dlZEF1dG9QID09PSB2b2lkIDAgPyBhbGxQbGFjZW1lbnRzIDogX29wdGlvbnMkYWxsb3dlZEF1dG9QO1xuICB2YXIgdmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCk7XG4gIHZhciBwbGFjZW1lbnRzID0gdmFyaWF0aW9uID8gZmxpcFZhcmlhdGlvbnMgPyB2YXJpYXRpb25QbGFjZW1lbnRzIDogdmFyaWF0aW9uUGxhY2VtZW50cy5maWx0ZXIoZnVuY3Rpb24gKHBsYWNlbWVudCkge1xuICAgIHJldHVybiBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gdmFyaWF0aW9uO1xuICB9KSA6IGJhc2VQbGFjZW1lbnRzO1xuICB2YXIgYWxsb3dlZFBsYWNlbWVudHMgPSBwbGFjZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIGFsbG93ZWRBdXRvUGxhY2VtZW50cy5pbmRleE9mKHBsYWNlbWVudCkgPj0gMDtcbiAgfSk7XG5cbiAgaWYgKGFsbG93ZWRQbGFjZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGFsbG93ZWRQbGFjZW1lbnRzID0gcGxhY2VtZW50cztcbiAgfSAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS10eXBlXTogRmxvdyBzZWVtcyB0byBoYXZlIHByb2JsZW1zIHdpdGggdHdvIGFycmF5IHVuaW9ucy4uLlxuXG5cbiAgdmFyIG92ZXJmbG93cyA9IGFsbG93ZWRQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICBhY2NbcGxhY2VtZW50XSA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZ1xuICAgIH0pW2dldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KV07XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICByZXR1cm4gT2JqZWN0LmtleXMob3ZlcmZsb3dzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIG92ZXJmbG93c1thXSAtIG92ZXJmbG93c1tiXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRPcHBvc2l0ZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0T3Bwb3NpdGVQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgY29tcHV0ZUF1dG9QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2NvbXB1dGVBdXRvUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyBib3R0b20sIHRvcCwgc3RhcnQsIHJpZ2h0LCBsZWZ0LCBhdXRvIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5mdW5jdGlvbiBnZXRFeHBhbmRlZEZhbGxiYWNrUGxhY2VtZW50cyhwbGFjZW1lbnQpIHtcbiAgaWYgKGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0bykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBvcHBvc2l0ZVBsYWNlbWVudCA9IGdldE9wcG9zaXRlUGxhY2VtZW50KHBsYWNlbWVudCk7XG4gIHJldHVybiBbZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQocGxhY2VtZW50KSwgb3Bwb3NpdGVQbGFjZW1lbnQsIGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KG9wcG9zaXRlUGxhY2VtZW50KV07XG59XG5cbmZ1bmN0aW9uIGZsaXAoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG5cbiAgaWYgKHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0uX3NraXApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgX29wdGlvbnMkbWFpbkF4aXMgPSBvcHRpb25zLm1haW5BeGlzLFxuICAgICAgY2hlY2tNYWluQXhpcyA9IF9vcHRpb25zJG1haW5BeGlzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkbWFpbkF4aXMsXG4gICAgICBfb3B0aW9ucyRhbHRBeGlzID0gb3B0aW9ucy5hbHRBeGlzLFxuICAgICAgY2hlY2tBbHRBeGlzID0gX29wdGlvbnMkYWx0QXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGFsdEF4aXMsXG4gICAgICBzcGVjaWZpZWRGYWxsYmFja1BsYWNlbWVudHMgPSBvcHRpb25zLmZhbGxiYWNrUGxhY2VtZW50cyxcbiAgICAgIHBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmcsXG4gICAgICBib3VuZGFyeSA9IG9wdGlvbnMuYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnkgPSBvcHRpb25zLnJvb3RCb3VuZGFyeSxcbiAgICAgIGFsdEJvdW5kYXJ5ID0gb3B0aW9ucy5hbHRCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9IG9wdGlvbnMuZmxpcFZhcmlhdGlvbnMsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGZsaXBWYXJpYXRpbyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50cyA9IG9wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzO1xuICB2YXIgcHJlZmVycmVkUGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwcmVmZXJyZWRQbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gYmFzZVBsYWNlbWVudCA9PT0gcHJlZmVycmVkUGxhY2VtZW50O1xuICB2YXIgZmFsbGJhY2tQbGFjZW1lbnRzID0gc3BlY2lmaWVkRmFsbGJhY2tQbGFjZW1lbnRzIHx8IChpc0Jhc2VQbGFjZW1lbnQgfHwgIWZsaXBWYXJpYXRpb25zID8gW2dldE9wcG9zaXRlUGxhY2VtZW50KHByZWZlcnJlZFBsYWNlbWVudCldIDogZ2V0RXhwYW5kZWRGYWxsYmFja1BsYWNlbWVudHMocHJlZmVycmVkUGxhY2VtZW50KSk7XG4gIHZhciBwbGFjZW1lbnRzID0gW3ByZWZlcnJlZFBsYWNlbWVudF0uY29uY2F0KGZhbGxiYWNrUGxhY2VtZW50cykucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0byA/IGNvbXB1dGVBdXRvUGxhY2VtZW50KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZyxcbiAgICAgIGZsaXBWYXJpYXRpb25zOiBmbGlwVmFyaWF0aW9ucyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50czogYWxsb3dlZEF1dG9QbGFjZW1lbnRzXG4gICAgfSkgOiBwbGFjZW1lbnQpO1xuICB9LCBbXSk7XG4gIHZhciByZWZlcmVuY2VSZWN0ID0gc3RhdGUucmVjdHMucmVmZXJlbmNlO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGNoZWNrc01hcCA9IG5ldyBNYXAoKTtcbiAgdmFyIG1ha2VGYWxsYmFja0NoZWNrcyA9IHRydWU7XG4gIHZhciBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBwbGFjZW1lbnRzWzBdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGxhY2VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwbGFjZW1lbnQgPSBwbGFjZW1lbnRzW2ldO1xuXG4gICAgdmFyIF9iYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuXG4gICAgdmFyIGlzU3RhcnRWYXJpYXRpb24gPSBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gc3RhcnQ7XG4gICAgdmFyIGlzVmVydGljYWwgPSBbdG9wLCBib3R0b21dLmluZGV4T2YoX2Jhc2VQbGFjZW1lbnQpID49IDA7XG4gICAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG4gICAgdmFyIG92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICAgIHBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeTogYWx0Qm91bmRhcnksXG4gICAgICBwYWRkaW5nOiBwYWRkaW5nXG4gICAgfSk7XG4gICAgdmFyIG1haW5WYXJpYXRpb25TaWRlID0gaXNWZXJ0aWNhbCA/IGlzU3RhcnRWYXJpYXRpb24gPyByaWdodCA6IGxlZnQgOiBpc1N0YXJ0VmFyaWF0aW9uID8gYm90dG9tIDogdG9wO1xuXG4gICAgaWYgKHJlZmVyZW5jZVJlY3RbbGVuXSA+IHBvcHBlclJlY3RbbGVuXSkge1xuICAgICAgbWFpblZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgfVxuXG4gICAgdmFyIGFsdFZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgdmFyIGNoZWNrcyA9IFtdO1xuXG4gICAgaWYgKGNoZWNrTWFpbkF4aXMpIHtcbiAgICAgIGNoZWNrcy5wdXNoKG92ZXJmbG93W19iYXNlUGxhY2VtZW50XSA8PSAwKTtcbiAgICB9XG5cbiAgICBpZiAoY2hlY2tBbHRBeGlzKSB7XG4gICAgICBjaGVja3MucHVzaChvdmVyZmxvd1ttYWluVmFyaWF0aW9uU2lkZV0gPD0gMCwgb3ZlcmZsb3dbYWx0VmFyaWF0aW9uU2lkZV0gPD0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrcy5ldmVyeShmdW5jdGlvbiAoY2hlY2spIHtcbiAgICAgIHJldHVybiBjaGVjaztcbiAgICB9KSkge1xuICAgICAgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50O1xuICAgICAgbWFrZUZhbGxiYWNrQ2hlY2tzID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjaGVja3NNYXAuc2V0KHBsYWNlbWVudCwgY2hlY2tzKTtcbiAgfVxuXG4gIGlmIChtYWtlRmFsbGJhY2tDaGVja3MpIHtcbiAgICAvLyBgMmAgbWF5IGJlIGRlc2lyZWQgaW4gc29tZSBjYXNlcyBcdTIwMTMgcmVzZWFyY2ggbGF0ZXJcbiAgICB2YXIgbnVtYmVyT2ZDaGVja3MgPSBmbGlwVmFyaWF0aW9ucyA/IDMgOiAxO1xuXG4gICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoX2kpIHtcbiAgICAgIHZhciBmaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50cy5maW5kKGZ1bmN0aW9uIChwbGFjZW1lbnQpIHtcbiAgICAgICAgdmFyIGNoZWNrcyA9IGNoZWNrc01hcC5nZXQocGxhY2VtZW50KTtcblxuICAgICAgICBpZiAoY2hlY2tzKSB7XG4gICAgICAgICAgcmV0dXJuIGNoZWNrcy5zbGljZSgwLCBfaSkuZXZlcnkoZnVuY3Rpb24gKGNoZWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZml0dGluZ1BsYWNlbWVudCkge1xuICAgICAgICBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBmaXR0aW5nUGxhY2VtZW50O1xuICAgICAgICByZXR1cm4gXCJicmVha1wiO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKHZhciBfaSA9IG51bWJlck9mQ2hlY2tzOyBfaSA+IDA7IF9pLS0pIHtcbiAgICAgIHZhciBfcmV0ID0gX2xvb3AoX2kpO1xuXG4gICAgICBpZiAoX3JldCA9PT0gXCJicmVha1wiKSBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUucGxhY2VtZW50ICE9PSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdLl9za2lwID0gdHJ1ZTtcbiAgICBzdGF0ZS5wbGFjZW1lbnQgPSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQ7XG4gICAgc3RhdGUucmVzZXQgPSB0cnVlO1xuICB9XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdmbGlwJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgZm46IGZsaXAsXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J10sXG4gIGRhdGE6IHtcbiAgICBfc2tpcDogZmFsc2VcbiAgfVxufTsiLCAiaW1wb3J0IHsgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFNpZGVPZmZzZXRzKG92ZXJmbG93LCByZWN0LCBwcmV2ZW50ZWRPZmZzZXRzKSB7XG4gIGlmIChwcmV2ZW50ZWRPZmZzZXRzID09PSB2b2lkIDApIHtcbiAgICBwcmV2ZW50ZWRPZmZzZXRzID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IG92ZXJmbG93LnRvcCAtIHJlY3QuaGVpZ2h0IC0gcHJldmVudGVkT2Zmc2V0cy55LFxuICAgIHJpZ2h0OiBvdmVyZmxvdy5yaWdodCAtIHJlY3Qud2lkdGggKyBwcmV2ZW50ZWRPZmZzZXRzLngsXG4gICAgYm90dG9tOiBvdmVyZmxvdy5ib3R0b20gLSByZWN0LmhlaWdodCArIHByZXZlbnRlZE9mZnNldHMueSxcbiAgICBsZWZ0OiBvdmVyZmxvdy5sZWZ0IC0gcmVjdC53aWR0aCAtIHByZXZlbnRlZE9mZnNldHMueFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0FueVNpZGVGdWxseUNsaXBwZWQob3ZlcmZsb3cpIHtcbiAgcmV0dXJuIFt0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRdLnNvbWUoZnVuY3Rpb24gKHNpZGUpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dbc2lkZV0gPj0gMDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhpZGUoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgcHJldmVudGVkT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucHJldmVudE92ZXJmbG93O1xuICB2YXIgcmVmZXJlbmNlT3ZlcmZsb3cgPSBkZXRlY3RPdmVyZmxvdyhzdGF0ZSwge1xuICAgIGVsZW1lbnRDb250ZXh0OiAncmVmZXJlbmNlJ1xuICB9KTtcbiAgdmFyIHBvcHBlckFsdE92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBhbHRCb3VuZGFyeTogdHJ1ZVxuICB9KTtcbiAgdmFyIHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyA9IGdldFNpZGVPZmZzZXRzKHJlZmVyZW5jZU92ZXJmbG93LCByZWZlcmVuY2VSZWN0KTtcbiAgdmFyIHBvcHBlckVzY2FwZU9mZnNldHMgPSBnZXRTaWRlT2Zmc2V0cyhwb3BwZXJBbHRPdmVyZmxvdywgcG9wcGVyUmVjdCwgcHJldmVudGVkT2Zmc2V0cyk7XG4gIHZhciBpc1JlZmVyZW5jZUhpZGRlbiA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMpO1xuICB2YXIgaGFzUG9wcGVyRXNjYXBlZCA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChwb3BwZXJFc2NhcGVPZmZzZXRzKTtcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IHtcbiAgICByZWZlcmVuY2VDbGlwcGluZ09mZnNldHM6IHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyxcbiAgICBwb3BwZXJFc2NhcGVPZmZzZXRzOiBwb3BwZXJFc2NhcGVPZmZzZXRzLFxuICAgIGlzUmVmZXJlbmNlSGlkZGVuOiBpc1JlZmVyZW5jZUhpZGRlbixcbiAgICBoYXNQb3BwZXJFc2NhcGVkOiBoYXNQb3BwZXJFc2NhcGVkXG4gIH07XG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcmVmZXJlbmNlLWhpZGRlbic6IGlzUmVmZXJlbmNlSGlkZGVuLFxuICAgICdkYXRhLXBvcHBlci1lc2NhcGVkJzogaGFzUG9wcGVyRXNjYXBlZFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2hpZGUnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ3ByZXZlbnRPdmVyZmxvdyddLFxuICBmbjogaGlkZVxufTsiLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIHBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2VBbmRTa2lkZGluZ1RvWFkocGxhY2VtZW50LCByZWN0cywgb2Zmc2V0KSB7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICB2YXIgaW52ZXJ0RGlzdGFuY2UgPSBbbGVmdCwgdG9wXS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDAgPyAtMSA6IDE7XG5cbiAgdmFyIF9yZWYgPSB0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gb2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSkpIDogb2Zmc2V0LFxuICAgICAgc2tpZGRpbmcgPSBfcmVmWzBdLFxuICAgICAgZGlzdGFuY2UgPSBfcmVmWzFdO1xuXG4gIHNraWRkaW5nID0gc2tpZGRpbmcgfHwgMDtcbiAgZGlzdGFuY2UgPSAoZGlzdGFuY2UgfHwgMCkgKiBpbnZlcnREaXN0YW5jZTtcbiAgcmV0dXJuIFtsZWZ0LCByaWdodF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSA+PSAwID8ge1xuICAgIHg6IGRpc3RhbmNlLFxuICAgIHk6IHNraWRkaW5nXG4gIH0gOiB7XG4gICAgeDogc2tpZGRpbmcsXG4gICAgeTogZGlzdGFuY2VcbiAgfTtcbn1cblxuZnVuY3Rpb24gb2Zmc2V0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZjIubmFtZTtcbiAgdmFyIF9vcHRpb25zJG9mZnNldCA9IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgb2Zmc2V0ID0gX29wdGlvbnMkb2Zmc2V0ID09PSB2b2lkIDAgPyBbMCwgMF0gOiBfb3B0aW9ucyRvZmZzZXQ7XG4gIHZhciBkYXRhID0gcGxhY2VtZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGxhY2VtZW50KSB7XG4gICAgYWNjW3BsYWNlbWVudF0gPSBkaXN0YW5jZUFuZFNraWRkaW5nVG9YWShwbGFjZW1lbnQsIHN0YXRlLnJlY3RzLCBvZmZzZXQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgdmFyIF9kYXRhJHN0YXRlJHBsYWNlbWVudCA9IGRhdGFbc3RhdGUucGxhY2VtZW50XSxcbiAgICAgIHggPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueCxcbiAgICAgIHkgPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMueCArPSB4O1xuICAgIHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cy55ICs9IHk7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ29mZnNldCcsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgZm46IG9mZnNldFxufTsiLCAiaW1wb3J0IGNvbXB1dGVPZmZzZXRzIGZyb20gXCIuLi91dGlscy9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuXG5mdW5jdGlvbiBwb3BwZXJPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG4gIC8vIE9mZnNldHMgYXJlIHRoZSBhY3R1YWwgcG9zaXRpb24gdGhlIHBvcHBlciBuZWVkcyB0byBoYXZlIHRvIGJlXG4gIC8vIHByb3Blcmx5IHBvc2l0aW9uZWQgbmVhciBpdHMgcmVmZXJlbmNlIGVsZW1lbnRcbiAgLy8gVGhpcyBpcyB0aGUgbW9zdCBiYXNpYyBwbGFjZW1lbnQsIGFuZCB3aWxsIGJlIGFkanVzdGVkIGJ5XG4gIC8vIHRoZSBtb2RpZmllcnMgaW4gdGhlIG5leHQgc3RlcFxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gY29tcHV0ZU9mZnNldHMoe1xuICAgIHJlZmVyZW5jZTogc3RhdGUucmVjdHMucmVmZXJlbmNlLFxuICAgIGVsZW1lbnQ6IHN0YXRlLnJlY3RzLnBvcHBlcixcbiAgICBzdHJhdGVneTogJ2Fic29sdXRlJyxcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3BvcHBlck9mZnNldHMnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ3JlYWQnLFxuICBmbjogcG9wcGVyT2Zmc2V0cyxcbiAgZGF0YToge31cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFsdEF4aXMoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xufSIsICJpbXBvcnQgeyB0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHN0YXJ0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0QWx0QXhpcyBmcm9tIFwiLi4vdXRpbHMvZ2V0QWx0QXhpcy5qc1wiO1xuaW1wb3J0IHsgd2l0aGluLCB3aXRoaW5NYXhDbGFtcCB9IGZyb20gXCIuLi91dGlscy93aXRoaW4uanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuLi91dGlscy9nZXRGcmVzaFNpZGVPYmplY3QuanNcIjtcbmltcG9ydCB7IG1pbiBhcyBtYXRoTWluLCBtYXggYXMgbWF0aE1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIHByZXZlbnRPdmVyZmxvdyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZi5vcHRpb25zLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIF9vcHRpb25zJG1haW5BeGlzID0gb3B0aW9ucy5tYWluQXhpcyxcbiAgICAgIGNoZWNrTWFpbkF4aXMgPSBfb3B0aW9ucyRtYWluQXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJG1haW5BeGlzLFxuICAgICAgX29wdGlvbnMkYWx0QXhpcyA9IG9wdGlvbnMuYWx0QXhpcyxcbiAgICAgIGNoZWNrQWx0QXhpcyA9IF9vcHRpb25zJGFsdEF4aXMgPT09IHZvaWQgMCA/IGZhbHNlIDogX29wdGlvbnMkYWx0QXhpcyxcbiAgICAgIGJvdW5kYXJ5ID0gb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeSA9IG9wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnkgPSBvcHRpb25zLmFsdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IG9wdGlvbnMucGFkZGluZyxcbiAgICAgIF9vcHRpb25zJHRldGhlciA9IG9wdGlvbnMudGV0aGVyLFxuICAgICAgdGV0aGVyID0gX29wdGlvbnMkdGV0aGVyID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkdGV0aGVyLFxuICAgICAgX29wdGlvbnMkdGV0aGVyT2Zmc2V0ID0gb3B0aW9ucy50ZXRoZXJPZmZzZXQsXG4gICAgICB0ZXRoZXJPZmZzZXQgPSBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQgPT09IHZvaWQgMCA/IDAgOiBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQ7XG4gIHZhciBvdmVyZmxvdyA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgYWx0Qm91bmRhcnk6IGFsdEJvdW5kYXJ5XG4gIH0pO1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQoc3RhdGUucGxhY2VtZW50KTtcbiAgdmFyIHZhcmlhdGlvbiA9IGdldFZhcmlhdGlvbihzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gIXZhcmlhdGlvbjtcbiAgdmFyIG1haW5BeGlzID0gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpO1xuICB2YXIgYWx0QXhpcyA9IGdldEFsdEF4aXMobWFpbkF4aXMpO1xuICB2YXIgcG9wcGVyT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cztcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgdGV0aGVyT2Zmc2V0VmFsdWUgPSB0eXBlb2YgdGV0aGVyT2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gdGV0aGVyT2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSkpIDogdGV0aGVyT2Zmc2V0O1xuICB2YXIgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlID0gdHlwZW9mIHRldGhlck9mZnNldFZhbHVlID09PSAnbnVtYmVyJyA/IHtcbiAgICBtYWluQXhpczogdGV0aGVyT2Zmc2V0VmFsdWUsXG4gICAgYWx0QXhpczogdGV0aGVyT2Zmc2V0VmFsdWVcbiAgfSA6IE9iamVjdC5hc3NpZ24oe1xuICAgIG1haW5BeGlzOiAwLFxuICAgIGFsdEF4aXM6IDBcbiAgfSwgdGV0aGVyT2Zmc2V0VmFsdWUpO1xuICB2YXIgb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0ID8gc3RhdGUubW9kaWZpZXJzRGF0YS5vZmZzZXRbc3RhdGUucGxhY2VtZW50XSA6IG51bGw7XG4gIHZhciBkYXRhID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmICghcG9wcGVyT2Zmc2V0cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjaGVja01haW5BeGlzKSB7XG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclN0YXRlJDtcblxuICAgIHZhciBtYWluU2lkZSA9IG1haW5BeGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICAgIHZhciBhbHRTaWRlID0gbWFpbkF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICAgIHZhciBvZmZzZXQgPSBwb3BwZXJPZmZzZXRzW21haW5BeGlzXTtcbiAgICB2YXIgbWluID0gb2Zmc2V0ICsgb3ZlcmZsb3dbbWFpblNpZGVdO1xuICAgIHZhciBtYXggPSBvZmZzZXQgLSBvdmVyZmxvd1thbHRTaWRlXTtcbiAgICB2YXIgYWRkaXRpdmUgPSB0ZXRoZXIgPyAtcG9wcGVyUmVjdFtsZW5dIC8gMiA6IDA7XG4gICAgdmFyIG1pbkxlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gOiBwb3BwZXJSZWN0W2xlbl07XG4gICAgdmFyIG1heExlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyAtcG9wcGVyUmVjdFtsZW5dIDogLXJlZmVyZW5jZVJlY3RbbGVuXTsgLy8gV2UgbmVlZCB0byBpbmNsdWRlIHRoZSBhcnJvdyBpbiB0aGUgY2FsY3VsYXRpb24gc28gdGhlIGFycm93IGRvZXNuJ3QgZ29cbiAgICAvLyBvdXRzaWRlIHRoZSByZWZlcmVuY2UgYm91bmRzXG5cbiAgICB2YXIgYXJyb3dFbGVtZW50ID0gc3RhdGUuZWxlbWVudHMuYXJyb3c7XG4gICAgdmFyIGFycm93UmVjdCA9IHRldGhlciAmJiBhcnJvd0VsZW1lbnQgPyBnZXRMYXlvdXRSZWN0KGFycm93RWxlbWVudCkgOiB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMFxuICAgIH07XG4gICAgdmFyIGFycm93UGFkZGluZ09iamVjdCA9IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXSA/IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXS5wYWRkaW5nIDogZ2V0RnJlc2hTaWRlT2JqZWN0KCk7XG4gICAgdmFyIGFycm93UGFkZGluZ01pbiA9IGFycm93UGFkZGluZ09iamVjdFttYWluU2lkZV07XG4gICAgdmFyIGFycm93UGFkZGluZ01heCA9IGFycm93UGFkZGluZ09iamVjdFthbHRTaWRlXTsgLy8gSWYgdGhlIHJlZmVyZW5jZSBsZW5ndGggaXMgc21hbGxlciB0aGFuIHRoZSBhcnJvdyBsZW5ndGgsIHdlIGRvbid0IHdhbnRcbiAgICAvLyB0byBpbmNsdWRlIGl0cyBmdWxsIHNpemUgaW4gdGhlIGNhbGN1bGF0aW9uLiBJZiB0aGUgcmVmZXJlbmNlIGlzIHNtYWxsXG4gICAgLy8gYW5kIG5lYXIgdGhlIGVkZ2Ugb2YgYSBib3VuZGFyeSwgdGhlIHBvcHBlciBjYW4gb3ZlcmZsb3cgZXZlbiBpZiB0aGVcbiAgICAvLyByZWZlcmVuY2UgaXMgbm90IG92ZXJmbG93aW5nIGFzIHdlbGwgKGUuZy4gdmlydHVhbCBlbGVtZW50cyB3aXRoIG5vXG4gICAgLy8gd2lkdGggb3IgaGVpZ2h0KVxuXG4gICAgdmFyIGFycm93TGVuID0gd2l0aGluKDAsIHJlZmVyZW5jZVJlY3RbbGVuXSwgYXJyb3dSZWN0W2xlbl0pO1xuICAgIHZhciBtaW5PZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gLyAyIC0gYWRkaXRpdmUgLSBhcnJvd0xlbiAtIGFycm93UGFkZGluZ01pbiAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcyA6IG1pbkxlbiAtIGFycm93TGVuIC0gYXJyb3dQYWRkaW5nTWluIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzO1xuICAgIHZhciBtYXhPZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyAtcmVmZXJlbmNlUmVjdFtsZW5dIC8gMiArIGFkZGl0aXZlICsgYXJyb3dMZW4gKyBhcnJvd1BhZGRpbmdNYXggKyBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUubWFpbkF4aXMgOiBtYXhMZW4gKyBhcnJvd0xlbiArIGFycm93UGFkZGluZ01heCArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcztcbiAgICB2YXIgYXJyb3dPZmZzZXRQYXJlbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdyAmJiBnZXRPZmZzZXRQYXJlbnQoc3RhdGUuZWxlbWVudHMuYXJyb3cpO1xuICAgIHZhciBjbGllbnRPZmZzZXQgPSBhcnJvd09mZnNldFBhcmVudCA/IG1haW5BeGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRUb3AgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudExlZnQgfHwgMCA6IDA7XG4gICAgdmFyIG9mZnNldE1vZGlmaWVyVmFsdWUgPSAoX29mZnNldE1vZGlmaWVyU3RhdGUkID0gb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9PSBudWxsID8gdm9pZCAwIDogb2Zmc2V0TW9kaWZpZXJTdGF0ZVttYWluQXhpc10pICE9IG51bGwgPyBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQgOiAwO1xuICAgIHZhciB0ZXRoZXJNaW4gPSBvZmZzZXQgKyBtaW5PZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlIC0gY2xpZW50T2Zmc2V0O1xuICAgIHZhciB0ZXRoZXJNYXggPSBvZmZzZXQgKyBtYXhPZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlO1xuICAgIHZhciBwcmV2ZW50ZWRPZmZzZXQgPSB3aXRoaW4odGV0aGVyID8gbWF0aE1pbihtaW4sIHRldGhlck1pbikgOiBtaW4sIG9mZnNldCwgdGV0aGVyID8gbWF0aE1heChtYXgsIHRldGhlck1heCkgOiBtYXgpO1xuICAgIHBvcHBlck9mZnNldHNbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0O1xuICAgIGRhdGFbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0IC0gb2Zmc2V0O1xuICB9XG5cbiAgaWYgKGNoZWNrQWx0QXhpcykge1xuICAgIHZhciBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyO1xuXG4gICAgdmFyIF9tYWluU2lkZSA9IG1haW5BeGlzID09PSAneCcgPyB0b3AgOiBsZWZ0O1xuXG4gICAgdmFyIF9hbHRTaWRlID0gbWFpbkF4aXMgPT09ICd4JyA/IGJvdHRvbSA6IHJpZ2h0O1xuXG4gICAgdmFyIF9vZmZzZXQgPSBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdO1xuXG4gICAgdmFyIF9sZW4gPSBhbHRBeGlzID09PSAneScgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgICB2YXIgX21pbiA9IF9vZmZzZXQgKyBvdmVyZmxvd1tfbWFpblNpZGVdO1xuXG4gICAgdmFyIF9tYXggPSBfb2Zmc2V0IC0gb3ZlcmZsb3dbX2FsdFNpZGVdO1xuXG4gICAgdmFyIGlzT3JpZ2luU2lkZSA9IFt0b3AsIGxlZnRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgIT09IC0xO1xuXG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclZhbHVlID0gKF9vZmZzZXRNb2RpZmllclN0YXRlJDIgPSBvZmZzZXRNb2RpZmllclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBvZmZzZXRNb2RpZmllclN0YXRlW2FsdEF4aXNdKSAhPSBudWxsID8gX29mZnNldE1vZGlmaWVyU3RhdGUkMiA6IDA7XG5cbiAgICB2YXIgX3RldGhlck1pbiA9IGlzT3JpZ2luU2lkZSA/IF9taW4gOiBfb2Zmc2V0IC0gcmVmZXJlbmNlUmVjdFtfbGVuXSAtIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzO1xuXG4gICAgdmFyIF90ZXRoZXJNYXggPSBpc09yaWdpblNpZGUgPyBfb2Zmc2V0ICsgcmVmZXJlbmNlUmVjdFtfbGVuXSArIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzIDogX21heDtcblxuICAgIHZhciBfcHJldmVudGVkT2Zmc2V0ID0gdGV0aGVyICYmIGlzT3JpZ2luU2lkZSA/IHdpdGhpbk1heENsYW1wKF90ZXRoZXJNaW4sIF9vZmZzZXQsIF90ZXRoZXJNYXgpIDogd2l0aGluKHRldGhlciA/IF90ZXRoZXJNaW4gOiBfbWluLCBfb2Zmc2V0LCB0ZXRoZXIgPyBfdGV0aGVyTWF4IDogX21heCk7XG5cbiAgICBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldDtcbiAgICBkYXRhW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldCAtIF9vZmZzZXQ7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBwcmV2ZW50T3ZlcmZsb3csXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J11cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEhUTUxFbGVtZW50U2Nyb2xsKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBlbGVtZW50LnNjcm9sbExlZnQsXG4gICAgc2Nyb2xsVG9wOiBlbGVtZW50LnNjcm9sbFRvcFxuICB9O1xufSIsICJpbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0SFRNTEVsZW1lbnRTY3JvbGwgZnJvbSBcIi4vZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVTY3JvbGwobm9kZSkge1xuICBpZiAobm9kZSA9PT0gZ2V0V2luZG93KG5vZGUpIHx8ICFpc0hUTUxFbGVtZW50KG5vZGUpKSB7XG4gICAgcmV0dXJuIGdldFdpbmRvd1Njcm9sbChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2V0SFRNTEVsZW1lbnRTY3JvbGwobm9kZSk7XG4gIH1cbn0iLCAiaW1wb3J0IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBmcm9tIFwiLi9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBnZXROb2RlU2Nyb2xsIGZyb20gXCIuL2dldE5vZGVTY3JvbGwuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgaXNTY3JvbGxQYXJlbnQgZnJvbSBcIi4vaXNTY3JvbGxQYXJlbnQuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50U2NhbGVkKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB2YXIgc2NhbGVYID0gcm91bmQocmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDE7XG4gIHZhciBzY2FsZVkgPSByb3VuZChyZWN0LmhlaWdodCkgLyBlbGVtZW50Lm9mZnNldEhlaWdodCB8fCAxO1xuICByZXR1cm4gc2NhbGVYICE9PSAxIHx8IHNjYWxlWSAhPT0gMTtcbn0gLy8gUmV0dXJucyB0aGUgY29tcG9zaXRlIHJlY3Qgb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byBpdHMgb2Zmc2V0UGFyZW50LlxuLy8gQ29tcG9zaXRlIG1lYW5zIGl0IHRha2VzIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zIGFzIHdlbGwgYXMgbGF5b3V0LlxuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbXBvc2l0ZVJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudCwgaXNGaXhlZCkge1xuICBpZiAoaXNGaXhlZCA9PT0gdm9pZCAwKSB7XG4gICAgaXNGaXhlZCA9IGZhbHNlO1xuICB9XG5cbiAgdmFyIGlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ID0gaXNIVE1MRWxlbWVudChvZmZzZXRQYXJlbnQpO1xuICB2YXIgb2Zmc2V0UGFyZW50SXNTY2FsZWQgPSBpc0hUTUxFbGVtZW50KG9mZnNldFBhcmVudCkgJiYgaXNFbGVtZW50U2NhbGVkKG9mZnNldFBhcmVudCk7XG4gIHZhciBkb2N1bWVudEVsZW1lbnQgPSBnZXREb2N1bWVudEVsZW1lbnQob2Zmc2V0UGFyZW50KTtcbiAgdmFyIHJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudElzU2NhbGVkLCBpc0ZpeGVkKTtcbiAgdmFyIHNjcm9sbCA9IHtcbiAgICBzY3JvbGxMZWZ0OiAwLFxuICAgIHNjcm9sbFRvcDogMFxuICB9O1xuICB2YXIgb2Zmc2V0cyA9IHtcbiAgICB4OiAwLFxuICAgIHk6IDBcbiAgfTtcblxuICBpZiAoaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgfHwgIWlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ICYmICFpc0ZpeGVkKSB7XG4gICAgaWYgKGdldE5vZGVOYW1lKG9mZnNldFBhcmVudCkgIT09ICdib2R5JyB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEwNzhcbiAgICBpc1Njcm9sbFBhcmVudChkb2N1bWVudEVsZW1lbnQpKSB7XG4gICAgICBzY3JvbGwgPSBnZXROb2RlU2Nyb2xsKG9mZnNldFBhcmVudCk7XG4gICAgfVxuXG4gICAgaWYgKGlzSFRNTEVsZW1lbnQob2Zmc2V0UGFyZW50KSkge1xuICAgICAgb2Zmc2V0cyA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChvZmZzZXRQYXJlbnQsIHRydWUpO1xuICAgICAgb2Zmc2V0cy54ICs9IG9mZnNldFBhcmVudC5jbGllbnRMZWZ0O1xuICAgICAgb2Zmc2V0cy55ICs9IG9mZnNldFBhcmVudC5jbGllbnRUb3A7XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIG9mZnNldHMueCA9IGdldFdpbmRvd1Njcm9sbEJhclgoZG9jdW1lbnRFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IHJlY3QubGVmdCArIHNjcm9sbC5zY3JvbGxMZWZ0IC0gb2Zmc2V0cy54LFxuICAgIHk6IHJlY3QudG9wICsgc2Nyb2xsLnNjcm9sbFRvcCAtIG9mZnNldHMueSxcbiAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IG1vZGlmaWVyUGhhc2VzIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7IC8vIHNvdXJjZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDk4NzUyNTVcblxuZnVuY3Rpb24gb3JkZXIobW9kaWZpZXJzKSB7XG4gIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gIHZhciB2aXNpdGVkID0gbmV3IFNldCgpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIG1hcC5zZXQobW9kaWZpZXIubmFtZSwgbW9kaWZpZXIpO1xuICB9KTsgLy8gT24gdmlzaXRpbmcgb2JqZWN0LCBjaGVjayBmb3IgaXRzIGRlcGVuZGVuY2llcyBhbmQgdmlzaXQgdGhlbSByZWN1cnNpdmVseVxuXG4gIGZ1bmN0aW9uIHNvcnQobW9kaWZpZXIpIHtcbiAgICB2aXNpdGVkLmFkZChtb2RpZmllci5uYW1lKTtcbiAgICB2YXIgcmVxdWlyZXMgPSBbXS5jb25jYXQobW9kaWZpZXIucmVxdWlyZXMgfHwgW10sIG1vZGlmaWVyLnJlcXVpcmVzSWZFeGlzdHMgfHwgW10pO1xuICAgIHJlcXVpcmVzLmZvckVhY2goZnVuY3Rpb24gKGRlcCkge1xuICAgICAgaWYgKCF2aXNpdGVkLmhhcyhkZXApKSB7XG4gICAgICAgIHZhciBkZXBNb2RpZmllciA9IG1hcC5nZXQoZGVwKTtcblxuICAgICAgICBpZiAoZGVwTW9kaWZpZXIpIHtcbiAgICAgICAgICBzb3J0KGRlcE1vZGlmaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJlc3VsdC5wdXNoKG1vZGlmaWVyKTtcbiAgfVxuXG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIGlmICghdmlzaXRlZC5oYXMobW9kaWZpZXIubmFtZSkpIHtcbiAgICAgIC8vIGNoZWNrIGZvciB2aXNpdGVkIG9iamVjdFxuICAgICAgc29ydChtb2RpZmllcik7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb3JkZXJNb2RpZmllcnMobW9kaWZpZXJzKSB7XG4gIC8vIG9yZGVyIGJhc2VkIG9uIGRlcGVuZGVuY2llc1xuICB2YXIgb3JkZXJlZE1vZGlmaWVycyA9IG9yZGVyKG1vZGlmaWVycyk7IC8vIG9yZGVyIGJhc2VkIG9uIHBoYXNlXG5cbiAgcmV0dXJuIG1vZGlmaWVyUGhhc2VzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwaGFzZSkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KG9yZGVyZWRNb2RpZmllcnMuZmlsdGVyKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgICAgcmV0dXJuIG1vZGlmaWVyLnBoYXNlID09PSBwaGFzZTtcbiAgICB9KSk7XG4gIH0sIFtdKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVib3VuY2UoZm4pIHtcbiAgdmFyIHBlbmRpbmc7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcGVuZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXNvbHZlKGZuKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufSIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtZXJnZUJ5TmFtZShtb2RpZmllcnMpIHtcbiAgdmFyIG1lcmdlZCA9IG1vZGlmaWVycy5yZWR1Y2UoZnVuY3Rpb24gKG1lcmdlZCwgY3VycmVudCkge1xuICAgIHZhciBleGlzdGluZyA9IG1lcmdlZFtjdXJyZW50Lm5hbWVdO1xuICAgIG1lcmdlZFtjdXJyZW50Lm5hbWVdID0gZXhpc3RpbmcgPyBPYmplY3QuYXNzaWduKHt9LCBleGlzdGluZywgY3VycmVudCwge1xuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgZXhpc3Rpbmcub3B0aW9ucywgY3VycmVudC5vcHRpb25zKSxcbiAgICAgIGRhdGE6IE9iamVjdC5hc3NpZ24oe30sIGV4aXN0aW5nLmRhdGEsIGN1cnJlbnQuZGF0YSlcbiAgICB9KSA6IGN1cnJlbnQ7XG4gICAgcmV0dXJuIG1lcmdlZDtcbiAgfSwge30pOyAvLyBJRTExIGRvZXMgbm90IHN1cHBvcnQgT2JqZWN0LnZhbHVlc1xuXG4gIHJldHVybiBPYmplY3Qua2V5cyhtZXJnZWQpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIG1lcmdlZFtrZXldO1xuICB9KTtcbn0iLCAiaW1wb3J0IGdldENvbXBvc2l0ZVJlY3QgZnJvbSBcIi4vZG9tLXV0aWxzL2dldENvbXBvc2l0ZVJlY3QuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgbGlzdFNjcm9sbFBhcmVudHMgZnJvbSBcIi4vZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBvcmRlck1vZGlmaWVycyBmcm9tIFwiLi91dGlscy9vcmRlck1vZGlmaWVycy5qc1wiO1xuaW1wb3J0IGRlYm91bmNlIGZyb20gXCIuL3V0aWxzL2RlYm91bmNlLmpzXCI7XG5pbXBvcnQgbWVyZ2VCeU5hbWUgZnJvbSBcIi4vdXRpbHMvbWVyZ2VCeU5hbWUuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IHsgaXNFbGVtZW50IH0gZnJvbSBcIi4vZG9tLXV0aWxzL2luc3RhbmNlT2YuanNcIjtcbnZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gIHBsYWNlbWVudDogJ2JvdHRvbScsXG4gIG1vZGlmaWVyczogW10sXG4gIHN0cmF0ZWd5OiAnYWJzb2x1dGUnXG59O1xuXG5mdW5jdGlvbiBhcmVWYWxpZEVsZW1lbnRzKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuICFhcmdzLnNvbWUoZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gIShlbGVtZW50ICYmIHR5cGVvZiBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCA9PT0gJ2Z1bmN0aW9uJyk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcG9wcGVyR2VuZXJhdG9yKGdlbmVyYXRvck9wdGlvbnMpIHtcbiAgaWYgKGdlbmVyYXRvck9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIGdlbmVyYXRvck9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfZ2VuZXJhdG9yT3B0aW9ucyA9IGdlbmVyYXRvck9wdGlvbnMsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYgPSBfZ2VuZXJhdG9yT3B0aW9ucy5kZWZhdWx0TW9kaWZpZXJzLFxuICAgICAgZGVmYXVsdE1vZGlmaWVycyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZiA9PT0gdm9pZCAwID8gW10gOiBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyID0gX2dlbmVyYXRvck9wdGlvbnMuZGVmYXVsdE9wdGlvbnMsXG4gICAgICBkZWZhdWx0T3B0aW9ucyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZjIgPT09IHZvaWQgMCA/IERFRkFVTFRfT1BUSU9OUyA6IF9nZW5lcmF0b3JPcHRpb25zJGRlZjI7XG4gIHJldHVybiBmdW5jdGlvbiBjcmVhdGVQb3BwZXIocmVmZXJlbmNlLCBwb3BwZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgICBvcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG4gICAgfVxuXG4gICAgdmFyIHN0YXRlID0ge1xuICAgICAgcGxhY2VtZW50OiAnYm90dG9tJyxcbiAgICAgIG9yZGVyZWRNb2RpZmllcnM6IFtdLFxuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBkZWZhdWx0T3B0aW9ucyksXG4gICAgICBtb2RpZmllcnNEYXRhOiB7fSxcbiAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgIHJlZmVyZW5jZTogcmVmZXJlbmNlLFxuICAgICAgICBwb3BwZXI6IHBvcHBlclxuICAgICAgfSxcbiAgICAgIGF0dHJpYnV0ZXM6IHt9LFxuICAgICAgc3R5bGVzOiB7fVxuICAgIH07XG4gICAgdmFyIGVmZmVjdENsZWFudXBGbnMgPSBbXTtcbiAgICB2YXIgaXNEZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB2YXIgaW5zdGFuY2UgPSB7XG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICBzZXRPcHRpb25zOiBmdW5jdGlvbiBzZXRPcHRpb25zKHNldE9wdGlvbnNBY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygc2V0T3B0aW9uc0FjdGlvbiA9PT0gJ2Z1bmN0aW9uJyA/IHNldE9wdGlvbnNBY3Rpb24oc3RhdGUub3B0aW9ucykgOiBzZXRPcHRpb25zQWN0aW9uO1xuICAgICAgICBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHN0YXRlLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0T3B0aW9ucywgc3RhdGUub3B0aW9ucywgb3B0aW9ucyk7XG4gICAgICAgIHN0YXRlLnNjcm9sbFBhcmVudHMgPSB7XG4gICAgICAgICAgcmVmZXJlbmNlOiBpc0VsZW1lbnQocmVmZXJlbmNlKSA/IGxpc3RTY3JvbGxQYXJlbnRzKHJlZmVyZW5jZSkgOiByZWZlcmVuY2UuY29udGV4dEVsZW1lbnQgPyBsaXN0U2Nyb2xsUGFyZW50cyhyZWZlcmVuY2UuY29udGV4dEVsZW1lbnQpIDogW10sXG4gICAgICAgICAgcG9wcGVyOiBsaXN0U2Nyb2xsUGFyZW50cyhwb3BwZXIpXG4gICAgICAgIH07IC8vIE9yZGVycyB0aGUgbW9kaWZpZXJzIGJhc2VkIG9uIHRoZWlyIGRlcGVuZGVuY2llcyBhbmQgYHBoYXNlYFxuICAgICAgICAvLyBwcm9wZXJ0aWVzXG5cbiAgICAgICAgdmFyIG9yZGVyZWRNb2RpZmllcnMgPSBvcmRlck1vZGlmaWVycyhtZXJnZUJ5TmFtZShbXS5jb25jYXQoZGVmYXVsdE1vZGlmaWVycywgc3RhdGUub3B0aW9ucy5tb2RpZmllcnMpKSk7IC8vIFN0cmlwIG91dCBkaXNhYmxlZCBtb2RpZmllcnNcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzID0gb3JkZXJlZE1vZGlmaWVycy5maWx0ZXIoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICByZXR1cm4gbS5lbmFibGVkO1xuICAgICAgICB9KTtcbiAgICAgICAgcnVuTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZS51cGRhdGUoKTtcbiAgICAgIH0sXG4gICAgICAvLyBTeW5jIHVwZGF0ZSBcdTIwMTMgaXQgd2lsbCBhbHdheXMgYmUgZXhlY3V0ZWQsIGV2ZW4gaWYgbm90IG5lY2Vzc2FyeS4gVGhpc1xuICAgICAgLy8gaXMgdXNlZnVsIGZvciBsb3cgZnJlcXVlbmN5IHVwZGF0ZXMgd2hlcmUgc3luYyBiZWhhdmlvciBzaW1wbGlmaWVzIHRoZVxuICAgICAgLy8gbG9naWMuXG4gICAgICAvLyBGb3IgaGlnaCBmcmVxdWVuY3kgdXBkYXRlcyAoZS5nLiBgcmVzaXplYCBhbmQgYHNjcm9sbGAgZXZlbnRzKSwgYWx3YXlzXG4gICAgICAvLyBwcmVmZXIgdGhlIGFzeW5jIFBvcHBlciN1cGRhdGUgbWV0aG9kXG4gICAgICBmb3JjZVVwZGF0ZTogZnVuY3Rpb24gZm9yY2VVcGRhdGUoKSB7XG4gICAgICAgIGlmIChpc0Rlc3Ryb3llZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfc3RhdGUkZWxlbWVudHMgPSBzdGF0ZS5lbGVtZW50cyxcbiAgICAgICAgICAgIHJlZmVyZW5jZSA9IF9zdGF0ZSRlbGVtZW50cy5yZWZlcmVuY2UsXG4gICAgICAgICAgICBwb3BwZXIgPSBfc3RhdGUkZWxlbWVudHMucG9wcGVyOyAvLyBEb24ndCBwcm9jZWVkIGlmIGByZWZlcmVuY2VgIG9yIGBwb3BwZXJgIGFyZSBub3QgdmFsaWQgZWxlbWVudHNcbiAgICAgICAgLy8gYW55bW9yZVxuXG4gICAgICAgIGlmICghYXJlVmFsaWRFbGVtZW50cyhyZWZlcmVuY2UsIHBvcHBlcikpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gU3RvcmUgdGhlIHJlZmVyZW5jZSBhbmQgcG9wcGVyIHJlY3RzIHRvIGJlIHJlYWQgYnkgbW9kaWZpZXJzXG5cblxuICAgICAgICBzdGF0ZS5yZWN0cyA9IHtcbiAgICAgICAgICByZWZlcmVuY2U6IGdldENvbXBvc2l0ZVJlY3QocmVmZXJlbmNlLCBnZXRPZmZzZXRQYXJlbnQocG9wcGVyKSwgc3RhdGUub3B0aW9ucy5zdHJhdGVneSA9PT0gJ2ZpeGVkJyksXG4gICAgICAgICAgcG9wcGVyOiBnZXRMYXlvdXRSZWN0KHBvcHBlcilcbiAgICAgICAgfTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gcmVzZXQgdGhlIGN1cnJlbnQgdXBkYXRlIGN5Y2xlLiBUaGVcbiAgICAgICAgLy8gbW9zdCBjb21tb24gdXNlIGNhc2UgZm9yIHRoaXMgaXMgdGhlIGBmbGlwYCBtb2RpZmllciBjaGFuZ2luZyB0aGVcbiAgICAgICAgLy8gcGxhY2VtZW50LCB3aGljaCB0aGVuIG5lZWRzIHRvIHJlLXJ1biBhbGwgdGhlIG1vZGlmaWVycywgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gbG9naWMgd2FzIHByZXZpb3VzbHkgcmFuIGZvciB0aGUgcHJldmlvdXMgcGxhY2VtZW50IGFuZCBpcyB0aGVyZWZvcmVcbiAgICAgICAgLy8gc3RhbGUvaW5jb3JyZWN0XG5cbiAgICAgICAgc3RhdGUucmVzZXQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7IC8vIE9uIGVhY2ggdXBkYXRlIGN5Y2xlLCB0aGUgYG1vZGlmaWVyc0RhdGFgIHByb3BlcnR5IGZvciBlYWNoIG1vZGlmaWVyXG4gICAgICAgIC8vIGlzIGZpbGxlZCB3aXRoIHRoZSBpbml0aWFsIGRhdGEgc3BlY2lmaWVkIGJ5IHRoZSBtb2RpZmllci4gVGhpcyBtZWFuc1xuICAgICAgICAvLyBpdCBkb2Vzbid0IHBlcnNpc3QgYW5kIGlzIGZyZXNoIG9uIGVhY2ggdXBkYXRlLlxuICAgICAgICAvLyBUbyBlbnN1cmUgcGVyc2lzdGVudCBkYXRhLCB1c2UgYCR7bmFtZX0jcGVyc2lzdGVudGBcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKG1vZGlmaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIHN0YXRlLm1vZGlmaWVyc0RhdGFbbW9kaWZpZXIubmFtZV0gPSBPYmplY3QuYXNzaWduKHt9LCBtb2RpZmllci5kYXRhKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRlLm9yZGVyZWRNb2RpZmllcnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgaWYgKHN0YXRlLnJlc2V0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBzdGF0ZS5yZXNldCA9IGZhbHNlO1xuICAgICAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfc3RhdGUkb3JkZXJlZE1vZGlmaWUgPSBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzW2luZGV4XSxcbiAgICAgICAgICAgICAgZm4gPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUuZm4sXG4gICAgICAgICAgICAgIF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUub3B0aW9ucyxcbiAgICAgICAgICAgICAgX29wdGlvbnMgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyID09PSB2b2lkIDAgPyB7fSA6IF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIsXG4gICAgICAgICAgICAgIG5hbWUgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUubmFtZTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHN0YXRlID0gZm4oe1xuICAgICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICAgIG9wdGlvbnM6IF9vcHRpb25zLFxuICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2VcbiAgICAgICAgICAgIH0pIHx8IHN0YXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIEFzeW5jIGFuZCBvcHRpbWlzdGljYWxseSBvcHRpbWl6ZWQgdXBkYXRlIFx1MjAxMyBpdCB3aWxsIG5vdCBiZSBleGVjdXRlZCBpZlxuICAgICAgLy8gbm90IG5lY2Vzc2FyeSAoZGVib3VuY2VkIHRvIHJ1biBhdCBtb3N0IG9uY2UtcGVyLXRpY2spXG4gICAgICB1cGRhdGU6IGRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICByZXNvbHZlKHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKTtcbiAgICAgICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgaW5zdGFuY2Uuc2V0T3B0aW9ucyhvcHRpb25zKS50aGVuKGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgaWYgKCFpc0Rlc3Ryb3llZCAmJiBvcHRpb25zLm9uRmlyc3RVcGRhdGUpIHtcbiAgICAgICAgb3B0aW9ucy5vbkZpcnN0VXBkYXRlKHN0YXRlKTtcbiAgICAgIH1cbiAgICB9KTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gZXhlY3V0ZSBhcmJpdHJhcnkgY29kZSBiZWZvcmUgdGhlIGZpcnN0XG4gICAgLy8gdXBkYXRlIGN5Y2xlIHJ1bnMuIFRoZXkgd2lsbCBiZSBleGVjdXRlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgdXBkYXRlXG4gICAgLy8gY3ljbGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gYSBtb2RpZmllciBhZGRzIHNvbWUgcGVyc2lzdGVudCBkYXRhIHRoYXRcbiAgICAvLyBvdGhlciBtb2RpZmllcnMgbmVlZCB0byB1c2UsIGJ1dCB0aGUgbW9kaWZpZXIgaXMgcnVuIGFmdGVyIHRoZSBkZXBlbmRlbnRcbiAgICAvLyBvbmUuXG5cbiAgICBmdW5jdGlvbiBydW5Nb2RpZmllckVmZmVjdHMoKSB7XG4gICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgICAgdmFyIG5hbWUgPSBfcmVmLm5hbWUsXG4gICAgICAgICAgICBfcmVmJG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICAgICAgICBvcHRpb25zID0gX3JlZiRvcHRpb25zID09PSB2b2lkIDAgPyB7fSA6IF9yZWYkb3B0aW9ucyxcbiAgICAgICAgICAgIGVmZmVjdCA9IF9yZWYuZWZmZWN0O1xuXG4gICAgICAgIGlmICh0eXBlb2YgZWZmZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdmFyIGNsZWFudXBGbiA9IGVmZmVjdCh7XG4gICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgaW5zdGFuY2U6IGluc3RhbmNlLFxuICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdmFyIG5vb3BGbiA9IGZ1bmN0aW9uIG5vb3BGbigpIHt9O1xuXG4gICAgICAgICAgZWZmZWN0Q2xlYW51cEZucy5wdXNoKGNsZWFudXBGbiB8fCBub29wRm4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCkge1xuICAgICAgZWZmZWN0Q2xlYW51cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgIH0pO1xuICAgICAgZWZmZWN0Q2xlYW51cEZucyA9IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfTtcbn1cbmV4cG9ydCB2YXIgY3JlYXRlUG9wcGVyID0gLyojX19QVVJFX18qL3BvcHBlckdlbmVyYXRvcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCB7IGRldGVjdE92ZXJmbG93IH07IiwgImltcG9ydCB7IHBvcHBlckdlbmVyYXRvciwgZGV0ZWN0T3ZlcmZsb3cgfSBmcm9tIFwiLi9jcmVhdGVQb3BwZXIuanNcIjtcbmltcG9ydCBldmVudExpc3RlbmVycyBmcm9tIFwiLi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanNcIjtcbmltcG9ydCBwb3BwZXJPZmZzZXRzIGZyb20gXCIuL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzXCI7XG5pbXBvcnQgY29tcHV0ZVN0eWxlcyBmcm9tIFwiLi9tb2RpZmllcnMvY29tcHV0ZVN0eWxlcy5qc1wiO1xuaW1wb3J0IGFwcGx5U3R5bGVzIGZyb20gXCIuL21vZGlmaWVycy9hcHBseVN0eWxlcy5qc1wiO1xuaW1wb3J0IG9mZnNldCBmcm9tIFwiLi9tb2RpZmllcnMvb2Zmc2V0LmpzXCI7XG5pbXBvcnQgZmxpcCBmcm9tIFwiLi9tb2RpZmllcnMvZmxpcC5qc1wiO1xuaW1wb3J0IHByZXZlbnRPdmVyZmxvdyBmcm9tIFwiLi9tb2RpZmllcnMvcHJldmVudE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgYXJyb3cgZnJvbSBcIi4vbW9kaWZpZXJzL2Fycm93LmpzXCI7XG5pbXBvcnQgaGlkZSBmcm9tIFwiLi9tb2RpZmllcnMvaGlkZS5qc1wiO1xudmFyIGRlZmF1bHRNb2RpZmllcnMgPSBbZXZlbnRMaXN0ZW5lcnMsIHBvcHBlck9mZnNldHMsIGNvbXB1dGVTdHlsZXMsIGFwcGx5U3R5bGVzLCBvZmZzZXQsIGZsaXAsIHByZXZlbnRPdmVyZmxvdywgYXJyb3csIGhpZGVdO1xudmFyIGNyZWF0ZVBvcHBlciA9IC8qI19fUFVSRV9fKi9wb3BwZXJHZW5lcmF0b3Ioe1xuICBkZWZhdWx0TW9kaWZpZXJzOiBkZWZhdWx0TW9kaWZpZXJzXG59KTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIsIHBvcHBlckdlbmVyYXRvciwgZGVmYXVsdE1vZGlmaWVycywgZGV0ZWN0T3ZlcmZsb3cgfTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIgYXMgY3JlYXRlUG9wcGVyTGl0ZSB9IGZyb20gXCIuL3BvcHBlci1saXRlLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0ICogZnJvbSBcIi4vbW9kaWZpZXJzL2luZGV4LmpzXCI7IiwgIi8vIFRoYW5rcyB0byBAbWdtZXllcnMgZm9yIHRoZSBjcmVhdGluZyB0aGUgb2JzaWRpYW4ga2FuYmFuIHBsdWdpbiBodHRwczovL2dpdGh1Yi5jb20vbWdtZXllcnMvb2JzaWRpYW4ta2FuYmFuXHJcbi8vIGZyb20gd2hlcmUgSSBnb3QgdGhlIHRlbXBsYXRlIGNvZGUgZm9yIHRoaXMgcGx1Z2luXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tZ21leWVycy9vYnNpZGlhbi1rYW5iYW4vYmxvYi80OGU2YzI3OGNlOTE0MGI3ZTAzNGIxODE0MzIzMjFmNjk3ZDZlNDVlL3NyYy9jb21wb25lbnRzL2hlbHBlcnMudHNcclxuXHJcbmltcG9ydCB7IFRGaWxlLCBBcHAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwbHlUZW1wbGF0ZShcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLFxyXG5cdGZpbGU6IFRGaWxlLFxyXG5cdHRlbXBsYXRlUGF0aD86IHN0cmluZ1xyXG4pIHtcclxuXHRjb25zdCB0ZW1wbGF0ZUZpbGUgPSB0ZW1wbGF0ZVBhdGhcclxuXHRcdD8gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGVtcGxhdGVQYXRoKVxyXG5cdFx0OiBudWxsO1xyXG5cclxuXHRpZiAodGVtcGxhdGVGaWxlICYmIHRlbXBsYXRlRmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHR0cnkge1xyXG5cclxuXHRcdFx0Y29uc3Qge1xyXG5cdFx0XHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHRcdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdFx0XHR0ZW1wbGF0ZXNQbHVnaW4sXHJcblx0XHRcdFx0dGVtcGxhdGVyUGx1Z2luLFxyXG5cdFx0XHR9ID0gZ2V0VGVtcGxhdGVQbHVnaW5zKHBsdWdpbi5hcHApO1xyXG5cdFx0XHRjb25zdCB0ZW1wbGF0ZUNvbnRlbnQgPSBhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlYWQodGVtcGxhdGVGaWxlKTtcclxuXHJcblx0XHRcdC8vIElmIGJvdGggcGx1Z2lucyBhcmUgZW5hYmxlZCwgYXR0ZW1wdCB0byBkZXRlY3QgdGVtcGxhdGVyIGZpcnN0XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCAmJiB0ZW1wbGF0ZXJFbmFibGVkKSB7XHJcblx0XHRcdFx0aWYgKC88JS8udGVzdCh0ZW1wbGF0ZUNvbnRlbnQpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHRcdHRlbXBsYXRlRmlsZSxcclxuXHRcdFx0XHRcdFx0ZmlsZVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIGF3YWl0IHRlbXBsYXRlc1BsdWdpbi5pbnN0YW5jZS5pbnNlcnRUZW1wbGF0ZSh0ZW1wbGF0ZUZpbGUpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCkge1xyXG5cdFx0XHRcdHJldHVybiBhd2FpdCB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2UuaW5zZXJ0VGVtcGxhdGUodGVtcGxhdGVGaWxlKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHRlbXBsYXRlckVuYWJsZWQpIHtcclxuXHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHR0ZW1wbGF0ZUZpbGUsXHJcblx0XHRcdFx0XHRmaWxlXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdH0gY2F0Y2ggKGUpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcihlKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW1wbGF0ZVBsdWdpbnMoYXBwOiBBcHApIHtcclxuXHRjb25zdCB0ZW1wbGF0ZXNQbHVnaW4gPSAoYXBwIGFzIGFueSkuaW50ZXJuYWxQbHVnaW5zLnBsdWdpbnMudGVtcGxhdGVzO1xyXG5cdGNvbnN0IHRlbXBsYXRlc0VuYWJsZWQgPSB0ZW1wbGF0ZXNQbHVnaW4uZW5hYmxlZDtcclxuXHRjb25zdCB0ZW1wbGF0ZXJQbHVnaW4gPSAoYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXTtcclxuXHRjb25zdCB0ZW1wbGF0ZXJFbmFibGVkID0gKGFwcCBhcyBhbnkpLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKFxyXG5cdFx0J3RlbXBsYXRlci1vYnNpZGlhbidcclxuXHQpO1xyXG5cdGNvbnN0IHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlID1cclxuXHRcdHRlbXBsYXRlclBsdWdpbiAmJlxyXG5cdFx0KHRoaXMuYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXS5zZXR0aW5nc1xyXG5cdFx0XHQ/LmVtcHR5X2ZpbGVfdGVtcGxhdGU7XHJcblxyXG5cdGNvbnN0IHRlbXBsYXRlRm9sZGVyID0gdGVtcGxhdGVzRW5hYmxlZFxyXG5cdFx0PyB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2Uub3B0aW9ucy5mb2xkZXJcclxuXHRcdDogdGVtcGxhdGVyUGx1Z2luXHJcblx0XHRcdD8gdGVtcGxhdGVyUGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlX2ZvbGRlclxyXG5cdFx0XHQ6IHVuZGVmaW5lZDtcclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHRlbXBsYXRlc1BsdWdpbixcclxuXHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHR0ZW1wbGF0ZXJQbHVnaW46IHRlbXBsYXRlclBsdWdpbj8udGVtcGxhdGVyLFxyXG5cdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlLFxyXG5cdFx0dGVtcGxhdGVGb2xkZXIsXHJcblx0fTtcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgVEZpbGUsIFBsYXRmb3JtLCBURm9sZGVyLCBUQWJzdHJhY3RGaWxlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IHR1cm5JbnRvRm9sZGVyTm90ZSB9IGZyb20gJ3NyYy9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsIGV4dGVuZHMgTW9kYWwge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0ZmlsZTogVEZpbGU7XHJcblx0Zm9sZGVyOiBURm9sZGVyO1xyXG5cdGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGU7XHJcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlLCBmb2xkZXI6IFRGb2xkZXIsIGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGUpIHtcclxuXHRcdHN1cGVyKGFwcCk7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdFx0dGhpcy5maWxlID0gZmlsZTtcclxuXHRcdHRoaXMuZm9sZGVyID0gZm9sZGVyO1xyXG5cdFx0dGhpcy5mb2xkZXJOb3RlID0gZm9sZGVyTm90ZTtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnQSBmb2xkZXIgbm90ZSBmb3IgdGhpcyBmb2xkZXIgYWxyZWFkeSBleGlzdHMnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byB0dXJuIHRoZSBub3RlIGludG8gYSBmb2xkZXIgbm90ZSBhbmQgcmVuYW1lIHRoZSBleGlzdGluZyBmb2xkZXIgbm90ZT8nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dSZW5hbWVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0dHVybkludG9Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUsIHRoaXMuZm9sZGVyLCB0aGlzLmZvbGRlck5vdGUsIHRydWUpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGNvbnN0IGNoZWNrYm94ID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdpbnB1dCcsIHsgdHlwZTogJ2NoZWNrYm94JyB9KTtcclxuXHRcdFx0Y2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHtcclxuXHRcdFx0XHRjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG5cdFx0XHRcdGlmICh0YXJnZXQuY2hlY2tlZCkge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiA9IGZhbHNlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93UmVuYW1lQ29uZmlybWF0aW9uID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjb25zdCBjaGVja0JveFRleHQgPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICdEb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNoZWNrQm94VGV4dC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcclxuXHRcdFx0XHRjaGVja2JveC5jbGljaygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lJyB9KTtcclxuXHRcdGJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtb2Qtd2FybmluZycsICdmbi1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9uJyk7XHJcblx0XHRidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdHR1cm5JbnRvRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgdGhpcy5maWxlLCB0aGlzLmZvbGRlciwgdGhpcy5mb2xkZXJOb3RlLCB0cnVlKTtcclxuXHRcdH0pO1xyXG5cdFx0YnV0dG9uLmZvY3VzKCk7XHJcblx0XHRjb25zdCBjYW5jZWxCdXR0b24gPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2J1dHRvbicsIHsgdGV4dDogJ0NhbmNlbCcgfSk7XHJcblx0XHRjYW5jZWxCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH0pO1xyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCBFeGlzdGluZ0ZvbGRlck5vdGVNb2RhbCBmcm9tICcuLi9tb2RhbHMvZXhpc3RpbmdOb3RlJztcclxuaW1wb3J0IHsgYXBwbHlUZW1wbGF0ZSB9IGZyb20gJy4uL3RlbXBsYXRlJztcclxuaW1wb3J0IHsgVEZvbGRlciwgVEZpbGUsIFRBYnN0cmFjdEZpbGUsIEtleW1hcCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsIGZyb20gJy4uL21vZGFscy9kZWxldGVDb25maXJtYXRpb24nO1xyXG5pbXBvcnQgeyBhZGRFeGNsdWRlZEZvbGRlciwgZGVsZXRlRXhjbHVkZWRGb2xkZXIsIGdldEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuLi9leGNsdWRlZEZvbGRlcic7XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIG9wZW5GaWxlOiBib29sZWFuLCB1c2VNb2RhbD86IGJvb2xlYW4sIGV4aXN0aW5nTm90ZT86IFRGaWxlKSB7XHJcblx0Y29uc3QgbGVhZiA9IHBsdWdpbi5hcHAud29ya3NwYWNlLmdldExlYWYoZmFsc2UpO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBwbHVnaW4uZ2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZvbGRlck5hbWUpO1xyXG5cdGxldCBwYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRjb25zdCBwYXJlbnRGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdFx0aWYgKHBhcmVudEZvbGRlclBhdGgudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAndmF1bHRGb2xkZXInKSB7XHJcblx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0cGF0aCA9IGAke2ZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9XHJcblx0bGV0IGZpbGU6IFRGaWxlO1xyXG5cdGlmICghZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRmaWxlID0gYXdhaXQgcGx1Z2luLmFwcC52YXVsdC5jcmVhdGUocGF0aCwgJycpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRmaWxlID0gZXhpc3RpbmdOb3RlO1xyXG5cdFx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZXhpc3RpbmdOb3RlLCBwYXRoKTtcclxuXHR9XHJcblx0aWYgKG9wZW5GaWxlKSB7XHJcblx0XHRhd2FpdCBsZWFmLm9wZW5GaWxlKGZpbGUpO1xyXG5cdH1cclxuXHRpZiAoZmlsZSAmJiAhZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRhcHBseVRlbXBsYXRlKHRoaXMsIGZpbGUsIHBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZVBhdGgpO1xyXG5cdH1cclxuXHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0dXJuSW50b0ZvbGRlck5vdGUocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZmlsZTogVEZpbGUsIGZvbGRlcjogVEZvbGRlciwgZm9sZGVyTm90ZT86IFRGaWxlIHwgbnVsbCB8IFRBYnN0cmFjdEZpbGUsIHNraXBDb25maXJtYXRpb24/OiBib29sZWFuKSB7XHJcblx0aWYgKGZvbGRlck5vdGUpIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiAmJiAhc2tpcENvbmZpcm1hdGlvbikge1xyXG5cdFx0XHRyZXR1cm4gbmV3IEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSwgZm9sZGVyLCBmb2xkZXJOb3RlKS5vcGVuKCk7XHJcblx0XHR9XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdFx0bGV0IGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IHRydWU7XHJcblx0XHRsZXQgZGlzYWJsZWRTeW5jID0gZmFsc2U7XHJcblxyXG5cdFx0aWYgKCFleGNsdWRlZEZvbGRlcikge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlckV4aXN0ZWQgPSBmYWxzZTtcclxuXHRcdFx0ZXhjbHVkZWRGb2xkZXIgPSBuZXcgRXhjbHVkZWRGb2xkZXIoZm9sZGVyLnBhdGgsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmb2xkZXIubmFtZX0gKCR7ZmlsZS5zdGF0LmN0aW1lLnRvU3RyaW5nKCkuc2xpY2UoMTApICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMCl9KSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHRwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmb2xkZXJOb3RlLCBuZXdQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0Y29uc3QgZmlsZU5hbWUgPSBwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSk7XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJykge1xyXG5cdFx0Y29uc3QgcGFyZW50Rm9sZGVyUGF0aCA9IGZvbGRlci5wYXJlbnQ/LnBhdGg7XHJcblx0XHRpZiAoIXBhcmVudEZvbGRlclBhdGgpIHJldHVybjtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0cGF0aCA9IGAke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRwYXRoID0gYCR7cGFyZW50Rm9sZGVyUGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBwYXRoKTtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBUQWJzdHJhY3RGaWxlLCBldnQ/OiBNb3VzZUV2ZW50KSB7XHJcblx0Y29uc3QgcGF0aCA9IGZpbGUucGF0aDtcclxuXHRpZiAocGx1Z2luLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpPy5wYXRoID09PSBwYXRoKSB7IHJldHVybjsgfVxyXG5cdGNvbnN0IGxlYWYgPSBwbHVnaW4uYXBwLndvcmtzcGFjZS5nZXRMZWFmKEtleW1hcC5pc01vZEV2ZW50KGV2dCkgfHwgcGx1Z2luLnNldHRpbmdzLm9wZW5Jbk5ld1RhYik7XHJcblx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0YXdhaXQgbGVhZi5vcGVuRmlsZShmaWxlKTtcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxldGVGb2xkZXJOb3RlKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlKSB7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uKSB7XHJcblx0XHRyZXR1cm4gbmV3IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSkub3BlbigpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIocGx1Z2luLCBmaWxlKTtcclxuXHRpZiAoIWZvbGRlcikgcmV0dXJuO1xyXG5cdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdGF3YWl0IHBsdWdpbi5hcHAudmF1bHQuZGVsZXRlKGZpbGUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEZvbGRlck5hbWUodGVtcGxhdGU6IHN0cmluZywgY2hhbmdlZEZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRjb25zdCBbcHJlZml4LCBzdWZmaXhdID0gdGVtcGxhdGUuc3BsaXQoJ3t7Zm9sZGVyX25hbWV9fScpO1xyXG5cdGlmIChwcmVmaXgudHJpbSgpID09PSAnJyAmJiBzdWZmaXgudHJpbSgpID09PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZTtcclxuXHR9XHJcblx0aWYgKCFjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpIHx8ICFjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdGlmIChjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpICYmIHByZWZpeC50cmltKCkgIT09ICcnKSB7XHJcblx0XHRyZXR1cm4gY2hhbmdlZEZpbGVOYW1lLnNsaWNlKHByZWZpeC5sZW5ndGgpLnJlcGxhY2Uoc3VmZml4LCAnJyk7XHJcblx0fSBlbHNlIGlmIChjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSAmJiBzdWZmaXgudHJpbSgpICE9PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZS5zbGljZSgwLCAtc3VmZml4Lmxlbmd0aCk7XHJcblx0fVxyXG5cdHJldHVybiBudWxsO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIHN0b3JhZ2VMb2NhdGlvbj86IHN0cmluZywgZmlsZT86IFRGaWxlKSB7XHJcblx0aWYgKCFmb2xkZXJQYXRoKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXIgPSB7XHJcblx0XHRwYXRoOiBmb2xkZXJQYXRoLFxyXG5cdFx0bmFtZTogcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhmb2xkZXJQYXRoKSxcclxuXHR9O1xyXG5cdGxldCBmaWxlTmFtZSA9IHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmb2xkZXIubmFtZSk7XHJcblx0aWYgKGZpbGUpIHtcclxuXHRcdGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdH1cclxuXHJcblx0aWYgKChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJyB8fCBzdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSAmJiBzdG9yYWdlTG9jYXRpb24gIT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJQYXRoKTtcclxuXHR9XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX1gO1xyXG5cdGlmIChmb2xkZXIucGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IGZpbGVOYW1lO1xyXG5cdFx0cGF0aCA9IGAke2ZpbGVOYW1lfWA7XHJcblx0fVxyXG5cdGxldCBmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArIHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSk7XHJcblx0aWYgKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0cmV0dXJuIGZvbGRlck5vdGU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPT09ICcuY2FudmFzJykge1xyXG5cdFx0XHRmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArICcubWQnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoICsgJy5jYW52YXMnKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmb2xkZXJOb3RlO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSwgc3RvcmFnZUxvY2F0aW9uPzogc3RyaW5nKSB7XHJcblx0aWYgKCFmaWxlKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0bGV0IGZvbGRlcjogVEZvbGRlciB8IFRBYnN0cmFjdEZpbGUgfCBudWxsID0gbnVsbDtcclxuXHRpZiAoKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInIHx8IHN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpICYmIHN0b3JhZ2VMb2NhdGlvbiAhPT0gJ2luc2lkZUZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0XHRmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0Zm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0fVxyXG5cdGlmICghZm9sZGVyKSB7IHJldHVybiBudWxsOyB9XHJcblx0cmV0dXJuIGZvbGRlcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTm90ZTogVEZpbGUgfCBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRpZiAoIWZvbGRlck5vdGUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmaWxlUGF0aCA9ICcnO1xyXG5cdGlmICh0eXBlb2YgZm9sZGVyTm90ZSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdGZpbGVQYXRoID0gZm9sZGVyTm90ZTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0ZmlsZU5hbWUgPSBmb2xkZXJOb3RlLmJhc2VuYW1lO1xyXG5cdFx0ZmlsZVBhdGggPSBmb2xkZXJOb3RlLnBhdGg7XHJcblx0fVxyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIGZpbGVOYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGVQYXRoKTtcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZVBhdGgpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHRpZiAoIWZvbGRlcikgeyByZXR1cm4gbnVsbDsgfVxyXG5cdHJldHVybiBmb2xkZXI7XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgTW9kYWwsIFNldHRpbmcsIFRGaWxlLCBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEZWxldGVDb25maXJtYXRpb25Nb2RhbCBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGZpbGU6IFRGaWxlO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLmZpbGUgPSBmaWxlO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdEZWxldGUgZm9sZGVyIG5vdGUnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlIGZvbGRlciBub3RlIFwiJHt0aGlzLmZpbGUubmFtZX1cIiA/YCB9KTtcclxuXHRcdHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnSXQgd2lsbCBiZSBtb3ZlZCB0byB5b3VyIHN5c3RlbSB0cmFzaC4nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnRGVsZXRlIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUpO1xyXG5cdFx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdFx0dGhpcy5wbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0dGhpcy5hcHAudmF1bHQuZGVsZXRlKHRoaXMuZmlsZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y29uc3QgY2hlY2tib3ggPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2lucHV0JywgeyB0eXBlOiAnY2hlY2tib3gnIH0pO1xyXG5cdFx0XHRjaGVja2JveC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcblx0XHRcdFx0aWYgKHRhcmdldC5jaGVja2VkKSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uID0gZmFsc2U7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0fSk7XHJcblx0XHRcdGNvbnN0IGNoZWNrQm94VGV4dCA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0RvblxcJ3QgYXNrIGFnYWluJyB9KTtcclxuXHRcdFx0Y2hlY2tCb3hUZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHRcdGNoZWNrYm94LmNsaWNrKCk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgYnV0dG9uID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdidXR0b24nLCB7IHRleHQ6ICdEZWxldGUnIH0pO1xyXG5cdFx0YnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21vZC13YXJuaW5nJywgJ2ZuLWNvbmZpcm1hdGlvbi1tb2RhbC1idXR0b24nKTtcclxuXHRcdGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcy5wbHVnaW4sIHRoaXMuZmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdHRoaXMucGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZSh0aGlzLmZpbGUpO1xyXG5cdFx0fSk7XHJcblx0XHRidXR0b24uZm9jdXMoKTtcclxuXHRcdGNvbnN0IGNhbmNlbEJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnQ2FuY2VsJyB9KTtcclxuXHRcdGNhbmNlbEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxuXHRvbkNsb3NlKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IFNldHRpbmcgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5pbXBvcnQgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBmcm9tICcuL21vZGFscy9leGNsdWRlRm9sZGVyU2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBGb2xkZXJTdWdnZXN0IH0gZnJvbSAnLi9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IFNldHRpbmdzVGFiIH0gZnJvbSAnLi9zZXR0aW5ncyc7XHJcbmltcG9ydCBQYXR0ZXJuU2V0dGluZ3MgZnJvbSAnLi9tb2RhbHMvcGF0dGVyblNldHRpbmdzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFeGNsdWRlZEZvbGRlciB7XHJcblx0dHlwZTogc3RyaW5nO1xyXG5cdHBhdGg6IHN0cmluZztcclxuXHRzdHJpbmc6IHN0cmluZztcclxuXHRzdWJGb2xkZXJzOiBib29sZWFuO1xyXG5cdGRpc2FibGVTeW5jOiBib29sZWFuO1xyXG5cdGRpc2FibGVBdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGRpc2FibGVGb2xkZXJOb3RlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0cG9zaXRpb246IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihwYXRoOiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIpIHtcclxuXHRcdHRoaXMudHlwZSA9ICdmb2xkZXInO1xyXG5cdFx0dGhpcy5wYXRoID0gcGF0aDtcclxuXHRcdHRoaXMuc3ViRm9sZGVycyA9IHRydWU7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XHJcblx0XHR0aGlzLnN0cmluZyA9ICcnO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEV4Y2x1ZGVQYXR0ZXJuIHtcclxuXHR0eXBlOiBzdHJpbmc7XHJcblx0c3RyaW5nOiBzdHJpbmc7XHJcblx0cGF0aDogc3RyaW5nO1xyXG5cdHBvc2l0aW9uOiBudW1iZXI7XHJcblx0c3ViRm9sZGVyczogYm9vbGVhbjtcclxuXHRkaXNhYmxlU3luYzogYm9vbGVhbjtcclxuXHRkaXNhYmxlQXV0b0NyZWF0ZTogYm9vbGVhbjtcclxuXHRkaXNhYmxlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBib29sZWFuO1xyXG5cdGNvbnN0cnVjdG9yKHBhdHRlcm46IHN0cmluZywgcG9zaXRpb246IG51bWJlcikge1xyXG5cdFx0dGhpcy50eXBlID0gJ3BhdHRlcm4nO1xyXG5cdFx0dGhpcy5zdHJpbmcgPSBwYXR0ZXJuO1xyXG5cdFx0dGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cdFx0dGhpcy5zdWJGb2xkZXJzID0gZmFsc2U7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBhdGggPSAnJztcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXRoOiBzdHJpbmcpIHtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhwYXRoKTtcclxuXHRjb25zdCBtYXRjaGVkUGF0dGVybiA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXR0ZXJuKHBsdWdpbiwgZm9sZGVyTmFtZSk7XHJcblx0aWYgKG1hdGNoZWRQYXR0ZXJuKSB7IHJldHVybiBtYXRjaGVkUGF0dGVybjsgfVxyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbiwgcGF0aCk7XHJcblx0cmV0dXJuIGV4Y2x1ZGVkRm9sZGVyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhjbHVkZWRGb2xkZXJCeVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTmFtZTogc3RyaW5nKSB7XHJcblx0cmV0dXJuIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maWx0ZXIoKHMpID0+IHMucGF0aCA9PT0gJycpLmZpbmQoKHBhdHRlcm4pID0+IHtcclxuXHRcdGlmICghcGF0dGVybi5zdHJpbmcpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAocGF0dGVybi5zdHJpbmcudG9Mb2NhbGVMb3dlckNhc2UoKS5zdGFydHNXaXRoKCd7cmVnZXh9JykgJiYgcGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpICE9PSAnJykge1xyXG5cdFx0XHRjb25zdCBtYXRjaCA9IG5ldyBSZWdFeHAocGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpKS5leGVjKGZvbGRlck5hbWUpO1xyXG5cdFx0XHRpZiAobWF0Y2gpIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmIChwYXR0ZXJuLnN0cmluZy5zdGFydHNXaXRoKCcqJykgJiYgcGF0dGVybi5zdHJpbmcuZW5kc1dpdGgoJyonKSkge1xyXG5cdFx0XHRpZiAoZm9sZGVyTmFtZS5pbmNsdWRlcyhwYXR0ZXJuLnN0cmluZy5zbGljZSgxLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSBpZiAocGF0dGVybi5zdHJpbmcuc3RhcnRzV2l0aCgnKicpKSB7XHJcblx0XHRcdGlmIChmb2xkZXJOYW1lLmVuZHNXaXRoKHBhdHRlcm4uc3RyaW5nLnNsaWNlKDEpKSkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHBhdHRlcm4uc3RyaW5nLmVuZHNXaXRoKCcqJykpIHtcclxuXHRcdFx0aWYgKGZvbGRlck5hbWUuc3RhcnRzV2l0aChwYXR0ZXJuLnN0cmluZy5zbGljZSgwLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIHBhdGg6IHN0cmluZykge1xyXG5cdHJldHVybiBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZXhjbHVkZWRGb2xkZXIpID0+IHtcclxuXHRcdGlmIChleGNsdWRlZEZvbGRlci5wYXRoID09PSBwYXRoKSB7IHJldHVybiB0cnVlOyB9XHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRyZXR1cm4gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpLnN0YXJ0c1dpdGgoZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0fSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlcik7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCB8fCBmb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKTtcclxuXHRwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0cmVzeW5jQXJyYXkocGx1Z2luKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4pIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKChmb2xkZXIpID0+IGZvbGRlci5zdHJpbmcgIT09IHBhdHRlcm4uc3RyaW5nIHx8IGZvbGRlci50eXBlID09PSAnZm9sZGVyJyk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdHJlc3luY0FycmF5KHBsdWdpbik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZVBhdHRlcm4sIG5ld0V4Y2x1ZGVGb2xkZXI6IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdFeGNsdWRlRm9sZGVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4sIG5ld1BhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nICE9PSBwYXR0ZXJuLnN0cmluZyk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdQYXR0ZXJuKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVzeW5jQXJyYXkocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5zb3J0KChhLCBiKSA9PiBhLnBvc2l0aW9uIC0gYi5wb3NpdGlvbik7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZvckVhY2goKGZvbGRlciwgaW5kZXgpID0+IHtcclxuXHRcdGZvbGRlci5wb3NpdGlvbiA9IGluZGV4O1xyXG5cdH0pO1xyXG5cdHBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0oc2V0dGluZ3M6IFNldHRpbmdzVGFiLCBjb250YWluZXJFbDogSFRNTEVsZW1lbnQsIHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0Y29uc3QgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiA9IHNldHRpbmdzLnBsdWdpbjtcclxuXHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpO1xyXG5cdHNldHRpbmcuc2V0Q2xhc3MoJ2ZuLWV4Y2x1ZGUtZm9sZGVyLWxpc3QnKTtcclxuXHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignUGF0dGVybicpO1xyXG5cdFx0Y2Iuc2V0VmFsdWUocGF0dGVybi5zdHJpbmcpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nID09PSB2YWx1ZSkpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHBhdHRlcm4uc3RyaW5nID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuLCBwYXR0ZXJuKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBwYXR0ZXJuJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0bmV3IFBhdHRlcm5TZXR0aW5ncyhwbHVnaW4uYXBwLCBwbHVnaW4sIHBhdHRlcm4pLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAocGF0dGVybi5wb3NpdGlvbiA9PT0gMCkgeyByZXR1cm47IH1cclxuXHRcdFx0cGF0dGVybi5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCdkb3duLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgZG93bicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGlmIChwYXR0ZXJuLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRwYXR0ZXJuLnBvc2l0aW9uICs9IDE7XHJcblxyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gLT0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCd0cmFzaC0yJyk7XHJcblx0XHRjYi5zZXRUb29sdGlwKCdEZWxldGUgcGF0dGVybicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGRlbGV0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gYWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHNldHRpbmdzOiBTZXR0aW5nc1RhYiwgY29udGFpbmVyRWw6IEhUTUxFbGVtZW50LCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRjb25zdCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luID0gc2V0dGluZ3MucGx1Z2luO1xyXG5cdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0c2V0dGluZy5zZXRDbGFzcygnZm4tZXhjbHVkZS1mb2xkZXItbGlzdCcpO1xyXG5cdHNldHRpbmcuYWRkU2VhcmNoKChjYikgPT4ge1xyXG5cdFx0bmV3IEZvbGRlclN1Z2dlc3QoXHJcblx0XHRcdGNiLmlucHV0RWwsXHJcblx0XHRcdHBsdWdpblxyXG5cdFx0KTtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignRm9sZGVyIHBhdGgnKTtcclxuXHRcdGNiLnNldFZhbHVlKGV4Y2x1ZGVkRm9sZGVyLnBhdGgpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmICh2YWx1ZS5zdGFydHNXaXRoKCd7cmVnZXh9JykgfHwgdmFsdWUuaW5jbHVkZXMoJyonKSkge1xyXG5cdFx0XHRcdGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdGNvbnN0IHBhdHRlcm4gPSBuZXcgRXhjbHVkZVBhdHRlcm4odmFsdWUsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgcGF0dGVybik7XHJcblx0XHRcdFx0YWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbShzZXR0aW5ncywgY29udGFpbmVyRWwsIHBhdHRlcm4pO1xyXG5cdFx0XHRcdHNldHRpbmcuY2xlYXIoKTtcclxuXHRcdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIXBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHZhbHVlKSkgcmV0dXJuO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBmb2xkZXIgbm90ZScpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdG5ldyBFeGNsdWRlZEZvbGRlclNldHRpbmdzKHBsdWdpbi5hcHAsIHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucG9zaXRpb24gPT09IDApIHsgcmV0dXJuOyB9XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uIC09IDE7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0Y29uc3Qgb2xkRXhjbHVkZWRGb2xkZXIgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uKTtcclxuXHRcdFx0aWYgKG9sZEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdFx0b2xkRXhjbHVkZWRGb2xkZXIucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKSB7XHJcblx0XHRcdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgb2xkRXhjbHVkZWRGb2xkZXIsIG9sZEV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ2Rvd24tY2hldnJvbi1nbHlwaCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnTW92ZSBkb3duJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wb3NpdGlvbiArPSAxO1xyXG5cclxuXHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBleGNsdWRlZEZvbGRlciwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRjb25zdCBvbGRFeGNsdWRlZEZvbGRlciA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmb2xkZXIpID0+IGZvbGRlci5wb3NpdGlvbiA9PT0gZXhjbHVkZWRGb2xkZXIucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRcdFx0XHRvbGRFeGNsdWRlZEZvbGRlci5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHRcdGlmIChvbGRFeGNsdWRlZEZvbGRlci50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIG9sZEV4Y2x1ZGVkRm9sZGVyLCBvbGRFeGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3RyYXNoLTInKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ0RlbGV0ZSBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcbiIsICJpbXBvcnQgeyBBcHAsIE1vZGFsLCBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IEV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnc3JjL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGV4Y2x1ZGVkRm9sZGVyOiBFeGNsdWRlZEZvbGRlcjtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRzdXBlcihhcHApO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmFwcCA9IGFwcDtcclxuXHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIgPSBleGNsdWRlZEZvbGRlcjtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0fVxyXG5cdGRpc3BsYXkoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0V4Y2x1ZGVkIGZvbGRlciBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIHN1YmZvbGRlcnMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBzdWJmb2xkZXJzIG9mIHRoZSBmb2xkZXIgc2hvdWxkIGFsc28gYmUgZXhjbHVkZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5zdWJGb2xkZXJzKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIG5hbWUgc3luYycpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBub3RlIHNob3VsZCBiZSByZW5hbWVkIHdoZW4gdGhlIGZvbGRlciBuYW1lIGlzIGNoYW5nZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSlcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGlmICghdGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSlcclxuXHRcdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IFRleHRJbnB1dFN1Z2dlc3QgfSBmcm9tICcuL3N1Z2dlc3QnO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmV4cG9ydCBlbnVtIEZpbGVTdWdnZXN0TW9kZSB7XHJcbiAgICBUZW1wbGF0ZUZpbGVzLFxyXG4gICAgU2NyaXB0RmlsZXMsXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBGb2xkZXJTdWdnZXN0IGV4dGVuZHMgVGV4dElucHV0U3VnZ2VzdDxURm9sZGVyPiB7XHJcblx0Y29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQsXHJcbiAgICAgICAgcHJpdmF0ZSBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luXHJcblx0KSB7XHJcblx0XHRzdXBlcihpbnB1dEVsKTtcclxuXHR9XHJcblxyXG5cclxuXHRnZXRfZXJyb3JfbXNnKG1vZGU6IEZpbGVTdWdnZXN0TW9kZSk6IHN0cmluZyB7XHJcblx0XHRzd2l0Y2ggKG1vZGUpIHtcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuVGVtcGxhdGVGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1RlbXBsYXRlcyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuU2NyaXB0RmlsZXM6XHJcblx0XHRcdFx0cmV0dXJuICdVc2VyIFNjcmlwdHMgZm9sZGVyIGRvZXNuXFwndCBleGlzdCc7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRnZXRTdWdnZXN0aW9ucyhpbnB1dF9zdHI6IHN0cmluZyk6IFRGb2xkZXJbXSB7XHJcblx0XHRjb25zdCBmb2xkZXJzOiBURm9sZGVyW10gPSBbXTtcclxuXHRcdGNvbnN0IGxvd2VyX2lucHV0X3N0ciA9IGlucHV0X3N0ci50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZm9sZGVyOiBUQWJzdHJhY3RGaWxlKSA9PiB7XHJcblx0XHRcdGlmIChcclxuXHRcdFx0XHRmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyICYmXHJcbiAgICAgICAgICAgICAgICBmb2xkZXIucGF0aC50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKGxvd2VyX2lucHV0X3N0cikgJiZcclxuICAgICAgICAgICAgICAgICF0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmKSA9PiBmLnBhdGggPT09IGZvbGRlci5wYXRoKVxyXG5cdFx0XHQpIHtcclxuXHRcdFx0XHRmb2xkZXJzLnB1c2goZm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIGZvbGRlcnM7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJTdWdnZXN0aW9uKGZvbGRlcjogVEZvbGRlciwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcblx0XHRlbC5zZXRUZXh0KGZvbGRlci5wYXRoKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZm9sZGVyOiBURm9sZGVyKTogdm9pZCB7XHJcblx0XHR0aGlzLmlucHV0RWwudmFsdWUgPSBmb2xkZXIucGF0aDtcclxuXHRcdHRoaXMuaW5wdXRFbC50cmlnZ2VyKCdpbnB1dCcpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBFeGNsdWRlUGF0dGVybiB9IGZyb20gJ3NyYy9leGNsdWRlZEZvbGRlcic7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhdHRlcm5TZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXR0ZXJuOiBFeGNsdWRlUGF0dGVybikge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHR9XHJcblx0ZGlzcGxheSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnUGF0dGVybiBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIGZvbGRlciBuYW1lIHN5bmMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbmFtZSBzaG91bGQgYmUgcmVuYW1lZCB3aGVuIHRoZSBmaWxlIG5hbWUgaGFzIGJlZW4gY2hhbmdlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZGlzYWJsZVN5bmMpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkIHRoYXQgbWF0Y2hlcyB0aGlzIHBhdHRlcm4nKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVBdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUZvbGRlck5vdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAoIXRoaXMucGF0dGVybi5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5lbmFibGVDb2xsYXBzaW5nID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cdG9uQ2xvc2UoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJ3NyYy9tYWluJztcclxuaW1wb3J0IHsgZ2V0RGVmZXIsIExpc3RlbmVyLCBFdmVudHMsIEFwaUludGVyZmFjZSwgRGVmZXJJbnRlcmZhY2UsIExpc3RlbmVyUmVmLCBFdmVudERpc3BhdGNoZXJJbnRlcmZhY2UgfSBmcm9tICdmcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlcic7XHJcbmltcG9ydCB7IEFwcCwgVEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgY2xhc3MgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0YXBpOiBBcGlJbnRlcmZhY2UgfCBudWxsID0gbnVsbDtcclxuXHRkZWZmZXI6IERlZmVySW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XHJcblx0bW9kaWZpZWRGb2xkZXJzOiBNYXA8c3RyaW5nLCBURm9sZGVyPiA9IG5ldyBNYXAoKTtcclxuXHRldmVudFJlZjogTGlzdGVuZXJSZWY8J21hbmFnZXI6dXBkYXRlJz47XHJcblx0ZGlzcGF0Y2hlcjogRXZlbnREaXNwYXRjaGVySW50ZXJmYWNlPEV2ZW50cz5cclxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gcGx1Z2luLmFwcDtcclxuXHJcblx0XHQoYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmRlZmZlciA9IGdldERlZmVyKHRoaXMuYXBwKTtcclxuXHRcdFx0aWYgKHRoaXMuZGVmZmVyLmlzUGx1Z2luUmVhZHkoKSkge1xyXG5cdFx0XHRcdHRoaXMuYXBpID0gdGhpcy5kZWZmZXIuZ2V0QXBpKCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0YXdhaXQgdGhpcy5kZWZmZXIuYXdhaXRQbHVnaW4oKTtcclxuXHRcdFx0XHR0aGlzLmFwaSA9IHRoaXMuZGVmZmVyLmdldEFwaSgpO1xyXG5cdFx0XHRcdC8vIGlmIHlvdSB3YW50IHRvIHdhaXQgZmVhdHVyZXMgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjaGFpblxyXG5cdFx0XHRcdGlmICghdGhpcy5kZWZmZXIuaXNGZWF0dXJlc1JlYWR5KCkpIHtcclxuXHRcdFx0XHRcdGF3YWl0IHRoaXMuZGVmZmVyLmF3YWl0RmVhdHVyZXMoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0Y29uc3QgZGlzcGF0Y2hlciA9IHRoaXMuYXBpPy5nZXRFdmVudERpc3BhdGNoZXIoKTtcclxuXHRcdFx0aWYgKGRpc3BhdGNoZXIpIHtcclxuXHRcdFx0XHR0aGlzLmRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbnN0IGV2ZW50OiBMaXN0ZW5lcjxFdmVudHMsICdtYW5hZ2VyOnVwZGF0ZSc+ID0ge1xyXG5cdFx0XHRcdG5hbWU6ICdtYW5hZ2VyOnVwZGF0ZScsXHJcblx0XHRcdFx0Y2I6IChkYXRhKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLmhhbmRsZVJlbmFtZShkYXRhIGFzIGFueSwgdHJ1ZSk7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0fTtcclxuXHRcdFx0Ly8gS2VlcCByZWYgdG8gcmVtb3ZlIGxpc3RlbmVyXHJcblx0XHRcdGNvbnN0IHJlZiA9IGRpc3BhdGNoZXI/LmFkZExpc3RlbmVyKGV2ZW50KTtcclxuXHRcdFx0aWYgKHJlZikge1xyXG5cdFx0XHRcdHRoaXMuZXZlbnRSZWYgPSByZWY7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdH0pKCk7XHJcblx0fVxyXG5cdGRlbGV0ZUV2ZW50KCkge1xyXG5cdFx0aWYgKHRoaXMuZXZlbnRSZWYpIHtcclxuXHRcdFx0dGhpcy5kaXNwYXRjaGVyLnJlbW92ZUxpc3RlbmVyKHRoaXMuZXZlbnRSZWYpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhc3luYyBoYW5kbGVSZW5hbWUoZGF0YToge1xyXG5cdFx0aWQ6IHN0cmluZztcclxuXHRcdHJlc3VsdDogYm9vbGVhbjtcclxuXHRcdHBhdGg6IHN0cmluZztcclxuXHR9LCBpc0V2ZW50OiBib29sZWFuKSB7XHJcblx0XHRpZiAoKGRhdGEgYXMgYW55KS5kYXRhKSBkYXRhID0gKGRhdGEgYXMgYW55KS5kYXRhXHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGRhdGEucGF0aCk7XHJcblx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdGNvbnN0IHJlc29sdmVyID0gdGhpcy5hcGk/LmdldFJlc29sdmVyRmFjdG9yeSgpPy5jcmVhdGVSZXNvbHZlcignI2ZlYXR1cmUtaWQjJyk7XHJcblx0XHRjb25zdCBuZXdOYW1lID0gcmVzb2x2ZXI/LnJlc29sdmUoZmlsZT8ucGF0aCA/PyAnJylcclxuXHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLnBsdWdpbiwgZmlsZSk7XHJcblxyXG5cdFx0aWYgKChleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZSkgIT09IGZvbGRlcj8ubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0aWYgKGlzRXZlbnQpIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIHRydWUpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIGZhbHNlKTtcclxuXHRcdH1cclxuXHRcdGlmIChuZXdOYW1lKSB7XHJcblx0XHRcdGZvbGRlci5uZXdOYW1lID0gbmV3TmFtZTtcclxuXHRcdFx0dGhpcy5tb2RpZmllZEZvbGRlcnMuc2V0KGZvbGRlci5wYXRoLCBmb2xkZXIpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Zm9sZGVyLm5ld05hbWUgPSBudWxsO1xyXG5cdFx0XHR0aGlzLm1vZGlmaWVkRm9sZGVycy5kZWxldGUoZm9sZGVyLnBhdGgpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgVEZvbGRlciwgTWVudSwgVEFic3RyYWN0RmlsZSwgTm90aWNlLCBURmlsZSwgRWRpdG9yLCBNYXJrZG93blZpZXcsIFBsYXRmb3JtIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0Rm9sZGVyTm90ZSwgY3JlYXRlRm9sZGVyTm90ZSwgZGVsZXRlRm9sZGVyTm90ZSwgdHVybkludG9Gb2xkZXJOb3RlLCBvcGVuRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGNsYXNzIENvbW1hbmRzIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdH1cclxuXHRyZWdpc3RlckNvbW1hbmRzKCkge1xyXG5cdFx0dGhpcy5wbHVnaW4ucmVnaXN0ZXJFdmVudCh0aGlzLnBsdWdpbi5hcHAud29ya3NwYWNlLm9uKCdlZGl0b3ItbWVudScsIChtZW51OiBNZW51LCBlZGl0b3I6IEVkaXRvciwgdmlldzogTWFya2Rvd25WaWV3KSA9PiB7XHJcblx0XHRcdGNvbnN0IHRleHQgPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCkudHJpbSgpO1xyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpdGVtLnNldFRpdGxlKCdDcmVhdGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdC5zZXRJY29uKCdlZGl0JylcclxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oJ2BgYGZvbGRlci1vdmVydmlld1xcbmBgYFxcbicpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRpZiAoIXRleHQgfHwgdGV4dC50cmltKCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdG1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0NyZWF0ZSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGZpbGUgPSB2aWV3LmZpbGU7XHJcblx0XHRcdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0Y29uc3QgYmxhY2tsaXN0ID0gWycqJywgJ1xcXFwnLCAnXCInLCAnLycsICc8JywgJz4nLCAnPycsICd8JywgJzonXTtcclxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCBjaGFyIG9mIGJsYWNrbGlzdCkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0ZXh0LmluY2x1ZGVzKGNoYXIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGNvbnRhaW4gYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKiBcIiBcXFxcIC8gPCA+IDogfCA/Jyk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmICh0ZXh0LmVuZHNXaXRoKCcuJykpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGVuZCB3aXRoIGEgZG90Jyk7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGxldCBmb2xkZXI6IFRBYnN0cmFjdEZpbGUgfCBudWxsO1xyXG5cdFx0XHRcdFx0XHRjb25zdCBmb2xkZXJQYXRoID0gdGhpcy5wbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdFx0XHRcdFx0aWYgKGZvbGRlclBhdGggPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0ZXh0KTtcclxuXHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBub3RlIGFscmVhZHkgZXhpc3RzJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5jcmVhdGVGb2xkZXIodGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0ZXh0LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbmV3IE5vdGljZSgnRm9sZGVyIG5vdGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICh0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQgKyB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZpbGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihmb2xkZXJQYXRoICsgJy8nICsgdGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyUGF0aCArICcvJyArIHRleHQsIGZhbHNlKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlTmFtZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRpZiAoZmlsZU5hbWUgPT09IHRleHQpIHtcclxuXHRcdFx0XHRcdFx0XHRlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgW1ske2ZpbGVOYW1lfV1dYCk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFtbJHtmaWxlTmFtZX18JHt0ZXh0fV1dYCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdmaWxlLW1lbnUnLCAobWVudTogTWVudSwgZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRsZXQgZm9sZGVyOiBUQWJzdHJhY3RGaWxlIHwgVEZvbGRlciB8IG51bGwgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRmb2xkZXIgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0XHRcdFx0XHRpZiAoZmlsZU5hbWUpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGZpbGUucGFyZW50Py5wYXRoID09PSAnJyB8fCBmaWxlLnBhcmVudD8ucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlTmFtZSk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlLnBhcmVudD8ucGF0aCArICcvJyArIGZpbGVOYW1lKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZvbGRlci5wYXRoKTtcclxuXHRcdFx0XHRcdGlmIChmb2xkZXJOb3RlPy5wYXRoID09PSBmaWxlLnBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0fSBlbHNlIGlmIChmaWxlLnBhcmVudCBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRcdGZvbGRlciA9IGZpbGUucGFyZW50O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wICYmICFQbGF0Zm9ybS5pc1RhYmxldCAmJiB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cykge1xyXG5cdFx0XHRcdFx0aXRlbVxyXG5cdFx0XHRcdFx0XHQuc2V0VGl0bGUoJ0ZvbGRlciBOb3RlIENvbW1hbmRzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ2ZvbGRlci1lZGl0Jyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxldCBzdWJNZW51OiBNZW51O1xyXG5cdFx0XHRcdGlmICghUGxhdGZvcm0uaXNEZXNrdG9wQXBwIHx8ICFQbGF0Zm9ybS5pc0Rlc2t0b3AgfHwgUGxhdGZvcm0uaXNUYWJsZXQgfHwgIXRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVN1Ym1lbnVzKSB7XHJcblx0XHRcdFx0XHRzdWJNZW51ID0gbWVudTtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0RGlzYWJsZWQodHJ1ZSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdHN1Yk1lbnUgPSBpdGVtLnNldFN1Ym1lbnUoKSBhcyBNZW51O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCFmb2xkZXIpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gZm9sZGVyLnBhdGggKyAnLycgKyBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKGZvbGRlci5wYXRoID09PSAnJyB8fCBmb2xkZXIucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdG5ld1BhdGggPSBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBhbHJlYWR5IGV4aXN0cycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihuZXdQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG5ld0ZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIShuZXdGb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgbmV3Rm9sZGVyLnBhdGgsIHRydWUsIGZhbHNlLCBmaWxlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0c3ViTWVudS5hZGRJdGVtKChpdGVtKSA9PiB7XHJcblx0XHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ1R1cm4gaW50byBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ2VkaXQnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghZm9sZGVyIHx8ICEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0dXJuSW50b0ZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZpbGUsIGZvbGRlciwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbmQoKGZvbGRlcikgPT4gZm9sZGVyLnBhdGggPT09IGZpbGUucGF0aCkpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdSZW1vdmUgZm9sZGVyIGZyb20gZXhjbHVkZWQgZm9sZGVycycpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ3RyYXNoJylcclxuXHRcdFx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcihcclxuXHRcdFx0XHRcdFx0XHRcdFx0KGZvbGRlcikgPT4gZm9sZGVyLnBhdGggIT09IGZpbGUucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoJ1N1Y2Nlc3NmdWxseSByZW1vdmVkIGZvbGRlciBmcm9tIGV4Y2x1ZGVkIGZvbGRlcnMnKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0V4Y2x1ZGUgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ3gtY2lyY2xlJylcclxuXHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKGZpbGUucGF0aCwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5wdXNoKGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdTdWNjZXNzZnVsbHkgZXhjbHVkZWQgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdEZWxldGUgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdFx0XHRcdC5zZXRJY29uKCd0cmFzaCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGVsZXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdPcGVuIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignY2hldnJvbi1yaWdodC1zcXVhcmUnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdG9wZW5Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXJOb3RlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCB0cnVlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KSk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgeyBLZXltYXAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICdzcmMvbWFpbic7XHJcbmltcG9ydCB7IG9wZW5Gb2xkZXJOb3RlLCBjcmVhdGVGb2xkZXJOb3RlLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnc3JjL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIgfSBmcm9tICdzcmMvZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlVmlld0hlYWRlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0aWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XHJcblx0aWYgKCFwbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSByZXR1cm47XHJcblxyXG5cdGNvbnN0IGZvbGRlclBhdGggPSBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnKTtcclxuXHRpZiAoIWZvbGRlclBhdGgpIHsgcmV0dXJuOyB9XHJcblx0Y29uc3QgZXhjbHVkZWRGb2xkZXIgPSBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChleGNsdWRlZEZvbGRlcj8uZGlzYWJsZUZvbGRlck5vdGUpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAoZXhjbHVkZWRGb2xkZXI/LmVuYWJsZUNvbGxhcHNpbmcgfHwgcGx1Z2luLnNldHRpbmdzLmVuYWJsZUNvbGxhcHNpbmcpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybjtcclxuXHRldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHJcblx0Y29uc3QgZm9sZGVyUGF0aCA9IGV2ZW50LnRhcmdldC5wYXJlbnRFbGVtZW50Py5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdGlmICghZm9sZGVyUGF0aCkgeyByZXR1cm47IH1cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyUGF0aCk7XHJcblx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0XHRyZXR1cm47XHJcblx0fSBlbHNlIGlmIChleGNsdWRlZEZvbGRlcj8uZW5hYmxlQ29sbGFwc2luZyB8fCBwbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZykge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0fVxyXG5cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcbiIsICJpbXBvcnQgeyBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTm90aWNlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnc3JjL21haW4nO1xyXG5pbXBvcnQgeyBleHRyYWN0Rm9sZGVyTmFtZSwgZ2V0Rm9sZGVyTm90ZSwgZ2V0Rm9sZGVyTm90ZUZvbGRlciB9IGZyb20gJy4uL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIsIEV4Y2x1ZGVkRm9sZGVyLCBhZGRFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIsIGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnLi4vZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRm9sZGVyUmVuYW1lKGZpbGU6IFRGb2xkZXIsIG9sZFBhdGg6IHN0cmluZywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUubmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZS5wYXRoKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgpO1xyXG5cdGlmICghKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRjb25zdCBleGNsdWRlZEZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKFxyXG5cdFx0KGV4Y2x1ZGVkRm9sZGVyKSA9PiBleGNsdWRlZEZvbGRlci5wYXRoLmluY2x1ZGVzKG9sZFBhdGgpXHJcblx0KTtcclxuXHJcblx0ZXhjbHVkZWRGb2xkZXJzLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucGF0aCA9PT0gb2xkUGF0aCkge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVyLnBhdGg7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGZvbGRlcnMgPSBleGNsdWRlZEZvbGRlci5wYXRoLnNwbGl0KCcvJyk7XHJcblx0XHRpZiAoZm9sZGVycy5sZW5ndGggPCAxKSB7XHJcblx0XHRcdGZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlci5wYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb2xkZXJzW2ZvbGRlcnMuaW5kZXhPZihmb2xkZXIubmFtZSldID0gZm9sZGVyLm5hbWU7XHJcblx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVycy5qb2luKCcvJyk7XHJcblx0fSk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZmlsZS5wYXRoKTtcclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmICFmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gcGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdH1cclxuXHJcblx0bGV0IG5ld1BhdGggPSAnJztcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGNvbnN0IG9sZFBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcob2xkUGF0aCk7XHJcblx0XHRpZiAocGFyZW50Rm9sZGVyUGF0aCAhPT0gb2xkUGFyZW50Rm9sZGVyUGF0aCkge1xyXG5cdFx0XHRpZiAoIXBsdWdpbi5zZXR0aW5ncy5zeW5jTW92ZSkgeyByZXR1cm47IH1cclxuXHRcdFx0bmV3UGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSBpZiAocGFyZW50Rm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZvbGRlck5vdGUubmFtZX1gO1xyXG5cdFx0XHRuZXdQYXRoID0gYCR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdG5ld1BhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfS4ke2ZvbGRlck5vdGUuZXh0ZW5zaW9ufWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdG5ld1BhdGggPSBgJHtmaWxlLnBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHR9XHJcblx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVGaWxlUmVuYW1lKGZpbGU6IFRGaWxlLCBvbGRQYXRoOiBzdHJpbmcsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRjb25zdCBvbGRGaWxlTmFtZSA9IHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcob2xkUGF0aCkpO1xyXG5cdGNvbnN0IG9sZEZvbGRlciA9IGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luLCBvbGRQYXRoLCBvbGRGaWxlTmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZTtcclxuXHRjb25zdCBvbGRGb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBvbGRGaWxlTmFtZSkgfHwgb2xkRmlsZU5hbWU7XHJcblx0Y29uc3QgbmV3Rm9sZGVyID0gZ2V0Rm9sZGVyTm90ZUZvbGRlcihwbHVnaW4sIGZpbGUsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgbmV3Rm9sZGVyPy5wYXRoIHx8ICcnKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgsIHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24sIGZpbGUpO1xyXG5cclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmIGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSkge1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwobmV3Rm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHJldHVybjtcclxuXHR9IGVsc2UgaWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlU3luYykge1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwobmV3Rm9sZGVyPy5wYXRoIHx8ICcnLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyBmaWxlIGhhcyBiZWVuIG1vdmVkIGludG8gcG9zaXRpb24gd2hlcmUgaXQgY2FuIGJlIGEgZm9sZGVyIG5vdGUhXHJcblx0aWYgKGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSAmJiBmb2xkZXJOb3RlKSB7XHJcblx0XHRuZXcgTm90aWNlKCdGb2xkZXIgd2l0aCBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMhJyk7XHJcblx0XHRsZXQgZXhjbHVkZWRGb2xkZXJFeGlzdGVkID0gdHJ1ZTtcclxuXHRcdGxldCBkaXNhYmxlZFN5bmMgPSBmYWxzZTtcclxuXHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlciA9IG5ldyBFeGNsdWRlZEZvbGRlcihvbGRGb2xkZXI/LnBhdGggfHwgJycsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRpZiAoZm9sZGVyTmFtZSA9PT0gbmV3Rm9sZGVyPy5uYW1lKSB7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChuZXdGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKG9sZEZvbGRlcj8ucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gZmlsZSBtYXRjaGVkIGZvbGRlciBuYW1lIGJlZm9yZSByZW5hbWVcclxuXHQvLyBmaWxlIGhhc250IG1vdmVkIGp1c3QgcmVuYW1lZFxyXG5cdC8vIE5lZWQgdG8gcmVuYW1lIHRoZSBmb2xkZXJcclxuXHRpZiAoIW9sZEZvbGRlcikgcmV0dXJuO1xyXG5cdGlmIChvbGRGb2xkZXJOYW1lID09PSBvbGRGb2xkZXIubmFtZSAmJiBuZXdGb2xkZXI/LnBhdGggPT09IG9sZEZvbGRlci5wYXRoKSB7XHJcblx0XHRyZXR1cm4gcmVuYW1lRm9sZGVyT25GaWxlUmVuYW1lKGZpbGUsIG9sZFBhdGgsIG9sZEZvbGRlciwgcGx1Z2luKTtcclxuXHR9IGVsc2UgaWYgKGZvbGRlck5vdGUgJiYgb2xkRm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHJldHVybiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgb2xkRm9sZGVyLCBwbHVnaW4pO1xyXG5cdH1cclxuXHJcblx0Ly8gdGhlIG5vdGUgaGFzIGJlZW4gbW92ZWQgc29tZXdoZXJlIGFuZCBpcyBubyBsb25nZXIgYSBmb2xkZXIgbm90ZVxyXG5cdC8vIGNsZWFudXAgY3NzIG9uIHRoZSBmb2xkZXIgYW5kIG5vdGVcclxuXHRpZiAob2xkRm9sZGVyLm5hbWUgPT09IG9sZEZpbGVOYW1lICYmIG5ld0ZvbGRlcj8ucGF0aCAhPT0gb2xkRm9sZGVyLnBhdGgpIHtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkUGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0fVxyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZTogVEZpbGUsIG9sZFBhdGg6IHN0cmluZywgb2xkRm9sZGVyOiBUQWJzdHJhY3RGaWxlLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0Y29uc3QgbmV3Rm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0aWYgKCFuZXdGb2xkZXJOYW1lKSB7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkRm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdpcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAobmV3Rm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdGxldCBuZXdGb2xkZXJQYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRuZXdGb2xkZXJQYXRoID0gb2xkRm9sZGVyLnBhcmVudD8ucGF0aCArICcvJyArIG5ld0ZvbGRlck5hbWU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0bmV3Rm9sZGVyUGF0aCA9IGAke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG5ld0ZvbGRlclBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlclBhdGgpIHx8IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlck5hbWUgfHwgJycpKSB7XHJcblx0XHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKTtcclxuXHRcdHJldHVybiBuZXcgTm90aWNlKCdBIGZvbGRlciB3aXRoIHRoZSBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHR9XHJcblx0YXdhaXQgcGx1Z2luLmFwcC52YXVsdC5yZW5hbWUob2xkRm9sZGVyLCBuZXdGb2xkZXJQYXRoKTtcclxufVxyXG4iLCAiaW1wb3J0IHsgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sLCBUQWJzdHJhY3RGaWxlLCBURm9sZGVyLCBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmV4cG9ydCB0eXBlIHlhbWxTZXR0aW5ncyA9IHtcclxuXHR0aXRsZT86IHN0cmluZztcclxuXHRkaXNhYmxlVGl0bGU/OiBib29sZWFuO1xyXG5cdGRlcHRoPzogbnVtYmVyO1xyXG5cdHR5cGU/OiAnZm9sZGVyJyB8ICdtYXJrZG93bicgfCAnY2FudmFzJyB8ICdvdGhlcicgfCAncGRmJyB8ICdpbWFnZXMnIHwgJ2F1ZGlvJyB8ICd2aWRlbycgfCAnYWxsJztcclxuXHRpbmNsdWRlVHlwZXM/OiBzdHJpbmdbXTtcclxuXHRzdHlsZT86ICdsaXN0JyB8ICdncmlkJztcclxuXHRkaXNhYmxlRmlsZVRhZz86IGJvb2xlYW47XHJcblx0c29ydEJ5PzogJ25hbWUnIHwgJ2NyZWF0ZWQnIHwgJ21vZGlmaWVkJyB8ICduYW1lQXNjJyB8ICdjcmVhdGVkQXNjJyB8ICdtb2RpZmllZEFzYyc7XHJcblx0c2hvd0VtcHR5Rm9sZGVycz86IGJvb2xlYW47XHJcblx0b25seUluY2x1ZGVTdWJmb2xkZXJzPzogYm9vbGVhbjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYW52YXNPdmVydmlldygpIHtcclxuXHQvLyBjb25zb2xlLmxvZygndGVzdCcpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3ZlcnZpZXcocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgc291cmNlOiBzdHJpbmcsIGVsOiBIVE1MRWxlbWVudCwgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0KSB7XHJcblx0Ly8gcGFyc2Ugc291cmNlIHRvIHlhbWxcclxuXHRsZXQgeWFtbDogeWFtbFNldHRpbmdzID0gcGFyc2VZYW1sKHNvdXJjZSk7XHJcblx0aWYgKCF5YW1sKSB7XHJcblx0XHR5YW1sID0ge1xyXG5cdFx0XHR0aXRsZTogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0ZGlzYWJsZVRpdGxlOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVUaXRsZSxcclxuXHRcdFx0ZGVwdGg6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGVwdGgsXHJcblx0XHRcdHR5cGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0aW5jbHVkZVR5cGVzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyxcclxuXHRcdFx0c3R5bGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc3R5bGUsXHJcblx0XHRcdGRpc2FibGVGaWxlVGFnOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRzb3J0Qnk6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5LFxyXG5cdFx0XHRzaG93RW1wdHlGb2xkZXJzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMsXHJcblx0XHRcdG9ubHlJbmNsdWRlU3ViZm9sZGVyczogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHR9O1xyXG5cdH1cclxuXHRjb25zdCBkZXB0aCA9IHlhbWw/LmRlcHRoIHx8IDE7XHJcblx0bGV0IHRpdGxlID0geWFtbD8udGl0bGUgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSB8fCAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhjdHguc291cmNlUGF0aCkpKTtcclxuXHR0aXRsZSA9IHRpdGxlLnJlcGxhY2VBbGwoJ3t7Zm9sZGVyTmFtZX19JywgZm9sZGVyTmFtZSB8fCAnJyk7XHJcblx0Y29uc3QgZGlzYWJsZVRpdGxlID0geWFtbD8uZGlzYWJsZVRpdGxlIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGlzYWJsZVRpdGxlIHx8IGZhbHNlO1xyXG5cdGxldCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdID0geWFtbD8uaW5jbHVkZVR5cGVzIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuaW5jbHVkZVR5cGVzIHx8IFsnZm9sZGVyJywgJ21hcmtkb3duJ107XHJcblx0aW5jbHVkZVR5cGVzID0gaW5jbHVkZVR5cGVzLm1hcCgodHlwZSkgPT4gdHlwZS50b0xvd2VyQ2FzZSgpKTtcclxuXHRjb25zdCBzdHlsZTogJ2xpc3QnIHwgJ2dyaWQnID0geWFtbD8uc3R5bGUgfHwgJ2xpc3QnO1xyXG5cdGNvbnN0IGRpc2FibGVGaWxlVGFnID0geWFtbD8uZGlzYWJsZUZpbGVUYWcgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlRmlsZVRhZyB8fCBmYWxzZTtcclxuXHRjb25zdCBzaG93RW1wdHlGb2xkZXJzID0geWFtbD8uc2hvd0VtcHR5Rm9sZGVycyB8fCBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMgfHwgZmFsc2U7XHJcblxyXG5cdGNvbnN0IHJvb3QgPSBlbC5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXcnIH0pO1xyXG5cdGNvbnN0IHRpdGxlRWwgPSByb290LmNyZWF0ZUVsKCdoMScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LXRpdGxlJyB9KTtcclxuXHRjb25zdCB1bCA9IHJvb3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0aWYgKCFkaXNhYmxlVGl0bGUpIHtcclxuXHRcdHRpdGxlRWwuaW5uZXJUZXh0ID0gdGl0bGU7XHJcblx0fVxyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxyXG5cdGxldCBmaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0Y29uc3Qgc291cmNlRmlsZSA9IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRpZiAoIXNvdXJjZUZpbGUpIHJldHVybjtcclxuXHRjb25zdCBzb3VyY2VGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRsZXQgc291cmNlRm9sZGVyOiBURm9sZGVyIHwgdW5kZWZpbmVkO1xyXG5cclxuXHRpZiAoc291cmNlRmlsZS5wYXJlbnQgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRzb3VyY2VGb2xkZXIgPSBzb3VyY2VGaWxlLnBhcmVudDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0c291cmNlRm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSkgYXMgVEZvbGRlcjtcclxuXHR9XHJcblxyXG5cdGZpbGVzID0gc291cmNlRm9sZGVyLmNoaWxkcmVuO1xyXG5cclxuXHRmaWxlcyA9IGZpbGVzLmZpbHRlcigoZmlsZSkgPT4ge1xyXG5cdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0aWYgKCFmb2xkZXJQYXRoLnN0YXJ0c1dpdGgoc291cmNlRm9sZGVyUGF0aCkpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAoZmlsZS5wYXRoID09PSBjdHguc291cmNlUGF0aCkgeyByZXR1cm4gZmFsc2U7IH1cclxuXHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGgpIHtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0aWYgKCFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ2ZvbGRlcicpKSB7XHJcblx0XHRmaWxlcyA9IGdldEFsbEZpbGVzKGZpbGVzLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCk7XHJcblx0fVxyXG5cdGZpbGVzID0gc29ydEZpbGVzKGZpbGVzLCB5YW1sLCBwbHVnaW4pO1xyXG5cclxuXHRpZiAoc3R5bGUgPT09ICdncmlkJykge1xyXG5cdFx0Y29uc3QgZ3JpZCA9IHJvb3QuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQnIH0pO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaChhc3luYyAoZmlsZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBncmlkSXRlbSA9IGdyaWQuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbScgfSk7XHJcblx0XHRcdGNvbnN0IGdyaWRBcnRpY2xlID0gZ3JpZEl0ZW0uY3JlYXRlRWwoJ2FydGljbGUnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tYXJ0aWNsZScgfSk7XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IHBsdWdpbi5hcHAudmF1bHQucmVhZChmaWxlKTtcclxuXHRcdFx0XHQvLyBza2lwIC0tLSB5YW1sXHJcblx0XHRcdFx0Y29uc3QgZGVzY3JpcHRpb25FbCA9IGdyaWRBcnRpY2xlLmNyZWF0ZUVsKCdwJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWRlc2NyaXB0aW9uJyB9KTtcclxuXHRcdFx0XHRsZXQgZGVzY3JpcHRpb24gPSBmaWxlQ29udGVudC5zcGxpdCgnXFxuJylbMF07XHJcblx0XHRcdFx0aWYgKGRlc2NyaXB0aW9uLmxlbmd0aCA+IDY0KSB7XHJcblx0XHRcdFx0XHRkZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLnNsaWNlKDAsIDY0KSArICcuLi4nO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRkZXNjcmlwdGlvbkVsLmlubmVyVGV4dCA9IGRlc2NyaXB0aW9uO1xyXG5cdFx0XHRcdGNvbnN0IGxpbmsgPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbS1saW5rIGludGVybmFsLWxpbmsnIH0pO1xyXG5cdFx0XHRcdGNvbnN0IHRpdGxlID0gbGluay5jcmVhdGVFbCgnaDEnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tbGluay10aXRsZScgfSk7XHJcblx0XHRcdFx0dGl0bGUuaW5uZXJUZXh0ID0gZmlsZS5uYW1lLnJlcGxhY2UoJy5tZCcsICcnKS5yZXBsYWNlKCcuY2FudmFzJywgJycpO1xyXG5cdFx0XHRcdGxpbmsuaHJlZiA9IGZpbGUucGF0aDtcclxuXHRcdFx0fSBlbHNlIGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlcicgfSk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyTmFtZSA9IGZvbGRlckl0ZW0uY3JlYXRlRWwoJ2gxJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlci1uYW1lJyB9KTtcclxuXHRcdFx0XHRmb2xkZXJOYW1lLmlubmVyVGV4dCA9IGZpbGUubmFtZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSBlbHNlIGlmIChzdHlsZSA9PT0gJ2xpc3QnKSB7XHJcblx0XHRjb25zdCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSA9IFtdO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJJdGVtID0gYWRkRm9sZGVyTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlKTtcclxuXHRcdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0YWRkRmlsZUxpc3QocGx1Z2luLCB1bCwgcGF0aEJsYWNrbGlzdCwgZmlsZSwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0gZWxzZSBpZiAoc3R5bGUgPT09ICdleHBsb3JlcicpIHtcclxuXHRcdC8qXHJcblx0XHRjb25zdCB2aWV3ID0gcGx1Z2luLmdldEZpbGVFeHBsb3JlclZpZXcoKTtcclxuXHRcdGNvbnN0IGZvbGRlckVsZW1lbnQgPSBwbHVnaW4uZ2V0RUwocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSk/LnBhcmVudEVsZW1lbnQ7XHJcblx0XHRpZiAoIWZvbGRlckVsZW1lbnQpIHJldHVybjtcclxuXHRcdC8vIGNvcHkgZm9sZGVyRWxlbWVudFxyXG5cdFx0Y29uc3QgbmV3Rm9sZGVyRWxlbWVudCA9IGZvbGRlckVsZW1lbnQuY2xvbmVOb2RlKHRydWUpIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0bmV3Rm9sZGVyRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmF2LWZvbGRlcicpLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRcdGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWNvbGxhcHNlZCcpO1xyXG5cdFx0fSk7XHJcblx0XHRyb290LmFwcGVuZENoaWxkKGZvbGRlckVsZW1lbnQpO1xyXG5cdFx0Ki9cclxuXHR9XHJcblx0aWYgKGluY2x1ZGVUeXBlcy5sZW5ndGggPiAxICYmIHN0eWxlICE9PSAnZ3JpZCcgJiYgKCFzaG93RW1wdHlGb2xkZXJzIHx8IHlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzKSkge1xyXG5cdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKHVsLCAxLCB5YW1sKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdvVGhyb3VnaEZvbGRlcnMocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgbGlzdDogSFRNTExJRWxlbWVudCB8IEhUTUxVTGlzdEVsZW1lbnQsIGZvbGRlcjogVEZvbGRlcixcclxuXHRkZXB0aDogbnVtYmVyLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgeWFtbDogeWFtbFNldHRpbmdzLCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSwgaW5jbHVkZVR5cGVzOiBzdHJpbmdbXSwgZGlzYWJsZUZpbGVUYWc6IGJvb2xlYW4pIHtcclxuXHRpZiAoc291cmNlRm9sZGVyUGF0aCA9PT0gJycpIHtcclxuXHRcdGRlcHRoLS07XHJcblx0fVxyXG5cdGxldCBmaWxlcyA9IGZvbGRlci5jaGlsZHJlbi5maWx0ZXIoKGZpbGUpID0+IHtcclxuXHRcdGNvbnN0IGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmICghZm9sZGVyUGF0aC5zdGFydHNXaXRoKHNvdXJjZUZvbGRlclBhdGgpKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cdFx0aWYgKChmaWxlLnBhdGguc3BsaXQoJy8nKS5sZW5ndGggLSBzb3VyY2VGb2xkZXJQYXRoLnNwbGl0KCcvJykubGVuZ3RoKSAtIDEgPCBkZXB0aCkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRmaWxlcyA9IHNvcnRGaWxlcyhmaWxlcywgeWFtbCwgcGx1Z2luKTtcclxuXHRjb25zdCB1bCA9IGxpc3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBhZGRGb2xkZXJMaXN0KHBsdWdpbiwgdWwsIHBhdGhCbGFja2xpc3QsIGZpbGUpO1xyXG5cdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHR9IGVsc2UgaWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRhZGRGaWxlTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlLCBpbmNsdWRlVHlwZXMsIGRpc2FibGVGaWxlVGFnKTtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gc29ydEZpbGVzKGZpbGVzOiBUQWJzdHJhY3RGaWxlW10sIHlhbWw6IHlhbWxTZXR0aW5ncywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGlmICgheWFtbD8uc29ydEJ5KSB7XHJcblx0XHR5YW1sLnNvcnRCeSA9IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5IHx8ICduYW1lJztcclxuXHR9XHJcblx0cmV0dXJuIGZpbGVzLnNvcnQoKGEsIGIpID0+IHtcclxuXHRcdC8vIHNvcnQgYnkgZm9sZGVyIGZpcnN0XHJcblx0XHRpZiAoYSBpbnN0YW5jZW9mIFRGb2xkZXIgJiYgIShiIGluc3RhbmNlb2YgVEZvbGRlcikpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGb2xkZXIpICYmIGIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGaWxlKSB8fCAhKGIgaW5zdGFuY2VvZiBURmlsZSkpIHsgcmV0dXJuIC0xOyB9XHJcblx0XHRpZiAoeWFtbC5zb3J0QnkgPT09ICdjcmVhdGVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0LmN0aW1lID4gYi5zdGF0LmN0aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnY3JlYXRlZEFzYycpIHtcclxuXHRcdFx0aWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAtMTtcclxuXHRcdFx0fSBlbHNlIGlmIChhLnN0YXQuY3RpbWUgPiBiLnN0YXQuY3RpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gMTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmICh5YW1sLnNvcnRCeSA9PT0gJ21vZGlmaWVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5tdGltZSA8IGIuc3RhdC5tdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnbW9kaWZpZWRBc2MnKSB7XHJcblx0XHRcdGlmIChhLnN0YXQubXRpbWUgPCBiLnN0YXQubXRpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gLTE7XHJcblx0XHRcdH0gZWxzZSBpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIDE7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdC8vIHNvcnQgYnkgbmFtZVxyXG5cdFx0aWYgKGEubmFtZSA8IGIubmFtZSAmJiB5YW1sLnNvcnRCeSA9PT0gJ25hbWUnKSB7XHJcblx0XHRcdHJldHVybiAtMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lID4gYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChhLm5hbWUgPiBiLm5hbWUgJiYgeWFtbC5zb3J0QnkgPT09ICduYW1lJykge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lIDwgYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gMDtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlRW1wdHlGb2xkZXJzKHVsOiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgZGVwdGg6IG51bWJlciwgeWFtbDogeWFtbFNldHRpbmdzKSB7XHJcblx0Y29uc3QgY2hpbGRyZW5zVG9SZW1vdmU6IENoaWxkTm9kZVtdID0gW107XHJcblx0dWwuY2hpbGROb2Rlcy5mb3JFYWNoKChlbCkgPT4ge1xyXG5cdFx0Y29uc3QgY2hpbGRyZW5zID0gKGVsIGFzIEVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3IoJ3VsJyk7XHJcblx0XHRpZiAoIWNoaWxkcmVucyB8fCBjaGlsZHJlbnMgPT09IG51bGwpIHsgcmV0dXJuOyB9XHJcblx0XHRpZiAoY2hpbGRyZW5zICYmICFjaGlsZHJlbnM/Lmhhc0NoaWxkTm9kZXMoKSAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCkpIHtcclxuXHRcdFx0Y2hpbGRyZW5zVG9SZW1vdmUucHVzaChlbCk7XHJcblx0XHR9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxMSUVsZW1lbnQpIHtcclxuXHRcdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKGVsLCBkZXB0aCArIDEsIHlhbWwpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdGNoaWxkcmVuc1RvUmVtb3ZlLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRpZiAoeWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgJiYgZGVwdGggPT09IDEpIHsgcmV0dXJuOyB9XHJcblx0XHRlbC5yZW1vdmUoKTtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRm9sZGVyTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZvbGRlcjogVEZvbGRlcikge1xyXG5cdGNvbnN0IGZvbGRlckl0ZW0gPSBsaXN0LmNyZWF0ZUVsKCdsaScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QgZm9sZGVyLWxpc3QnIH0pO1xyXG5cdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdGNvbnN0IGZvbGRlck5vdGVMaW5rID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtIGludGVybmFsLWxpbmsnLCBocmVmOiBmb2xkZXJOb3RlLnBhdGggfSk7XHJcblx0XHRmb2xkZXJOb3RlTGluay5pbm5lclRleHQgPSBmb2xkZXIubmFtZTtcclxuXHRcdHBhdGhCbGFja2xpc3QucHVzaChmb2xkZXJOb3RlLnBhdGgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnc3BhbicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtJyB9KTtcclxuXHRcdGZvbGRlck5hbWUuaW5uZXJUZXh0ID0gZm9sZGVyLm5hbWU7XHJcblx0fVxyXG5cdHJldHVybiBmb2xkZXJJdGVtO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRGaWxlTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZpbGU6IFRGaWxlLCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdLCBkaXNhYmxlRmlsZVRhZzogYm9vbGVhbikge1xyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID4gMCAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0aWYgKGZpbGUuZXh0ZW5zaW9uID09PSAnbWQnICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ21hcmtkb3duJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ2NhbnZhcycgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygnY2FudmFzJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ3BkZicgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygncGRmJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGltYWdlVHlwZXMgPSBbJ2pwZycsICdqcGVnJywgJ3BuZycsICdnaWYnLCAnc3ZnJywgJ3dlYnAnXTtcclxuXHRcdGlmIChpbWFnZVR5cGVzLmluY2x1ZGVzKGZpbGUuZXh0ZW5zaW9uKSAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdpbWFnZScpKSByZXR1cm47XHJcblx0XHRjb25zdCB2aWRlb1R5cGVzID0gWydtcDQnLCAnd2VibScsICdvZ3YnLCAnbW92JywgJ21rdiddO1xyXG5cdFx0aWYgKHZpZGVvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ3ZpZGVvJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGF1ZGlvVHlwZXMgPSBbJ21wMycsICd3YXYnLCAnbTRhJywgJzNncCcsICdmbGFjJywgJ29nZycsICdvZ2EnLCAnb3B1cyddO1xyXG5cdFx0aWYgKGF1ZGlvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmIGluY2x1ZGVUeXBlcy5pbmNsdWRlcygnYXVkaW8nKSkgcmV0dXJuO1xyXG5cdFx0Y29uc3QgYWxsVHlwZXMgPSBbJ21kJywgJ2NhbnZhcycsICdwZGYnLCAuLi5pbWFnZVR5cGVzLCAuLi52aWRlb1R5cGVzLCAuLi5hdWRpb1R5cGVzXTtcclxuXHRcdGlmICghYWxsVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ290aGVyJykpIHJldHVybjtcclxuXHR9XHJcblx0aWYgKHBhdGhCbGFja2xpc3QuaW5jbHVkZXMoZmlsZS5wYXRoKSkgcmV0dXJuO1xyXG5cdGNvbnN0IGxpc3RJdGVtID0gbGlzdC5jcmVhdGVFbCgnbGknLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1saXN0IGZpbGUtbGluaycgfSk7XHJcblx0Y29uc3QgbmFtZUl0ZW0gPSBsaXN0SXRlbS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdC1pdGVtJyB9KTtcclxuXHRjb25zdCBsaW5rID0gbmFtZUl0ZW0uY3JlYXRlRWwoJ2EnLCB7IGNsczogJ2ludGVybmFsLWxpbmsnLCBocmVmOiBmaWxlLnBhdGggfSk7XHJcblx0bGluay5pbm5lclRleHQgPSBmaWxlLmJhc2VuYW1lO1xyXG5cdGlmIChmaWxlLmV4dGVuc2lvbiAhPT0gJ21kJyAmJiAhZGlzYWJsZUZpbGVUYWcpIHtcclxuXHRcdG5hbWVJdGVtLmNyZWF0ZURpdih7IGNsczogJ25hdi1maWxlLXRhZycgfSkuaW5uZXJUZXh0ID0gZmlsZS5leHRlbnNpb247XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRBbGxGaWxlcyhmaWxlczogVEFic3RyYWN0RmlsZVtdLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGRlcHRoOiBudW1iZXIpIHtcclxuXHRjb25zdCBhbGxGaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGggLSAxKSB7XHJcblx0XHRcdFx0YWxsRmlsZXMucHVzaCguLi5nZXRBbGxGaWxlcyhmaWxlLmNoaWxkcmVuLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCkpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRhbGxGaWxlcy5wdXNoKGZpbGUpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdHJldHVybiBhbGxGaWxlcztcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgc3RyaW5naWZ5WWFtbCwgVEZpbGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IHlhbWxTZXR0aW5ncyB9IGZyb20gJ3NyYy9mb2xkZXJPdmVydmlldyc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IExpc3RDb21wb25lbnQgZnJvbSAnc3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50JztcclxuZXhwb3J0IGNsYXNzIEZvbGRlck92ZXJ2aWV3U2V0dGluZ3MgZXh0ZW5kcyBNb2RhbCB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHR5YW1sOiB5YW1sU2V0dGluZ3M7XHJcblx0Y3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0O1xyXG5cdGVsOiBIVE1MRWxlbWVudDtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgeWFtbDogeWFtbFNldHRpbmdzLCBjdHg6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIGVsOiBIVE1MRWxlbWVudCkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnlhbWwgPSB5YW1sO1xyXG5cdFx0dGhpcy5jdHggPSBjdHg7XHJcblx0XHR0aGlzLmVsID0gZWw7XHJcblx0XHRpZiAoIXRoaXMueWFtbCkge1xyXG5cdFx0XHR0aGlzLnlhbWwgPSB7XHJcblx0XHRcdFx0dGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0XHRkaXNhYmxlVGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlVGl0bGUsXHJcblx0XHRcdFx0ZGVwdGg6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kZXB0aCxcclxuXHRcdFx0XHR0eXBlOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0XHRpbmNsdWRlVHlwZXM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMsXHJcblx0XHRcdFx0c3R5bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zdHlsZSxcclxuXHRcdFx0XHRkaXNhYmxlRmlsZVRhZzogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRcdHNvcnRCeTogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNvcnRCeSxcclxuXHRcdFx0XHRzaG93RW1wdHlGb2xkZXJzOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc2hvd0VtcHR5Rm9sZGVycyxcclxuXHRcdFx0XHRvbmx5SW5jbHVkZVN1YmZvbGRlcnM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0fVxyXG5cdG9uT3BlbigpIHtcclxuXHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdH1cclxuXHRkaXNwbGF5KCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHRcdC8vIGNsb3NlIHdoZW4gdXNlciBwcmVzc2VzIGVudGVyXHJcblx0XHRjb250ZW50RWwuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XHJcblx0XHRcdGlmIChlLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnRm9sZGVyIG92ZXJ2aWV3IHNldHRpbmdzJyB9KTtcclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgdGhlIHRpdGxlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgdGl0bGUgc2hvdWxkIGJlIHNob3duJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgfHwgZmFsc2UpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdGlmICghdGhpcy55YW1sLmRpc2FibGVUaXRsZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ1RpdGxlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSB0aXRsZSBvZiB0aGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHQuYWRkVGV4dCgodGV4dCkgPT5cclxuXHRcdFx0XHRcdHRleHRcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8udGl0bGUgfHwgJ3t7Zm9sZGVyTmFtZX19IG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC50aXRsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblx0XHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGVudEVsKTtcclxuXHRcdHNldHRpbmcuc2V0TmFtZSgnSW5jbHVkZSB0eXBlcycpO1xyXG5cdFx0Y29uc3QgbGlzdCA9IHNldHRpbmcuY3JlYXRlTGlzdCgobGlzdDogTGlzdENvbXBvbmVudCkgPT5cclxuXHRcdFx0bGlzdFxyXG5cdFx0XHRcdC5hZGRNb2RhbCh0aGlzKVxyXG5cdFx0XHRcdC5zZXRWYWx1ZXModGhpcy55YW1sPy5pbmNsdWRlVHlwZXMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSlcclxuXHRcdFx0XHQuYWRkUmVzZXRCdXR0b24oKVxyXG5cdFx0KTtcclxuXHRcdGlmICgodGhpcy55YW1sPy5pbmNsdWRlVHlwZXM/Lmxlbmd0aCB8fCAwKSA8IDggJiYgIXRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0XHRzZXR0aW5nLmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcykgdGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMgfHwgW107XHJcblx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXMubWFwKCh0eXBlOiBzdHJpbmcpID0+IHR5cGUudG9Mb3dlckNhc2UoKSk7XHJcblx0XHRcdFx0Y29uc3Qgb3B0aW9ucyA9IFtcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICdtYXJrZG93bicsIGxhYmVsOiAnTWFya2Rvd24nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnZm9sZGVyJywgbGFiZWw6ICdGb2xkZXInIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnY2FudmFzJywgbGFiZWw6ICdDYW52YXMnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAncGRmJywgbGFiZWw6ICdQREYnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnaW1hZ2UnLCBsYWJlbDogJ0ltYWdlJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2F1ZGlvJywgbGFiZWw6ICdBdWRpbycgfSxcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICd2aWRlbycsIGxhYmVsOiAnVmlkZW8nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnb3RoZXInLCBsYWJlbDogJ0FsbCBvdGhlciBmaWxlIHR5cGVzJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2FsbCcsIGxhYmVsOiAnQWxsIGZpbGUgdHlwZXMnIH0sXHJcblx0XHRcdFx0XTtcclxuXHJcblx0XHRcdFx0b3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcclxuXHRcdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcz8uaW5jbHVkZXMob3B0aW9uLnZhbHVlKSkge1xyXG5cdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24ob3B0aW9uLnZhbHVlLCBvcHRpb24ubGFiZWwpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignKycsICcrJyk7XHJcblx0XHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUoJysnKTtcclxuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdGlmICh2YWx1ZSA9PT0gJ2FsbCcpIHtcclxuXHRcdFx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmZpbHRlcigodHlwZTogc3RyaW5nKSA9PiB0eXBlID09PSAnZm9sZGVyJyk7XHJcblx0XHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdFx0bGlzdC5zZXRWYWx1ZXModGhpcy55YW1sLmluY2x1ZGVUeXBlcyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRhd2FpdCBsaXN0LmFkZFZhbHVlKHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRsZXQgZGlzYWJsZUZpbGVUYWc7XHJcblx0XHR0aGlzLnlhbWwuaW5jbHVkZVR5cGVzPy5mb3JFYWNoKCh0eXBlOiBzdHJpbmcpID0+IHtcclxuXHRcdFx0dHlwZSA9PT0gJ2ZvbGRlcicgfHwgdHlwZSA9PT0gJ21hcmtkb3duJyA/IChkaXNhYmxlRmlsZVRhZyA9IHRydWUpIDogbnVsbDtcclxuXHRcdH0pO1xyXG5cdFx0aWYgKGRpc2FibGVGaWxlVGFnKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBmaWxlIHRhZycpXHJcblx0XHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgZmlsZSB0YWcgc2hvdWxkIGJlIHNob3duIGFmdGVyIHRoZSBmaWxlIG5hbWUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWwuZGlzYWJsZUZpbGVUYWcgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy55YW1sLmRpc2FibGVGaWxlVGFnID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZpbGUgZGVwdGgnKVxyXG5cdFx0XHQuc2V0RGVzYygnRmlsZSAmIGZvbGRlciA9ICsxIGRlcHRoJylcclxuXHRcdFx0LmFkZFNsaWRlcigoc2xpZGVyKSA9PlxyXG5cdFx0XHRcdHNsaWRlclxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uZGVwdGggfHwgMilcclxuXHRcdFx0XHRcdC5zZXRMaW1pdHMoMSwgMTAsIDEpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kZXB0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnT3ZlcnZpZXcgc3R5bGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSBzdHlsZSBvZiB0aGUgb3ZlcnZpZXcgKGdyaWQgc3R5bGUgc29vbiknKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdsaXN0JywgJ0xpc3QnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uc3R5bGUgfHwgJ2xpc3QnKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJ2xpc3QnKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5zdHlsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnU29ydCBmaWxlcyBieScpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaG93IHRoZSBmaWxlcyBzaG91bGQgYmUgc29ydGVkJylcclxuXHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT5cclxuXHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbmFtZScsICdOYW1lIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignY3JlYXRlZCcsICdDcmVhdGVkIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWQnLCAnTW9kaWZpZWQgZGVzY2VuZGluZycpXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCduYW1lQXNjJywgJ05hbWUgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5hZGRPcHRpb24oJ2NyZWF0ZWRBc2MnLCAnQ3JlYXRlZCBhc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWRBc2MnLCAnTW9kaWZpZWQgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWw/LnNvcnRCeSB8fCAnbmFtZScpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnbmFtZScgfCAnY3JlYXRlZCcgfCAnbW9kaWZpZWQnIHwgJ25hbWVBc2MnIHwgJ2NyZWF0ZWRBc2MnIHwgJ21vZGlmaWVkQXNjJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc29ydEJ5ID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdTaG93IGZvbGRlciBuYW1lcyBvZiBlbXB0eSBmb2xkZXJzJylcclxuXHRcdFx0LnNldERlc2MoJ1RoYXQgaW5jbHVkZXMgc3ViZm9sZGVycyBvZiB0aGUgY3VycmVudCBmb2xkZXIgd2hlbiB5b3UgYXJlIG9uIGZpbGUgZGVwdGggMScpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5zaG93RW1wdHlGb2xkZXJzIHx8IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zaG93RW1wdHlGb2xkZXJzIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc2hvd0VtcHR5Rm9sZGVycyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRpZiAodGhpcy55YW1sLnNob3dFbXB0eUZvbGRlcnMpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdPbmx5IHNob3cgZmlyc3QgZW1wdHkgc3ViZm9sZGVycyBvZiBjdXJyZW50IGZvbGRlcicpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3Lm9ubHlJbmNsdWRlU3ViZm9sZGVycyB8fCBmYWxzZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG5cdGFzeW5jIHVwZGF0ZVlhbWwoKSB7XHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0aGlzLmN0eC5zb3VyY2VQYXRoKTtcclxuXHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdGxldCBzdHJpbmdZYW1sID0gc3RyaW5naWZ5WWFtbCh0aGlzLnlhbWwpO1xyXG5cdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LnByb2Nlc3MoZmlsZSwgKHRleHQpID0+IHtcclxuXHRcdFx0Y29uc3QgaW5mbyA9IHRoaXMuY3R4LmdldFNlY3Rpb25JbmZvKHRoaXMuZWwpO1xyXG5cdFx0XHQvLyBjaGVjayBpZiBzdHJpbmdZYW1sIGVuZHMgd2l0aCBhIG5ld2xpbmVcclxuXHRcdFx0aWYgKHN0cmluZ1lhbWxbc3RyaW5nWWFtbC5sZW5ndGggLSAxXSAhPT0gJ1xcbicpIHtcclxuXHRcdFx0XHRzdHJpbmdZYW1sICs9ICdcXG4nO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChpbmZvKSB7XHJcblx0XHRcdFx0Y29uc3QgeyBsaW5lU3RhcnQgfSA9IGluZm87XHJcblx0XHRcdFx0Y29uc3QgbGluZUVuZCA9IHRoaXMuZ2V0Q29kZUJsb2NrRW5kTGluZSh0ZXh0LCBsaW5lU3RhcnQpO1xyXG5cdFx0XHRcdGlmIChsaW5lRW5kID09PSAtMSB8fCAhbGluZUVuZCkgcmV0dXJuIHRleHQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZUxlbmd0aCA9IGxpbmVFbmQgLSBsaW5lU3RhcnQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdFx0XHRsaW5lcy5zcGxpY2UobGluZVN0YXJ0LCBsaW5lTGVuZ3RoICsgMSwgYFxcYFxcYFxcYGZvbGRlci1vdmVydmlld1xcbiR7c3RyaW5nWWFtbH1cXGBcXGBcXGBgKTtcclxuXHRcdFx0XHRyZXR1cm4gbGluZXMuam9pbignXFxuJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGBcXGBcXGBcXGBmb2xkZXItb3ZlcnZpZXdcXG4ke3N0cmluZ1lhbWx9XFxgXFxgXFxgYDtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRnZXRDb2RlQmxvY2tFbmRMaW5lKHRleHQ6IHN0cmluZywgc3RhcnRMaW5lOiBudW1iZXIsIGNvdW50ID0gMSkge1xyXG5cdFx0bGV0IGxpbmUgPSBzdGFydExpbmUgKyAxO1xyXG5cdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdHdoaWxlIChsaW5lIDwgbGluZXMubGVuZ3RoKSB7XHJcblx0XHRcdGlmIChjb3VudCA+IDIwKSB7IHJldHVybiAtMTsgfVxyXG5cdFx0XHRpZiAobGluZXNbbGluZV0uc3RhcnRzV2l0aCgnYGBgJykpIHtcclxuXHRcdFx0XHRyZXR1cm4gbGluZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsaW5lKys7XHJcblx0XHRcdGNvdW50Kys7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGluZTtcclxuXHR9XHJcbn1cclxuXHJcbiIsICJpbXBvcnQgeyBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi4vbW9kYWxzL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGlzdENvbXBvbmVudCB7XHJcblx0Y29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xyXG5cdGNvbnRyb2xFbDogSFRNTEVsZW1lbnQ7XHJcblx0ZW1wdHlTdGF0ZUVsOiBIVE1MRWxlbWVudDtcclxuXHRsaXN0RWw6IEhUTUxFbGVtZW50O1xyXG5cdHZhbHVlczogc3RyaW5nW107XHJcblx0bW9kYWw6IEZvbGRlck92ZXJ2aWV3U2V0dGluZ3M7XHJcblx0Y29uc3RydWN0b3IoY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KSB7XHJcblx0XHR0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XHJcblx0XHR0aGlzLmNvbnRyb2xFbCA9IGNvbnRhaW5lckVsLnF1ZXJ5U2VsZWN0b3IoJy5zZXR0aW5nLWl0ZW0tY29udHJvbCcpIHx8IGNvbnRhaW5lckVsO1xyXG5cdFx0dGhpcy5saXN0RWwgPSB0aGlzLmNvbnRyb2xFbC5jcmVhdGVEaXYoJ3NldHRpbmctY29tbWFuZC1ob3RrZXlzJyk7XHJcblx0fVxyXG5cdGFkZE1vZGFsKG1vZGFsOiBGb2xkZXJPdmVydmlld1NldHRpbmdzKSB7XHJcblx0XHR0aGlzLm1vZGFsID0gbW9kYWw7XHJcblx0XHR0aGlzLnZhbHVlcyA9IG1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzIHx8IFtdO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdHNldFZhbHVlcyh2YWx1ZXM6IHN0cmluZ1tdKSB7XHJcblx0XHR0aGlzLmxpc3RFbC5lbXB0eSgpO1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB2YWx1ZXM7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdmFsdWVzO1xyXG5cdFx0aWYgKHZhbHVlcy5sZW5ndGggIT09IDApIHtcclxuXHRcdFx0dmFsdWVzLmZvckVhY2goKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5hZGRFbGVtZW50KHZhbHVlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHR0aGlzLm1vZGFsLnVwZGF0ZVlhbWwoKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRhZGRFbGVtZW50KHZhbHVlOiBzdHJpbmcpIHtcclxuXHRcdHRoaXMubGlzdEVsLmNyZWF0ZVNwYW4oJ3NldHRpbmctaG90a2V5JywgKHNwYW4pID0+IHtcclxuXHRcdFx0c3Bhbi5pbm5lclRleHQgPSB2YWx1ZTtcclxuXHRcdFx0Y29uc3QgcmVtb3ZlU3BhbiA9IHNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlIHNldHRpbmctaG90a2V5LWljb24nIH0pO1xyXG5cdFx0XHQvLyBhZGQgc3ZnIGljb25cclxuXHRcdFx0Y29uc3Qgc3ZnID0gJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBjbGFzcz1cInN2Zy1pY29uIGx1Y2lkZS14XCI+PGxpbmUgeDE9XCIxOFwiIHkxPVwiNlwiIHgyPVwiNlwiIHkyPVwiMThcIj48L2xpbmU+PGxpbmUgeDE9XCI2XCIgeTE9XCI2XCIgeDI9XCIxOFwiIHkyPVwiMThcIj48L2xpbmU+PC9zdmc+JztcclxuXHRcdFx0Y29uc3Qgc3ZnRWxlbWVudCA9IHJlbW92ZVNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlLWljb24nIH0pO1xyXG5cdFx0XHRzdmdFbGVtZW50LmlubmVySFRNTCA9IHN2ZztcclxuXHRcdFx0cmVtb3ZlU3Bhbi5vbkNsaWNrRXZlbnQoKGUpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZVZhbHVlKHZhbHVlKTtcclxuXHRcdFx0XHRzcGFuLnJlbW92ZSgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRhc3luYyBhZGRWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnZhbHVlcy5wdXNoKHZhbHVlKTtcclxuXHRcdHRoaXMuYWRkRWxlbWVudCh2YWx1ZSk7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdGhpcy52YWx1ZXM7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0YWRkUmVzZXRCdXR0b24oKSB7XHJcblx0XHRjb25zdCByZXNldEJ1dHRvbiA9IHRoaXMuY29udHJvbEVsLmNyZWF0ZUVsKCdzcGFuJywgeyBjbHM6ICdjbGlja2FibGUtaWNvbiBzZXR0aW5nLXJlc3RvcmUtaG90a2V5LWJ1dHRvbicgfSk7XHJcblx0XHRjb25zdCBzdmcgPSAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIGNsYXNzPVwic3ZnLWljb24gbHVjaWRlLXJvdGF0ZS1jY3dcIj48cGF0aCBkPVwiTTMgMnY2aDZcIj48L3BhdGg+PHBhdGggZD1cIk0zIDEzYTkgOSAwIDEgMCAzLTcuN0wzIDhcIj48L3BhdGg+PC9zdmc+JztcclxuXHRcdHJlc2V0QnV0dG9uLmlubmVySFRNTCA9IHN2ZztcclxuXHRcdHJlc2V0QnV0dG9uLm9uQ2xpY2tFdmVudCgoZSkgPT4ge1xyXG5cdFx0XHR0aGlzLm1vZGFsLnBsdWdpbi5sb2FkU2V0dGluZ3MoKTtcclxuXHRcdFx0dGhpcy5zZXRWYWx1ZXModGhpcy5tb2RhbC5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSk7XHJcblx0XHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0cmVtb3ZlVmFsdWUodmFsdWU6IHN0cmluZykge1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlcy5maWx0ZXIoKHYpID0+IHYgIT09IHZhbHVlKTtcclxuXHRcdHRoaXMuc2V0VmFsdWVzKHRoaXMudmFsdWVzKTtcclxuXHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGlzdCh0aGlzOiBTZXR0aW5nLCBjYjogKGxpc3Q6IExpc3RDb21wb25lbnQpID0+IExpc3RDb21wb25lbnQpIHtcclxuXHRjb25zdCBsaXN0ID0gbmV3IExpc3RDb21wb25lbnQodGhpcy5zZXR0aW5nRWwpO1xyXG5cdGNiKGxpc3QpO1xyXG5cdHJldHVybiBsaXN0O1xyXG59XHJcblxyXG4vLyBMaXN0Q29tcG9uZW50LnByb3RvdHlwZS5zZXRWYWx1ZXMgPSBzZXRWYWx1ZXM7XHJcbihTZXR0aW5nIGFzIGFueSkucHJvdG90eXBlLmNyZWF0ZUxpc3QgPSBjcmVhdGVMaXN0O1xyXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFDQSxXQUFPLGVBQWUsU0FBUyxjQUFjLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFBQTtBQUFBOzs7QUNENUQ7QUFBQTtBQUFBO0FBQ0EsV0FBTyxlQUFlLFNBQVMsY0FBYyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUE7QUFBQTs7O0FDRDVEO0FBQUE7QUFBQTtBQUNBLFdBQU8sZUFBZSxTQUFTLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUFBO0FBQUE7OztBQ0Q1RDtBQUFBO0FBQUE7QUFDQSxRQUFJLGtCQUFtQixXQUFRLFFBQUssbUJBQXFCLFFBQU8sU0FBVSxTQUFTLEdB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QUFrQixFQUFFLFFBQVEsQ0FBQyxTQUFTO0FBQ3BELFVBQUksQ0FBRSxpQkFBZ0IsNEJBQVU7QUFBRTtBQUFBLE1BQVE7QUFDMUMsWUFBTSxhQUFhLGNBQWMsTUFBTSxLQUFLLElBQUk7QUFDaEQsVUFBSSxDQUFDLFlBQVk7QUFDaEIsYUFBSyxxQkFBcUIsNkJBQU0sTUFBTSxpQkFBaUI7QUFDdkQ7QUFBQSxNQUNEO0FBRUEsWUFBTSxpQkFBaUIsa0JBQWtCLE1BQU0sS0FBSyxJQUFJO0FBR3hELFVBQUksaURBQWdCLG1CQUFtQjtBQUN0QyxhQUFLLHFCQUFxQixXQUFXLE1BQU0sZ0JBQWdCO0FBQzNELGFBQUsscUJBQXFCLEtBQUssTUFBTSxpQkFBaUI7QUFBQSxNQUN2RCxPQUFPO0FBQ04sYUFBSyxxQkFBcUIsV0FBVyxNQUFNLGdCQUFnQjtBQUMzRCxhQUFLLHFCQUFxQixLQUFLLE1BQU0saUJBQWlCO0FBQUEsTUFDdkQ7QUFBQSxJQUNELENBQUM7QUFBQSxFQUNGO0FBQUEsRUFFQSxpQkFBaUI7QUFDaEIsYUFBUyxpQkFBaUIsOEJBQThCLEVBQ3RELFFBQVEsQ0FBQyxZQUF5QjtBQUNsQyxVQUFJLFFBQVE7QUFBUztBQUNyQixjQUFRLFVBQVUsQ0FBQyxVQUFzQixrQkFBa0IsT0FBTyxJQUFJO0FBQUEsSUFDdkUsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQUVBLFdBQVc7QUFDVixZQUFRLElBQUksK0JBQStCO0FBQzNDLFNBQUssU0FBUyxXQUFXO0FBQ3pCLGFBQVMsS0FBSyxVQUFVLE9BQU8scUJBQXFCO0FBQ3BELGFBQVMsS0FBSyxVQUFVLE9BQU8sdUJBQXVCO0FBQ3RELGFBQVMsS0FBSyxVQUFVLE9BQU8sa0JBQWtCO0FBQ2pELGFBQVMsS0FBSyxVQUFVLE9BQU8sK0JBQStCO0FBQzlELFFBQUksS0FBSyxpQkFBaUI7QUFBRSxXQUFLLGdCQUFnQixZQUFZLFdBQVc7QUFBQSxJQUFHO0FBQzNFLFFBQUksS0FBSyxhQUFhO0FBQ3JCLFdBQUssWUFBWSxZQUFZO0FBQUEsSUFDOUI7QUFBQSxFQUVEO0FBQUEsRUFFQSxNQUFNLGVBQWU7QUFDcEIsU0FBSyxXQUFXLE9BQU8sT0FBTyxDQUFDLEdBQUcsa0JBQWtCLE1BQU0sS0FBSyxTQUFTLENBQUM7QUFBQSxFQUMxRTtBQUFBLEVBRUEsTUFBTSxlQUFlO0FBQ3BCLFVBQU0sS0FBSyxTQUFTLEtBQUssUUFBUTtBQUVqQyxTQUFLLGdCQUFnQixJQUFJO0FBQUEsRUFDMUI7QUFDRDsiLAogICJuYW1lcyI6IFtdCn0K From e04f41d25fc411ddb8836df86e48a94ee5fbeec4 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Tue, 1 Aug 2023 21:44:42 +0200 Subject: [PATCH 2/2] Delete main.js --- main.js | 4250 ------------------------------------------------------- 1 file changed, 4250 deletions(-) delete mode 100644 main.js diff --git a/main.js b/main.js deleted file mode 100644 index 9d02e2e..0000000 --- a/main.js +++ /dev/null @@ -1,4250 +0,0 @@ -/* -THIS IS A GENERATED/BUNDLED FILE BY ESBUILD -if you want to view the source, please visit the github repository of this plugin -*/ - -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; -}; -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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js -var require_Api = __commonJS({ - "node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } -}); - -// node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js -var require_EventDispatcher = __commonJS({ - "node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } -}); - -// node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js -var require_Resolver = __commonJS({ - "node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } -}); - -// node_modules/front-matter-plugin-api-provider/lib/index.js -var require_lib = __commonJS({ - "node_modules/front-matter-plugin-api-provider/lib/index.js"(exports) { - "use strict"; - var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) { - if (k2 === void 0) - k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { - return m[k]; - } }; - } - Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { - if (k2 === void 0) - k2 = k; - o[k2] = m[k]; - }); - var __exportStar = exports && exports.__exportStar || function(m, exports2) { - for (var p in m) - if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) - __createBinding(exports2, m, p); - }; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.getApiSafe = exports.getDefer = exports.isPluginEnabled = exports.PluginNotEnabledError = exports.pluginId = void 0; - __exportStar(require_Api(), exports); - __exportStar(require_EventDispatcher(), exports); - __exportStar(require_Resolver(), exports); - exports.pluginId = "obsidian-front-matter-title-plugin"; - var PluginNotEnabledError = class extends Error { - }; - exports.PluginNotEnabledError = PluginNotEnabledError; - function isPluginEnabled(app2) { - var _a, _b, _c; - return (_c = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.enabledPlugins) === null || _b === void 0 ? void 0 : _b.has(exports.pluginId)) !== null && _c !== void 0 ? _c : false; - } - exports.isPluginEnabled = isPluginEnabled; - function getDefer2(app2) { - var _a, _b, _c, _d; - const plugin = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin(exports.pluginId)) !== null && _b !== void 0 ? _b : null; - const defer = (_d = (_c = plugin === null || plugin === void 0 ? void 0 : plugin.getDefer) === null || _c === void 0 ? void 0 : _c.call(plugin)) !== null && _d !== void 0 ? _d : null; - if (defer === null) { - throw new PluginNotEnabledError(`Plugin ${exports.pluginId} is not enabled or old version`); - } - return defer; - } - exports.getDefer = getDefer2; - function getApiSafe(app2) { - return new ApiWrapper(null, app2); - } - exports.getApiSafe = getApiSafe; - var ApiWrapper = class { - constructor(api, app2) { - this.api = api; - this.app = app2; - } - before() { - if (this.api !== null) { - return; - } - const defer = this.getDeffer(); - if (defer === null) { - return; - } - const api = defer.getApi(); - if (api === null) { - return defer.awaitPlugin().then(() => { - this.api = defer.getApi(); - }); - } else { - this.api = api; - } - } - getDeffer() { - try { - return getDefer2(this.app); - } catch (e) { - if (e instanceof PluginNotEnabledError) { - return null; - } - throw e; - } - } - getResolverFactory() { - var _a, _b; - this.before(); - return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getResolverFactory()) !== null && _b !== void 0 ? _b : null; - } - getEventDispatcher() { - var _a, _b; - this.before(); - return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEventDispatcher()) !== null && _b !== void 0 ? _b : null; - } - getEnabledFeatures() { - var _a, _b; - this.before(); - return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEnabledFeatures()) !== null && _b !== void 0 ? _b : []; - } - }; - } -}); - -// src/main.ts -var main_exports = {}; -__export(main_exports, { - default: () => FolderNotesPlugin -}); -module.exports = __toCommonJS(main_exports); -var import_obsidian19 = require("obsidian"); - -// src/settings.ts -var import_obsidian12 = require("obsidian"); - -// src/suggesters/templateSuggester.ts -var import_obsidian3 = require("obsidian"); - -// src/suggesters/suggest.ts -var import_obsidian = require("obsidian"); - -// node_modules/@popperjs/core/lib/enums.js -var top = "top"; -var bottom = "bottom"; -var right = "right"; -var left = "left"; -var auto = "auto"; -var basePlacements = [top, bottom, right, left]; -var start = "start"; -var end = "end"; -var clippingParents = "clippingParents"; -var viewport = "viewport"; -var popper = "popper"; -var reference = "reference"; -var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) { - return acc.concat([placement + "-" + start, placement + "-" + end]); -}, []); -var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) { - return acc.concat([placement, placement + "-" + start, placement + "-" + end]); -}, []); -var beforeRead = "beforeRead"; -var read = "read"; -var afterRead = "afterRead"; -var beforeMain = "beforeMain"; -var main = "main"; -var afterMain = "afterMain"; -var beforeWrite = "beforeWrite"; -var write = "write"; -var afterWrite = "afterWrite"; -var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; - -// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js -function getNodeName(element) { - return element ? (element.nodeName || "").toLowerCase() : null; -} - -// node_modules/@popperjs/core/lib/dom-utils/getWindow.js -function getWindow(node) { - if (node == null) { - return window; - } - if (node.toString() !== "[object Window]") { - var ownerDocument = node.ownerDocument; - return ownerDocument ? ownerDocument.defaultView || window : window; - } - return node; -} - -// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js -function isElement(node) { - var OwnElement = getWindow(node).Element; - return node instanceof OwnElement || node instanceof Element; -} -function isHTMLElement(node) { - var OwnElement = getWindow(node).HTMLElement; - return node instanceof OwnElement || node instanceof HTMLElement; -} -function isShadowRoot(node) { - if (typeof ShadowRoot === "undefined") { - return false; - } - var OwnElement = getWindow(node).ShadowRoot; - return node instanceof OwnElement || node instanceof ShadowRoot; -} - -// node_modules/@popperjs/core/lib/modifiers/applyStyles.js -function applyStyles(_ref) { - var state = _ref.state; - Object.keys(state.elements).forEach(function(name) { - var style = state.styles[name] || {}; - var attributes = state.attributes[name] || {}; - var element = state.elements[name]; - if (!isHTMLElement(element) || !getNodeName(element)) { - return; - } - Object.assign(element.style, style); - Object.keys(attributes).forEach(function(name2) { - var value = attributes[name2]; - if (value === false) { - element.removeAttribute(name2); - } else { - element.setAttribute(name2, value === true ? "" : value); - } - }); - }); -} -function effect(_ref2) { - var state = _ref2.state; - var initialStyles = { - popper: { - position: state.options.strategy, - left: "0", - top: "0", - margin: "0" - }, - arrow: { - position: "absolute" - }, - reference: {} - }; - Object.assign(state.elements.popper.style, initialStyles.popper); - state.styles = initialStyles; - if (state.elements.arrow) { - Object.assign(state.elements.arrow.style, initialStyles.arrow); - } - return function() { - Object.keys(state.elements).forEach(function(name) { - var element = state.elements[name]; - var attributes = state.attributes[name] || {}; - var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); - var style = styleProperties.reduce(function(style2, property) { - style2[property] = ""; - return style2; - }, {}); - if (!isHTMLElement(element) || !getNodeName(element)) { - return; - } - Object.assign(element.style, style); - Object.keys(attributes).forEach(function(attribute) { - element.removeAttribute(attribute); - }); - }); - }; -} -var applyStyles_default = { - name: "applyStyles", - enabled: true, - phase: "write", - fn: applyStyles, - effect, - requires: ["computeStyles"] -}; - -// node_modules/@popperjs/core/lib/utils/getBasePlacement.js -function getBasePlacement(placement) { - return placement.split("-")[0]; -} - -// node_modules/@popperjs/core/lib/utils/math.js -var max = Math.max; -var min = Math.min; -var round = Math.round; - -// node_modules/@popperjs/core/lib/utils/userAgent.js -function getUAString() { - var uaData = navigator.userAgentData; - if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { - return uaData.brands.map(function(item) { - return item.brand + "/" + item.version; - }).join(" "); - } - return navigator.userAgent; -} - -// node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js -function isLayoutViewport() { - return !/^((?!chrome|android).)*safari/i.test(getUAString()); -} - -// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js -function getBoundingClientRect(element, includeScale, isFixedStrategy) { - if (includeScale === void 0) { - includeScale = false; - } - if (isFixedStrategy === void 0) { - isFixedStrategy = false; - } - var clientRect = element.getBoundingClientRect(); - var scaleX = 1; - var scaleY = 1; - if (includeScale && isHTMLElement(element)) { - scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; - scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; - } - var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport; - var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; - var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; - var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; - var width = clientRect.width / scaleX; - var height = clientRect.height / scaleY; - return { - width, - height, - top: y, - right: x + width, - bottom: y + height, - left: x, - x, - y - }; -} - -// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js -function getLayoutRect(element) { - var clientRect = getBoundingClientRect(element); - var width = element.offsetWidth; - var height = element.offsetHeight; - if (Math.abs(clientRect.width - width) <= 1) { - width = clientRect.width; - } - if (Math.abs(clientRect.height - height) <= 1) { - height = clientRect.height; - } - return { - x: element.offsetLeft, - y: element.offsetTop, - width, - height - }; -} - -// node_modules/@popperjs/core/lib/dom-utils/contains.js -function contains(parent, child) { - var rootNode = child.getRootNode && child.getRootNode(); - if (parent.contains(child)) { - return true; - } else if (rootNode && isShadowRoot(rootNode)) { - var next = child; - do { - if (next && parent.isSameNode(next)) { - return true; - } - next = next.parentNode || next.host; - } while (next); - } - return false; -} - -// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js -function getComputedStyle(element) { - return getWindow(element).getComputedStyle(element); -} - -// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js -function isTableElement(element) { - return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0; -} - -// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js -function getDocumentElement(element) { - return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement; -} - -// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js -function getParentNode(element) { - if (getNodeName(element) === "html") { - return element; - } - return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element); -} - -// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js -function getTrueOffsetParent(element) { - if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") { - return null; - } - return element.offsetParent; -} -function getContainingBlock(element) { - var isFirefox = /firefox/i.test(getUAString()); - var isIE = /Trident/i.test(getUAString()); - if (isIE && isHTMLElement(element)) { - var elementCss = getComputedStyle(element); - if (elementCss.position === "fixed") { - return null; - } - } - var currentNode = getParentNode(element); - if (isShadowRoot(currentNode)) { - currentNode = currentNode.host; - } - while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) { - var css = getComputedStyle(currentNode); - if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { - return currentNode; - } else { - currentNode = currentNode.parentNode; - } - } - return null; -} -function getOffsetParent(element) { - var window2 = getWindow(element); - var offsetParent = getTrueOffsetParent(element); - while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") { - offsetParent = getTrueOffsetParent(offsetParent); - } - if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) { - return window2; - } - return offsetParent || getContainingBlock(element) || window2; -} - -// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js -function getMainAxisFromPlacement(placement) { - return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y"; -} - -// node_modules/@popperjs/core/lib/utils/within.js -function within(min2, value, max2) { - return max(min2, min(value, max2)); -} -function withinMaxClamp(min2, value, max2) { - var v = within(min2, value, max2); - return v > max2 ? max2 : v; -} - -// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js -function getFreshSideObject() { - return { - top: 0, - right: 0, - bottom: 0, - left: 0 - }; -} - -// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js -function mergePaddingObject(paddingObject) { - return Object.assign({}, getFreshSideObject(), paddingObject); -} - -// node_modules/@popperjs/core/lib/utils/expandToHashMap.js -function expandToHashMap(value, keys) { - return keys.reduce(function(hashMap, key) { - hashMap[key] = value; - return hashMap; - }, {}); -} - -// node_modules/@popperjs/core/lib/modifiers/arrow.js -var toPaddingObject = function toPaddingObject2(padding, state) { - padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { - placement: state.placement - })) : padding; - return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); -}; -function arrow(_ref) { - var _state$modifiersData$; - var state = _ref.state, name = _ref.name, options = _ref.options; - var arrowElement = state.elements.arrow; - var popperOffsets2 = state.modifiersData.popperOffsets; - var basePlacement = getBasePlacement(state.placement); - var axis = getMainAxisFromPlacement(basePlacement); - var isVertical = [left, right].indexOf(basePlacement) >= 0; - var len = isVertical ? "height" : "width"; - if (!arrowElement || !popperOffsets2) { - return; - } - var paddingObject = toPaddingObject(options.padding, state); - var arrowRect = getLayoutRect(arrowElement); - var minProp = axis === "y" ? top : left; - var maxProp = axis === "y" ? bottom : right; - var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len]; - var startDiff = popperOffsets2[axis] - state.rects.reference[axis]; - var arrowOffsetParent = getOffsetParent(arrowElement); - var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; - var centerToReference = endDiff / 2 - startDiff / 2; - var min2 = paddingObject[minProp]; - var max2 = clientSize - arrowRect[len] - paddingObject[maxProp]; - var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; - var offset2 = within(min2, center, max2); - var axisProp = axis; - state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$); -} -function effect2(_ref2) { - var state = _ref2.state, options = _ref2.options; - var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; - if (arrowElement == null) { - return; - } - if (typeof arrowElement === "string") { - arrowElement = state.elements.popper.querySelector(arrowElement); - if (!arrowElement) { - return; - } - } - if (!contains(state.elements.popper, arrowElement)) { - return; - } - state.elements.arrow = arrowElement; -} -var arrow_default = { - name: "arrow", - enabled: true, - phase: "main", - fn: arrow, - effect: effect2, - requires: ["popperOffsets"], - requiresIfExists: ["preventOverflow"] -}; - -// node_modules/@popperjs/core/lib/utils/getVariation.js -function getVariation(placement) { - return placement.split("-")[1]; -} - -// node_modules/@popperjs/core/lib/modifiers/computeStyles.js -var unsetSides = { - top: "auto", - right: "auto", - bottom: "auto", - left: "auto" -}; -function roundOffsetsByDPR(_ref, win) { - var x = _ref.x, y = _ref.y; - var dpr = win.devicePixelRatio || 1; - return { - x: round(x * dpr) / dpr || 0, - y: round(y * dpr) / dpr || 0 - }; -} -function mapToStyles(_ref2) { - var _Object$assign2; - var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; - var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; - var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ - x, - y - }) : { - x, - y - }; - x = _ref3.x; - y = _ref3.y; - var hasX = offsets.hasOwnProperty("x"); - var hasY = offsets.hasOwnProperty("y"); - var sideX = left; - var sideY = top; - var win = window; - if (adaptive) { - var offsetParent = getOffsetParent(popper2); - var heightProp = "clientHeight"; - var widthProp = "clientWidth"; - if (offsetParent === getWindow(popper2)) { - offsetParent = getDocumentElement(popper2); - if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") { - heightProp = "scrollHeight"; - widthProp = "scrollWidth"; - } - } - offsetParent = offsetParent; - if (placement === top || (placement === left || placement === right) && variation === end) { - sideY = bottom; - var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp]; - y -= offsetY - popperRect.height; - y *= gpuAcceleration ? 1 : -1; - } - if (placement === left || (placement === top || placement === bottom) && variation === end) { - sideX = right; - var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp]; - x -= offsetX - popperRect.width; - x *= gpuAcceleration ? 1 : -1; - } - } - var commonStyles = Object.assign({ - position - }, adaptive && unsetSides); - var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ - x, - y - }, getWindow(popper2)) : { - x, - y - }; - x = _ref4.x; - y = _ref4.y; - if (gpuAcceleration) { - var _Object$assign; - return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); - } - return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); -} -function computeStyles(_ref5) { - var state = _ref5.state, options = _ref5.options; - var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; - var commonStyles = { - placement: getBasePlacement(state.placement), - variation: getVariation(state.placement), - popper: state.elements.popper, - popperRect: state.rects.popper, - gpuAcceleration, - isFixed: state.options.strategy === "fixed" - }; - if (state.modifiersData.popperOffsets != null) { - state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.popperOffsets, - position: state.options.strategy, - adaptive, - roundOffsets - }))); - } - if (state.modifiersData.arrow != null) { - state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.arrow, - position: "absolute", - adaptive: false, - roundOffsets - }))); - } - state.attributes.popper = Object.assign({}, state.attributes.popper, { - "data-popper-placement": state.placement - }); -} -var computeStyles_default = { - name: "computeStyles", - enabled: true, - phase: "beforeWrite", - fn: computeStyles, - data: {} -}; - -// node_modules/@popperjs/core/lib/modifiers/eventListeners.js -var passive = { - passive: true -}; -function effect3(_ref) { - var state = _ref.state, instance = _ref.instance, options = _ref.options; - var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize; - var window2 = getWindow(state.elements.popper); - var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); - if (scroll) { - scrollParents.forEach(function(scrollParent) { - scrollParent.addEventListener("scroll", instance.update, passive); - }); - } - if (resize) { - window2.addEventListener("resize", instance.update, passive); - } - return function() { - if (scroll) { - scrollParents.forEach(function(scrollParent) { - scrollParent.removeEventListener("scroll", instance.update, passive); - }); - } - if (resize) { - window2.removeEventListener("resize", instance.update, passive); - } - }; -} -var eventListeners_default = { - name: "eventListeners", - enabled: true, - phase: "write", - fn: function fn() { - }, - effect: effect3, - data: {} -}; - -// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js -var hash = { - left: "right", - right: "left", - bottom: "top", - top: "bottom" -}; -function getOppositePlacement(placement) { - return placement.replace(/left|right|bottom|top/g, function(matched) { - return hash[matched]; - }); -} - -// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js -var hash2 = { - start: "end", - end: "start" -}; -function getOppositeVariationPlacement(placement) { - return placement.replace(/start|end/g, function(matched) { - return hash2[matched]; - }); -} - -// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js -function getWindowScroll(node) { - var win = getWindow(node); - var scrollLeft = win.pageXOffset; - var scrollTop = win.pageYOffset; - return { - scrollLeft, - scrollTop - }; -} - -// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js -function getWindowScrollBarX(element) { - return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; -} - -// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js -function getViewportRect(element, strategy) { - var win = getWindow(element); - var html = getDocumentElement(element); - var visualViewport = win.visualViewport; - var width = html.clientWidth; - var height = html.clientHeight; - var x = 0; - var y = 0; - if (visualViewport) { - width = visualViewport.width; - height = visualViewport.height; - var layoutViewport = isLayoutViewport(); - if (layoutViewport || !layoutViewport && strategy === "fixed") { - x = visualViewport.offsetLeft; - y = visualViewport.offsetTop; - } - } - return { - width, - height, - x: x + getWindowScrollBarX(element), - y - }; -} - -// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js -function getDocumentRect(element) { - var _element$ownerDocumen; - var html = getDocumentElement(element); - var winScroll = getWindowScroll(element); - var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; - var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); - var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); - var x = -winScroll.scrollLeft + getWindowScrollBarX(element); - var y = -winScroll.scrollTop; - if (getComputedStyle(body || html).direction === "rtl") { - x += max(html.clientWidth, body ? body.clientWidth : 0) - width; - } - return { - width, - height, - x, - y - }; -} - -// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js -function isScrollParent(element) { - var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; - return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); -} - -// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js -function getScrollParent(node) { - if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) { - return node.ownerDocument.body; - } - if (isHTMLElement(node) && isScrollParent(node)) { - return node; - } - return getScrollParent(getParentNode(node)); -} - -// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js -function listScrollParents(element, list) { - var _element$ownerDocumen; - if (list === void 0) { - list = []; - } - var scrollParent = getScrollParent(element); - var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); - var win = getWindow(scrollParent); - var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; - var updatedList = list.concat(target); - return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target))); -} - -// node_modules/@popperjs/core/lib/utils/rectToClientRect.js -function rectToClientRect(rect) { - return Object.assign({}, rect, { - left: rect.x, - top: rect.y, - right: rect.x + rect.width, - bottom: rect.y + rect.height - }); -} - -// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js -function getInnerBoundingClientRect(element, strategy) { - var rect = getBoundingClientRect(element, false, strategy === "fixed"); - rect.top = rect.top + element.clientTop; - rect.left = rect.left + element.clientLeft; - rect.bottom = rect.top + element.clientHeight; - rect.right = rect.left + element.clientWidth; - rect.width = element.clientWidth; - rect.height = element.clientHeight; - rect.x = rect.left; - rect.y = rect.top; - return rect; -} -function getClientRectFromMixedType(element, clippingParent, strategy) { - return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); -} -function getClippingParents(element) { - var clippingParents2 = listScrollParents(getParentNode(element)); - var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0; - var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; - if (!isElement(clipperElement)) { - return []; - } - return clippingParents2.filter(function(clippingParent) { - return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body"; - }); -} -function getClippingRect(element, boundary, rootBoundary, strategy) { - var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); - var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]); - var firstClippingParent = clippingParents2[0]; - var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) { - var rect = getClientRectFromMixedType(element, clippingParent, strategy); - accRect.top = max(rect.top, accRect.top); - accRect.right = min(rect.right, accRect.right); - accRect.bottom = min(rect.bottom, accRect.bottom); - accRect.left = max(rect.left, accRect.left); - return accRect; - }, getClientRectFromMixedType(element, firstClippingParent, strategy)); - clippingRect.width = clippingRect.right - clippingRect.left; - clippingRect.height = clippingRect.bottom - clippingRect.top; - clippingRect.x = clippingRect.left; - clippingRect.y = clippingRect.top; - return clippingRect; -} - -// node_modules/@popperjs/core/lib/utils/computeOffsets.js -function computeOffsets(_ref) { - var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement; - var basePlacement = placement ? getBasePlacement(placement) : null; - var variation = placement ? getVariation(placement) : null; - var commonX = reference2.x + reference2.width / 2 - element.width / 2; - var commonY = reference2.y + reference2.height / 2 - element.height / 2; - var offsets; - switch (basePlacement) { - case top: - offsets = { - x: commonX, - y: reference2.y - element.height - }; - break; - case bottom: - offsets = { - x: commonX, - y: reference2.y + reference2.height - }; - break; - case right: - offsets = { - x: reference2.x + reference2.width, - y: commonY - }; - break; - case left: - offsets = { - x: reference2.x - element.width, - y: commonY - }; - break; - default: - offsets = { - x: reference2.x, - y: reference2.y - }; - } - var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; - if (mainAxis != null) { - var len = mainAxis === "y" ? "height" : "width"; - switch (variation) { - case start: - offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2); - break; - case end: - offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2); - break; - default: - } - } - return offsets; -} - -// node_modules/@popperjs/core/lib/utils/detectOverflow.js -function detectOverflow(state, options) { - if (options === void 0) { - options = {}; - } - var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; - var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); - var altContext = elementContext === popper ? reference : popper; - var popperRect = state.rects.popper; - var element = state.elements[altBoundary ? altContext : elementContext]; - var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); - var referenceClientRect = getBoundingClientRect(state.elements.reference); - var popperOffsets2 = computeOffsets({ - reference: referenceClientRect, - element: popperRect, - strategy: "absolute", - placement - }); - var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2)); - var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; - var overflowOffsets = { - top: clippingClientRect.top - elementClientRect.top + paddingObject.top, - bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, - left: clippingClientRect.left - elementClientRect.left + paddingObject.left, - right: elementClientRect.right - clippingClientRect.right + paddingObject.right - }; - var offsetData = state.modifiersData.offset; - if (elementContext === popper && offsetData) { - var offset2 = offsetData[placement]; - Object.keys(overflowOffsets).forEach(function(key) { - var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; - var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x"; - overflowOffsets[key] += offset2[axis] * multiply; - }); - } - return overflowOffsets; -} - -// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js -function computeAutoPlacement(state, options) { - if (options === void 0) { - options = {}; - } - var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; - var variation = getVariation(placement); - var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) { - return getVariation(placement2) === variation; - }) : basePlacements; - var allowedPlacements = placements2.filter(function(placement2) { - return allowedAutoPlacements.indexOf(placement2) >= 0; - }); - if (allowedPlacements.length === 0) { - allowedPlacements = placements2; - } - var overflows = allowedPlacements.reduce(function(acc, placement2) { - acc[placement2] = detectOverflow(state, { - placement: placement2, - boundary, - rootBoundary, - padding - })[getBasePlacement(placement2)]; - return acc; - }, {}); - return Object.keys(overflows).sort(function(a, b) { - return overflows[a] - overflows[b]; - }); -} - -// node_modules/@popperjs/core/lib/modifiers/flip.js -function getExpandedFallbackPlacements(placement) { - if (getBasePlacement(placement) === auto) { - return []; - } - var oppositePlacement = getOppositePlacement(placement); - return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; -} -function flip(_ref) { - var state = _ref.state, options = _ref.options, name = _ref.name; - if (state.modifiersData[name]._skip) { - return; - } - var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements; - var preferredPlacement = state.options.placement; - var basePlacement = getBasePlacement(preferredPlacement); - var isBasePlacement = basePlacement === preferredPlacement; - var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); - var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) { - return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, { - placement: placement2, - boundary, - rootBoundary, - padding, - flipVariations, - allowedAutoPlacements - }) : placement2); - }, []); - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var checksMap = /* @__PURE__ */ new Map(); - var makeFallbackChecks = true; - var firstFittingPlacement = placements2[0]; - for (var i = 0; i < placements2.length; i++) { - var placement = placements2[i]; - var _basePlacement = getBasePlacement(placement); - var isStartVariation = getVariation(placement) === start; - var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; - var len = isVertical ? "width" : "height"; - var overflow = detectOverflow(state, { - placement, - boundary, - rootBoundary, - altBoundary, - padding - }); - var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; - if (referenceRect[len] > popperRect[len]) { - mainVariationSide = getOppositePlacement(mainVariationSide); - } - var altVariationSide = getOppositePlacement(mainVariationSide); - var checks = []; - if (checkMainAxis) { - checks.push(overflow[_basePlacement] <= 0); - } - if (checkAltAxis) { - checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); - } - if (checks.every(function(check) { - return check; - })) { - firstFittingPlacement = placement; - makeFallbackChecks = false; - break; - } - checksMap.set(placement, checks); - } - if (makeFallbackChecks) { - var numberOfChecks = flipVariations ? 3 : 1; - var _loop = function _loop2(_i2) { - var fittingPlacement = placements2.find(function(placement2) { - var checks2 = checksMap.get(placement2); - if (checks2) { - return checks2.slice(0, _i2).every(function(check) { - return check; - }); - } - }); - if (fittingPlacement) { - firstFittingPlacement = fittingPlacement; - return "break"; - } - }; - for (var _i = numberOfChecks; _i > 0; _i--) { - var _ret = _loop(_i); - if (_ret === "break") - break; - } - } - if (state.placement !== firstFittingPlacement) { - state.modifiersData[name]._skip = true; - state.placement = firstFittingPlacement; - state.reset = true; - } -} -var flip_default = { - name: "flip", - enabled: true, - phase: "main", - fn: flip, - requiresIfExists: ["offset"], - data: { - _skip: false - } -}; - -// node_modules/@popperjs/core/lib/modifiers/hide.js -function getSideOffsets(overflow, rect, preventedOffsets) { - if (preventedOffsets === void 0) { - preventedOffsets = { - x: 0, - y: 0 - }; - } - return { - top: overflow.top - rect.height - preventedOffsets.y, - right: overflow.right - rect.width + preventedOffsets.x, - bottom: overflow.bottom - rect.height + preventedOffsets.y, - left: overflow.left - rect.width - preventedOffsets.x - }; -} -function isAnySideFullyClipped(overflow) { - return [top, right, bottom, left].some(function(side) { - return overflow[side] >= 0; - }); -} -function hide(_ref) { - var state = _ref.state, name = _ref.name; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var preventedOffsets = state.modifiersData.preventOverflow; - var referenceOverflow = detectOverflow(state, { - elementContext: "reference" - }); - var popperAltOverflow = detectOverflow(state, { - altBoundary: true - }); - var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); - var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); - var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); - var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); - state.modifiersData[name] = { - referenceClippingOffsets, - popperEscapeOffsets, - isReferenceHidden, - hasPopperEscaped - }; - state.attributes.popper = Object.assign({}, state.attributes.popper, { - "data-popper-reference-hidden": isReferenceHidden, - "data-popper-escaped": hasPopperEscaped - }); -} -var hide_default = { - name: "hide", - enabled: true, - phase: "main", - requiresIfExists: ["preventOverflow"], - fn: hide -}; - -// node_modules/@popperjs/core/lib/modifiers/offset.js -function distanceAndSkiddingToXY(placement, rects, offset2) { - var basePlacement = getBasePlacement(placement); - var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; - var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, { - placement - })) : offset2, skidding = _ref[0], distance = _ref[1]; - skidding = skidding || 0; - distance = (distance || 0) * invertDistance; - return [left, right].indexOf(basePlacement) >= 0 ? { - x: distance, - y: skidding - } : { - x: skidding, - y: distance - }; -} -function offset(_ref2) { - var state = _ref2.state, options = _ref2.options, name = _ref2.name; - var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset; - var data = placements.reduce(function(acc, placement) { - acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2); - return acc; - }, {}); - var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; - if (state.modifiersData.popperOffsets != null) { - state.modifiersData.popperOffsets.x += x; - state.modifiersData.popperOffsets.y += y; - } - state.modifiersData[name] = data; -} -var offset_default = { - name: "offset", - enabled: true, - phase: "main", - requires: ["popperOffsets"], - fn: offset -}; - -// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js -function popperOffsets(_ref) { - var state = _ref.state, name = _ref.name; - state.modifiersData[name] = computeOffsets({ - reference: state.rects.reference, - element: state.rects.popper, - strategy: "absolute", - placement: state.placement - }); -} -var popperOffsets_default = { - name: "popperOffsets", - enabled: true, - phase: "read", - fn: popperOffsets, - data: {} -}; - -// node_modules/@popperjs/core/lib/utils/getAltAxis.js -function getAltAxis(axis) { - return axis === "x" ? "y" : "x"; -} - -// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js -function preventOverflow(_ref) { - var state = _ref.state, options = _ref.options, name = _ref.name; - var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; - var overflow = detectOverflow(state, { - boundary, - rootBoundary, - padding, - altBoundary - }); - var basePlacement = getBasePlacement(state.placement); - var variation = getVariation(state.placement); - var isBasePlacement = !variation; - var mainAxis = getMainAxisFromPlacement(basePlacement); - var altAxis = getAltAxis(mainAxis); - var popperOffsets2 = state.modifiersData.popperOffsets; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { - placement: state.placement - })) : tetherOffset; - var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { - mainAxis: tetherOffsetValue, - altAxis: tetherOffsetValue - } : Object.assign({ - mainAxis: 0, - altAxis: 0 - }, tetherOffsetValue); - var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; - var data = { - x: 0, - y: 0 - }; - if (!popperOffsets2) { - return; - } - if (checkMainAxis) { - var _offsetModifierState$; - var mainSide = mainAxis === "y" ? top : left; - var altSide = mainAxis === "y" ? bottom : right; - var len = mainAxis === "y" ? "height" : "width"; - var offset2 = popperOffsets2[mainAxis]; - var min2 = offset2 + overflow[mainSide]; - var max2 = offset2 - overflow[altSide]; - var additive = tether ? -popperRect[len] / 2 : 0; - var minLen = variation === start ? referenceRect[len] : popperRect[len]; - var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; - var arrowElement = state.elements.arrow; - var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { - width: 0, - height: 0 - }; - var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); - var arrowPaddingMin = arrowPaddingObject[mainSide]; - var arrowPaddingMax = arrowPaddingObject[altSide]; - var arrowLen = within(0, referenceRect[len], arrowRect[len]); - var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; - var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; - var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); - var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; - var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; - var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset; - var tetherMax = offset2 + maxOffset - offsetModifierValue; - var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2); - popperOffsets2[mainAxis] = preventedOffset; - data[mainAxis] = preventedOffset - offset2; - } - if (checkAltAxis) { - var _offsetModifierState$2; - var _mainSide = mainAxis === "x" ? top : left; - var _altSide = mainAxis === "x" ? bottom : right; - var _offset = popperOffsets2[altAxis]; - var _len = altAxis === "y" ? "height" : "width"; - var _min = _offset + overflow[_mainSide]; - var _max = _offset - overflow[_altSide]; - var isOriginSide = [top, left].indexOf(basePlacement) !== -1; - var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; - var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; - var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; - var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); - popperOffsets2[altAxis] = _preventedOffset; - data[altAxis] = _preventedOffset - _offset; - } - state.modifiersData[name] = data; -} -var preventOverflow_default = { - name: "preventOverflow", - enabled: true, - phase: "main", - fn: preventOverflow, - requiresIfExists: ["offset"] -}; - -// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js -function getHTMLElementScroll(element) { - return { - scrollLeft: element.scrollLeft, - scrollTop: element.scrollTop - }; -} - -// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js -function getNodeScroll(node) { - if (node === getWindow(node) || !isHTMLElement(node)) { - return getWindowScroll(node); - } else { - return getHTMLElementScroll(node); - } -} - -// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js -function isElementScaled(element) { - var rect = element.getBoundingClientRect(); - var scaleX = round(rect.width) / element.offsetWidth || 1; - var scaleY = round(rect.height) / element.offsetHeight || 1; - return scaleX !== 1 || scaleY !== 1; -} -function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { - if (isFixed === void 0) { - isFixed = false; - } - var isOffsetParentAnElement = isHTMLElement(offsetParent); - var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); - var documentElement = getDocumentElement(offsetParent); - var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); - var scroll = { - scrollLeft: 0, - scrollTop: 0 - }; - var offsets = { - x: 0, - y: 0 - }; - if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { - if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) { - scroll = getNodeScroll(offsetParent); - } - if (isHTMLElement(offsetParent)) { - offsets = getBoundingClientRect(offsetParent, true); - offsets.x += offsetParent.clientLeft; - offsets.y += offsetParent.clientTop; - } else if (documentElement) { - offsets.x = getWindowScrollBarX(documentElement); - } - } - return { - x: rect.left + scroll.scrollLeft - offsets.x, - y: rect.top + scroll.scrollTop - offsets.y, - width: rect.width, - height: rect.height - }; -} - -// node_modules/@popperjs/core/lib/utils/orderModifiers.js -function order(modifiers) { - var map = /* @__PURE__ */ new Map(); - var visited = /* @__PURE__ */ new Set(); - var result = []; - modifiers.forEach(function(modifier) { - map.set(modifier.name, modifier); - }); - function sort(modifier) { - visited.add(modifier.name); - var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); - requires.forEach(function(dep) { - if (!visited.has(dep)) { - var depModifier = map.get(dep); - if (depModifier) { - sort(depModifier); - } - } - }); - result.push(modifier); - } - modifiers.forEach(function(modifier) { - if (!visited.has(modifier.name)) { - sort(modifier); - } - }); - return result; -} -function orderModifiers(modifiers) { - var orderedModifiers = order(modifiers); - return modifierPhases.reduce(function(acc, phase) { - return acc.concat(orderedModifiers.filter(function(modifier) { - return modifier.phase === phase; - })); - }, []); -} - -// node_modules/@popperjs/core/lib/utils/debounce.js -function debounce(fn2) { - var pending; - return function() { - if (!pending) { - pending = new Promise(function(resolve) { - Promise.resolve().then(function() { - pending = void 0; - resolve(fn2()); - }); - }); - } - return pending; - }; -} - -// node_modules/@popperjs/core/lib/utils/mergeByName.js -function mergeByName(modifiers) { - var merged = modifiers.reduce(function(merged2, current) { - var existing = merged2[current.name]; - merged2[current.name] = existing ? Object.assign({}, existing, current, { - options: Object.assign({}, existing.options, current.options), - data: Object.assign({}, existing.data, current.data) - }) : current; - return merged2; - }, {}); - return Object.keys(merged).map(function(key) { - return merged[key]; - }); -} - -// node_modules/@popperjs/core/lib/createPopper.js -var DEFAULT_OPTIONS = { - placement: "bottom", - modifiers: [], - strategy: "absolute" -}; -function areValidElements() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - return !args.some(function(element) { - return !(element && typeof element.getBoundingClientRect === "function"); - }); -} -function popperGenerator(generatorOptions) { - if (generatorOptions === void 0) { - generatorOptions = {}; - } - var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; - return function createPopper2(reference2, popper2, options) { - if (options === void 0) { - options = defaultOptions; - } - var state = { - placement: "bottom", - orderedModifiers: [], - options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), - modifiersData: {}, - elements: { - reference: reference2, - popper: popper2 - }, - attributes: {}, - styles: {} - }; - var effectCleanupFns = []; - var isDestroyed = false; - var instance = { - state, - setOptions: function setOptions(setOptionsAction) { - var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; - cleanupModifierEffects(); - state.options = Object.assign({}, defaultOptions, state.options, options2); - state.scrollParents = { - reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [], - popper: listScrollParents(popper2) - }; - var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers))); - state.orderedModifiers = orderedModifiers.filter(function(m) { - return m.enabled; - }); - runModifierEffects(); - return instance.update(); - }, - forceUpdate: function forceUpdate() { - if (isDestroyed) { - return; - } - var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper; - if (!areValidElements(reference3, popper3)) { - return; - } - state.rects = { - reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"), - popper: getLayoutRect(popper3) - }; - state.reset = false; - state.placement = state.options.placement; - state.orderedModifiers.forEach(function(modifier) { - return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); - }); - for (var index = 0; index < state.orderedModifiers.length; index++) { - if (state.reset === true) { - state.reset = false; - index = -1; - continue; - } - var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; - if (typeof fn2 === "function") { - state = fn2({ - state, - options: _options, - name, - instance - }) || state; - } - } - }, - update: debounce(function() { - return new Promise(function(resolve) { - instance.forceUpdate(); - resolve(state); - }); - }), - destroy: function destroy() { - cleanupModifierEffects(); - isDestroyed = true; - } - }; - if (!areValidElements(reference2, popper2)) { - return instance; - } - instance.setOptions(options).then(function(state2) { - if (!isDestroyed && options.onFirstUpdate) { - options.onFirstUpdate(state2); - } - }); - function runModifierEffects() { - state.orderedModifiers.forEach(function(_ref) { - var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect4 = _ref.effect; - if (typeof effect4 === "function") { - var cleanupFn = effect4({ - state, - name, - instance, - options: options2 - }); - var noopFn = function noopFn2() { - }; - effectCleanupFns.push(cleanupFn || noopFn); - } - }); - } - function cleanupModifierEffects() { - effectCleanupFns.forEach(function(fn2) { - return fn2(); - }); - effectCleanupFns = []; - } - return instance; - }; -} - -// node_modules/@popperjs/core/lib/popper.js -var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default]; -var createPopper = /* @__PURE__ */ popperGenerator({ - defaultModifiers -}); - -// src/suggesters/suggest.ts -var wrapAround = (value, size) => { - return (value % size + size) % size; -}; -var Suggest = class { - constructor(owner, containerEl, scope) { - this.owner = owner; - this.containerEl = containerEl; - containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this)); - containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this)); - scope.register([], "ArrowUp", (event) => { - if (!event.isComposing) { - this.setSelectedItem(this.selectedItem - 1, true); - return false; - } - }); - scope.register([], "ArrowDown", (event) => { - if (!event.isComposing) { - this.setSelectedItem(this.selectedItem + 1, true); - return false; - } - }); - scope.register([], "Enter", (event) => { - if (!event.isComposing) { - this.useSelectedItem(event); - return false; - } - }); - } - onSuggestionClick(event, el) { - event.preventDefault(); - const item = this.suggestions.indexOf(el); - this.setSelectedItem(item, false); - this.useSelectedItem(event); - } - onSuggestionMouseover(_event, el) { - const item = this.suggestions.indexOf(el); - this.setSelectedItem(item, false); - } - setSuggestions(values) { - this.containerEl.empty(); - const suggestionEls = []; - values.forEach((value) => { - const suggestionEl = this.containerEl.createDiv("suggestion-item"); - this.owner.renderSuggestion(value, suggestionEl); - suggestionEls.push(suggestionEl); - }); - this.values = values; - this.suggestions = suggestionEls; - this.setSelectedItem(0, false); - } - useSelectedItem(event) { - const currentValue = this.values[this.selectedItem]; - if (currentValue) { - this.owner.selectSuggestion(currentValue, event); - } - } - setSelectedItem(selectedIndex, scrollIntoView) { - const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length); - const prevSelectedSuggestion = this.suggestions[this.selectedItem]; - const selectedSuggestion = this.suggestions[normalizedIndex]; - prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected"); - selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected"); - this.selectedItem = normalizedIndex; - if (scrollIntoView) { - selectedSuggestion.scrollIntoView(false); - } - } -}; -var TextInputSuggest = class { - constructor(inputEl) { - this.inputEl = inputEl; - this.scope = new import_obsidian.Scope(); - this.suggestEl = createDiv("suggestion-container"); - const suggestion = this.suggestEl.createDiv("suggestion"); - this.suggest = new Suggest(this, suggestion, this.scope); - this.scope.register([], "Escape", this.close.bind(this)); - this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); - this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); - this.inputEl.addEventListener("blur", this.close.bind(this)); - this.suggestEl.on("mousedown", ".suggestion-container", (event) => { - event.preventDefault(); - }); - } - onInputChanged() { - const inputStr = this.inputEl.value; - const suggestions = this.getSuggestions(inputStr); - if (!suggestions) { - this.close(); - return; - } - if (suggestions.length > 0) { - this.suggest.setSuggestions(suggestions); - this.open(app.dom.appContainerEl, this.inputEl); - } else { - this.close(); - } - } - open(container, inputEl) { - app.keymap.pushScope(this.scope); - container.appendChild(this.suggestEl); - this.popper = createPopper(inputEl, this.suggestEl, { - placement: "bottom-start", - modifiers: [ - { - name: "sameWidth", - enabled: true, - fn: ({ state, instance }) => { - const targetWidth = `${state.rects.reference.width}px`; - if (state.styles.popper.width === targetWidth) { - return; - } - state.styles.popper.width = targetWidth; - instance.update(); - }, - phase: "beforeWrite", - requires: ["computeStyles"] - } - ] - }); - } - close() { - app.keymap.popScope(this.scope); - this.suggest.setSuggestions([]); - if (this.popper) - this.popper.destroy(); - this.suggestEl.detach(); - } -}; - -// src/template.ts -var import_obsidian2 = require("obsidian"); -async function applyTemplate(plugin, file, templatePath) { - const templateFile = templatePath ? plugin.app.vault.getAbstractFileByPath(templatePath) : null; - if (templateFile && templateFile instanceof import_obsidian2.TFile) { - try { - const { - templatesEnabled, - templaterEnabled, - templatesPlugin, - templaterPlugin - } = getTemplatePlugins(plugin.app); - const templateContent = await plugin.app.vault.read(templateFile); - if (templatesEnabled && templaterEnabled) { - if (/<%/.test(templateContent)) { - return await templaterPlugin.write_template_to_file(templateFile, file); - } - return await templatesPlugin.instance.insertTemplate(templateFile); - } - if (templatesEnabled) { - return await templatesPlugin.instance.insertTemplate(templateFile); - } - if (templaterEnabled) { - return await templaterPlugin.write_template_to_file(templateFile, file); - } - } catch (e) { - console.error(e); - } - } -} -function getTemplatePlugins(app2) { - var _a; - const templatesPlugin = app2.internalPlugins.plugins.templates; - const templatesEnabled = templatesPlugin.enabled; - const templaterPlugin = app2.plugins.plugins["templater-obsidian"]; - const templaterEnabled = app2.plugins.enabledPlugins.has("templater-obsidian"); - const templaterEmptyFileTemplate = templaterPlugin && ((_a = this.app.plugins.plugins["templater-obsidian"].settings) == null ? void 0 : _a.empty_file_template); - const templateFolder = templatesEnabled ? templatesPlugin.instance.options.folder : templaterPlugin ? templaterPlugin.settings.template_folder : void 0; - return { - templatesPlugin, - templatesEnabled, - templaterPlugin: templaterPlugin == null ? void 0 : templaterPlugin.templater, - templaterEnabled, - templaterEmptyFileTemplate, - templateFolder - }; -} - -// src/suggesters/templateSuggester.ts -var TemplateSuggest = class extends TextInputSuggest { - constructor(inputEl, plugin) { - super(inputEl); - this.inputEl = inputEl; - this.plugin = plugin; - } - get_error_msg(mode) { - switch (mode) { - case 0 /* TemplateFiles */: - return "Templates folder doesn't exist"; - case 1 /* ScriptFiles */: - return "User Scripts folder doesn't exist"; - } - } - getSuggestions(input_str) { - var _a, _b; - const { templateFolder, templaterPlugin } = getTemplatePlugins(this.plugin.app); - if ((!templateFolder || (templateFolder == null ? void 0 : templateFolder.trim()) === "") && !templaterPlugin) { - this.plugin.settings.templatePath = ""; - this.plugin.saveSettings(); - return []; - } - let folder; - if (templaterPlugin) { - folder = this.plugin.app.vault.getAbstractFileByPath((_b = (_a = templaterPlugin.plugin) == null ? void 0 : _a.settings) == null ? void 0 : _b.templates_folder); - } else { - folder = this.plugin.app.vault.getAbstractFileByPath(templateFolder); - } - const files = []; - const lower_input_str = input_str.toLowerCase(); - import_obsidian3.Vault.recurseChildren(folder, (file) => { - if (file instanceof import_obsidian3.TFile && file.path.toLowerCase().contains(lower_input_str)) { - files.push(file); - } - }); - return files; - } - renderSuggestion(file, el) { - el.setText(file.name.replace(".md", "")); - } - selectSuggestion(file) { - this.inputEl.value = file.name.replace(".md", ""); - this.inputEl.trigger("input"); - this.plugin.settings.templatePath = file.path; - this.plugin.saveSettings(); - this.close(); - } -}; - -// src/modals/existingNote.ts -var import_obsidian4 = require("obsidian"); -var ExistingFolderNoteModal = class extends import_obsidian4.Modal { - constructor(app2, plugin, file, folder, folderNote) { - super(app2); - this.plugin = plugin; - this.app = app2; - this.file = file; - this.folder = folder; - this.folderNote = folderNote; - } - onOpen() { - var _a; - const { contentEl } = this; - contentEl.createEl("h2", { text: "A folder note for this folder already exists" }); - const setting = new import_obsidian4.Setting(contentEl); - setting.infoEl.createEl("p", { text: "Are you sure you want to turn the note into a folder note and rename the existing folder note?" }); - (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal"); - const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" }); - if (import_obsidian4.Platform.isMobileApp) { - const confirmButton = buttonContainer.createEl("button", { text: "Rename and don't ask again" }); - confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button"); - confirmButton.addEventListener("click", async () => { - this.plugin.settings.showRenameConfirmation = false; - this.plugin.saveSettings(); - this.close(); - turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true); - }); - } else { - const checkbox = buttonContainer.createEl("input", { type: "checkbox" }); - checkbox.addEventListener("change", (e) => { - const target = e.target; - if (target.checked) { - this.plugin.settings.showRenameConfirmation = false; - } else { - this.plugin.settings.showRenameConfirmation = true; - } - }); - const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" }); - checkBoxText.addEventListener("click", () => { - checkbox.click(); - }); - } - const button = buttonContainer.createEl("button", { text: "Rename" }); - button.classList.add("mod-warning", "fn-confirmation-modal-button"); - button.addEventListener("click", async () => { - this.plugin.saveSettings(); - this.close(); - turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true); - }); - button.focus(); - const cancelButton = buttonContainer.createEl("button", { text: "Cancel" }); - cancelButton.addEventListener("click", async () => { - this.close(); - }); - } - onClose() { - const { contentEl } = this; - contentEl.empty(); - } -}; - -// src/functions/folderNoteFunctions.ts -var import_obsidian10 = require("obsidian"); - -// src/modals/deleteConfirmation.ts -var import_obsidian5 = require("obsidian"); -var DeleteConfirmationModal = class extends import_obsidian5.Modal { - constructor(app2, plugin, file) { - super(app2); - this.plugin = plugin; - this.app = app2; - this.file = file; - } - onOpen() { - var _a; - const { contentEl } = this; - contentEl.createEl("h2", { text: "Delete folder note" }); - const setting = new import_obsidian5.Setting(contentEl); - setting.infoEl.createEl("p", { text: `Are you sure you want to delete the folder note "${this.file.name}" ?` }); - setting.infoEl.createEl("p", { text: "It will be moved to your system trash." }); - (_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal"); - const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" }); - if (import_obsidian5.Platform.isMobileApp) { - const confirmButton = buttonContainer.createEl("button", { text: "Delete and don't ask again" }); - confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button"); - confirmButton.addEventListener("click", async () => { - this.plugin.settings.showDeleteConfirmation = false; - this.plugin.saveSettings(); - this.close(); - const folder = getFolder(this.plugin, this.file); - if (!folder) - return; - this.plugin.removeCSSClassFromEL(folder == null ? void 0 : folder.path, "has-folder-note"); - this.app.vault.delete(this.file); - }); - } else { - const checkbox = buttonContainer.createEl("input", { type: "checkbox" }); - checkbox.addEventListener("change", (e) => { - const target = e.target; - if (target.checked) { - this.plugin.settings.showDeleteConfirmation = false; - } else { - this.plugin.settings.showDeleteConfirmation = true; - } - this.plugin.saveSettings(); - }); - const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" }); - checkBoxText.addEventListener("click", () => { - checkbox.click(); - }); - } - const button = buttonContainer.createEl("button", { text: "Delete" }); - button.classList.add("mod-warning", "fn-confirmation-modal-button"); - button.addEventListener("click", async () => { - this.close(); - const folder = getFolder(this.plugin, this.file); - if (!folder) - return; - this.plugin.removeCSSClassFromEL(folder.path, "has-folder-note"); - this.app.vault.delete(this.file); - }); - button.focus(); - const cancelButton = buttonContainer.createEl("button", { text: "Cancel" }); - cancelButton.addEventListener("click", async () => { - this.close(); - }); - } - onClose() { - const { contentEl } = this; - contentEl.empty(); - } -}; - -// src/excludedFolder.ts -var import_obsidian9 = require("obsidian"); - -// src/modals/excludeFolderSettings.ts -var import_obsidian6 = require("obsidian"); -var ExcludedFolderSettings = class extends import_obsidian6.Modal { - constructor(app2, plugin, excludedFolder) { - super(app2); - this.plugin = plugin; - this.app = app2; - this.excludedFolder = excludedFolder; - } - onOpen() { - this.display(); - } - display() { - const { contentEl } = this; - contentEl.empty(); - contentEl.createEl("h2", { text: "Excluded folder settings" }); - new import_obsidian6.Setting(contentEl).setName("Include subfolders").setDesc("Choose if the subfolders of the folder should also be excluded").addToggle((toggle) => toggle.setValue(this.excludedFolder.subFolders).onChange(async (value) => { - this.excludedFolder.subFolders = value; - await this.plugin.saveSettings(); - })); - new import_obsidian6.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder note should be renamed when the folder name is changed").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableSync).onChange(async (value) => { - this.excludedFolder.disableSync = value; - await this.plugin.saveSettings(); - })); - new import_obsidian6.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableAutoCreate).onChange(async (value) => { - this.excludedFolder.disableAutoCreate = value; - await this.plugin.saveSettings(); - })); - new import_obsidian6.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableFolderNote).onChange(async (value) => { - this.excludedFolder.disableFolderNote = value; - await this.plugin.saveSettings(); - this.display(); - })); - if (!this.excludedFolder.disableFolderNote) { - new import_obsidian6.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.enableCollapsing).onChange(async (value) => { - this.excludedFolder.enableCollapsing = value; - await this.plugin.saveSettings(); - })); - } - } - onClose() { - const { contentEl } = this; - contentEl.empty(); - } -}; - -// src/suggesters/FolderSuggester.ts -var import_obsidian7 = require("obsidian"); -var FolderSuggest = class extends TextInputSuggest { - constructor(inputEl, plugin) { - super(inputEl); - this.inputEl = inputEl; - this.plugin = plugin; - } - get_error_msg(mode) { - switch (mode) { - case 0 /* TemplateFiles */: - return "Templates folder doesn't exist"; - case 1 /* ScriptFiles */: - return "User Scripts folder doesn't exist"; - } - } - getSuggestions(input_str) { - const folders = []; - const lower_input_str = input_str.toLowerCase(); - this.plugin.app.vault.getAllLoadedFiles().forEach((folder) => { - if (folder instanceof import_obsidian7.TFolder && folder.path.toLowerCase().contains(lower_input_str) && !this.plugin.settings.excludeFolders.find((f) => f.path === folder.path)) { - folders.push(folder); - } - }); - return folders; - } - renderSuggestion(folder, el) { - el.setText(folder.path); - } - selectSuggestion(folder) { - this.inputEl.value = folder.path; - this.inputEl.trigger("input"); - this.close(); - } -}; - -// src/modals/patternSettings.ts -var import_obsidian8 = require("obsidian"); -var PatternSettings = class extends import_obsidian8.Modal { - constructor(app2, plugin, pattern) { - super(app2); - this.plugin = plugin; - this.app = app2; - this.pattern = pattern; - } - onOpen() { - this.display(); - } - display() { - const { contentEl } = this; - contentEl.empty(); - contentEl.createEl("h2", { text: "Pattern settings" }); - new import_obsidian8.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder name should be renamed when the file name has been changed").addToggle((toggle) => toggle.setValue(this.pattern.disableSync).onChange(async (value) => { - this.pattern.disableSync = value; - await this.plugin.saveSettings(); - })); - new import_obsidian8.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created that matches this pattern").addToggle((toggle) => toggle.setValue(this.pattern.disableAutoCreate).onChange(async (value) => { - this.pattern.disableAutoCreate = value; - await this.plugin.saveSettings(); - })); - new import_obsidian8.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.pattern.disableFolderNote).onChange(async (value) => { - this.pattern.disableFolderNote = value; - await this.plugin.saveSettings(); - this.display(); - })); - if (!this.pattern.disableFolderNote) { - new import_obsidian8.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.pattern.enableCollapsing).onChange(async (value) => { - this.pattern.enableCollapsing = value; - await this.plugin.saveSettings(); - })); - } - } - onClose() { - const { contentEl } = this; - contentEl.empty(); - } -}; - -// src/excludedFolder.ts -var ExcludedFolder = class { - constructor(path, position) { - this.type = "folder"; - this.path = path; - this.subFolders = true; - this.disableSync = true; - this.disableAutoCreate = true; - this.disableFolderNote = false; - this.enableCollapsing = false; - this.position = position; - this.string = ""; - } -}; -var ExcludePattern = class { - constructor(pattern, position) { - this.type = "pattern"; - this.string = pattern; - this.position = position; - this.subFolders = false; - this.disableSync = true; - this.disableAutoCreate = true; - this.disableFolderNote = false; - this.enableCollapsing = false; - this.path = ""; - } -}; -function getExcludedFolder(plugin, path) { - const folderName = plugin.getFolderNameFromPathString(path); - const matchedPattern = getExcludedFolderByPattern(plugin, folderName); - if (matchedPattern) { - return matchedPattern; - } - const excludedFolder = getExcludedFolderByPath(plugin, path); - return excludedFolder; -} -function getExcludedFolderByPattern(plugin, folderName) { - return plugin.settings.excludeFolders.filter((s) => s.path === "").find((pattern) => { - if (!pattern.string) { - return false; - } - if (pattern.string.toLocaleLowerCase().startsWith("{regex}") && pattern.string.slice(7).trim() !== "") { - const match = new RegExp(pattern.string.slice(7).trim()).exec(folderName); - if (match) { - return true; - } - } else if (pattern.string.startsWith("*") && pattern.string.endsWith("*")) { - if (folderName.includes(pattern.string.slice(1, -1))) { - return true; - } - } else if (pattern.string.startsWith("*")) { - if (folderName.endsWith(pattern.string.slice(1))) { - return true; - } - } else if (pattern.string.endsWith("*")) { - if (folderName.startsWith(pattern.string.slice(0, -1))) { - return true; - } - } - }); -} -function getExcludedFolderByPath(plugin, path) { - return plugin.settings.excludeFolders.find((excludedFolder) => { - if (excludedFolder.path === path) { - return true; - } - if (!excludedFolder.subFolders) { - return false; - } - return plugin.getFolderPathFromString(path).startsWith(excludedFolder.path); - }); -} -function addExcludedFolder(plugin, excludedFolder) { - plugin.settings.excludeFolders.push(excludedFolder); - plugin.saveSettings(); -} -function deleteExcludedFolder(plugin, excludedFolder) { - plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path || folder.type === "pattern"); - plugin.saveSettings(); - resyncArray(plugin); -} -function deletePattern(plugin, pattern) { - plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string || folder.type === "folder"); - plugin.saveSettings(); - resyncArray(plugin); -} -function updateExcludedFolder(plugin, excludedFolder, newExcludeFolder) { - plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path); - addExcludedFolder(plugin, newExcludeFolder); -} -function updatePattern(plugin, pattern, newPattern) { - plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string); - addExcludedFolder(plugin, newPattern); -} -function resyncArray(plugin) { - plugin.settings.excludeFolders = plugin.settings.excludeFolders.sort((a, b) => a.position - b.position); - plugin.settings.excludeFolders.forEach((folder, index) => { - folder.position = index; - }); - plugin.saveSettings(); -} -function addExcludePatternListItem(settings, containerEl, pattern) { - const plugin = settings.plugin; - const setting = new import_obsidian9.Setting(containerEl); - setting.setClass("fn-exclude-folder-list"); - setting.addSearch((cb) => { - cb.containerEl.addClass("fn-exclude-folder-path"); - cb.setPlaceholder("Pattern"); - cb.setValue(pattern.string); - cb.onChange((value) => { - if (plugin.settings.excludeFolders.find((folder) => folder.string === value)) { - return; - } - pattern.string = value; - updatePattern(plugin, pattern, pattern); - }); - }); - setting.addButton((cb) => { - cb.setIcon("edit"); - cb.setTooltip("Edit pattern"); - cb.onClick(() => { - new PatternSettings(plugin.app, plugin, pattern).open(); - }); - }); - setting.addButton((cb) => { - cb.setIcon("up-chevron-glyph"); - cb.setTooltip("Move up"); - cb.onClick(() => { - if (pattern.position === 0) { - return; - } - pattern.position -= 1; - updatePattern(plugin, pattern, pattern); - const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position); - if (oldPattern) { - oldPattern.position += 1; - if (oldPattern.type === "pattern") { - updatePattern(plugin, oldPattern, oldPattern); - } else { - updateExcludedFolder(plugin, oldPattern, oldPattern); - } - } - settings.display(); - }); - }); - setting.addButton((cb) => { - cb.setIcon("down-chevron-glyph"); - cb.setTooltip("Move down"); - cb.onClick(() => { - if (pattern.position === plugin.settings.excludeFolders.length - 1) { - return; - } - pattern.position += 1; - updatePattern(plugin, pattern, pattern); - const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position); - if (oldPattern) { - oldPattern.position -= 1; - if (oldPattern.type === "pattern") { - updatePattern(plugin, oldPattern, oldPattern); - } else { - updateExcludedFolder(plugin, oldPattern, oldPattern); - } - } - settings.display(); - }); - }); - setting.addButton((cb) => { - cb.setIcon("trash-2"); - cb.setTooltip("Delete pattern"); - cb.onClick(() => { - deletePattern(plugin, pattern); - setting.clear(); - setting.settingEl.remove(); - }); - }); -} -function addExcludeFolderListItem(settings, containerEl, excludedFolder) { - const plugin = settings.plugin; - const setting = new import_obsidian9.Setting(containerEl); - setting.setClass("fn-exclude-folder-list"); - setting.addSearch((cb) => { - new FolderSuggest(cb.inputEl, plugin); - cb.containerEl.addClass("fn-exclude-folder-path"); - cb.setPlaceholder("Folder path"); - cb.setValue(excludedFolder.path); - cb.onChange((value) => { - if (value.startsWith("{regex}") || value.includes("*")) { - deleteExcludedFolder(plugin, excludedFolder); - const pattern = new ExcludePattern(value, plugin.settings.excludeFolders.length); - addExcludedFolder(plugin, pattern); - addExcludePatternListItem(settings, containerEl, pattern); - setting.clear(); - setting.settingEl.remove(); - } - if (!plugin.app.vault.getAbstractFileByPath(value)) - return; - excludedFolder.path = value; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - }); - }); - setting.addButton((cb) => { - cb.setIcon("edit"); - cb.setTooltip("Edit folder note"); - cb.onClick(() => { - new ExcludedFolderSettings(plugin.app, plugin, excludedFolder).open(); - }); - }); - setting.addButton((cb) => { - cb.setIcon("up-chevron-glyph"); - cb.setTooltip("Move up"); - cb.onClick(() => { - if (excludedFolder.position === 0) { - return; - } - excludedFolder.position -= 1; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position); - if (oldExcludedFolder) { - oldExcludedFolder.position += 1; - if (oldExcludedFolder.type === "pattern") { - updatePattern(plugin, oldExcludedFolder, oldExcludedFolder); - } else { - updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder); - } - } - settings.display(); - }); - }); - setting.addButton((cb) => { - cb.setIcon("down-chevron-glyph"); - cb.setTooltip("Move down"); - cb.onClick(() => { - if (excludedFolder.position === plugin.settings.excludeFolders.length - 1) { - return; - } - excludedFolder.position += 1; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position); - if (oldExcludedFolder) { - oldExcludedFolder.position -= 1; - if (oldExcludedFolder.type === "pattern") { - updatePattern(plugin, oldExcludedFolder, oldExcludedFolder); - } else { - updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder); - } - } - settings.display(); - }); - }); - setting.addButton((cb) => { - cb.setIcon("trash-2"); - cb.setTooltip("Delete excluded folder"); - cb.onClick(() => { - deleteExcludedFolder(plugin, excludedFolder); - setting.clear(); - setting.settingEl.remove(); - }); - }); -} - -// src/functions/folderNoteFunctions.ts -async function createFolderNote(plugin, folderPath, openFile, useModal, existingNote) { - const leaf = plugin.app.workspace.getLeaf(false); - const folderName = plugin.getFolderNameFromPathString(folderPath); - const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName); - let path = ""; - if (plugin.settings.storageLocation === "parentFolder") { - const parentFolderPath = plugin.getFolderPathFromString(folderPath); - if (parentFolderPath.trim() === "") { - path = `${fileName}${plugin.settings.folderNoteType}`; - } else { - path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`; - } - } else if (plugin.settings.storageLocation === "vaultFolder") { - path = `${fileName}${plugin.settings.folderNoteType}`; - } else { - path = `${folderPath}/${fileName}${plugin.settings.folderNoteType}`; - } - let file; - if (!existingNote) { - file = await plugin.app.vault.create(path, ""); - } else { - file = existingNote; - plugin.app.vault.rename(existingNote, path); - } - if (openFile) { - await leaf.openFile(file); - } - if (file && !existingNote) { - applyTemplate(this, file, plugin.settings.templatePath); - } - const folder = plugin.app.vault.getAbstractFileByPath(folderPath); - if (!(folder instanceof import_obsidian10.TFolder)) - return; - plugin.addCSSClassToTitleEL(path, "is-folder-note", true); - plugin.addCSSClassToTitleEL(folder.path, "has-folder-note"); -} -async function turnIntoFolderNote(plugin, file, folder, folderNote, skipConfirmation) { - var _a; - if (folderNote) { - if (plugin.settings.showRenameConfirmation && !skipConfirmation) { - return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open(); - } - plugin.removeCSSClassFromEL(folderNote.path, "is-folder-note"); - let excludedFolder = getExcludedFolder(plugin, folder.path); - let excludedFolderExisted = true; - let disabledSync = false; - if (!excludedFolder) { - excludedFolderExisted = false; - excludedFolder = new ExcludedFolder(folder.path, plugin.settings.excludeFolders.length); - addExcludedFolder(plugin, excludedFolder); - } else if (!excludedFolder.disableSync) { - disabledSync = false; - excludedFolder.disableSync = true; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - } - const newPath = `${folder.path}/${folder.name} (${file.stat.ctime.toString().slice(10) + Math.floor(Math.random() * 1e3)})${plugin.settings.folderNoteType}`; - plugin.app.vault.rename(folderNote, newPath).then(() => { - if (!excludedFolder) { - return; - } - if (!excludedFolderExisted) { - deleteExcludedFolder(plugin, excludedFolder); - } else if (!disabledSync) { - excludedFolder.disableSync = false; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - } - }); - } - const folderName = folder.name; - const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName); - let path = `${folder.path}/${fileName}${plugin.settings.folderNoteType}`; - if (plugin.settings.storageLocation === "parentFolder") { - const parentFolderPath = (_a = folder.parent) == null ? void 0 : _a.path; - if (!parentFolderPath) - return; - if (parentFolderPath.trim() === "") { - path = `${fileName}${plugin.settings.folderNoteType}`; - } else { - path = `${parentFolderPath}/${fileName}${plugin.settings.folderNoteType}`; - } - } - await plugin.app.vault.rename(file, path); - plugin.addCSSClassToTitleEL(path, "is-folder-note", true); - plugin.addCSSClassToTitleEL(folder.path, "has-folder-note"); -} -async function openFolderNote(plugin, file, evt) { - var _a; - const path = file.path; - if (((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path) === path) { - return; - } - const leaf = plugin.app.workspace.getLeaf(import_obsidian10.Keymap.isModEvent(evt) || plugin.settings.openInNewTab); - if (file instanceof import_obsidian10.TFile) { - await leaf.openFile(file); - } -} -async function deleteFolderNote(plugin, file) { - if (plugin.settings.showDeleteConfirmation) { - return new DeleteConfirmationModal(plugin.app, plugin, file).open(); - } - const folder = getFolder(plugin, file); - if (!folder) - return; - plugin.removeCSSClassFromEL(folder.path, "has-folder-note"); - await plugin.app.vault.delete(file); -} -function extractFolderName(template, changedFileName) { - const [prefix, suffix] = template.split("{{folder_name}}"); - if (prefix.trim() === "" && suffix.trim() === "") { - return changedFileName; - } - if (!changedFileName.startsWith(prefix) || !changedFileName.endsWith(suffix)) { - return null; - } - if (changedFileName.startsWith(prefix) && prefix.trim() !== "") { - return changedFileName.slice(prefix.length).replace(suffix, ""); - } else if (changedFileName.endsWith(suffix) && suffix.trim() !== "") { - return changedFileName.slice(0, -suffix.length); - } - return null; -} -function getFolderNote(plugin, folderPath, storageLocation, file) { - if (!folderPath) - return null; - const folder = { - path: folderPath, - name: plugin.getFolderNameFromPathString(folderPath) - }; - let fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folder.name); - if (file) { - fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.basename); - } - if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") { - folder.path = plugin.getFolderPathFromString(folderPath); - } - let path = `${folder.path}/${fileName}`; - if (folder.path.trim() === "") { - folder.path = fileName; - path = `${fileName}`; - } - let folderNote = plugin.app.vault.getAbstractFileByPath(path + plugin.settings.folderNoteType); - if (folderNote instanceof import_obsidian10.TFile) { - return folderNote; - } else { - if (plugin.settings.folderNoteType === ".canvas") { - folderNote = plugin.app.vault.getAbstractFileByPath(path + ".md"); - } else { - folderNote = plugin.app.vault.getAbstractFileByPath(path + ".canvas"); - } - return folderNote; - } -} -function getFolder(plugin, file, storageLocation) { - if (!file) - return null; - const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename); - if (!folderName) - return null; - let folderPath = plugin.getFolderPathFromString(file.path); - let folder = null; - if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") { - if (folderPath.trim() === "") { - folderPath = folderName; - } else { - folderPath = `${folderPath}/${folderName}`; - } - folder = plugin.app.vault.getAbstractFileByPath(folderPath); - } else { - folder = plugin.app.vault.getAbstractFileByPath(folderPath); - } - if (!folder) { - return null; - } - return folder; -} -function getFolderNoteFolder(plugin, folderNote, fileName) { - if (!folderNote) - return null; - let filePath = ""; - if (typeof folderNote === "string") { - filePath = folderNote; - } else { - fileName = folderNote.basename; - filePath = folderNote.path; - } - const folderName = extractFolderName(plugin.settings.folderNoteName, fileName); - if (!folderName) - return null; - let folderPath = plugin.getFolderPathFromString(filePath); - if (plugin.settings.storageLocation === "parentFolder") { - if (folderPath.trim() === "") { - folderPath = folderName; - } else { - folderPath = `${folderPath}/${folderName}`; - } - } else { - folderPath = plugin.getFolderPathFromString(filePath); - } - const folder = plugin.app.vault.getAbstractFileByPath(folderPath); - if (!folder) { - return null; - } - return folder; -} - -// src/events/frontMatterTitle.ts -var import_front_matter_plugin_api_provider = __toESM(require_lib()); -var import_obsidian11 = require("obsidian"); -var FrontMatterTitlePluginHandler = class { - constructor(plugin) { - this.api = null; - this.deffer = null; - this.modifiedFolders = /* @__PURE__ */ new Map(); - this.plugin = plugin; - this.app = plugin.app; - (async () => { - var _a; - this.deffer = (0, import_front_matter_plugin_api_provider.getDefer)(this.app); - if (this.deffer.isPluginReady()) { - this.api = this.deffer.getApi(); - } else { - await this.deffer.awaitPlugin(); - this.api = this.deffer.getApi(); - if (!this.deffer.isFeaturesReady()) { - await this.deffer.awaitFeatures(); - } - } - const dispatcher = (_a = this.api) == null ? void 0 : _a.getEventDispatcher(); - if (dispatcher) { - this.dispatcher = dispatcher; - } - const event = { - name: "manager:update", - cb: (data) => { - this.handleRename(data, true); - } - }; - const ref = dispatcher == null ? void 0 : dispatcher.addListener(event); - if (ref) { - this.eventRef = ref; - } - this.plugin.app.vault.getFiles().forEach((file) => { - this.handleRename({ id: "", result: false, path: file.path }, false); - }); - this.plugin.updateBreadcrumbs(); - })(); - } - deleteEvent() { - if (this.eventRef) { - this.dispatcher.removeListener(this.eventRef); - } - } - async handleRename(data, isEvent) { - var _a, _b, _c; - if (data.data) - data = data.data; - const file = this.app.vault.getAbstractFileByPath(data.path); - if (!(file instanceof import_obsidian11.TFile)) { - return; - } - const resolver = (_b = (_a = this.api) == null ? void 0 : _a.getResolverFactory()) == null ? void 0 : _b.createResolver("#feature-id#"); - const newName = resolver == null ? void 0 : resolver.resolve((_c = file == null ? void 0 : file.path) != null ? _c : ""); - const folder = getFolder(this.plugin, file); - if ((extractFolderName(this.plugin.settings.folderNoteName, file.basename) || file.basename) !== (folder == null ? void 0 : folder.name)) { - return; - } - if (!(folder instanceof import_obsidian11.TFolder)) { - return; - } - if (isEvent) { - this.plugin.changeName(folder, newName, true); - } else { - this.plugin.changeName(folder, newName, false); - } - if (newName) { - folder.newName = newName; - this.modifiedFolders.set(folder.path, folder); - } else { - folder.newName = null; - this.modifiedFolders.delete(folder.path); - } - } -}; - -// src/settings.ts -var DEFAULT_SETTINGS = { - syncFolderName: true, - ctrlKey: true, - altKey: false, - hideFolderNote: true, - templatePath: "", - autoCreate: false, - enableCollapsing: false, - excludeFolders: [], - showDeleteConfirmation: true, - underlineFolder: true, - allowWhitespaceCollapsing: false, - underlineFolderInPath: true, - openFolderNoteOnClickInPath: true, - openInNewTab: false, - folderNoteName: "{{folder_name}}", - folderNoteType: ".md", - disableFolderHighlighting: false, - newFolderNoteName: "{{folder_name}}", - storageLocation: "insideFolder", - syncDelete: false, - showRenameConfirmation: true, - defaultOverview: { - title: "{{folderName}} overview", - disableTitle: false, - depth: 3, - includeTypes: ["folder", "markdown"], - style: "list", - disableFileTag: false - }, - useSubmenus: true, - syncMove: true, - frontMatterTitle: { - enabled: false, - explorer: true, - path: true - } -}; -var SettingsTab = class extends import_obsidian12.PluginSettingTab { - constructor(app2, plugin) { - super(app2, plugin); - } - display() { - const { containerEl } = this; - containerEl.empty(); - containerEl.createEl("h2", { text: "Folder notes settings" }); - const nameSetting = new import_obsidian12.Setting(containerEl).setName("Folder note name").setDesc("{{folder_name}} will be replaced with the name of the folder").addText((text) => text.setValue(this.plugin.settings.newFolderNoteName).onChange(async (value) => { - if (value.trim() === "") { - return; - } - this.plugin.settings.newFolderNoteName = value; - await this.plugin.saveSettings(); - })).addButton((button) => button.setButtonText("Rename existing folder notes").setCta().onClick(async () => { - this.updateFolderNotes(this.plugin.settings.folderNoteName, this.plugin.settings.newFolderNoteName); - })); - nameSetting.infoEl.appendText("Make sure to back up your vault before renaming all folder notes and restart Obsidian after renaming them"); - nameSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - new import_obsidian12.Setting(containerEl).setName("Folder note type").setDesc("Choose the file type for creating new folder notes (markdown or canvas) old folder notes will not be changed and you can also create canvas/markdown files and change the name manually to the custom folder note name or to the name of the folder.").addDropdown((dropdown) => dropdown.addOption(".md", "markdown").addOption(".canvas", "canvas").setValue(this.plugin.settings.folderNoteType).onChange(async (value) => { - this.plugin.settings.folderNoteType = value; - await this.plugin.saveSettings(); - })); - const setting = new import_obsidian12.Setting(containerEl); - const desc = document.createDocumentFragment(); - desc.append("After setting the template path, restart Obsidian if the template folder path (from templater/templates) had been changed beforehand.", desc.createEl("br"), "Obsidian should also be restarted if the template path was removed."); - setting.setName("Template path"); - setting.setDesc(desc).descEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - setting.addSearch((cb) => { - var _a; - new TemplateSuggest(cb.inputEl, this.plugin); - cb.setPlaceholder("Template path"); - cb.setValue(((_a = this.plugin.app.vault.getAbstractFileByPath(this.plugin.settings.templatePath)) == null ? void 0 : _a.name.replace(".md", "")) || ""); - cb.onChange(async (value) => { - if (value.trim() === "") { - this.plugin.settings.templatePath = ""; - await this.plugin.saveSettings(); - this.display(); - return; - } - }); - }); - const storageLocation = new import_obsidian12.Setting(containerEl).setName("Storage location").setDesc("Choose where to store the folder notes").addDropdown((dropdown) => dropdown.addOption("insideFolder", "Inside the folder").addOption("parentFolder", "In the parent folder").setValue(this.plugin.settings.storageLocation).onChange(async (value) => { - this.plugin.settings.storageLocation = value; - await this.plugin.saveSettings(); - this.display(); - this.plugin.loadFileClasses(); - })); - storageLocation.infoEl.appendText("Requires a restart to take effect"); - storageLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - const switchLocation = new import_obsidian12.Setting(containerEl).setName("Switch to new storage location").setDesc("Move all folder notes to the new storage location").addButton((button) => button.setButtonText("Switch").setCta().onClick(async () => { - let oldStorageLocation = this.plugin.settings.storageLocation; - if (this.plugin.settings.storageLocation === "parentFolder") { - oldStorageLocation = "insideFolder"; - } else if (this.plugin.settings.storageLocation === "insideFolder") { - oldStorageLocation = "parentFolder"; - } - this.switchStorageLocation(oldStorageLocation); - })); - switchLocation.infoEl.appendText("Requires a restart to take effect"); - switchLocation.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - if (this.plugin.settings.storageLocation === "parentFolder") { - new import_obsidian12.Setting(containerEl).setName("Delete folder notes when deleting the folder").setDesc("Delete the folder note when deleting the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncDelete).onChange(async (value) => { - this.plugin.settings.syncDelete = value; - await this.plugin.saveSettings(); - })); - new import_obsidian12.Setting(containerEl).setName("Move folder notes when moving the folder").setDesc("Move the folder note when moving the folder").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncMove).onChange(async (value) => { - this.plugin.settings.syncMove = value; - await this.plugin.saveSettings(); - })); - } - const disableSetting = new import_obsidian12.Setting(containerEl); - disableSetting.setName("Disable folder collapsing"); - disableSetting.setDesc("Disable the ability to collapse folders by clicking exactly on the folder name"); - disableSetting.addToggle((toggle) => toggle.setValue(!this.plugin.settings.enableCollapsing).onChange(async (value) => { - this.plugin.settings.enableCollapsing = !value; - await this.plugin.saveSettings(); - })); - disableSetting.infoEl.appendText("Requires a restart to take effect"); - disableSetting.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - if (import_obsidian12.Platform.isDesktopApp) { - new import_obsidian12.Setting(containerEl).setName("Key for creating folder note").setDesc("The key combination to create a folder note").addDropdown((dropdown) => { - if (!import_obsidian12.Platform.isMacOS) { - dropdown.addOption("ctrl", "Ctrl + Click"); - } else { - dropdown.addOption("ctrl", "Cmd + Click"); - } - dropdown.addOption("alt", "Alt + Click"); - dropdown.setValue(this.plugin.settings.ctrlKey ? "ctrl" : "alt"); - dropdown.onChange(async (value) => { - this.plugin.settings.ctrlKey = value === "ctrl"; - this.plugin.settings.altKey = value === "alt"; - await this.plugin.saveSettings(); - this.display(); - }); - }); - } - new import_obsidian12.Setting(containerEl).setName("Only open folder notes through the name").setDesc("Only open folder notes in the file explorer by clicking on the folder name").addToggle((toggle) => toggle.setValue(this.plugin.settings.allowWhitespaceCollapsing).onChange(async (value) => { - if (!value) { - document.body.classList.add("fn-whitespace-stop-collapsing"); - } else { - document.body.classList.remove("fn-whitespace-stop-collapsing"); - } - this.plugin.settings.allowWhitespaceCollapsing = value; - await this.plugin.saveSettings(); - })); - new import_obsidian12.Setting(containerEl).setName("Hide folder note").setDesc("Hide the folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.hideFolderNote).onChange(async (value) => { - this.plugin.settings.hideFolderNote = value; - await this.plugin.saveSettings(); - if (value) { - document.body.classList.add("hide-folder-note"); - } else { - document.body.classList.remove("hide-folder-note"); - } - this.display(); - })); - new import_obsidian12.Setting(containerEl).setName("Sync folder name").setDesc("Automatically rename the folder note when the folder name is changed").addToggle((toggle) => toggle.setValue(this.plugin.settings.syncFolderName).onChange(async (value) => { - this.plugin.settings.syncFolderName = value; - await this.plugin.saveSettings(); - this.display(); - })); - if (import_obsidian12.Platform.isDesktop) { - const setting3 = new import_obsidian12.Setting(containerEl); - setting3.setName("Open folder note in a new tab by default"); - setting3.setDesc("Always open folder notes in a new tab (except when you try to open the same note) instead of having to use ctrl/cmd + click to open in a new tab"); - setting3.addToggle((toggle) => toggle.setValue(this.plugin.settings.openInNewTab).onChange(async (value) => { - this.plugin.settings.openInNewTab = value; - await this.plugin.saveSettings(); - this.display(); - })); - setting3.infoEl.appendText("Requires a restart to take effect"); - setting3.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - } - new import_obsidian12.Setting(containerEl).setName("Automatically create folder notes").setDesc("Automatically create a folder note when a new folder is created").addToggle((toggle) => toggle.setValue(this.plugin.settings.autoCreate).onChange(async (value) => { - this.plugin.settings.autoCreate = value; - await this.plugin.saveSettings(); - this.display(); - })); - new import_obsidian12.Setting(containerEl).setName("Use submenus").setDesc("Use submenus for file/folder commands").addToggle((toggle) => toggle.setValue(this.plugin.settings.useSubmenus).onChange(async (value) => { - this.plugin.settings.useSubmenus = value; - await this.plugin.saveSettings(); - this.display(); - })); - new import_obsidian12.Setting(containerEl).setName("Add underline to folders with folder notes").setDesc("Add an underline to folders that have a folder note in the file explorer").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolder).onChange(async (value) => { - this.plugin.settings.underlineFolder = value; - if (value) { - document.body.classList.add("folder-note-underline"); - } else { - document.body.classList.remove("folder-note-underline"); - } - await this.plugin.saveSettings(); - })); - new import_obsidian12.Setting(containerEl).setName("Open folder note through path").setDesc("Open a folder note when clicking on a folder name in the path if it is a folder note").addToggle((toggle) => toggle.setValue(this.plugin.settings.openFolderNoteOnClickInPath).onChange(async (value) => { - this.plugin.settings.openFolderNoteOnClickInPath = value; - await this.plugin.saveSettings(); - this.display(); - })); - if (this.plugin.settings.openFolderNoteOnClickInPath) { - new import_obsidian12.Setting(containerEl).setName("Underline folders in the path").setDesc("Add an underline to folders that have a folder note in the path above a note").addToggle((toggle) => toggle.setValue(this.plugin.settings.underlineFolderInPath).onChange(async (value) => { - this.plugin.settings.underlineFolderInPath = value; - if (value) { - document.body.classList.add("folder-note-underline-path"); - } else { - document.body.classList.remove("folder-note-underline-path"); - } - await this.plugin.saveSettings(); - })); - } - new import_obsidian12.Setting(containerEl).setName("Enable front matter title plugin integration").setDesc("Automatically rename a folder name when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.enabled).onChange(async (value) => { - var _a; - this.plugin.settings.frontMatterTitle.enabled = value; - await this.plugin.saveSettings(); - if (value) { - this.plugin.fmtpHandler = new FrontMatterTitlePluginHandler(this.plugin); - } else { - if (this.plugin.fmtpHandler) { - this.plugin.updateBreadcrumbs(true); - } - this.plugin.app.vault.getFiles().forEach((file) => { - var _a2; - (_a2 = this.plugin.fmtpHandler) == null ? void 0 : _a2.handleRename({ id: "", result: false, path: file.path }, false); - }); - (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.deleteEvent(); - this.plugin.fmtpHandler = null; - } - this.display(); - })); - if (this.plugin.settings.frontMatterTitle.enabled) { - new import_obsidian12.Setting(containerEl).setName("Include file explorer").setDesc("Automatically rename a folder name in the file explorer when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.explorer).onChange(async (value) => { - this.plugin.settings.frontMatterTitle.explorer = value; - await this.plugin.saveSettings(); - this.plugin.app.vault.getFiles().forEach((file) => { - var _a; - (_a = this.plugin.fmtpHandler) == null ? void 0 : _a.handleRename({ id: "", result: false, path: file.path }, false); - }); - })); - new import_obsidian12.Setting(containerEl).setName("Include path above note").setDesc("Automatically rename a folder name in the path above a note when the folder note is renamed").addToggle((toggle) => toggle.setValue(this.plugin.settings.frontMatterTitle.path).onChange(async (value) => { - this.plugin.settings.frontMatterTitle.path = value; - await this.plugin.saveSettings(); - if (value) { - this.plugin.updateBreadcrumbs(); - } else { - this.plugin.updateBreadcrumbs(true); - } - })); - } - const manageExcluded = new import_obsidian12.Setting(containerEl).setHeading().setClass("fn-excluded-folder-heading").setName("Manage excluded folders"); - const desc3 = document.createDocumentFragment(); - desc3.append("Add {regex} at the beginning of the folder name to use a regex pattern.", desc.createEl("br"), "Use * before and after to exclude folders that include the name between the *s.", desc.createEl("br"), "Use * before the folder name to exclude folders that end with the folder name.", desc.createEl("br"), "Use * after the folder name to exclude folders that start with the folder name."); - manageExcluded.setDesc(desc3); - manageExcluded.infoEl.appendText("The regexes and wildcards are only for the folder name, not the path."); - manageExcluded.infoEl.createEl("br"); - manageExcluded.infoEl.appendText("If you want to switch to a folder path delete the pattern first."); - manageExcluded.infoEl.style.color = this.app.vault.getConfig("accentColor") || "#7d5bed"; - new import_obsidian12.Setting(containerEl).setName("Add excluded folder").setClass("add-exclude-folder-item").addButton((cb) => { - cb.setIcon("plus"); - cb.setClass("add-exclude-folder"); - cb.setTooltip("Add excluded folder"); - cb.onClick(() => { - const excludedFolder = new ExcludedFolder("", this.plugin.settings.excludeFolders.length); - addExcludeFolderListItem(this, containerEl, excludedFolder); - addExcludedFolder(this.plugin, excludedFolder); - this.display(); - }); - }); - this.plugin.settings.excludeFolders.sort((a, b) => a.position - b.position).forEach((excludedFolder) => { - var _a, _b; - if (((_a = excludedFolder.string) == null ? void 0 : _a.trim()) !== "" && ((_b = excludedFolder.path) == null ? void 0 : _b.trim()) === "") { - addExcludePatternListItem(this, containerEl, excludedFolder); - } else { - addExcludeFolderListItem(this, containerEl, excludedFolder); - } - }); - } - updateFolderNotes(oldTemplate, newTemplate) { - this.plugin.settings.folderNoteName = newTemplate; - this.plugin.saveSettings(); - new import_obsidian12.Notice("Starting to update folder notes..."); - this.app.vault.getFiles().forEach((file) => { - if (file instanceof import_obsidian12.TFile) { - const folderPath = this.plugin.getFolderPathFromString(file.path); - let folder = this.app.vault.getAbstractFileByPath(folderPath); - let folderName = file.name.slice(0, -file.extension.length - 1); - folderName = extractFolderName(oldTemplate, folderName) || ""; - if (!(folder instanceof import_obsidian12.TFolder) || folderName !== (folder == null ? void 0 : folder.name)) { - if (folderPath.trim() === "") { - folder = this.app.vault.getAbstractFileByPath(folderName); - } else { - folder = this.app.vault.getAbstractFileByPath(folderPath + "/" + folderName); - } - } - if (!(folder instanceof import_obsidian12.TFolder)) { - return; - } - if (folderName === (folder == null ? void 0 : folder.name)) { - const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", folderName)}.${file.extension}`; - this.app.vault.rename(file, newPath); - } else if ((folder == null ? void 0 : folder.name) === file.name.slice(0, -file.extension.length - 1) || "") { - const newPath = `${folder == null ? void 0 : folder.path}/${this.plugin.settings.folderNoteName.replace("{{folder_name}}", file.name.slice(0, -file.extension.length - 1) || "")}.${file.extension}`; - this.app.vault.rename(file, newPath); - } - } - }); - new import_obsidian12.Notice("Finished updating folder notes"); - } - switchStorageLocation(oldMethod) { - new import_obsidian12.Notice("Starting to switch storage location..."); - this.app.vault.getAllLoadedFiles().forEach((file) => { - if (file instanceof import_obsidian12.TFolder) { - const folderNote = getFolderNote(this.plugin, file.path, oldMethod); - if (folderNote instanceof import_obsidian12.TFile) { - if (this.plugin.settings.storageLocation === "parentFolder") { - let newPath = ""; - if (this.plugin.getFolderPathFromString(file.path).trim() === "") { - newPath = `${folderNote.name}`; - } else { - newPath = `${this.plugin.getFolderPathFromString(file.path)}/${folderNote.name}`; - } - this.app.vault.rename(folderNote, newPath); - } else if (this.plugin.settings.storageLocation === "insideFolder") { - if (this.plugin.getFolderPathFromString(folderNote.path) === file.path) { - return; - } else { - const newPath = `${file.path}/${folderNote.name}`; - this.app.vault.rename(folderNote, newPath); - } - } - } - } - }); - new import_obsidian12.Notice("Finished switching storage location"); - } -}; - -// src/commands.ts -var import_obsidian13 = require("obsidian"); -var Commands = class { - constructor(app2, plugin) { - this.plugin = plugin; - this.app = app2; - } - registerCommands() { - this.plugin.registerEvent(this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => { - const text = editor.getSelection().trim(); - menu.addItem((item) => { - item.setTitle("Create folder overview").setIcon("edit").onClick(() => { - editor.replaceSelection("```folder-overview\n```\n"); - }); - }); - if (!text || text.trim() === "") - return; - menu.addItem((item) => { - item.setTitle("Create folder note").setIcon("edit").onClick(() => { - const file = view.file; - if (!(file instanceof import_obsidian13.TFile)) - return; - const blacklist = ["*", "\\", '"', "/", "<", ">", "?", "|", ":"]; - for (const char of blacklist) { - if (text.includes(char)) { - new import_obsidian13.Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?'); - return; - } - } - if (text.endsWith(".")) { - new import_obsidian13.Notice("File name cannot end with a dot"); - return; - } - let folder; - const folderPath = this.plugin.getFolderPathFromString(file.path); - if (folderPath === "") { - folder = this.plugin.app.vault.getAbstractFileByPath(text); - if (folder instanceof import_obsidian13.TFolder) { - return new import_obsidian13.Notice("Folder note already exists"); - } else { - this.plugin.app.vault.createFolder(text); - createFolderNote(this.plugin, text, false); - } - } else { - folder = this.plugin.app.vault.getAbstractFileByPath(folderPath + "/" + text); - if (folder instanceof import_obsidian13.TFolder) { - return new import_obsidian13.Notice("Folder note already exists"); - } - if (this.plugin.settings.storageLocation === "parentFolder") { - if (this.app.vault.getAbstractFileByPath(folderPath + "/" + text + this.plugin.settings.folderNoteType)) { - return new import_obsidian13.Notice("File already exists"); - } - } - this.plugin.app.vault.createFolder(folderPath + "/" + text); - createFolderNote(this.plugin, folderPath + "/" + text, false); - } - const fileName = this.plugin.settings.folderNoteName.replace("{{folder_name}}", text); - if (fileName === text) { - editor.replaceSelection(`[[${fileName}]]`); - } else { - editor.replaceSelection(`[[${fileName}|${text}]]`); - } - }); - }); - })); - this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => { - var _a, _b, _c; - let folder = file.parent; - if (file instanceof import_obsidian13.TFile) { - if (this.plugin.settings.storageLocation === "insideFolder") { - folder = file.parent; - } else { - const fileName = extractFolderName(this.plugin.settings.folderNoteName, file.basename); - if (fileName) { - if (((_a = file.parent) == null ? void 0 : _a.path) === "" || ((_b = file.parent) == null ? void 0 : _b.path) === "/") { - folder = this.plugin.app.vault.getAbstractFileByPath(fileName); - } else { - folder = this.plugin.app.vault.getAbstractFileByPath(((_c = file.parent) == null ? void 0 : _c.path) + "/" + fileName); - } - } - } - if (folder instanceof import_obsidian13.TFolder) { - const folderNote = getFolderNote(this.plugin, folder.path); - if ((folderNote == null ? void 0 : folderNote.path) === file.path) { - return; - } - } else if (file.parent instanceof import_obsidian13.TFolder) { - folder = file.parent; - } - } - menu.addItem((item) => { - if (import_obsidian13.Platform.isDesktop && !import_obsidian13.Platform.isTablet && this.plugin.settings.useSubmenus) { - item.setTitle("Folder Note Commands").setIcon("folder-edit"); - } - let subMenu; - if (!import_obsidian13.Platform.isDesktopApp || !import_obsidian13.Platform.isDesktop || import_obsidian13.Platform.isTablet || !this.plugin.settings.useSubmenus) { - subMenu = menu; - item.setDisabled(true); - } else { - subMenu = item.setSubmenu(); - } - if (file instanceof import_obsidian13.TFile) { - subMenu.addItem((item2) => { - item2.setTitle("Create folder note").setIcon("edit").onClick(async () => { - if (!folder) - return; - let newPath = folder.path + "/" + file.basename; - if (folder.path === "" || folder.path === "/") { - newPath = file.basename; - } - if (this.plugin.app.vault.getAbstractFileByPath(newPath)) { - return new import_obsidian13.Notice("Folder already exists"); - } - await this.plugin.app.vault.createFolder(newPath); - const newFolder = this.plugin.app.vault.getAbstractFileByPath(newPath); - if (!(newFolder instanceof import_obsidian13.TFolder)) - return; - createFolderNote(this.plugin, newFolder.path, true, false, file); - }); - }); - if (this.plugin.getFolderPathFromString(file.path) === "") - return; - if (!(folder instanceof import_obsidian13.TFolder)) - return; - subMenu.addItem((item2) => { - item2.setTitle("Turn into folder note").setIcon("edit").onClick(() => { - if (!folder || !(folder instanceof import_obsidian13.TFolder)) - return; - const folderNote2 = getFolderNote(this.plugin, folder.path); - turnIntoFolderNote(this.plugin, file, folder, folderNote2); - }); - }); - } - if (!(file instanceof import_obsidian13.TFolder)) - return; - if (this.plugin.settings.excludeFolders.find((folder2) => folder2.path === file.path)) { - subMenu.addItem((item2) => { - item2.setTitle("Remove folder from excluded folders").setIcon("trash").onClick(() => { - this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder2) => folder2.path !== file.path); - this.plugin.saveSettings(); - new import_obsidian13.Notice("Successfully removed folder from excluded folders"); - }); - }); - return; - } - subMenu.addItem((item2) => { - item2.setTitle("Exclude folder from folder notes").setIcon("x-circle").onClick(() => { - const excludedFolder = new ExcludedFolder(file.path, this.plugin.settings.excludeFolders.length); - this.plugin.settings.excludeFolders.push(excludedFolder); - this.plugin.saveSettings(); - new import_obsidian13.Notice("Successfully excluded folder from folder notes"); - }); - }); - if (!(file instanceof import_obsidian13.TFolder)) - return; - const folderNote = getFolderNote(this.plugin, file.path); - if (folderNote instanceof import_obsidian13.TFile) { - subMenu.addItem((item2) => { - item2.setTitle("Delete folder note").setIcon("trash").onClick(() => { - deleteFolderNote(this.plugin, folderNote); - }); - }); - subMenu.addItem((item2) => { - item2.setTitle("Open folder note").setIcon("chevron-right-square").onClick(() => { - openFolderNote(this.plugin, folderNote); - }); - }); - } else { - subMenu.addItem((item2) => { - item2.setTitle("Create folder note").setIcon("edit").onClick(() => { - createFolderNote(this.plugin, file.path, true); - }); - }); - } - }); - })); - } -}; - -// src/events/handleClick.ts -var import_obsidian14 = require("obsidian"); -async function handleViewHeaderClick(event, plugin) { - if (!(event.target instanceof HTMLElement)) - return; - if (!plugin.settings.openFolderNoteOnClickInPath) - return; - const folderPath = event.target.getAttribute("data-path"); - if (!folderPath) { - return; - } - const excludedFolder = getExcludedFolder(plugin, folderPath); - if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) { - event.target.onclick = null; - event.target.click(); - return; - } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) { - event.target.onclick = null; - event.target.click(); - } - const folderNote = getFolderNote(plugin, folderPath); - if (folderNote) { - return openFolderNote(plugin, folderNote, event); - } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") { - if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") { - await createFolderNote(plugin, folderPath, true, true); - plugin.addCSSClassToTitleEL(folderPath, "has-folder-note"); - plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note"); - return; - } - } - event.target.onclick = null; - event.target.click(); -} -async function handleFolderClick(event, plugin) { - var _a; - if (!(event.target instanceof HTMLElement)) - return; - event.stopImmediatePropagation(); - const folderPath = (_a = event.target.parentElement) == null ? void 0 : _a.getAttribute("data-path"); - if (!folderPath) { - return; - } - const excludedFolder = getExcludedFolder(plugin, folderPath); - if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) { - event.target.onclick = null; - event.target.click(); - return; - } else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) { - event.target.onclick = null; - event.target.click(); - } - const folderNote = getFolderNote(plugin, folderPath); - if (folderNote) { - return openFolderNote(plugin, folderNote, event); - } else if (event.altKey || import_obsidian14.Keymap.isModEvent(event) === "tab") { - if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian14.Keymap.isModEvent(event) === "tab") { - await createFolderNote(plugin, folderPath, true, true); - plugin.addCSSClassToTitleEL(folderPath, "has-folder-note"); - plugin.removeCSSClassFromEL(folderPath, "has-not-folder-note"); - return; - } - } - event.target.onclick = null; - event.target.click(); -} - -// src/events/handleRename.ts -var import_obsidian15 = require("obsidian"); -function handleFolderRename(file, oldPath, plugin) { - const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.name); - const folder = plugin.app.vault.getAbstractFileByPath(file.path); - const folderNote = getFolderNote(plugin, oldPath); - if (!(folderNote instanceof import_obsidian15.TFile)) - return; - if (!(folder instanceof import_obsidian15.TFolder)) - return; - const excludedFolders = plugin.settings.excludeFolders.filter((excludedFolder2) => excludedFolder2.path.includes(oldPath)); - excludedFolders.forEach((excludedFolder2) => { - if (excludedFolder2.path === oldPath) { - excludedFolder2.path = folder.path; - return; - } - const folders = excludedFolder2.path.split("/"); - if (folders.length < 1) { - folders.push(excludedFolder2.path); - } - folders[folders.indexOf(folder.name)] = folder.name; - excludedFolder2.path = folders.join("/"); - }); - plugin.saveSettings(); - const excludedFolder = getExcludedFolder(plugin, file.path); - if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && !folderNote) { - return plugin.removeCSSClassFromEL(file.path, "has-folder-note"); - } - let newPath = ""; - if (plugin.settings.storageLocation === "parentFolder") { - const parentFolderPath = plugin.getFolderPathFromString(file.path); - const oldParentFolderPath = plugin.getFolderPathFromString(oldPath); - if (parentFolderPath !== oldParentFolderPath) { - if (!plugin.settings.syncMove) { - return; - } - newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`; - } else if (parentFolderPath.trim() === "") { - folderNote.path = `${folderNote.name}`; - newPath = `${fileName}.${folderNote.extension}`; - } else { - folderNote.path = `${parentFolderPath}/${folderNote.name}`; - newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`; - } - } else { - folderNote.path = `${file.path}/${folderNote.name}`; - newPath = `${file.path}/${fileName}.${folderNote.extension}`; - } - plugin.app.vault.rename(folderNote, newPath); -} -function handleFileRename(file, oldPath, plugin) { - const oldFileName = plugin.removeExtension(plugin.getFileNameFromPathString(oldPath)); - const oldFolder = getFolderNoteFolder(plugin, oldPath, oldFileName); - const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename) || file.basename; - const oldFolderName = extractFolderName(plugin.settings.folderNoteName, oldFileName) || oldFileName; - const newFolder = getFolderNoteFolder(plugin, file, file.basename); - let excludedFolder = getExcludedFolder(plugin, (newFolder == null ? void 0 : newFolder.path) || ""); - const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file); - if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && folderName === (newFolder == null ? void 0 : newFolder.name)) { - plugin.addCSSClassToTitleEL(file.path, "is-folder-note"); - plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note"); - return; - } else if (excludedFolder == null ? void 0 : excludedFolder.disableSync) { - plugin.removeCSSClassFromEL(file.path, "is-folder-note"); - plugin.removeCSSClassFromEL((newFolder == null ? void 0 : newFolder.path) || "", "has-folder-note"); - return; - } - if (folderName === (newFolder == null ? void 0 : newFolder.name) && folderNote) { - new import_obsidian15.Notice("Folder with same name already exists!"); - let excludedFolderExisted = true; - let disabledSync = false; - if (!excludedFolder) { - excludedFolderExisted = false; - excludedFolder = new ExcludedFolder((oldFolder == null ? void 0 : oldFolder.path) || "", plugin.settings.excludeFolders.length); - addExcludedFolder(plugin, excludedFolder); - } else if (!excludedFolder.disableSync) { - disabledSync = false; - excludedFolder.disableSync = true; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - } - return plugin.app.vault.rename(file, oldPath).then(() => { - if (!excludedFolder) { - return; - } - if (!excludedFolderExisted) { - deleteExcludedFolder(plugin, excludedFolder); - } else if (!disabledSync) { - excludedFolder.disableSync = false; - updateExcludedFolder(plugin, excludedFolder, excludedFolder); - } - }); - } - if (folderName === (newFolder == null ? void 0 : newFolder.name)) { - plugin.addCSSClassToTitleEL(file.path, "is-folder-note"); - plugin.addCSSClassToTitleEL(newFolder.path, "has-folder-note"); - plugin.removeCSSClassFromEL(oldFolder == null ? void 0 : oldFolder.path, "has-folder-note"); - return; - } - if (!oldFolder) - return; - if (oldFolderName === oldFolder.name && (newFolder == null ? void 0 : newFolder.path) === oldFolder.path) { - return renameFolderOnFileRename(file, oldPath, oldFolder, plugin); - } else if (folderNote && oldFolderName === oldFolder.name) { - return renameFolderOnFileRename(file, oldPath, oldFolder, plugin); - } - if (oldFolder.name === oldFileName && (newFolder == null ? void 0 : newFolder.path) !== oldFolder.path) { - plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note"); - plugin.removeCSSClassFromEL(file.path, "is-folder-note"); - plugin.removeCSSClassFromEL(oldPath, "is-folder-note"); - } -} -async function renameFolderOnFileRename(file, oldPath, oldFolder, plugin) { - var _a; - const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename); - if (!newFolderName) { - plugin.removeCSSClassFromEL(oldFolder.path, "has-folder-note"); - plugin.removeCSSClassFromEL(file.path, "is-folder-note"); - return; - } else if (newFolderName === oldFolder.name) { - plugin.addCSSClassToTitleEL(oldFolder.path, "has-folder-note"); - plugin.addCSSClassToTitleEL(file.path, "is-folder-note"); - return; - } - let newFolderPath = ""; - if (plugin.settings.storageLocation === "insideFolder") { - newFolderPath = ((_a = oldFolder.parent) == null ? void 0 : _a.path) + "/" + newFolderName; - } else { - const parentFolderPath = plugin.getFolderPathFromString(file.path); - if (parentFolderPath.trim() === "") { - newFolderPath = `${newFolderName}`; - } else { - newFolderPath = `${parentFolderPath}/${newFolderName}`; - } - } - if (plugin.app.vault.getAbstractFileByPath(newFolderPath) || plugin.app.vault.getAbstractFileByPath(newFolderName || "")) { - await plugin.app.vault.rename(file, oldPath); - return new import_obsidian15.Notice("A folder with the same name already exists"); - } - await plugin.app.vault.rename(oldFolder, newFolderPath); -} - -// src/folderOverview.ts -var import_obsidian16 = require("obsidian"); -function createOverview(plugin, source, el, ctx) { - let yaml = (0, import_obsidian16.parseYaml)(source); - if (!yaml) { - yaml = { - title: plugin.settings.defaultOverview.title, - disableTitle: plugin.settings.defaultOverview.disableTitle, - depth: plugin.settings.defaultOverview.depth, - type: plugin.settings.defaultOverview.type, - includeTypes: plugin.settings.defaultOverview.includeTypes, - style: plugin.settings.defaultOverview.style, - disableFileTag: plugin.settings.defaultOverview.disableFileTag, - sortBy: plugin.settings.defaultOverview.sortBy, - showEmptyFolders: plugin.settings.defaultOverview.showEmptyFolders, - onlyIncludeSubfolders: plugin.settings.defaultOverview.onlyIncludeSubfolders - }; - } - const depth = (yaml == null ? void 0 : yaml.depth) || 1; - let title = (yaml == null ? void 0 : yaml.title) || plugin.settings.defaultOverview.title || "{{folderName}} overview"; - const folderName = extractFolderName(plugin.settings.folderNoteName, plugin.removeExtension(plugin.getFolderNameFromPathString(ctx.sourcePath))); - title = title.replaceAll("{{folderName}}", folderName || ""); - const disableTitle = (yaml == null ? void 0 : yaml.disableTitle) || plugin.settings.defaultOverview.disableTitle || false; - let includeTypes = (yaml == null ? void 0 : yaml.includeTypes) || plugin.settings.defaultOverview.includeTypes || ["folder", "markdown"]; - includeTypes = includeTypes.map((type) => type.toLowerCase()); - const style = (yaml == null ? void 0 : yaml.style) || "list"; - const disableFileTag = (yaml == null ? void 0 : yaml.disableFileTag) || plugin.settings.defaultOverview.disableFileTag || false; - const showEmptyFolders = (yaml == null ? void 0 : yaml.showEmptyFolders) || plugin.settings.defaultOverview.showEmptyFolders || false; - const root = el.createEl("div", { cls: "folder-overview" }); - const titleEl = root.createEl("h1", { cls: "folder-overview-title" }); - const ul = root.createEl("ul", { cls: "folder-overview-list" }); - if (!disableTitle) { - titleEl.innerText = title; - } - if (includeTypes.length === 0) { - return; - } - let files = []; - const sourceFile = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath); - if (!sourceFile) - return; - const sourceFolderPath = plugin.getFolderPathFromString(ctx.sourcePath); - let sourceFolder; - if (sourceFile.parent instanceof import_obsidian16.TFolder) { - sourceFolder = sourceFile.parent; - } else { - sourceFolder = plugin.app.vault.getAbstractFileByPath(plugin.getFolderPathFromString(ctx.sourcePath)); - } - files = sourceFolder.children; - files = files.filter((file) => { - const folderPath = plugin.getFolderPathFromString(file.path); - if (!folderPath.startsWith(sourceFolderPath)) { - return false; - } - if (file.path === ctx.sourcePath) { - return false; - } - if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) { - return true; - } - }); - if (!includeTypes.includes("folder")) { - files = getAllFiles(files, sourceFolderPath, depth); - } - files = sortFiles(files, yaml, plugin); - if (style === "grid") { - const grid = root.createEl("div", { cls: "folder-overview-grid" }); - files.forEach(async (file) => { - const gridItem = grid.createEl("div", { cls: "folder-overview-grid-item" }); - const gridArticle = gridItem.createEl("article", { cls: "folder-overview-grid-item-article" }); - if (file instanceof import_obsidian16.TFile) { - const fileContent = await plugin.app.vault.read(file); - const descriptionEl = gridArticle.createEl("p", { cls: "folder-overview-grid-item-description" }); - let description = fileContent.split("\n")[0]; - if (description.length > 64) { - description = description.slice(0, 64) + "..."; - } - descriptionEl.innerText = description; - const link = gridArticle.createEl("a", { cls: "folder-overview-grid-item-link internal-link" }); - const title2 = link.createEl("h1", { cls: "folder-overview-grid-item-link-title" }); - title2.innerText = file.name.replace(".md", "").replace(".canvas", ""); - link.href = file.path; - } else if (file instanceof import_obsidian16.TFolder) { - const folderItem = gridArticle.createEl("div", { cls: "folder-overview-grid-item-folder" }); - const folderName2 = folderItem.createEl("h1", { cls: "folder-overview-grid-item-folder-name" }); - folderName2.innerText = file.name; - } - }); - } else if (style === "list") { - const pathBlacklist = []; - files.forEach((file) => { - if (file instanceof import_obsidian16.TFolder) { - const folderItem = addFolderList(plugin, ul, pathBlacklist, file); - goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag); - } else if (file instanceof import_obsidian16.TFile) { - addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag); - } - }); - } else if (style === "explorer") { - } - if (includeTypes.length > 1 && style !== "grid" && (!showEmptyFolders || yaml.onlyIncludeSubfolders)) { - removeEmptyFolders(ul, 1, yaml); - } -} -function goThroughFolders(plugin, list, folder, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag) { - if (sourceFolderPath === "") { - depth--; - } - let files = folder.children.filter((file) => { - const folderPath = plugin.getFolderPathFromString(file.path); - if (!folderPath.startsWith(sourceFolderPath)) { - return false; - } - if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) { - return true; - } - }); - files = sortFiles(files, yaml, plugin); - const ul = list.createEl("ul", { cls: "folder-overview-list" }); - files.forEach((file) => { - if (file instanceof import_obsidian16.TFolder) { - const folderItem = addFolderList(plugin, ul, pathBlacklist, file); - goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag); - } else if (file instanceof import_obsidian16.TFile) { - addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag); - } - }); -} -function sortFiles(files, yaml, plugin) { - if (!(yaml == null ? void 0 : yaml.sortBy)) { - yaml.sortBy = plugin.settings.defaultOverview.sortBy || "name"; - } - return files.sort((a, b) => { - if (a instanceof import_obsidian16.TFolder && !(b instanceof import_obsidian16.TFolder)) { - return -1; - } - if (!(a instanceof import_obsidian16.TFolder) && b instanceof import_obsidian16.TFolder) { - return 1; - } - if (!(a instanceof import_obsidian16.TFile) || !(b instanceof import_obsidian16.TFile)) { - return -1; - } - if (yaml.sortBy === "created") { - if (a.stat.ctime > b.stat.ctime) { - return -1; - } else if (a.stat.ctime < b.stat.ctime) { - return 1; - } - } else if (yaml.sortBy === "createdAsc") { - if (a.stat.ctime < b.stat.ctime) { - return -1; - } else if (a.stat.ctime > b.stat.ctime) { - return 1; - } - } else if (yaml.sortBy === "modified") { - if (a.stat.mtime > b.stat.mtime) { - return -1; - } else if (a.stat.mtime < b.stat.mtime) { - return 1; - } - } else if (yaml.sortBy === "modifiedAsc") { - if (a.stat.mtime < b.stat.mtime) { - return -1; - } else if (a.stat.mtime > b.stat.mtime) { - return 1; - } - } - if (a.name < b.name && yaml.sortBy === "name") { - return -1; - } else if (a.name > b.name && yaml.sortBy === "nameAsc") { - return -1; - } - if (a.name > b.name && yaml.sortBy === "name") { - return 1; - } else if (a.name < b.name && yaml.sortBy === "nameAsc") { - return 1; - } - return 0; - }); -} -function removeEmptyFolders(ul, depth, yaml) { - const childrensToRemove = []; - ul.childNodes.forEach((el) => { - const childrens = el.querySelector("ul"); - if (!childrens || childrens === null) { - return; - } - if (childrens && !(childrens == null ? void 0 : childrens.hasChildNodes()) && !(el instanceof HTMLUListElement)) { - childrensToRemove.push(el); - } else if (el instanceof HTMLUListElement || el instanceof HTMLLIElement) { - removeEmptyFolders(el, depth + 1, yaml); - } - }); - childrensToRemove.forEach((el) => { - if (yaml.onlyIncludeSubfolders && depth === 1) { - return; - } - el.remove(); - }); -} -function addFolderList(plugin, list, pathBlacklist, folder) { - const folderItem = list.createEl("li", { cls: "folder-overview-list folder-list" }); - const folderNote = getFolderNote(plugin, folder.path); - if (folderNote instanceof import_obsidian16.TFile) { - const folderNoteLink = folderItem.createEl("a", { cls: "folder-overview-list-item folder-name-item internal-link", href: folderNote.path }); - folderNoteLink.innerText = folder.name; - pathBlacklist.push(folderNote.path); - } else { - const folderName = folderItem.createEl("span", { cls: "folder-overview-list-item folder-name-item" }); - folderName.innerText = folder.name; - } - return folderItem; -} -function addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag) { - if (includeTypes.length > 0 && !includeTypes.includes("all")) { - if (file.extension === "md" && !includeTypes.includes("markdown")) - return; - if (file.extension === "canvas" && !includeTypes.includes("canvas")) - return; - if (file.extension === "pdf" && !includeTypes.includes("pdf")) - return; - const imageTypes = ["jpg", "jpeg", "png", "gif", "svg", "webp"]; - if (imageTypes.includes(file.extension) && !includeTypes.includes("image")) - return; - const videoTypes = ["mp4", "webm", "ogv", "mov", "mkv"]; - if (videoTypes.includes(file.extension) && !includeTypes.includes("video")) - return; - const audioTypes = ["mp3", "wav", "m4a", "3gp", "flac", "ogg", "oga", "opus"]; - if (audioTypes.includes(file.extension) && includeTypes.includes("audio")) - return; - const allTypes = ["md", "canvas", "pdf", ...imageTypes, ...videoTypes, ...audioTypes]; - if (!allTypes.includes(file.extension) && !includeTypes.includes("other")) - return; - } - if (pathBlacklist.includes(file.path)) - return; - const listItem = list.createEl("li", { cls: "folder-overview-list file-link" }); - const nameItem = listItem.createEl("div", { cls: "folder-overview-list-item" }); - const link = nameItem.createEl("a", { cls: "internal-link", href: file.path }); - link.innerText = file.basename; - if (file.extension !== "md" && !disableFileTag) { - nameItem.createDiv({ cls: "nav-file-tag" }).innerText = file.extension; - } -} -function getAllFiles(files, sourceFolderPath, depth) { - const allFiles = []; - files.forEach((file) => { - if (file instanceof import_obsidian16.TFolder) { - if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth - 1) { - allFiles.push(...getAllFiles(file.children, sourceFolderPath, depth)); - } - } else { - allFiles.push(file); - } - }); - return allFiles; -} - -// src/modals/folderOverview.ts -var import_obsidian17 = require("obsidian"); -var FolderOverviewSettings = class extends import_obsidian17.Modal { - constructor(app2, plugin, yaml, ctx, el) { - super(app2); - this.plugin = plugin; - this.app = app2; - this.yaml = yaml; - this.ctx = ctx; - this.el = el; - if (!this.yaml) { - this.yaml = { - title: this.plugin.settings.defaultOverview.title, - disableTitle: this.plugin.settings.defaultOverview.disableTitle, - depth: this.plugin.settings.defaultOverview.depth, - type: this.plugin.settings.defaultOverview.type, - includeTypes: this.plugin.settings.defaultOverview.includeTypes, - style: this.plugin.settings.defaultOverview.style, - disableFileTag: this.plugin.settings.defaultOverview.disableFileTag, - sortBy: this.plugin.settings.defaultOverview.sortBy, - showEmptyFolders: this.plugin.settings.defaultOverview.showEmptyFolders, - onlyIncludeSubfolders: this.plugin.settings.defaultOverview.onlyIncludeSubfolders - }; - } - } - onOpen() { - this.display(); - } - display() { - var _a, _b, _c, _d; - const { contentEl } = this; - contentEl.empty(); - contentEl.addEventListener("keydown", (e) => { - if (e.key === "Enter") { - this.close(); - } - }); - contentEl.createEl("h2", { text: "Folder overview settings" }); - new import_obsidian17.Setting(contentEl).setName("Disable the title").setDesc("Choose if the title should be shown").addToggle((toggle) => toggle.setValue(this.yaml.disableTitle || false).onChange(async (value) => { - this.yaml.disableTitle = value; - this.display(); - await this.updateYaml(); - })); - if (!this.yaml.disableTitle) { - new import_obsidian17.Setting(contentEl).setName("Title").setDesc("Choose the title of the folder overview").addText((text) => { - var _a2; - return text.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.title) || "{{folderName}} overview").onChange(async (value) => { - this.yaml.title = value; - await this.updateYaml(); - }); - }); - } - const setting = new import_obsidian17.Setting(contentEl); - setting.setName("Include types"); - const list = setting.createList((list2) => { - var _a2; - return list2.addModal(this).setValues(((_a2 = this.yaml) == null ? void 0 : _a2.includeTypes) || this.plugin.settings.defaultOverview.includeTypes || []).addResetButton(); - }); - if ((((_b = (_a = this.yaml) == null ? void 0 : _a.includeTypes) == null ? void 0 : _b.length) || 0) < 8 && !((_c = this.yaml.includeTypes) == null ? void 0 : _c.includes("all"))) { - setting.addDropdown((dropdown) => { - if (!this.yaml.includeTypes) - this.yaml.includeTypes = this.plugin.settings.defaultOverview.includeTypes || []; - this.yaml.includeTypes = this.yaml.includeTypes.map((type) => type.toLowerCase()); - const options = [ - { value: "markdown", label: "Markdown" }, - { value: "folder", label: "Folder" }, - { value: "canvas", label: "Canvas" }, - { value: "pdf", label: "PDF" }, - { value: "image", label: "Image" }, - { value: "audio", label: "Audio" }, - { value: "video", label: "Video" }, - { value: "other", label: "All other file types" }, - { value: "all", label: "All file types" } - ]; - options.forEach((option) => { - var _a2; - if (!((_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.includes(option.value))) { - dropdown.addOption(option.value, option.label); - } - }); - dropdown.addOption("+", "+"); - dropdown.setValue("+"); - dropdown.onChange(async (value) => { - var _a2; - if (value === "all") { - this.yaml.includeTypes = (_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.filter((type) => type === "folder"); - list.setValues(this.yaml.includeTypes); - } - await list.addValue(value.toLowerCase()); - await this.updateYaml(); - this.display(); - }); - }); - } - let disableFileTag; - (_d = this.yaml.includeTypes) == null ? void 0 : _d.forEach((type) => { - type === "folder" || type === "markdown" ? disableFileTag = true : null; - }); - if (disableFileTag) { - new import_obsidian17.Setting(contentEl).setName("Disable file tag").setDesc("Choose if the file tag should be shown after the file name").addToggle((toggle) => { - toggle.setValue(this.yaml.disableFileTag || this.plugin.settings.defaultOverview.disableFileTag || false).onChange(async (value) => { - this.yaml.disableFileTag = value; - await this.updateYaml(); - }); - }); - } - new import_obsidian17.Setting(contentEl).setName("File depth").setDesc("File & folder = +1 depth").addSlider((slider) => { - var _a2; - return slider.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.depth) || 2).setLimits(1, 10, 1).onChange(async (value) => { - this.yaml.depth = value; - await this.updateYaml(); - }); - }); - new import_obsidian17.Setting(contentEl).setName("Overview style").setDesc("Choose the style of the overview (grid style soon)").addDropdown((dropdown) => { - var _a2; - return dropdown.addOption("list", "List").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.style) || "list").onChange(async (value) => { - this.yaml.style = value; - await this.updateYaml(); - }); - }); - new import_obsidian17.Setting(contentEl).setName("Sort files by").setDesc("Choose how the files should be sorted").addDropdown((dropdown) => { - var _a2; - return dropdown.addOption("name", "Name descending").addOption("created", "Created descending").addOption("modified", "Modified descending").addOption("nameAsc", "Name ascending").addOption("createdAsc", "Created ascending").addOption("modifiedAsc", "Modified ascending").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.sortBy) || "name").onChange(async (value) => { - this.yaml.sortBy = value; - await this.updateYaml(); - }); - }); - new import_obsidian17.Setting(contentEl).setName("Show folder names of empty folders").setDesc("That includes subfolders of the current folder when you are on file depth 1").addToggle((toggle) => { - toggle.setValue(this.yaml.showEmptyFolders || this.plugin.settings.defaultOverview.showEmptyFolders || false).onChange(async (value) => { - this.yaml.showEmptyFolders = value; - this.yaml.onlyIncludeSubfolders = false; - this.display(); - await this.updateYaml(); - }); - }); - if (this.yaml.showEmptyFolders) { - new import_obsidian17.Setting(contentEl).setName("Only show first empty subfolders of current folder").addToggle((toggle) => { - toggle.setValue(this.yaml.onlyIncludeSubfolders || this.plugin.settings.defaultOverview.onlyIncludeSubfolders || false).onChange(async (value) => { - this.yaml.onlyIncludeSubfolders = value; - await this.updateYaml(); - }); - }); - } - } - onClose() { - const { contentEl } = this; - contentEl.empty(); - } - async updateYaml() { - const file = this.plugin.app.vault.getAbstractFileByPath(this.ctx.sourcePath); - if (!(file instanceof import_obsidian17.TFile)) - return; - let stringYaml = (0, import_obsidian17.stringifyYaml)(this.yaml); - await this.plugin.app.vault.process(file, (text) => { - const info = this.ctx.getSectionInfo(this.el); - if (stringYaml[stringYaml.length - 1] !== "\n") { - stringYaml += "\n"; - } - if (info) { - const { lineStart } = info; - const lineEnd = this.getCodeBlockEndLine(text, lineStart); - if (lineEnd === -1 || !lineEnd) - return text; - const lineLength = lineEnd - lineStart; - const lines = text.split("\n"); - lines.splice(lineStart, lineLength + 1, `\`\`\`folder-overview -${stringYaml}\`\`\``); - return lines.join("\n"); - } - return `\`\`\`folder-overview -${stringYaml}\`\`\``; - }); - } - getCodeBlockEndLine(text, startLine, count = 1) { - let line = startLine + 1; - const lines = text.split("\n"); - while (line < lines.length) { - if (count > 20) { - return -1; - } - if (lines[line].startsWith("```")) { - return line; - } - line++; - count++; - } - return line; - } -}; - -// src/functions/ListComponent.ts -var import_obsidian18 = require("obsidian"); -var ListComponent = class { - constructor(containerEl) { - this.containerEl = containerEl; - this.controlEl = containerEl.querySelector(".setting-item-control") || containerEl; - this.listEl = this.controlEl.createDiv("setting-command-hotkeys"); - } - addModal(modal) { - this.modal = modal; - this.values = modal.yaml.includeTypes || []; - return this; - } - setValues(values) { - this.listEl.empty(); - this.values = values; - this.modal.yaml.includeTypes = values; - if (values.length !== 0) { - values.forEach((value) => { - this.addElement(value); - }); - } - this.modal.updateYaml(); - return this; - } - addElement(value) { - this.listEl.createSpan("setting-hotkey", (span) => { - span.innerText = value; - const removeSpan = span.createEl("span", { cls: "ofn-list-item-remove setting-hotkey-icon" }); - const svg = ''; - const svgElement = removeSpan.createEl("span", { cls: "ofn-list-item-remove-icon" }); - svgElement.innerHTML = svg; - removeSpan.onClickEvent((e) => { - this.removeValue(value); - span.remove(); - }); - }); - } - async addValue(value) { - this.values.push(value); - this.addElement(value); - this.modal.yaml.includeTypes = this.values; - return this; - } - addResetButton() { - const resetButton = this.controlEl.createEl("span", { cls: "clickable-icon setting-restore-hotkey-button" }); - const svg = ''; - resetButton.innerHTML = svg; - resetButton.onClickEvent((e) => { - this.modal.plugin.loadSettings(); - this.setValues(this.modal.plugin.settings.defaultOverview.includeTypes || []); - this.modal.display(); - }); - return this; - } - removeValue(value) { - this.values = this.values.filter((v) => v !== value); - this.setValues(this.values); - this.modal.display(); - } -}; -function createList(cb) { - const list = new ListComponent(this.settingEl); - cb(list); - return list; -} -import_obsidian18.Setting.prototype.createList = createList; - -// src/main.ts -var FolderNotesPlugin = class extends import_obsidian19.Plugin { - constructor() { - super(...arguments); - this.fmtpHandler = null; - } - async onload() { - console.log("loading folder notes plugin"); - await this.loadSettings(); - this.settingsTab = new SettingsTab(this.app, this); - this.addSettingTab(this.settingsTab); - this.saveSettings(); - document.body.classList.add("folder-notes-plugin"); - if (this.settings.hideFolderNote) { - document.body.classList.add("hide-folder-note"); - } - if (this.settings.underlineFolder) { - document.body.classList.add("folder-note-underline"); - } - if (this.settings.underlineFolderInPath) { - document.body.classList.add("folder-note-underline-path"); - } - if (!this.settings.allowWhitespaceCollapsing) { - document.body.classList.add("fn-whitespace-stop-collapsing"); - } - new Commands(this.app, this).registerCommands(); - this.app.workspace.onLayoutReady(() => { - if (this.settings.frontMatterTitle.enabled) { - this.fmtpHandler = new FrontMatterTitlePluginHandler(this); - } - }); - this.observer = new MutationObserver((mutations) => { - mutations.forEach((rec) => { - if (rec.type === "childList") { - rec.target.querySelectorAll("div.nav-folder-title-content").forEach((element) => { - if (element.onclick) - return; - element.onclick = (event) => handleFolderClick(event, this); - }); - if (!this.settings.openFolderNoteOnClickInPath) { - return; - } - rec.target.querySelectorAll("span.view-header-breadcrumb").forEach((element) => { - var _a, _b; - const breadcrumbs = (_a = element.parentElement) == null ? void 0 : _a.querySelectorAll("span.view-header-breadcrumb"); - if (!breadcrumbs) - return; - let path = ""; - breadcrumbs.forEach((breadcrumb) => { - var _a2; - if (breadcrumb.hasAttribute("old-name")) { - path += breadcrumb.getAttribute("old-name") + "/"; - } else { - path += breadcrumb.innerText.trim() + "/"; - } - const folderPath = path.slice(0, -1); - breadcrumb.setAttribute("data-path", folderPath); - const folder = (_a2 = this.fmtpHandler) == null ? void 0 : _a2.modifiedFolders.get(folderPath); - if (folder && this.settings.frontMatterTitle.path && this.settings.frontMatterTitle.enabled) { - breadcrumb.setAttribute("old-name", folder.name || ""); - breadcrumb.innerText = folder.newName || ""; - } - const folderNote = getFolderNote(this, folderPath); - if (folderNote) { - breadcrumb.classList.add("has-folder-note"); - } - }); - (_b = element.parentElement) == null ? void 0 : _b.setAttribute("data-path", path.slice(0, -1)); - if (breadcrumbs.length > 0) { - breadcrumbs.forEach((breadcrumb) => { - if (breadcrumb.onclick) - return; - breadcrumb.onclick = (event) => handleViewHeaderClick(event, this); - }); - } - }); - } - }); - }); - this.observer.observe(document.body, { - childList: true, - subtree: true - }); - this.registerEvent(this.app.workspace.on("layout-change", () => { - this.loadFileClasses(); - })); - this.registerEvent(this.app.vault.on("delete", (file) => { - if (!(file instanceof import_obsidian19.TFile)) { - return; - } - const parentPath = this.getFolderPathFromString(file.path); - const parentName = this.getFileNameFromPathString(parentPath); - if (parentName !== file.basename) { - return; - } - this.removeCSSClassFromEL(parentPath, "has-folder-note"); - })); - this.registerEvent(this.app.vault.on("create", (file) => { - if (file instanceof import_obsidian19.TFile) { - const folderName = extractFolderName(this.settings.folderNoteName, file.basename); - const folder = getFolder(this, file); - if (!folder) { - return; - } - if (folderName !== folder.name) { - return; - } - this.addCSSClassToTitleEL(folder.path, "has-folder-note"); - this.addCSSClassToTitleEL(file.path, "is-folder-note"); - } - if (!this.app.workspace.layoutReady) - return; - if (!this.settings.autoCreate) - return; - if (!(file instanceof import_obsidian19.TFolder)) - return; - const excludedFolder = getExcludedFolder(this, file.path); - if (excludedFolder == null ? void 0 : excludedFolder.disableAutoCreate) - return; - const folderNote = getFolderNote(this, file.path); - if (folderNote) - return; - createFolderNote(this, file.path, true, true); - this.addCSSClassToTitleEL(file.path, "has-folder-note"); - })); - this.registerEvent(this.app.workspace.on("file-open", (openFile) => { - if (this.activeFolderDom) { - this.activeFolderDom.removeClass("is-active"); - this.activeFolderDom = null; - } - if (!openFile || !openFile.basename) { - return; - } - const folder = getFolder(this, openFile); - if (!folder) { - return; - } - if (extractFolderName(this.settings.folderNoteName, openFile.basename) !== folder.name) { - return; - } - this.activeFolderDom = this.getEL(folder.path); - if (this.activeFolderDom) - this.activeFolderDom.addClass("is-active"); - })); - this.registerEvent(this.app.vault.on("rename", (file, oldPath) => { - if (!this.settings.syncFolderName) { - this.removeCSSClassFromEL(file.path, "has-folder-note"); - this.removeCSSClassFromEL(file.path, "is-folder-note"); - return; - } - if (file instanceof import_obsidian19.TFolder) { - return handleFolderRename(file, oldPath, this); - } else if (file instanceof import_obsidian19.TFile) { - return handleFileRename(file, oldPath, this); - } - })); - this.registerEvent(this.app.vault.on("delete", (file) => { - if (file instanceof import_obsidian19.TFile) { - const folder = getFolder(this, file); - if (!folder) { - return; - } - this.removeCSSClassFromEL(folder.path, "has-folder-note"); - } - if (!(file instanceof import_obsidian19.TFolder)) { - return; - } - const folderNote = getFolderNote(this, file.path); - if (!folderNote) { - return; - } - this.removeCSSClassFromEL(folderNote.path, "is-folder-note"); - if (!this.settings.syncDelete) { - return; - } - this.app.vault.delete(folderNote); - })); - this.registerMarkdownCodeBlockProcessor("folder-overview", (source, el, ctx) => { - const observer = new MutationObserver(() => { - var _a; - const editButton = (_a = el.parentElement) == null ? void 0 : _a.childNodes.item(1); - if (editButton) { - editButton.addEventListener("click", (e) => { - e.stopImmediatePropagation(); - e.preventDefault(); - e.stopPropagation(); - new FolderOverviewSettings(this.app, this, (0, import_obsidian19.parseYaml)(source), ctx, el).open(); - }, { capture: true }); - } - }); - observer.observe(el, { - childList: true, - subtree: true - }); - createOverview(this, source, el, ctx); - }); - if (this.app.workspace.layoutReady) { - this.loadFileClasses(); - } else { - this.app.workspace.onLayoutReady(async () => this.loadFileClasses()); - } - } - getFileNameFromPathString(path) { - return path.substring(path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") + 1 : 0); - } - getFolderNameFromPathString(path) { - if (path.endsWith(".md") || path.endsWith(".canvas")) { - return path.split("/").slice(-2)[0]; - } else { - return path.split("/").slice(-1)[0]; - } - } - removeExtension(name) { - return name.replace(/\.[^/.]+$/, ""); - } - getExtensionFromPathString(path) { - return path.slice(path.lastIndexOf(".") >= 0 ? path.lastIndexOf(".") : 0); - } - getFolderPathFromString(path) { - const subString = path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") : 0; - return path.substring(0, subString); - } - getParentFolderPath(path) { - return this.getFolderPathFromString(this.getFolderPathFromString(path)); - } - getFileExplorer() { - return this.app.workspace.getLeavesOfType("file-explorer")[0]; - } - getFileExplorerView() { - return this.getFileExplorer().view; - } - async addCSSClassToTitleEL(path, cssClass, waitForCreate = false, count = 0) { - const fileExplorerItem = this.getEL(path); - if (!fileExplorerItem) { - if (waitForCreate && count < 5) { - await new Promise((r) => setTimeout(r, 500)); - this.addCSSClassToTitleEL(path, cssClass, waitForCreate, count + 1); - return; - } - return; - } - fileExplorerItem.addClass(cssClass); - const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`); - viewHeaderItems.forEach((item) => { - item.addClass(cssClass); - }); - } - async changeName(folder, name, replacePath, waitForCreate = false, count = 0) { - if (!name) - name = folder.name; - let fileExplorerItem = this.getEL(folder.path); - if (!fileExplorerItem) { - if (waitForCreate && count < 5) { - await new Promise((r) => setTimeout(r, 500)); - this.changeName(folder, name, replacePath, waitForCreate, count + 1); - return; - } - return; - } - fileExplorerItem = fileExplorerItem.querySelector("div.nav-folder-title-content"); - if (!fileExplorerItem) { - return; - } - if (this.settings.frontMatterTitle.explorer && this.settings.frontMatterTitle.enabled) { - fileExplorerItem.innerText = name; - fileExplorerItem.setAttribute("old-name", folder.name); - } else { - fileExplorerItem.innerText = folder.name; - fileExplorerItem.removeAttribute("old-name"); - } - if (replacePath) { - this.updateBreadcrumbs(); - } - } - updateBreadcrumbs(remove) { - if (!this.settings.frontMatterTitle.path && !remove) { - return; - } - const viewHeaderItems = document.querySelectorAll("span.view-header-breadcrumb"); - const files = this.app.vault.getAllLoadedFiles().filter((file) => file instanceof import_obsidian19.TFolder); - viewHeaderItems.forEach((item) => { - if (!item.hasAttribute("data-path")) { - return; - } - const path = item.getAttribute("data-path"); - const folder = files.find((file) => file.path === path); - if (!(folder instanceof import_obsidian19.TFolder)) { - return; - } - if (remove) { - item.textContent = folder.name; - item.removeAttribute("old-name"); - } else { - item.textContent = folder.newName || folder.name; - item.setAttribute("old-name", folder.name); - item.setAttribute("data-path", folder.path); - } - }); - } - removeCSSClassFromEL(path, cssClass) { - if (!path) - return; - const fileExplorerItem = this.getEL(path); - const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`); - viewHeaderItems.forEach((item) => { - item.removeClass(cssClass); - }); - if (!fileExplorerItem) { - return; - } - fileExplorerItem.removeClass(cssClass); - } - getEL(path) { - const fileExplorer = this.getFileExplorer(); - if (!fileExplorer) { - return null; - } - const fileExplorerItem = fileExplorer.view.fileItems[path]; - if (!fileExplorerItem) { - return null; - } - if (fileExplorerItem.selfEl) - return fileExplorerItem.selfEl; - return fileExplorerItem.titleEl; - } - loadFileClasses(forceReload = false) { - if (this.activeFileExplorer === this.getFileExplorer() && !forceReload) { - return; - } - this.activeFileExplorer = this.getFileExplorer(); - this.app.vault.getAllLoadedFiles().forEach((file) => { - if (!(file instanceof import_obsidian19.TFolder)) { - return; - } - const folderNote = getFolderNote(this, file.path); - if (!folderNote) { - this.removeCSSClassFromEL(file == null ? void 0 : file.path, "has-folder-note"); - return; - } - const excludedFolder = getExcludedFolder(this, file.path); - if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) { - this.removeCSSClassFromEL(folderNote.path, "is-folder-note"); - this.removeCSSClassFromEL(file.path, "has-folder-note"); - } else { - this.addCSSClassToTitleEL(folderNote.path, "is-folder-note"); - this.addCSSClassToTitleEL(file.path, "has-folder-note"); - } - }); - } - reloadHandlers() { - document.querySelectorAll("div.nav-folder-title-content").forEach((element) => { - if (element.onclick) - return; - element.onclick = (event) => handleFolderClick(event, this); - }); - } - onunload() { - console.log("unloading folder notes plugin"); - this.observer.disconnect(); - document.body.classList.remove("folder-notes-plugin"); - document.body.classList.remove("folder-note-underline"); - document.body.classList.remove("hide-folder-note"); - document.body.classList.remove("fn-whitespace-stop-collapsing"); - if (this.activeFolderDom) { - this.activeFolderDom.removeClass("is-active"); - } - if (this.fmtpHandler) { - this.fmtpHandler.deleteEvent(); - } - } - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } - async saveSettings() { - await this.saveData(this.settings); - this.loadFileClasses(true); - } -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibm9kZV9tb2R1bGVzL2Zyb250LW1hdHRlci1wbHVnaW4tYXBpLXByb3ZpZGVyL2xpYi9jb250cmFjdHMvQXBpLmpzIiwgIm5vZGVfbW9kdWxlcy9mcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlci9saWIvY29udHJhY3RzL0V2ZW50RGlzcGF0Y2hlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2NvbnRyYWN0cy9SZXNvbHZlci5qcyIsICJub2RlX21vZHVsZXMvZnJvbnQtbWF0dGVyLXBsdWdpbi1hcGktcHJvdmlkZXIvbGliL2luZGV4LmpzIiwgInNyYy9tYWluLnRzIiwgInNyYy9zZXR0aW5ncy50cyIsICJzcmMvc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlci50cyIsICJzcmMvc3VnZ2VzdGVycy9zdWdnZXN0LnRzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZW51bXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZU5hbWUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2luc3RhbmNlT2YuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvYXBwbHlTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWF0aC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3VzZXJBZ2VudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc0xheW91dFZpZXdwb3J0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2NvbnRhaW5zLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNUYWJsZUVsZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFBhcmVudE5vZGUuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvd2l0aGluLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0RnJlc2hTaWRlT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZXhwYW5kVG9IYXNoTWFwLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2Fycm93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0VmFyaWF0aW9uLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2NvbXB1dGVTdHlsZXMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRPcHBvc2l0ZVBsYWNlbWVudC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvd1Njcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFZpZXdwb3J0UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXREb2N1bWVudFJlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNTY3JvbGxQYXJlbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0U2Nyb2xsUGFyZW50LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvcmVjdFRvQ2xpZW50UmVjdC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9jb21wdXRlT2Zmc2V0cy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvY29tcHV0ZUF1dG9QbGFjZW1lbnQuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvZmxpcC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9oaWRlLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL29mZnNldC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0QWx0QXhpcy5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wcmV2ZW50T3ZlcmZsb3cuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZVNjcm9sbC5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvb3JkZXJNb2RpZmllcnMuanMiLCAibm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9kZWJvdW5jZS5qcyIsICJub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21lcmdlQnlOYW1lLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvY3JlYXRlUG9wcGVyLmpzIiwgIm5vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvcG9wcGVyLmpzIiwgInNyYy90ZW1wbGF0ZS50cyIsICJzcmMvbW9kYWxzL2V4aXN0aW5nTm90ZS50cyIsICJzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMudHMiLCAic3JjL21vZGFscy9kZWxldGVDb25maXJtYXRpb24udHMiLCAic3JjL2V4Y2x1ZGVkRm9sZGVyLnRzIiwgInNyYy9tb2RhbHMvZXhjbHVkZUZvbGRlclNldHRpbmdzLnRzIiwgInNyYy9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlci50cyIsICJzcmMvbW9kYWxzL3BhdHRlcm5TZXR0aW5ncy50cyIsICJzcmMvZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUudHMiLCAic3JjL2NvbW1hbmRzLnRzIiwgInNyYy9ldmVudHMvaGFuZGxlQ2xpY2sudHMiLCAic3JjL2V2ZW50cy9oYW5kbGVSZW5hbWUudHMiLCAic3JjL2ZvbGRlck92ZXJ2aWV3LnRzIiwgInNyYy9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcudHMiLCAic3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbiIsICJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2NyZWF0ZUJpbmRpbmcgPSAodGhpcyAmJiB0aGlzLl9fY3JlYXRlQmluZGluZykgfHwgKE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcbiAgICB9XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcbiAgICBvW2syXSA9IG1ba107XG59KSk7XG52YXIgX19leHBvcnRTdGFyID0gKHRoaXMgJiYgdGhpcy5fX2V4cG9ydFN0YXIpIHx8IGZ1bmN0aW9uKG0sIGV4cG9ydHMpIHtcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGV4cG9ydHMsIHApKSBfX2NyZWF0ZUJpbmRpbmcoZXhwb3J0cywgbSwgcCk7XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5nZXRBcGlTYWZlID0gZXhwb3J0cy5nZXREZWZlciA9IGV4cG9ydHMuaXNQbHVnaW5FbmFibGVkID0gZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBleHBvcnRzLnBsdWdpbklkID0gdm9pZCAwO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9BcGlcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9FdmVudERpc3BhdGNoZXJcIiksIGV4cG9ydHMpO1xuX19leHBvcnRTdGFyKHJlcXVpcmUoXCIuL2NvbnRyYWN0cy9SZXNvbHZlclwiKSwgZXhwb3J0cyk7XG5leHBvcnRzLnBsdWdpbklkID0gJ29ic2lkaWFuLWZyb250LW1hdHRlci10aXRsZS1wbHVnaW4nO1xuY2xhc3MgUGx1Z2luTm90RW5hYmxlZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuZXhwb3J0cy5QbHVnaW5Ob3RFbmFibGVkRXJyb3IgPSBQbHVnaW5Ob3RFbmFibGVkRXJyb3I7XG4vKipcbiAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgb2JzaWRpYW4tZnJvbnQtbWF0dGVyLXRpdGxlLXBsdWdpbiBpcyBlbmFibGVkXG4gKiBAcGFyYW0gYXBwXG4gKi9cbmZ1bmN0aW9uIGlzUGx1Z2luRW5hYmxlZChhcHApIHtcbiAgICB2YXIgX2EsIF9iLCBfYztcbiAgICAvL0B0cy1pZ25vcmVcbiAgICByZXR1cm4gKF9jID0gKF9iID0gKF9hID0gYXBwID09PSBudWxsIHx8IGFwcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogYXBwLnBsdWdpbnMpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5lbmFibGVkUGx1Z2lucykgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmhhcyhleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2MgIT09IHZvaWQgMCA/IF9jIDogZmFsc2U7XG59XG5leHBvcnRzLmlzUGx1Z2luRW5hYmxlZCA9IGlzUGx1Z2luRW5hYmxlZDtcbi8qKlxuICpcbiAqIEB0aHJvd3MgUGx1Z2luTm90RW5hYmxlZEVycm9yXG4gKi9cbmZ1bmN0aW9uIGdldERlZmVyKGFwcCkge1xuICAgIHZhciBfYSwgX2IsIF9jLCBfZDtcbiAgICAvL0B0cy1pZ25vcmVcbiAgICBjb25zdCBwbHVnaW4gPSAoX2IgPSAoX2EgPSBhcHAgPT09IG51bGwgfHwgYXBwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhcHAucGx1Z2lucykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFBsdWdpbihleHBvcnRzLnBsdWdpbklkKSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogbnVsbDtcbiAgICBjb25zdCBkZWZlciA9IChfZCA9IChfYyA9IHBsdWdpbiA9PT0gbnVsbCB8fCBwbHVnaW4gPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBsdWdpbi5nZXREZWZlcikgPT09IG51bGwgfHwgX2MgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jLmNhbGwocGx1Z2luKSkgIT09IG51bGwgJiYgX2QgIT09IHZvaWQgMCA/IF9kIDogbnVsbDtcbiAgICBpZiAoZGVmZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBsdWdpbk5vdEVuYWJsZWRFcnJvcihgUGx1Z2luICR7ZXhwb3J0cy5wbHVnaW5JZH0gaXMgbm90IGVuYWJsZWQgb3Igb2xkIHZlcnNpb25gKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmVyO1xufVxuZXhwb3J0cy5nZXREZWZlciA9IGdldERlZmVyO1xuLyoqXG4gKiBXcmFwcGVyIGZvciBvYmplY3QuIEl0IHdpbGwgY2hlY2sgaXRzZWxmIGlmIHBsdWdpbiBpcyBlbmFibGVkIGFuZCByZWFkeVxuICogQHBhcmFtIGFwcFxuICovXG5mdW5jdGlvbiBnZXRBcGlTYWZlKGFwcCkge1xuICAgIHJldHVybiBuZXcgQXBpV3JhcHBlcihudWxsLCBhcHApO1xufVxuZXhwb3J0cy5nZXRBcGlTYWZlID0gZ2V0QXBpU2FmZTtcbmNsYXNzIEFwaVdyYXBwZXIge1xuICAgIGNvbnN0cnVjdG9yKGFwaSwgYXBwKSB7XG4gICAgICAgIHRoaXMuYXBpID0gYXBpO1xuICAgICAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICB9XG4gICAgYmVmb3JlKCkge1xuICAgICAgICBpZiAodGhpcy5hcGkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZWZlciA9IHRoaXMuZ2V0RGVmZmVyKCk7XG4gICAgICAgIGlmIChkZWZlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICBpZiAoYXBpID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVmZXIuYXdhaXRQbHVnaW4oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaSA9IGRlZmVyLmdldEFwaSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXREZWZmZXIoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RGVmZXIodGhpcy5hcHApO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFBsdWdpbk5vdEVuYWJsZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRSZXNvbHZlckZhY3RvcnkoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldFJlc29sdmVyRmFjdG9yeSgpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFdmVudERpc3BhdGNoZXIoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEV2ZW50RGlzcGF0Y2hlcigpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBudWxsO1xuICAgIH1cbiAgICBnZXRFbmFibGVkRmVhdHVyZXMoKSB7XG4gICAgICAgIHZhciBfYSwgX2I7XG4gICAgICAgIHRoaXMuYmVmb3JlKCk7XG4gICAgICAgIHJldHVybiAoX2IgPSAoX2EgPSB0aGlzLmFwaSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmdldEVuYWJsZWRGZWF0dXJlcygpKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBbXTtcbiAgICB9XG59XG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBERUZBVUxUX1NFVFRJTkdTLCBGb2xkZXJOb3Rlc1NldHRpbmdzLCBTZXR0aW5nc1RhYiB9IGZyb20gJy4vc2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBDb21tYW5kcyB9IGZyb20gJy4vY29tbWFuZHMnO1xyXG5pbXBvcnQgeyBGaWxlRXhwbG9yZXJXb3Jrc3BhY2VMZWFmIH0gZnJvbSAnLi9nbG9iYWxzJztcclxuaW1wb3J0IHsgaGFuZGxlVmlld0hlYWRlckNsaWNrLCBoYW5kbGVGb2xkZXJDbGljayB9IGZyb20gJy4vZXZlbnRzL2hhbmRsZUNsaWNrJztcclxuaW1wb3J0IHsgaGFuZGxlRmlsZVJlbmFtZSwgaGFuZGxlRm9sZGVyUmVuYW1lIH0gZnJvbSAnLi9ldmVudHMvaGFuZGxlUmVuYW1lJztcclxuaW1wb3J0IHsgY3JlYXRlRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUsIGdldEZvbGRlciB9IGZyb20gJy4vZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBnZXRFeGNsdWRlZEZvbGRlciB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG5pbXBvcnQgeyBjcmVhdGVPdmVydmlldyBhcyBjcmVhdGVGb2xkZXJPdmVydmlldyB9IGZyb20gJy4vZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi9tb2RhbHMvZm9sZGVyT3ZlcnZpZXcnO1xyXG5pbXBvcnQgJy4vZnVuY3Rpb25zL0xpc3RDb21wb25lbnQnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGb2xkZXJOb3Rlc1BsdWdpbiBleHRlbmRzIFBsdWdpbiB7XHJcblx0b2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XHJcblx0c2V0dGluZ3M6IEZvbGRlck5vdGVzU2V0dGluZ3M7XHJcblx0c2V0dGluZ3NUYWI6IFNldHRpbmdzVGFiO1xyXG5cdGFjdGl2ZUZvbGRlckRvbTogSFRNTEVsZW1lbnQgfCBudWxsO1xyXG5cdGFjdGl2ZUZpbGVFeHBsb3JlcjogRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHRmbXRwSGFuZGxlcjogRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIgfCBudWxsID0gbnVsbDtcclxuXHRhc3luYyBvbmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygnbG9hZGluZyBmb2xkZXIgbm90ZXMgcGx1Z2luJyk7XHJcblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5zZXR0aW5nc1RhYiA9IG5ldyBTZXR0aW5nc1RhYih0aGlzLmFwcCwgdGhpcyk7XHJcblx0XHR0aGlzLmFkZFNldHRpbmdUYWIodGhpcy5zZXR0aW5nc1RhYik7XHJcblx0XHR0aGlzLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRcdC8vIEFkZCBDU1MgQ2xhc3Nlc1xyXG5cdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZXMtcGx1Z2luJyk7XHJcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2hpZGUtZm9sZGVyLW5vdGUnKTsgfVxyXG5cdFx0aWYgKHRoaXMuc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLnVuZGVybGluZUZvbGRlckluUGF0aCkgeyBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7IH1cclxuXHRcdGlmICghdGhpcy5zZXR0aW5ncy5hbGxvd1doaXRlc3BhY2VDb2xsYXBzaW5nKSB7IGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTsgfVxyXG5cclxuXHRcdG5ldyBDb21tYW5kcyh0aGlzLmFwcCwgdGhpcykucmVnaXN0ZXJDb21tYW5kcygpO1xyXG5cclxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHtcclxuXHRcdFx0aWYgKHRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdFx0dGhpcy5mbXRwSGFuZGxlciA9IG5ldyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlcih0aGlzKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnM6IE11dGF0aW9uUmVjb3JkW10pID0+IHtcclxuXHRcdFx0bXV0YXRpb25zLmZvckVhY2goKHJlYykgPT4ge1xyXG5cdFx0XHRcdGlmIChyZWMudHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcclxuXHRcdFx0XHRcdCg8RWxlbWVudD5yZWMudGFyZ2V0KS5xdWVyeVNlbGVjdG9yQWxsKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGVsZW1lbnQub25jbGljaykgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQub25jbGljayA9IChldmVudDogTW91c2VFdmVudCkgPT4gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0XHQoPEVsZW1lbnQ+cmVjLnRhcmdldCkucXVlcnlTZWxlY3RvckFsbCgnc3Bhbi52aWV3LWhlYWRlci1icmVhZGNydW1iJylcclxuXHRcdFx0XHRcdFx0LmZvckVhY2goKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgYnJlYWRjcnVtYnMgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3JBbGwoJ3NwYW4udmlldy1oZWFkZXItYnJlYWRjcnVtYicpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICghYnJlYWRjcnVtYnMpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRsZXQgcGF0aCA9ICcnO1xyXG5cdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoYnJlYWRjcnVtYi5oYXNBdHRyaWJ1dGUoJ29sZC1uYW1lJykpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cGF0aCArPSBicmVhZGNydW1iLmdldEF0dHJpYnV0ZSgnb2xkLW5hbWUnKSArICcvJztcclxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHBhdGggKz0gYnJlYWRjcnVtYi5pbm5lclRleHQudHJpbSgpICsgJy8nO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBhdGguc2xpY2UoMCwgLTEpO1xyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcsIGZvbGRlclBhdGgpO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyID0gdGhpcy5mbXRwSGFuZGxlcj8ubW9kaWZpZWRGb2xkZXJzLmdldChmb2xkZXJQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLnBhdGggJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUgfHwgJycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmlubmVyVGV4dCA9IGZvbGRlci5uZXdOYW1lIHx8ICcnO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhZGNydW1iLmNsYXNzTGlzdC5hZGQoJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHRcdGVsZW1lbnQucGFyZW50RWxlbWVudD8uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBwYXRoLnNsaWNlKDAsIC0xKSk7XHJcblx0XHRcdFx0XHRcdFx0aWYgKGJyZWFkY3J1bWJzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFkY3J1bWJzLmZvckVhY2goKGJyZWFkY3J1bWI6IEhUTUxFbGVtZW50KSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmIChicmVhZGNydW1iLm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWRjcnVtYi5vbmNsaWNrID0gKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiBoYW5kbGVWaWV3SGVhZGVyQ2xpY2soZXZlbnQsIHRoaXMpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5vYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LmJvZHksIHtcclxuXHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRzdWJ0cmVlOiB0cnVlLFxyXG5cdFx0fSk7XHJcblx0XHR0aGlzLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdsYXlvdXQtY2hhbmdlJywgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmxvYWRGaWxlQ2xhc3NlcygpO1xyXG5cdFx0fSkpO1xyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdkZWxldGUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cdFx0XHQvLyBwYXJlbnQgaXMgbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIHBhcmVudCBleGlzdHNcclxuXHRcdFx0Ly8gbm90IGVudGlyZWx5IHN1cmUgd2h5XHJcblx0XHRcdGNvbnN0IHBhcmVudFBhdGggPSB0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0XHRcdGNvbnN0IHBhcmVudE5hbWUgPSB0aGlzLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGFyZW50UGF0aCk7XHJcblx0XHRcdGlmIChwYXJlbnROYW1lICE9PSBmaWxlLmJhc2VuYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKHBhcmVudFBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignY3JlYXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcywgZmlsZSk7XHJcblx0XHRcdFx0aWYgKCFmb2xkZXIpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0aWYgKGZvbGRlck5hbWUgIT09IGZvbGRlci5uYW1lKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCF0aGlzLmFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHkpIHJldHVybjtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLmF1dG9DcmVhdGUpIHJldHVybjtcclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gZ2V0RXhjbHVkZWRGb2xkZXIodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlQXV0b0NyZWF0ZSkgcmV0dXJuO1xyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoZm9sZGVyTm90ZSkgcmV0dXJuO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMsIGZpbGUucGF0aCwgdHJ1ZSwgdHJ1ZSk7XHJcblx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblxyXG5cdFx0fSkpO1xyXG5cclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2ZpbGUtb3BlbicsIChvcGVuRmlsZTogVEZpbGUgfCBudWxsKSA9PiB7XHJcblx0XHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkge1xyXG5cdFx0XHRcdHRoaXMuYWN0aXZlRm9sZGVyRG9tLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHRcdFx0XHR0aGlzLmFjdGl2ZUZvbGRlckRvbSA9IG51bGw7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCFvcGVuRmlsZSB8fCAhb3BlbkZpbGUuYmFzZW5hbWUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBvcGVuRmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSB7IHJldHVybjsgfVxyXG5cdFx0XHRpZiAoZXh0cmFjdEZvbGRlck5hbWUodGhpcy5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgb3BlbkZpbGUuYmFzZW5hbWUpICE9PSBmb2xkZXIubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdFx0dGhpcy5hY3RpdmVGb2xkZXJEb20gPSB0aGlzLmdldEVMKGZvbGRlci5wYXRoKTtcclxuXHRcdFx0aWYgKHRoaXMuYWN0aXZlRm9sZGVyRG9tKSB0aGlzLmFjdGl2ZUZvbGRlckRvbS5hZGRDbGFzcygnaXMtYWN0aXZlJyk7XHJcblx0XHR9KSk7XHJcblxyXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKCdyZW5hbWUnLCAoZmlsZTogVEFic3RyYWN0RmlsZSwgb2xkUGF0aDogc3RyaW5nKSA9PiB7XHJcblx0XHRcdGlmICghdGhpcy5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSkge1xyXG5cdFx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdHJldHVybiBoYW5kbGVGb2xkZXJSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0cmV0dXJuIGhhbmRsZUZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgdGhpcyk7XHJcblx0XHRcdH1cclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbignZGVsZXRlJywgKGZpbGU6IFRBYnN0cmFjdEZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLCBmaWxlKTtcclxuXHRcdFx0XHRpZiAoIWZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRpZiAoIWZvbGRlck5vdGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0aWYgKCF0aGlzLnNldHRpbmdzLnN5bmNEZWxldGUpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZShmb2xkZXJOb3RlKTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucmVnaXN0ZXJNYXJrZG93bkNvZGVCbG9ja1Byb2Nlc3NvcignZm9sZGVyLW92ZXJ2aWV3JywgKHNvdXJjZTogc3RyaW5nLCBlbDogSFRNTEVsZW1lbnQsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCkgPT4ge1xyXG5cdFx0XHRjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBlZGl0QnV0dG9uID0gZWwucGFyZW50RWxlbWVudD8uY2hpbGROb2Rlcy5pdGVtKDEpO1xyXG5cdFx0XHRcdGlmIChlZGl0QnV0dG9uKSB7XHJcblx0XHRcdFx0XHRlZGl0QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcclxuXHRcdFx0XHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHRcdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHRuZXcgRm9sZGVyT3ZlcnZpZXdTZXR0aW5ncyh0aGlzLmFwcCwgdGhpcywgcGFyc2VZYW1sKHNvdXJjZSksIGN0eCwgZWwpLm9wZW4oKTtcclxuXHRcdFx0XHRcdH0sIHsgY2FwdHVyZTogdHJ1ZSB9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRvYnNlcnZlci5vYnNlcnZlKGVsLCB7XHJcblx0XHRcdFx0Y2hpbGRMaXN0OiB0cnVlLFxyXG5cdFx0XHRcdHN1YnRyZWU6IHRydWUsXHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjcmVhdGVGb2xkZXJPdmVydmlldyh0aGlzLCBzb3VyY2UsIGVsLCBjdHgpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAodGhpcy5hcHAud29ya3NwYWNlLmxheW91dFJlYWR5KSB7XHJcblx0XHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeShhc3luYyAoKSA9PiB0aGlzLmxvYWRGaWxlQ2xhc3NlcygpKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBwYXRoLnN1YnN0cmluZyhwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpICsgMSA6IDApO1xyXG5cdH1cclxuXHJcblx0Z2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRpZiAocGF0aC5lbmRzV2l0aCgnLm1kJykgfHwgcGF0aC5lbmRzV2l0aCgnLmNhbnZhcycpKSB7XHJcblx0XHRcdHJldHVybiBwYXRoLnNwbGl0KCcvJykuc2xpY2UoLTIpWzBdO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cmV0dXJuIHBhdGguc3BsaXQoJy8nKS5zbGljZSgtMSlbMF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZW1vdmVFeHRlbnNpb24obmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBuYW1lLnJlcGxhY2UoL1xcLlteLy5dKyQvLCAnJyk7XHJcblx0fVxyXG5cclxuXHRnZXRFeHRlbnNpb25Gcm9tUGF0aFN0cmluZyhwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIHBhdGguc2xpY2UocGF0aC5sYXN0SW5kZXhPZignLicpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcuJykgOiAwKTtcclxuXHR9XHJcblxyXG5cdGdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRjb25zdCBzdWJTdHJpbmcgPSBwYXRoLmxhc3RJbmRleE9mKCcvJyB8fCAnXFxcXCcpID49IDAgPyBwYXRoLmxhc3RJbmRleE9mKCcvJykgOiAwO1xyXG5cdFx0cmV0dXJuIHBhdGguc3Vic3RyaW5nKDAsIHN1YlN0cmluZyk7XHJcblx0fVxyXG5cclxuXHRnZXRQYXJlbnRGb2xkZXJQYXRoKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyh0aGlzLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpKTtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlcigpIHtcclxuXHRcdHJldHVybiB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhdmVzT2ZUeXBlKCdmaWxlLWV4cGxvcmVyJylbMF0gYXMgRmlsZUV4cGxvcmVyV29ya3NwYWNlTGVhZjtcclxuXHR9XHJcblxyXG5cdGdldEZpbGVFeHBsb3JlclZpZXcoKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRGaWxlRXhwbG9yZXIoKS52aWV3O1xyXG5cdH1cclxuXHJcblx0YXN5bmMgYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aDogc3RyaW5nLCBjc3NDbGFzczogc3RyaW5nLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0Y29uc3QgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwocGF0aCk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHtcclxuXHRcdFx0aWYgKHdhaXRGb3JDcmVhdGUgJiYgY291bnQgPCA1KSB7XHJcblx0XHRcdFx0Ly8gc2xlZXAgZm9yIGEgc2Vjb25kIGZvciB0aGUgZmlsZS1leHBsb3JlciBldmVudCB0byBjYXRjaCB1cFxyXG5cdFx0XHRcdC8vIHRoaXMgaXMgYW5ub3lpbmcgYXMgaW4gbW9zdCBzY2FuYXJpb3Mgb3VyIHBsdWdpbiByZWNpZXZlcyB0aGUgZXZlbnQgYmVmb3JlIGZpbGUgZXhwbG9yZXJcclxuXHRcdFx0XHQvLyBJZiB3ZSBjb3VsZCBndWFycmFudGVlIGxvYWQgb3JkZXIgaXQgd291bGRuJ3QgYmUgYW4gaXNzdWUgYnV0IHdlIGNhbid0XHJcblx0XHRcdFx0Ly8gcmVhbGlzZSB0aGlzIGlzIHJhY2V5IGFuZCBuZWVkcyB0byBiZSBmaXhlZC5cclxuXHRcdFx0XHRhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCA1MDApKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKHBhdGgsIGNzc0NsYXNzLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdGNvbnN0IHZpZXdIZWFkZXJJdGVtcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLXBhdGg9XCIke3BhdGh9XCJdYCk7XHJcblx0XHR2aWV3SGVhZGVySXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xyXG5cdFx0XHRpdGVtLmFkZENsYXNzKGNzc0NsYXNzKTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgY2hhbmdlTmFtZShmb2xkZXI6IFRGb2xkZXIsIG5hbWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIHJlcGxhY2VQYXRoOiBib29sZWFuLCB3YWl0Rm9yQ3JlYXRlID0gZmFsc2UsIGNvdW50ID0gMCkge1xyXG5cdFx0aWYgKCFuYW1lKSBuYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0XHRsZXQgZmlsZUV4cGxvcmVySXRlbSA9IHRoaXMuZ2V0RUwoZm9sZGVyLnBhdGgpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXJJdGVtKSB7XHJcblx0XHRcdGlmICh3YWl0Rm9yQ3JlYXRlICYmIGNvdW50IDwgNSkge1xyXG5cdFx0XHRcdGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUwMCkpO1xyXG5cdFx0XHRcdHRoaXMuY2hhbmdlTmFtZShmb2xkZXIsIG5hbWUsIHJlcGxhY2VQYXRoLCB3YWl0Rm9yQ3JlYXRlLCBjb3VudCArIDEpO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtID0gZmlsZUV4cGxvcmVySXRlbS5xdWVyeVNlbGVjdG9yKCdkaXYubmF2LWZvbGRlci10aXRsZS1jb250ZW50JylcclxuXHRcdGlmICghZmlsZUV4cGxvcmVySXRlbSkgeyByZXR1cm47IH1cclxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgJiYgdGhpcy5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpIHtcclxuXHRcdFx0ZmlsZUV4cGxvcmVySXRlbS5pbm5lclRleHQgPSBuYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnNldEF0dHJpYnV0ZSgnb2xkLW5hbWUnLCBmb2xkZXIubmFtZSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLmlubmVyVGV4dCA9IGZvbGRlci5uYW1lO1xyXG5cdFx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdH1cclxuXHRcdGlmIChyZXBsYWNlUGF0aCkge1xyXG5cdFx0XHR0aGlzLnVwZGF0ZUJyZWFkY3J1bWJzKCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHR1cGRhdGVCcmVhZGNydW1icyhyZW1vdmU/OiBib29sZWFuKSB7XHJcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5wYXRoICYmICFyZW1vdmUpIHsgcmV0dXJuOyB9XHJcblx0XHRjb25zdCB2aWV3SGVhZGVySXRlbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuLnZpZXctaGVhZGVyLWJyZWFkY3J1bWInKTtcclxuXHRcdGNvbnN0IGZpbGVzID0gdGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5maWx0ZXIoKGZpbGUpID0+IGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGlmICghaXRlbS5oYXNBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRjb25zdCBwYXRoID0gaXRlbS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBmaWxlcy5maW5kKChmaWxlKSA9PiBmaWxlLnBhdGggPT09IHBhdGgpO1xyXG5cdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKHJlbW92ZSkge1xyXG5cdFx0XHRcdGl0ZW0udGV4dENvbnRlbnQgPSBmb2xkZXIubmFtZTtcclxuXHRcdFx0XHRpdGVtLnJlbW92ZUF0dHJpYnV0ZSgnb2xkLW5hbWUnKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRpdGVtLnRleHRDb250ZW50ID0gZm9sZGVyLm5ld05hbWUgfHwgZm9sZGVyLm5hbWU7XHJcblx0XHRcdFx0aXRlbS5zZXRBdHRyaWJ1dGUoJ29sZC1uYW1lJywgZm9sZGVyLm5hbWUpO1xyXG5cdFx0XHRcdGl0ZW0uc2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0cmVtb3ZlQ1NTQ2xhc3NGcm9tRUwocGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLCBjc3NDbGFzczogc3RyaW5nKSB7XHJcblx0XHRpZiAoIXBhdGgpIHJldHVybjtcclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSB0aGlzLmdldEVMKHBhdGgpO1xyXG5cdFx0Y29uc3Qgdmlld0hlYWRlckl0ZW1zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtcGF0aD1cIiR7cGF0aH1cIl1gKTtcclxuXHRcdHZpZXdIZWFkZXJJdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcblx0XHRcdGl0ZW0ucmVtb3ZlQ2xhc3MoY3NzQ2xhc3MpO1xyXG5cdFx0fSk7XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuOyB9XHJcblx0XHRmaWxlRXhwbG9yZXJJdGVtLnJlbW92ZUNsYXNzKGNzc0NsYXNzKTtcclxuXHR9XHJcblxyXG5cdGdldEVMKHBhdGg6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XHJcblx0XHRjb25zdCBmaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0aWYgKCFmaWxlRXhwbG9yZXIpIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGNvbnN0IGZpbGVFeHBsb3Jlckl0ZW0gPSBmaWxlRXhwbG9yZXIudmlldy5maWxlSXRlbXNbcGF0aF07XHJcblx0XHRpZiAoIWZpbGVFeHBsb3Jlckl0ZW0pIHsgcmV0dXJuIG51bGw7IH1cclxuXHRcdGlmIChmaWxlRXhwbG9yZXJJdGVtLnNlbGZFbCkgcmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0uc2VsZkVsO1xyXG5cdFx0cmV0dXJuIGZpbGVFeHBsb3Jlckl0ZW0udGl0bGVFbDtcclxuXHR9XHJcblxyXG5cdGxvYWRGaWxlQ2xhc3Nlcyhmb3JjZVJlbG9hZCA9IGZhbHNlKSB7XHJcblx0XHRpZiAodGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPT09IHRoaXMuZ2V0RmlsZUV4cGxvcmVyKCkgJiYgIWZvcmNlUmVsb2FkKSB7IHJldHVybjsgfVxyXG5cdFx0dGhpcy5hY3RpdmVGaWxlRXhwbG9yZXIgPSB0aGlzLmdldEZpbGVFeHBsb3JlcigpO1xyXG5cdFx0dGhpcy5hcHAudmF1bHQuZ2V0QWxsTG9hZGVkRmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgeyByZXR1cm47IH1cclxuXHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcywgZmlsZS5wYXRoKTtcclxuXHRcdFx0aWYgKCFmb2xkZXJOb3RlKSB7XHJcblx0XHRcdFx0dGhpcy5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHRoaXMsIGZpbGUucGF0aCk7XHJcblx0XHRcdC8vIGNsZWFudXAgYWZ0ZXIgb3Vyc2VsdmVzXHJcblx0XHRcdC8vIEluY2FzZSBzZXR0aW5ncyBoYXZlIGNoYW5nZWRcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRcdHRoaXMucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHRoaXMuYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0XHR0aGlzLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJlbG9hZEhhbmRsZXJzKCkge1xyXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnZGl2Lm5hdi1mb2xkZXItdGl0bGUtY29udGVudCcpXHJcblx0XHRcdC5mb3JFYWNoKChlbGVtZW50OiBIVE1MRWxlbWVudCkgPT4ge1xyXG5cdFx0XHRcdGlmIChlbGVtZW50Lm9uY2xpY2spIHJldHVybjtcclxuXHRcdFx0XHRlbGVtZW50Lm9uY2xpY2sgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IGhhbmRsZUZvbGRlckNsaWNrKGV2ZW50LCB0aGlzKTtcclxuXHRcdFx0fSk7XHJcblx0fVxyXG5cclxuXHRvbnVubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKCd1bmxvYWRpbmcgZm9sZGVyIG5vdGVzIHBsdWdpbicpO1xyXG5cdFx0dGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3Rlcy1wbHVnaW4nKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lJyk7XHJcblx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdGlmICh0aGlzLmFjdGl2ZUZvbGRlckRvbSkgeyB0aGlzLmFjdGl2ZUZvbGRlckRvbS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJyk7IH1cclxuXHRcdGlmICh0aGlzLmZtdHBIYW5kbGVyKSB7XHJcblx0XHRcdHRoaXMuZm10cEhhbmRsZXIuZGVsZXRlRXZlbnQoKTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cclxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XHJcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIHNhdmVTZXR0aW5ncygpIHtcclxuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XHJcblx0XHQvLyBjbGVhbnVwIGFueSBjc3MgaWYgd2UgbmVlZCB0b29cclxuXHRcdHRoaXMubG9hZEZpbGVDbGFzc2VzKHRydWUpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFBsYXRmb3JtLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBURmlsZSwgVEZvbGRlciB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmltcG9ydCB7IFRlbXBsYXRlU3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdGVycy90ZW1wbGF0ZVN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnLi9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmltcG9ydCB7IGFkZEV4Y2x1ZGVGb2xkZXJMaXN0SXRlbSwgRXhjbHVkZWRGb2xkZXIsIGFkZEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlUGF0dGVybiwgYWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbSB9IGZyb20gJy4vZXhjbHVkZWRGb2xkZXInO1xyXG5pbXBvcnQgeyBGcm9udE1hdHRlclRpdGxlUGx1Z2luSGFuZGxlciB9IGZyb20gJy4vZXZlbnRzL2Zyb250TWF0dGVyVGl0bGUnO1xyXG4vLyBpbXBvcnQgQ29uZmlybWF0aW9uTW9kYWwgZnJvbSBcIi4vbW9kYWxzL2NvbmZpcm1DcmVhdGlvblwiO1xyXG5pbXBvcnQgeyB5YW1sU2V0dGluZ3MgfSBmcm9tICcuL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJOb3Rlc1NldHRpbmdzIHtcclxuXHRzeW5jRm9sZGVyTmFtZTogYm9vbGVhbjtcclxuXHRjdHJsS2V5OiBib29sZWFuO1xyXG5cdGFsdEtleTogYm9vbGVhbjtcclxuXHRoaWRlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHR0ZW1wbGF0ZVBhdGg6IHN0cmluZztcclxuXHRhdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0ZXhjbHVkZUZvbGRlcnM6IChFeGNsdWRlUGF0dGVybiB8IEV4Y2x1ZGVkRm9sZGVyKVtdO1xyXG5cdHNob3dEZWxldGVDb25maXJtYXRpb246IGJvb2xlYW47XHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXI6IGJvb2xlYW47XHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogYm9vbGVhbjtcclxuXHR1bmRlcmxpbmVGb2xkZXJJblBhdGg6IGJvb2xlYW47XHJcblx0b3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoOiBib29sZWFuO1xyXG5cdG9wZW5Jbk5ld1RhYjogYm9vbGVhbjtcclxuXHRmb2xkZXJOb3RlTmFtZTogc3RyaW5nO1xyXG5cdG5ld0ZvbGRlck5vdGVOYW1lOiBzdHJpbmc7XHJcblx0Zm9sZGVyTm90ZVR5cGU6ICcubWQnIHwgJy5jYW52YXMnO1xyXG5cdGRpc2FibGVGb2xkZXJIaWdobGlnaHRpbmc6IGJvb2xlYW47XHJcblx0c3RvcmFnZUxvY2F0aW9uOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJztcclxuXHRzeW5jRGVsZXRlOiBib29sZWFuO1xyXG5cdGRlZmF1bHRPdmVydmlldzogeWFtbFNldHRpbmdzO1xyXG5cdHVzZVN1Ym1lbnVzOiBib29sZWFuO1xyXG5cdHN5bmNNb3ZlOiBib29sZWFuO1xyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGJvb2xlYW47XHJcblx0XHRleHBsb3JlcjogYm9vbGVhbjtcclxuXHRcdHBhdGg6IGJvb2xlYW47XHJcblx0fVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogRm9sZGVyTm90ZXNTZXR0aW5ncyA9IHtcclxuXHRzeW5jRm9sZGVyTmFtZTogdHJ1ZSxcclxuXHRjdHJsS2V5OiB0cnVlLFxyXG5cdGFsdEtleTogZmFsc2UsXHJcblx0aGlkZUZvbGRlck5vdGU6IHRydWUsXHJcblx0dGVtcGxhdGVQYXRoOiAnJyxcclxuXHRhdXRvQ3JlYXRlOiBmYWxzZSxcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBmYWxzZSxcclxuXHRleGNsdWRlRm9sZGVyczogW10sXHJcblx0c2hvd0RlbGV0ZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHR1bmRlcmxpbmVGb2xkZXI6IHRydWUsXHJcblx0YWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZzogZmFsc2UsXHJcblx0dW5kZXJsaW5lRm9sZGVySW5QYXRoOiB0cnVlLFxyXG5cdG9wZW5Gb2xkZXJOb3RlT25DbGlja0luUGF0aDogdHJ1ZSxcclxuXHRvcGVuSW5OZXdUYWI6IGZhbHNlLFxyXG5cdGZvbGRlck5vdGVOYW1lOiAne3tmb2xkZXJfbmFtZX19JyxcclxuXHRmb2xkZXJOb3RlVHlwZTogJy5tZCcsXHJcblx0ZGlzYWJsZUZvbGRlckhpZ2hsaWdodGluZzogZmFsc2UsXHJcblx0bmV3Rm9sZGVyTm90ZU5hbWU6ICd7e2ZvbGRlcl9uYW1lfX0nLFxyXG5cdHN0b3JhZ2VMb2NhdGlvbjogJ2luc2lkZUZvbGRlcicsXHJcblx0c3luY0RlbGV0ZTogZmFsc2UsXHJcblx0c2hvd1JlbmFtZUNvbmZpcm1hdGlvbjogdHJ1ZSxcclxuXHRkZWZhdWx0T3ZlcnZpZXc6IHtcclxuXHRcdHRpdGxlOiAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnLFxyXG5cdFx0ZGlzYWJsZVRpdGxlOiBmYWxzZSxcclxuXHRcdGRlcHRoOiAzLFxyXG5cdFx0aW5jbHVkZVR5cGVzOiBbJ2ZvbGRlcicsICdtYXJrZG93biddLFxyXG5cdFx0c3R5bGU6ICdsaXN0JyxcclxuXHRcdGRpc2FibGVGaWxlVGFnOiBmYWxzZSxcclxuXHR9LFxyXG5cdHVzZVN1Ym1lbnVzOiB0cnVlLFxyXG5cdHN5bmNNb3ZlOiB0cnVlLFxyXG5cdGZyb250TWF0dGVyVGl0bGU6IHtcclxuXHRcdGVuYWJsZWQ6IGZhbHNlLFxyXG5cdFx0ZXhwbG9yZXI6IHRydWUsXHJcblx0XHRwYXRoOiB0cnVlLFxyXG5cdH1cclxufTtcclxuZXhwb3J0IGNsYXNzIFNldHRpbmdzVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHRleGNsdWRlRm9sZGVyczogRXhjbHVkZWRGb2xkZXJbXTtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xyXG5cdH1cclxuXHRkaXNwbGF5KCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcclxuXHJcblx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xyXG5cclxuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0ZvbGRlciBub3RlcyBzZXR0aW5ncycgfSk7XHJcblxyXG5cdFx0Y29uc3QgbmFtZVNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZvbGRlciBub3RlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygne3tmb2xkZXJfbmFtZX19IHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgbmFtZSBvZiB0aGUgZm9sZGVyJylcclxuXHRcdFx0LmFkZFRleHQoKHRleHQpID0+XHJcblx0XHRcdFx0dGV4dFxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm5ld0ZvbGRlck5vdGVOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykgeyByZXR1cm47IH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MubmV3Rm9sZGVyTm90ZU5hbWUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdSZW5hbWUgZXhpc3RpbmcgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdC5zZXRDdGEoKVxyXG5cdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUZvbGRlck5vdGVzKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5uZXdGb2xkZXJOb3RlTmFtZSk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLmFwcGVuZFRleHQoJ01ha2Ugc3VyZSB0byBiYWNrIHVwIHlvdXIgdmF1bHQgYmVmb3JlIHJlbmFtaW5nIGFsbCBmb2xkZXIgbm90ZXMgYW5kIHJlc3RhcnQgT2JzaWRpYW4gYWZ0ZXIgcmVuYW1pbmcgdGhlbScpO1xyXG5cdFx0bmFtZVNldHRpbmcuaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdGb2xkZXIgbm90ZSB0eXBlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSB0aGUgZmlsZSB0eXBlIGZvciBjcmVhdGluZyBuZXcgZm9sZGVyIG5vdGVzIChtYXJrZG93biBvciBjYW52YXMpIG9sZCBmb2xkZXIgbm90ZXMgd2lsbCBub3QgYmUgY2hhbmdlZCBhbmQgeW91IGNhbiBhbHNvIGNyZWF0ZSBjYW52YXMvbWFya2Rvd24gZmlsZXMgYW5kIGNoYW5nZSB0aGUgbmFtZSBtYW51YWxseSB0byB0aGUgY3VzdG9tIGZvbGRlciBub3RlIG5hbWUgb3IgdG8gdGhlIG5hbWUgb2YgdGhlIGZvbGRlci4nKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCcubWQnLCAnbWFya2Rvd24nKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignLmNhbnZhcycsICdjYW52YXMnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJy5tZCcgfCAnLmNhbnZhcycpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0XHRjb25zdCBkZXNjID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xyXG5cdFx0ZGVzYy5hcHBlbmQoXHJcblx0XHRcdCdBZnRlciBzZXR0aW5nIHRoZSB0ZW1wbGF0ZSBwYXRoLCByZXN0YXJ0IE9ic2lkaWFuIGlmIHRoZSB0ZW1wbGF0ZSBmb2xkZXIgcGF0aCAoZnJvbSB0ZW1wbGF0ZXIvdGVtcGxhdGVzKSBoYWQgYmVlbiBjaGFuZ2VkIGJlZm9yZWhhbmQuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J09ic2lkaWFuIHNob3VsZCBhbHNvIGJlIHJlc3RhcnRlZCBpZiB0aGUgdGVtcGxhdGUgcGF0aCB3YXMgcmVtb3ZlZC4nXHJcblx0XHQpO1xyXG5cdFx0c2V0dGluZy5zZXROYW1lKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRzZXR0aW5nLnNldERlc2MoZGVzYykuZGVzY0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblx0XHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdFx0bmV3IFRlbXBsYXRlU3VnZ2VzdChjYi5pbnB1dEVsLCB0aGlzLnBsdWdpbik7XHJcblx0XHRcdGNiLnNldFBsYWNlaG9sZGVyKCdUZW1wbGF0ZSBwYXRoJyk7XHJcblx0XHRcdGNiLnNldFZhbHVlKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoKT8ubmFtZS5yZXBsYWNlKCcubWQnLCAnJykgfHwgJycpO1xyXG5cdFx0XHRjYi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRpZiAodmFsdWUudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHJcblx0XHRjb25zdCBzdG9yYWdlTG9jYXRpb24gPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ1N0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHdoZXJlIHRvIHN0b3JlIHRoZSBmb2xkZXIgbm90ZXMnKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdpbnNpZGVGb2xkZXInLCAnSW5zaWRlIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbigncGFyZW50Rm9sZGVyJywgJ0luIHRoZSBwYXJlbnQgZm9sZGVyJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24pXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnaW5zaWRlRm9sZGVyJyB8ICdwYXJlbnRGb2xkZXInIHwgJ3ZhdWx0Rm9sZGVyJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5sb2FkRmlsZUNsYXNzZXMoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblx0XHRzdG9yYWdlTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3RvcmFnZUxvY2F0aW9uLmluZm9FbC5zdHlsZS5jb2xvciA9IHRoaXMuYXBwLnZhdWx0LmdldENvbmZpZygnYWNjZW50Q29sb3InKSBhcyBzdHJpbmcgfHwgJyM3ZDViZWQnO1xyXG5cclxuXHRcdGNvbnN0IHN3aXRjaExvY2F0aW9uID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTd2l0Y2ggdG8gbmV3IHN0b3JhZ2UgbG9jYXRpb24nKVxyXG5cdFx0XHQuc2V0RGVzYygnTW92ZSBhbGwgZm9sZGVyIG5vdGVzIHRvIHRoZSBuZXcgc3RvcmFnZSBsb2NhdGlvbicpXHJcblx0XHRcdC5hZGRCdXR0b24oKGJ1dHRvbikgPT5cclxuXHRcdFx0XHRidXR0b25cclxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KCdTd2l0Y2gnKVxyXG5cdFx0XHRcdFx0LnNldEN0YSgpXHJcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGxldCBvbGRTdG9yYWdlTG9jYXRpb24gPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb247XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0b2xkU3RvcmFnZUxvY2F0aW9uID0gJ2luc2lkZUZvbGRlcic7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAnaW5zaWRlRm9sZGVyJykge1xyXG5cdFx0XHRcdFx0XHRcdG9sZFN0b3JhZ2VMb2NhdGlvbiA9ICdwYXJlbnRGb2xkZXInO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuc3dpdGNoU3RvcmFnZUxvY2F0aW9uKG9sZFN0b3JhZ2VMb2NhdGlvbik7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0c3dpdGNoTG9jYXRpb24uaW5mb0VsLnN0eWxlLmNvbG9yID0gdGhpcy5hcHAudmF1bHQuZ2V0Q29uZmlnKCdhY2NlbnRDb2xvcicpIGFzIHN0cmluZyB8fCAnIzdkNWJlZCc7XHJcblxyXG5cdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0RlbGV0ZSBmb2xkZXIgbm90ZXMgd2hlbiBkZWxldGluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuc2V0RGVzYygnRGVsZXRlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIGRlbGV0aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY0RlbGV0ZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNEZWxldGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ01vdmUgZm9sZGVyIG5vdGVzIHdoZW4gbW92aW5nIHRoZSBmb2xkZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdNb3ZlIHRoZSBmb2xkZXIgbm90ZSB3aGVuIG1vdmluZyB0aGUgZm9sZGVyJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNNb3ZlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc3luY01vdmUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRjb25zdCBkaXNhYmxlU2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIGNvbGxhcHNpbmcnKTtcclxuXHRcdGRpc2FibGVTZXR0aW5nLnNldERlc2MoJ0Rpc2FibGUgdGhlIGFiaWxpdHkgdG8gY29sbGFwc2UgZm9sZGVycyBieSBjbGlja2luZyBleGFjdGx5IG9uIHRoZSBmb2xkZXIgbmFtZScpO1xyXG5cdFx0ZGlzYWJsZVNldHRpbmcuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdC5zZXRWYWx1ZSghdGhpcy5wbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5lbmFibGVDb2xsYXBzaW5nID0gIXZhbHVlO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0fSlcclxuXHRcdCk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuYXBwZW5kVGV4dCgnUmVxdWlyZXMgYSByZXN0YXJ0IHRvIHRha2UgZWZmZWN0Jyk7XHJcblx0XHRkaXNhYmxlU2V0dGluZy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdLZXkgZm9yIGNyZWF0aW5nIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnVGhlIGtleSBjb21iaW5hdGlvbiB0byBjcmVhdGUgYSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdFx0aWYgKCFQbGF0Zm9ybS5pc01hY09TKSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDdHJsICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignY3RybCcsICdDbWQgKyBDbGljaycpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0ZHJvcGRvd24uYWRkT3B0aW9uKCdhbHQnLCAnQWx0ICsgQ2xpY2snKTtcclxuXHRcdFx0XHRcdGRyb3Bkb3duLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmN0cmxLZXkgPyAnY3RybCcgOiAnYWx0Jyk7XHJcblx0XHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY3RybEtleSA9IHZhbHVlID09PSAnY3RybCc7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmFsdEtleSA9IHZhbHVlID09PSAnYWx0JztcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPbmx5IG9wZW4gZm9sZGVyIG5vdGVzIHRocm91Z2ggdGhlIG5hbWUnKVxyXG5cdFx0XHQuc2V0RGVzYygnT25seSBvcGVuIGZvbGRlciBub3RlcyBpbiB0aGUgZmlsZSBleHBsb3JlciBieSBjbGlja2luZyBvbiB0aGUgZm9sZGVyIG5hbWUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0aWYgKCF2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZm4td2hpdGVzcGFjZS1zdG9wLWNvbGxhcHNpbmcnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZuLXdoaXRlc3BhY2Utc3RvcC1jb2xsYXBzaW5nJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYWxsb3dXaGl0ZXNwYWNlQ29sbGFwc2luZyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdIaWRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0LnNldERlc2MoJ0hpZGUgdGhlIGZvbGRlciBub3RlIGluIHRoZSBmaWxlIGV4cGxvcmVyJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmhpZGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5oaWRlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdTeW5jIGZvbGRlciBuYW1lJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIHRoZSBmb2xkZXIgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbmFtZSBpcyBjaGFuZ2VkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnN5bmNGb2xkZXJOYW1lKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zeW5jRm9sZGVyTmFtZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0aWYgKFBsYXRmb3JtLmlzRGVza3RvcCkge1xyXG5cdFx0XHRjb25zdCBzZXR0aW5nMyA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKTtcclxuXHRcdFx0c2V0dGluZzMuc2V0TmFtZSgnT3BlbiBmb2xkZXIgbm90ZSBpbiBhIG5ldyB0YWIgYnkgZGVmYXVsdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5zZXREZXNjKCdBbHdheXMgb3BlbiBmb2xkZXIgbm90ZXMgaW4gYSBuZXcgdGFiIChleGNlcHQgd2hlbiB5b3UgdHJ5IHRvIG9wZW4gdGhlIHNhbWUgbm90ZSkgaW5zdGVhZCBvZiBoYXZpbmcgdG8gdXNlIGN0cmwvY21kICsgY2xpY2sgdG8gb3BlbiBpbiBhIG5ldyB0YWInKTtcclxuXHRcdFx0c2V0dGluZzMuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkluTmV3VGFiKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuSW5OZXdUYWIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdFx0c2V0dGluZzMuaW5mb0VsLmFwcGVuZFRleHQoJ1JlcXVpcmVzIGEgcmVzdGFydCB0byB0YWtlIGVmZmVjdCcpO1xyXG5cdFx0XHRzZXR0aW5nMy5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHRcdH1cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnQXV0b21hdGljYWxseSBjcmVhdGUgZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgY3JlYXRlIGEgZm9sZGVyIG5vdGUgd2hlbiBhIG5ldyBmb2xkZXIgaXMgY3JlYXRlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvQ3JlYXRlID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdVc2Ugc3VibWVudXMnKVxyXG5cdFx0XHQuc2V0RGVzYygnVXNlIHN1Ym1lbnVzIGZvciBmaWxlL2ZvbGRlciBjb21tYW5kcycpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlU3VibWVudXMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCB1bmRlcmxpbmUgdG8gZm9sZGVycyB3aXRoIGZvbGRlciBub3RlcycpXHJcblx0XHRcdC5zZXREZXNjKCdBZGQgYW4gdW5kZXJsaW5lIHRvIGZvbGRlcnMgdGhhdCBoYXZlIGEgZm9sZGVyIG5vdGUgaW4gdGhlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVyKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy51bmRlcmxpbmVGb2xkZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmb2xkZXItbm90ZS11bmRlcmxpbmUnKTtcclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2ZvbGRlci1ub3RlLXVuZGVybGluZScpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXROYW1lKCdPcGVuIGZvbGRlciBub3RlIHRocm91Z2ggcGF0aCcpXHJcblx0XHRcdC5zZXREZXNjKCdPcGVuIGEgZm9sZGVyIG5vdGUgd2hlbiBjbGlja2luZyBvbiBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGlmIGl0IGlzIGEgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5vcGVuRm9sZGVyTm90ZU9uQ2xpY2tJblBhdGggPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdVbmRlcmxpbmUgZm9sZGVycyBpbiB0aGUgcGF0aCcpXHJcblx0XHRcdFx0LnNldERlc2MoJ0FkZCBhbiB1bmRlcmxpbmUgdG8gZm9sZGVycyB0aGF0IGhhdmUgYSBmb2xkZXIgbm90ZSBpbiB0aGUgcGF0aCBhYm92ZSBhIG5vdGUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudW5kZXJsaW5lRm9sZGVySW5QYXRoID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2ZvbGRlci1ub3RlLXVuZGVybGluZS1wYXRoJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZm9sZGVyLW5vdGUtdW5kZXJsaW5lLXBhdGgnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0VuYWJsZSBmcm9udCBtYXR0ZXIgdGl0bGUgcGx1Z2luIGludGVncmF0aW9uJylcclxuXHRcdFx0LnNldERlc2MoJ0F1dG9tYXRpY2FsbHkgcmVuYW1lIGEgZm9sZGVyIG5hbWUgd2hlbiB0aGUgZm9sZGVyIG5vdGUgaXMgcmVuYW1lZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mcm9udE1hdHRlclRpdGxlLmVuYWJsZWQpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZW5hYmxlZCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlKSB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBuZXcgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIodGhpcy5wbHVnaW4pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmZtdHBIYW5kbGVyPy5oYW5kbGVSZW5hbWUoeyBpZDogJycsIHJlc3VsdDogZmFsc2UsIHBhdGg6IGZpbGUucGF0aCB9LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXI/LmRlbGV0ZUV2ZW50KCk7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZm10cEhhbmRsZXIgPSBudWxsO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5lbmFibGVkKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIGZpbGUgZXhwbG9yZXInKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBmaWxlIGV4cGxvcmVyIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIHJlbmFtZWQnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZnJvbnRNYXR0ZXJUaXRsZS5leHBsb3JlcilcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUuZXhwbG9yZXIgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0RmlsZXMoKS5mb3JFYWNoKChmaWxlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5mbXRwSGFuZGxlcj8uaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblxyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnSW5jbHVkZSBwYXRoIGFib3ZlIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdBdXRvbWF0aWNhbGx5IHJlbmFtZSBhIGZvbGRlciBuYW1lIGluIHRoZSBwYXRoIGFib3ZlIGEgbm90ZSB3aGVuIHRoZSBmb2xkZXIgbm90ZSBpcyByZW5hbWVkJylcclxuXHRcdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aClcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmZyb250TWF0dGVyVGl0bGUucGF0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRcdFx0XHRcdGlmICh2YWx1ZSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnModHJ1ZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRHVlIHRvIGFuIGlzc3VlIHdpdGggdGVtcGxhdGVyIGl0IGhhcyBiZWVuIGRpc2FibGVkIGZvciBub3dcclxuXHRcdC8vIElmIHlvdSB3YW50IHRvIHRyeSBpdCB5b3Vyc2VsZiBtYWtlIGEgcHJcclxuXHRcdC8vIFRoZSBpc3N1ZSB3YXMgdGhhdCBpdCBvbmx5IHVzZWQgdGhlIGZpcnN0IGZvbGRlciBmb3IgYWxsIG9mIHRoZSBvdGhlciBmb2xkZXIgbm90ZXNcclxuXHRcdC8qXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdC5zZXROYW1lKCdDcmVhdGUgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlcicpXHJcblx0XHQuc2V0RGVzYygnQ3JlYXRlIGEgZm9sZGVyIG5vdGUgZm9yIGV2ZXJ5IGZvbGRlciBpbiB0aGUgdmF1bHQnKVxyXG5cdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0Y2Iuc2V0SWNvbigncGx1cycpO1xyXG5cdFx0XHRjYi5zZXRUb29sdGlwKCdDcmVhdGUgZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdGNiLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdG5ldyBDb25maXJtYXRpb25Nb2RhbCh0aGlzLmFwcCwgdGhpcy5wbHVnaW4pLm9wZW4oKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9KTtcclxuXHRcdCovXHJcblxyXG5cclxuXHRcdGNvbnN0IG1hbmFnZUV4Y2x1ZGVkID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXHJcblx0XHRcdC5zZXRIZWFkaW5nKClcclxuXHRcdFx0LnNldENsYXNzKCdmbi1leGNsdWRlZC1mb2xkZXItaGVhZGluZycpXHJcblx0XHRcdC5zZXROYW1lKCdNYW5hZ2UgZXhjbHVkZWQgZm9sZGVycycpO1xyXG5cdFx0Y29uc3QgZGVzYzMgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XHJcblx0XHRkZXNjMy5hcHBlbmQoXHJcblx0XHRcdCdBZGQge3JlZ2V4fSBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmb2xkZXIgbmFtZSB0byB1c2UgYSByZWdleCBwYXR0ZXJuLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBiZWZvcmUgYW5kIGFmdGVyIHRvIGV4Y2x1ZGUgZm9sZGVycyB0aGF0IGluY2x1ZGUgdGhlIG5hbWUgYmV0d2VlbiB0aGUgKnMuJyxcclxuXHRcdFx0ZGVzYy5jcmVhdGVFbCgnYnInKSxcclxuXHRcdFx0J1VzZSAqIGJlZm9yZSB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgZW5kIHdpdGggdGhlIGZvbGRlciBuYW1lLicsXHJcblx0XHRcdGRlc2MuY3JlYXRlRWwoJ2JyJyksXHJcblx0XHRcdCdVc2UgKiBhZnRlciB0aGUgZm9sZGVyIG5hbWUgdG8gZXhjbHVkZSBmb2xkZXJzIHRoYXQgc3RhcnQgd2l0aCB0aGUgZm9sZGVyIG5hbWUuJyxcclxuXHRcdCk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5zZXREZXNjKGRlc2MzKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdUaGUgcmVnZXhlcyBhbmQgd2lsZGNhcmRzIGFyZSBvbmx5IGZvciB0aGUgZm9sZGVyIG5hbWUsIG5vdCB0aGUgcGF0aC4nKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5jcmVhdGVFbCgnYnInKTtcclxuXHRcdG1hbmFnZUV4Y2x1ZGVkLmluZm9FbC5hcHBlbmRUZXh0KCdJZiB5b3Ugd2FudCB0byBzd2l0Y2ggdG8gYSBmb2xkZXIgcGF0aCBkZWxldGUgdGhlIHBhdHRlcm4gZmlyc3QuJyk7XHJcblx0XHRtYW5hZ2VFeGNsdWRlZC5pbmZvRWwuc3R5bGUuY29sb3IgPSB0aGlzLmFwcC52YXVsdC5nZXRDb25maWcoJ2FjY2VudENvbG9yJykgYXMgc3RyaW5nIHx8ICcjN2Q1YmVkJztcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuXHRcdFx0LnNldE5hbWUoJ0FkZCBleGNsdWRlZCBmb2xkZXInKVxyXG5cdFx0XHQuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlci1pdGVtJylcclxuXHRcdFx0LmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdFx0XHRjYi5zZXRJY29uKCdwbHVzJyk7XHJcblx0XHRcdFx0Y2Iuc2V0Q2xhc3MoJ2FkZC1leGNsdWRlLWZvbGRlcicpO1xyXG5cdFx0XHRcdGNiLnNldFRvb2x0aXAoJ0FkZCBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdFx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKCcnLCB0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdFx0YWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHRoaXMsIGNvbnRhaW5lckVsLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0XHRhZGRFeGNsdWRlZEZvbGRlcih0aGlzLnBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuc29ydCgoYSwgYikgPT4gYS5wb3NpdGlvbiAtIGIucG9zaXRpb24pLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRcdGlmIChleGNsdWRlZEZvbGRlci5zdHJpbmc/LnRyaW0oKSAhPT0gJycgJiYgZXhjbHVkZWRGb2xkZXIucGF0aD8udHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRhZGRFeGNsdWRlRm9sZGVyTGlzdEl0ZW0odGhpcywgY29udGFpbmVyRWwsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHR1cGRhdGVGb2xkZXJOb3RlcyhvbGRUZW1wbGF0ZTogc3RyaW5nLCBuZXdUZW1wbGF0ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSA9IG5ld1RlbXBsYXRlO1xyXG5cdFx0dGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRuZXcgTm90aWNlKCdTdGFydGluZyB0byB1cGRhdGUgZm9sZGVyIG5vdGVzLi4uJyk7XHJcblx0XHR0aGlzLmFwcC52YXVsdC5nZXRGaWxlcygpLmZvckVhY2goKGZpbGUpID0+IHtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlclBhdGggPSB0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGxldCBmb2xkZXIgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0XHRcdFx0bGV0IGZvbGRlck5hbWUgPSBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpO1xyXG5cdFx0XHRcdGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShvbGRUZW1wbGF0ZSwgZm9sZGVyTmFtZSkgfHwgJyc7XHJcblx0XHRcdFx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikgfHwgZm9sZGVyTmFtZSAhPT0gZm9sZGVyPy5uYW1lKSB7XHJcblx0XHRcdFx0XHRpZiAoZm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJOYW1lKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoICsgJy8nICsgZm9sZGVyTmFtZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0XHRcdGlmIChmb2xkZXJOYW1lID09PSBmb2xkZXI/Lm5hbWUpIHtcclxuXHRcdFx0XHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXI/LnBhdGh9LyR7dGhpcy5wbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSl9LiR7ZmlsZS5leHRlbnNpb259YDtcclxuXHRcdFx0XHRcdHRoaXMuYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBuZXdQYXRoKTtcclxuXHRcdFx0XHR9IGVsc2UgaWYgKGZvbGRlcj8ubmFtZSA9PT0gZmlsZS5uYW1lLnNsaWNlKDAsIC1maWxlLmV4dGVuc2lvbi5sZW5ndGggLSAxKSB8fCAnJykge1xyXG5cdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZvbGRlcj8ucGF0aH0vJHt0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmaWxlLm5hbWUuc2xpY2UoMCwgLWZpbGUuZXh0ZW5zaW9uLmxlbmd0aCAtIDEpIHx8ICcnKX0uJHtmaWxlLmV4dGVuc2lvbn1gO1xyXG5cdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZpbGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRuZXcgTm90aWNlKCdGaW5pc2hlZCB1cGRhdGluZyBmb2xkZXIgbm90ZXMnKTtcclxuXHR9XHJcblxyXG5cdHN3aXRjaFN0b3JhZ2VMb2NhdGlvbihvbGRNZXRob2Q6IHN0cmluZykge1xyXG5cdFx0bmV3IE5vdGljZSgnU3RhcnRpbmcgdG8gc3dpdGNoIHN0b3JhZ2UgbG9jYXRpb24uLi4nKTtcclxuXHRcdHRoaXMuYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCBvbGRNZXRob2QpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gJyc7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXdQYXRoID0gYCR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0bmV3UGF0aCA9IGAke3RoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCl9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQucmVuYW1lKGZvbGRlck5vdGUsIG5ld1BhdGgpO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJOb3RlLnBhdGgpID09PSBmaWxlLnBhdGgpIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Y29uc3QgbmV3UGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdFx0bmV3IE5vdGljZSgnRmluaXNoZWQgc3dpdGNoaW5nIHN0b3JhZ2UgbG9jYXRpb24nKTtcclxuXHR9XHJcblxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGaWxlLCBURm9sZGVyLCBWYXVsdCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgVGV4dElucHV0U3VnZ2VzdCB9IGZyb20gJy4vc3VnZ2VzdCc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0VGVtcGxhdGVQbHVnaW5zIH0gZnJvbSAnc3JjL3RlbXBsYXRlJztcclxuZXhwb3J0IGVudW0gRmlsZVN1Z2dlc3RNb2RlIHtcclxuICAgIFRlbXBsYXRlRmlsZXMsXHJcbiAgICBTY3JpcHRGaWxlcyxcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlU3VnZ2VzdCBleHRlbmRzIFRleHRJbnB1dFN1Z2dlc3Q8VEZpbGU+IHtcclxuXHRjb25zdHJ1Y3RvcihcclxuICAgICAgICBwdWJsaWMgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCxcclxuICAgICAgICBwcml2YXRlIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW5cclxuXHQpIHtcclxuXHRcdHN1cGVyKGlucHV0RWwpO1xyXG5cdH1cclxuXHJcblxyXG5cdGdldF9lcnJvcl9tc2cobW9kZTogRmlsZVN1Z2dlc3RNb2RlKTogc3RyaW5nIHtcclxuXHRcdHN3aXRjaCAobW9kZSkge1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5UZW1wbGF0ZUZpbGVzOlxyXG5cdFx0XHRcdHJldHVybiAnVGVtcGxhdGVzIGZvbGRlciBkb2VzblxcJ3QgZXhpc3QnO1xyXG5cdFx0XHRjYXNlIEZpbGVTdWdnZXN0TW9kZS5TY3JpcHRGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1VzZXIgU2NyaXB0cyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldFN1Z2dlc3Rpb25zKGlucHV0X3N0cjogc3RyaW5nKTogVEZpbGVbXSB7XHJcblx0XHRjb25zdCB7IHRlbXBsYXRlRm9sZGVyLCB0ZW1wbGF0ZXJQbHVnaW4gfSA9IGdldFRlbXBsYXRlUGx1Z2lucyh0aGlzLnBsdWdpbi5hcHApO1xyXG5cdFx0aWYgKCghdGVtcGxhdGVGb2xkZXIgfHwgdGVtcGxhdGVGb2xkZXI/LnRyaW0oKSA9PT0gJycpICYmICF0ZW1wbGF0ZXJQbHVnaW4pIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MudGVtcGxhdGVQYXRoID0gJyc7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHRyZXR1cm4gW107XHJcblx0XHR9XHJcblx0XHRsZXQgZm9sZGVyOiBURm9sZGVyO1xyXG5cdFx0aWYgKHRlbXBsYXRlclBsdWdpbikge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlclBsdWdpbi5wbHVnaW4/LnNldHRpbmdzPy50ZW1wbGF0ZXNfZm9sZGVyIGFzIHN0cmluZykgYXMgVEZvbGRlcjtcclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXIgPSB0aGlzLnBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHRlbXBsYXRlRm9sZGVyKSBhcyBURm9sZGVyO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGZpbGVzOiBURmlsZVtdID0gW107XHJcblx0XHRjb25zdCBsb3dlcl9pbnB1dF9zdHIgPSBpbnB1dF9zdHIudG9Mb3dlckNhc2UoKTtcclxuXHJcblx0XHRWYXVsdC5yZWN1cnNlQ2hpbGRyZW4oZm9sZGVyLCAoZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlICYmXHJcbiAgICAgICAgICAgICAgICBmaWxlLnBhdGgudG9Mb3dlckNhc2UoKS5jb250YWlucyhsb3dlcl9pbnB1dF9zdHIpXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdGZpbGVzLnB1c2goZmlsZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiBmaWxlcztcclxuXHR9XHJcblxyXG5cdHJlbmRlclN1Z2dlc3Rpb24oZmlsZTogVEZpbGUsIGVsOiBIVE1MRWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZWwuc2V0VGV4dChmaWxlLm5hbWUucmVwbGFjZSgnLm1kJywgJycpKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZmlsZTogVEZpbGUpOiB2b2lkIHtcclxuXHRcdHRoaXMuaW5wdXRFbC52YWx1ZSA9IGZpbGUubmFtZS5yZXBsYWNlKCcubWQnLCAnJyk7XHJcblx0XHR0aGlzLmlucHV0RWwudHJpZ2dlcignaW5wdXQnKTtcclxuXHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlUGF0aCA9IGZpbGUucGF0aDtcclxuXHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiLy8gQ3JlZGl0cyBnbyB0byBMaWFtJ3MgUGVyaW9kaWMgTm90ZXMgUGx1Z2luOiBodHRwczovL2dpdGh1Yi5jb20vbGlhbWNhaW4vb2JzaWRpYW4tcGVyaW9kaWMtbm90ZXMgYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9TaWxlbnRWb2lkMTMvVGVtcGxhdGVyXHJcblxyXG5cclxuaW1wb3J0IHsgSVN1Z2dlc3RPd25lciwgU2NvcGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGNyZWF0ZVBvcHBlciwgSW5zdGFuY2UgYXMgUG9wcGVySW5zdGFuY2UgfSBmcm9tICdAcG9wcGVyanMvY29yZSc7XHJcblxyXG5jb25zdCB3cmFwQXJvdW5kID0gKHZhbHVlOiBudW1iZXIsIHNpemU6IG51bWJlcik6IG51bWJlciA9PiB7XHJcblx0cmV0dXJuICgodmFsdWUgJSBzaXplKSArIHNpemUpICUgc2l6ZTtcclxufTtcclxuXHJcbmNsYXNzIFN1Z2dlc3Q8VD4ge1xyXG5cdHByaXZhdGUgb3duZXI6IElTdWdnZXN0T3duZXI8VD47XHJcblx0cHJpdmF0ZSB2YWx1ZXM6IFRbXTtcclxuXHRwcml2YXRlIHN1Z2dlc3Rpb25zOiBIVE1MRGl2RWxlbWVudFtdO1xyXG5cdHByaXZhdGUgc2VsZWN0ZWRJdGVtOiBudW1iZXI7XHJcblx0cHJpdmF0ZSBjb250YWluZXJFbDogSFRNTEVsZW1lbnQ7XHJcblxyXG5cdGNvbnN0cnVjdG9yKFxyXG5cdFx0b3duZXI6IElTdWdnZXN0T3duZXI8VD4sXHJcblx0XHRjb250YWluZXJFbDogSFRNTEVsZW1lbnQsXHJcblx0XHRzY29wZTogU2NvcGVcclxuXHQpIHtcclxuXHRcdHRoaXMub3duZXIgPSBvd25lcjtcclxuXHRcdHRoaXMuY29udGFpbmVyRWwgPSBjb250YWluZXJFbDtcclxuXHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J2NsaWNrJyxcclxuXHRcdFx0Jy5zdWdnZXN0aW9uLWl0ZW0nLFxyXG5cdFx0XHR0aGlzLm9uU3VnZ2VzdGlvbkNsaWNrLmJpbmQodGhpcylcclxuXHRcdCk7XHJcblx0XHRjb250YWluZXJFbC5vbihcclxuXHRcdFx0J21vdXNlbW92ZScsXHJcblx0XHRcdCcuc3VnZ2VzdGlvbi1pdGVtJyxcclxuXHRcdFx0dGhpcy5vblN1Z2dlc3Rpb25Nb3VzZW92ZXIuYmluZCh0aGlzKVxyXG5cdFx0KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93VXAnLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKHRoaXMuc2VsZWN0ZWRJdGVtIC0gMSwgdHJ1ZSk7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRzY29wZS5yZWdpc3RlcihbXSwgJ0Fycm93RG93bicsIChldmVudCkgPT4ge1xyXG5cdFx0XHRpZiAoIWV2ZW50LmlzQ29tcG9zaW5nKSB7XHJcblx0XHRcdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0odGhpcy5zZWxlY3RlZEl0ZW0gKyAxLCB0cnVlKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHNjb3BlLnJlZ2lzdGVyKFtdLCAnRW50ZXInLCAoZXZlbnQpID0+IHtcclxuXHRcdFx0aWYgKCFldmVudC5pc0NvbXBvc2luZykge1xyXG5cdFx0XHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0b25TdWdnZXN0aW9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcblx0XHRjb25zdCBpdGVtID0gdGhpcy5zdWdnZXN0aW9ucy5pbmRleE9mKGVsKTtcclxuXHRcdHRoaXMuc2V0U2VsZWN0ZWRJdGVtKGl0ZW0sIGZhbHNlKTtcclxuXHRcdHRoaXMudXNlU2VsZWN0ZWRJdGVtKGV2ZW50KTtcclxuXHR9XHJcblxyXG5cdG9uU3VnZ2VzdGlvbk1vdXNlb3ZlcihfZXZlbnQ6IE1vdXNlRXZlbnQsIGVsOiBIVE1MRGl2RWxlbWVudCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaXRlbSA9IHRoaXMuc3VnZ2VzdGlvbnMuaW5kZXhPZihlbCk7XHJcblx0XHR0aGlzLnNldFNlbGVjdGVkSXRlbShpdGVtLCBmYWxzZSk7XHJcblx0fVxyXG5cclxuXHRzZXRTdWdnZXN0aW9ucyh2YWx1ZXM6IFRbXSkge1xyXG5cdFx0dGhpcy5jb250YWluZXJFbC5lbXB0eSgpO1xyXG5cdFx0Y29uc3Qgc3VnZ2VzdGlvbkVsczogSFRNTERpdkVsZW1lbnRbXSA9IFtdO1xyXG5cclxuXHRcdHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBzdWdnZXN0aW9uRWwgPSB0aGlzLmNvbnRhaW5lckVsLmNyZWF0ZURpdignc3VnZ2VzdGlvbi1pdGVtJyk7XHJcblx0XHRcdHRoaXMub3duZXIucmVuZGVyU3VnZ2VzdGlvbih2YWx1ZSwgc3VnZ2VzdGlvbkVsKTtcclxuXHRcdFx0c3VnZ2VzdGlvbkVscy5wdXNoKHN1Z2dlc3Rpb25FbCk7XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLnZhbHVlcyA9IHZhbHVlcztcclxuXHRcdHRoaXMuc3VnZ2VzdGlvbnMgPSBzdWdnZXN0aW9uRWxzO1xyXG5cdFx0dGhpcy5zZXRTZWxlY3RlZEl0ZW0oMCwgZmFsc2UpO1xyXG5cdH1cclxuXHJcblx0dXNlU2VsZWN0ZWRJdGVtKGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCkge1xyXG5cdFx0Y29uc3QgY3VycmVudFZhbHVlID0gdGhpcy52YWx1ZXNbdGhpcy5zZWxlY3RlZEl0ZW1dO1xyXG5cdFx0aWYgKGN1cnJlbnRWYWx1ZSkge1xyXG5cdFx0XHR0aGlzLm93bmVyLnNlbGVjdFN1Z2dlc3Rpb24oY3VycmVudFZhbHVlLCBldmVudCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRzZXRTZWxlY3RlZEl0ZW0oc2VsZWN0ZWRJbmRleDogbnVtYmVyLCBzY3JvbGxJbnRvVmlldzogYm9vbGVhbikge1xyXG5cdFx0Y29uc3Qgbm9ybWFsaXplZEluZGV4ID0gd3JhcEFyb3VuZChcclxuXHRcdFx0c2VsZWN0ZWRJbmRleCxcclxuXHRcdFx0dGhpcy5zdWdnZXN0aW9ucy5sZW5ndGhcclxuXHRcdCk7XHJcblx0XHRjb25zdCBwcmV2U2VsZWN0ZWRTdWdnZXN0aW9uID0gdGhpcy5zdWdnZXN0aW9uc1t0aGlzLnNlbGVjdGVkSXRlbV07XHJcblx0XHRjb25zdCBzZWxlY3RlZFN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3Rpb25zW25vcm1hbGl6ZWRJbmRleF07XHJcblxyXG5cdFx0cHJldlNlbGVjdGVkU3VnZ2VzdGlvbj8ucmVtb3ZlQ2xhc3MoJ2lzLXNlbGVjdGVkJyk7XHJcblx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24/LmFkZENsYXNzKCdpcy1zZWxlY3RlZCcpO1xyXG5cclxuXHRcdHRoaXMuc2VsZWN0ZWRJdGVtID0gbm9ybWFsaXplZEluZGV4O1xyXG5cclxuXHRcdGlmIChzY3JvbGxJbnRvVmlldykge1xyXG5cdFx0XHRzZWxlY3RlZFN1Z2dlc3Rpb24uc2Nyb2xsSW50b1ZpZXcoZmFsc2UpO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRleHRJbnB1dFN1Z2dlc3Q8VD4gaW1wbGVtZW50cyBJU3VnZ2VzdE93bmVyPFQ+IHtcclxuXHRwcm90ZWN0ZWQgaW5wdXRFbDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQ7XHJcblxyXG5cdHByaXZhdGUgcG9wcGVyOiBQb3BwZXJJbnN0YW5jZTtcclxuXHRwcml2YXRlIHNjb3BlOiBTY29wZTtcclxuXHRwcml2YXRlIHN1Z2dlc3RFbDogSFRNTEVsZW1lbnQ7XHJcblx0cHJpdmF0ZSBzdWdnZXN0OiBTdWdnZXN0PFQ+O1xyXG5cclxuXHRjb25zdHJ1Y3RvcihpbnB1dEVsOiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudCkge1xyXG5cdFx0dGhpcy5pbnB1dEVsID0gaW5wdXRFbDtcclxuXHRcdHRoaXMuc2NvcGUgPSBuZXcgU2NvcGUoKTtcclxuXHJcblx0XHR0aGlzLnN1Z2dlc3RFbCA9IGNyZWF0ZURpdignc3VnZ2VzdGlvbi1jb250YWluZXInKTtcclxuXHRcdGNvbnN0IHN1Z2dlc3Rpb24gPSB0aGlzLnN1Z2dlc3RFbC5jcmVhdGVEaXYoJ3N1Z2dlc3Rpb24nKTtcclxuXHRcdHRoaXMuc3VnZ2VzdCA9IG5ldyBTdWdnZXN0KHRoaXMsIHN1Z2dlc3Rpb24sIHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc2NvcGUucmVnaXN0ZXIoW10sICdFc2NhcGUnLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cclxuXHRcdHRoaXMuaW5wdXRFbC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIHRoaXMub25JbnB1dENoYW5nZWQuYmluZCh0aGlzKSk7XHJcblx0XHR0aGlzLmlucHV0RWwuYWRkRXZlbnRMaXN0ZW5lcignZm9jdXMnLCB0aGlzLm9uSW5wdXRDaGFuZ2VkLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5pbnB1dEVsLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0aGlzLmNsb3NlLmJpbmQodGhpcykpO1xyXG5cdFx0dGhpcy5zdWdnZXN0RWwub24oXHJcblx0XHRcdCdtb3VzZWRvd24nLFxyXG5cdFx0XHQnLnN1Z2dlc3Rpb24tY29udGFpbmVyJyxcclxuXHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0fVxyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdG9uSW5wdXRDaGFuZ2VkKCk6IHZvaWQge1xyXG5cdFx0Y29uc3QgaW5wdXRTdHIgPSB0aGlzLmlucHV0RWwudmFsdWU7XHJcblx0XHRjb25zdCBzdWdnZXN0aW9ucyA9IHRoaXMuZ2V0U3VnZ2VzdGlvbnMoaW5wdXRTdHIpO1xyXG5cclxuXHRcdGlmICghc3VnZ2VzdGlvbnMpIHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0dGhpcy5zdWdnZXN0LnNldFN1Z2dlc3Rpb25zKHN1Z2dlc3Rpb25zKTtcclxuXHRcdFx0Ly8gQHRzLWlnbm9yZVxyXG5cdFx0XHR0aGlzLm9wZW4oYXBwLmRvbS5hcHBDb250YWluZXJFbCwgdGhpcy5pbnB1dEVsKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdG9wZW4oY29udGFpbmVyOiBIVE1MRWxlbWVudCwgaW5wdXRFbDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XHJcblx0XHRhcHAua2V5bWFwLnB1c2hTY29wZSh0aGlzLnNjb3BlKTtcclxuXHJcblx0XHRjb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5zdWdnZXN0RWwpO1xyXG5cdFx0dGhpcy5wb3BwZXIgPSBjcmVhdGVQb3BwZXIoaW5wdXRFbCwgdGhpcy5zdWdnZXN0RWwsIHtcclxuXHRcdFx0cGxhY2VtZW50OiAnYm90dG9tLXN0YXJ0JyxcclxuXHRcdFx0bW9kaWZpZXJzOiBbXHJcblx0XHRcdFx0e1xyXG5cdFx0XHRcdFx0bmFtZTogJ3NhbWVXaWR0aCcsXHJcblx0XHRcdFx0XHRlbmFibGVkOiB0cnVlLFxyXG5cdFx0XHRcdFx0Zm46ICh7IHN0YXRlLCBpbnN0YW5jZSB9KSA9PiB7XHJcblx0XHRcdFx0XHRcdC8vIE5vdGU6IHBvc2l0aW9uaW5nIG5lZWRzIHRvIGJlIGNhbGN1bGF0ZWQgdHdpY2UgLVxyXG5cdFx0XHRcdFx0XHQvLyBmaXJzdCBwYXNzIC0gcG9zaXRpb25pbmcgaXQgYWNjb3JkaW5nIHRvIHRoZSB3aWR0aCBvZiB0aGUgcG9wcGVyXHJcblx0XHRcdFx0XHRcdC8vIHNlY29uZCBwYXNzIC0gcG9zaXRpb24gaXQgd2l0aCB0aGUgd2lkdGggYm91bmQgdG8gdGhlIHJlZmVyZW5jZSBlbGVtZW50XHJcblx0XHRcdFx0XHRcdC8vIHdlIG5lZWQgdG8gZWFybHkgZXhpdCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wXHJcblx0XHRcdFx0XHRcdGNvbnN0IHRhcmdldFdpZHRoID0gYCR7c3RhdGUucmVjdHMucmVmZXJlbmNlLndpZHRofXB4YDtcclxuXHRcdFx0XHRcdFx0aWYgKHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPT09IHRhcmdldFdpZHRoKSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHN0YXRlLnN0eWxlcy5wb3BwZXIud2lkdGggPSB0YXJnZXRXaWR0aDtcclxuXHRcdFx0XHRcdFx0aW5zdGFuY2UudXBkYXRlKCk7XHJcblx0XHRcdFx0XHR9LFxyXG5cdFx0XHRcdFx0cGhhc2U6ICdiZWZvcmVXcml0ZScsXHJcblx0XHRcdFx0XHRyZXF1aXJlczogWydjb21wdXRlU3R5bGVzJ10sXHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XSxcclxuXHRcdH0pO1xyXG5cdH1cclxuXHJcblx0Y2xvc2UoKTogdm9pZCB7XHJcblx0XHRhcHAua2V5bWFwLnBvcFNjb3BlKHRoaXMuc2NvcGUpO1xyXG5cclxuXHRcdHRoaXMuc3VnZ2VzdC5zZXRTdWdnZXN0aW9ucyhbXSk7XHJcblx0XHRpZiAodGhpcy5wb3BwZXIpIHRoaXMucG9wcGVyLmRlc3Ryb3koKTtcclxuXHRcdHRoaXMuc3VnZ2VzdEVsLmRldGFjaCgpO1xyXG5cdH1cclxuXHJcbiAgICBhYnN0cmFjdCBnZXRTdWdnZXN0aW9ucyhpbnB1dFN0cjogc3RyaW5nKTogVFtdO1xyXG4gICAgYWJzdHJhY3QgcmVuZGVyU3VnZ2VzdGlvbihpdGVtOiBULCBlbDogSFRNTEVsZW1lbnQpOiB2b2lkO1xyXG4gICAgYWJzdHJhY3Qgc2VsZWN0U3VnZ2VzdGlvbihpdGVtOiBUKTogdm9pZDtcclxufVxyXG4iLCAiZXhwb3J0IHZhciB0b3AgPSAndG9wJztcbmV4cG9ydCB2YXIgYm90dG9tID0gJ2JvdHRvbSc7XG5leHBvcnQgdmFyIHJpZ2h0ID0gJ3JpZ2h0JztcbmV4cG9ydCB2YXIgbGVmdCA9ICdsZWZ0JztcbmV4cG9ydCB2YXIgYXV0byA9ICdhdXRvJztcbmV4cG9ydCB2YXIgYmFzZVBsYWNlbWVudHMgPSBbdG9wLCBib3R0b20sIHJpZ2h0LCBsZWZ0XTtcbmV4cG9ydCB2YXIgc3RhcnQgPSAnc3RhcnQnO1xuZXhwb3J0IHZhciBlbmQgPSAnZW5kJztcbmV4cG9ydCB2YXIgY2xpcHBpbmdQYXJlbnRzID0gJ2NsaXBwaW5nUGFyZW50cyc7XG5leHBvcnQgdmFyIHZpZXdwb3J0ID0gJ3ZpZXdwb3J0JztcbmV4cG9ydCB2YXIgcG9wcGVyID0gJ3BvcHBlcic7XG5leHBvcnQgdmFyIHJlZmVyZW5jZSA9ICdyZWZlcmVuY2UnO1xuZXhwb3J0IHZhciB2YXJpYXRpb25QbGFjZW1lbnRzID0gLyojX19QVVJFX18qL2Jhc2VQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCArIFwiLVwiICsgc3RhcnQsIHBsYWNlbWVudCArIFwiLVwiICsgZW5kXSk7XG59LCBbXSk7XG5leHBvcnQgdmFyIHBsYWNlbWVudHMgPSAvKiNfX1BVUkVfXyovW10uY29uY2F0KGJhc2VQbGFjZW1lbnRzLCBbYXV0b10pLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIGFjYy5jb25jYXQoW3BsYWNlbWVudCwgcGxhY2VtZW50ICsgXCItXCIgKyBzdGFydCwgcGxhY2VtZW50ICsgXCItXCIgKyBlbmRdKTtcbn0sIFtdKTsgLy8gbW9kaWZpZXJzIHRoYXQgbmVlZCB0byByZWFkIHRoZSBET01cblxuZXhwb3J0IHZhciBiZWZvcmVSZWFkID0gJ2JlZm9yZVJlYWQnO1xuZXhwb3J0IHZhciByZWFkID0gJ3JlYWQnO1xuZXhwb3J0IHZhciBhZnRlclJlYWQgPSAnYWZ0ZXJSZWFkJzsgLy8gcHVyZS1sb2dpYyBtb2RpZmllcnNcblxuZXhwb3J0IHZhciBiZWZvcmVNYWluID0gJ2JlZm9yZU1haW4nO1xuZXhwb3J0IHZhciBtYWluID0gJ21haW4nO1xuZXhwb3J0IHZhciBhZnRlck1haW4gPSAnYWZ0ZXJNYWluJzsgLy8gbW9kaWZpZXIgd2l0aCB0aGUgcHVycG9zZSB0byB3cml0ZSB0byB0aGUgRE9NIChvciB3cml0ZSBpbnRvIGEgZnJhbWV3b3JrIHN0YXRlKVxuXG5leHBvcnQgdmFyIGJlZm9yZVdyaXRlID0gJ2JlZm9yZVdyaXRlJztcbmV4cG9ydCB2YXIgd3JpdGUgPSAnd3JpdGUnO1xuZXhwb3J0IHZhciBhZnRlcldyaXRlID0gJ2FmdGVyV3JpdGUnO1xuZXhwb3J0IHZhciBtb2RpZmllclBoYXNlcyA9IFtiZWZvcmVSZWFkLCByZWFkLCBhZnRlclJlYWQsIGJlZm9yZU1haW4sIG1haW4sIGFmdGVyTWFpbiwgYmVmb3JlV3JpdGUsIHdyaXRlLCBhZnRlcldyaXRlXTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Tm9kZU5hbWUoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCA/IChlbGVtZW50Lm5vZGVOYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpIDogbnVsbDtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICBpZiAobm9kZS50b1N0cmluZygpICE9PSAnW29iamVjdCBXaW5kb3ddJykge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBvd25lckRvY3VtZW50ID8gb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3cgOiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuRWxlbWVudDtcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBPd25FbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBpc0hUTUxFbGVtZW50KG5vZGUpIHtcbiAgdmFyIE93bkVsZW1lbnQgPSBnZXRXaW5kb3cobm9kZSkuSFRNTEVsZW1lbnQ7XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgT3duRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzU2hhZG93Um9vdChub2RlKSB7XG4gIC8vIElFIDExIGhhcyBubyBTaGFkb3dSb290XG4gIGlmICh0eXBlb2YgU2hhZG93Um9vdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5TaGFkb3dSb290O1xuICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE93bkVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIFNoYWRvd1Jvb3Q7XG59XG5cbmV4cG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCwgaXNTaGFkb3dSb290IH07IiwgImltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4uL2RvbS11dGlscy9pbnN0YW5jZU9mLmpzXCI7IC8vIFRoaXMgbW9kaWZpZXIgdGFrZXMgdGhlIHN0eWxlcyBwcmVwYXJlZCBieSB0aGUgYGNvbXB1dGVTdHlsZXNgIG1vZGlmaWVyXG4vLyBhbmQgYXBwbGllcyB0aGVtIHRvIHRoZSBIVE1MRWxlbWVudHMgc3VjaCBhcyBwb3BwZXIgYW5kIGFycm93XG5cbmZ1bmN0aW9uIGFwcGx5U3R5bGVzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZTtcbiAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgc3R5bGUgPSBzdGF0ZS5zdHlsZXNbbmFtZV0gfHwge307XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBzdGF0ZS5hdHRyaWJ1dGVzW25hbWVdIHx8IHt9O1xuICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07IC8vIGFycm93IGlzIG9wdGlvbmFsICsgdmlydHVhbCBlbGVtZW50c1xuXG4gICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gRmxvdyBkb2Vzbid0IHN1cHBvcnQgdG8gZXh0ZW5kIHRoaXMgcHJvcGVydHksIGJ1dCBpdCdzIHRoZSBtb3N0XG4gICAgLy8gZWZmZWN0aXZlIHdheSB0byBhcHBseSBzdHlsZXMgdG8gYW4gSFRNTEVsZW1lbnRcbiAgICAvLyAkRmxvd0ZpeE1lW2Nhbm5vdC13cml0ZV1cblxuXG4gICAgT2JqZWN0LmFzc2lnbihlbGVtZW50LnN0eWxlLCBzdHlsZSk7XG4gICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cmlidXRlc1tuYW1lXTtcblxuICAgICAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlID09PSB0cnVlID8gJycgOiB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGU7XG4gIHZhciBpbml0aWFsU3R5bGVzID0ge1xuICAgIHBvcHBlcjoge1xuICAgICAgcG9zaXRpb246IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBsZWZ0OiAnMCcsXG4gICAgICB0b3A6ICcwJyxcbiAgICAgIG1hcmdpbjogJzAnXG4gICAgfSxcbiAgICBhcnJvdzoge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZSdcbiAgICB9LFxuICAgIHJlZmVyZW5jZToge31cbiAgfTtcbiAgT2JqZWN0LmFzc2lnbihzdGF0ZS5lbGVtZW50cy5wb3BwZXIuc3R5bGUsIGluaXRpYWxTdHlsZXMucG9wcGVyKTtcbiAgc3RhdGUuc3R5bGVzID0gaW5pdGlhbFN0eWxlcztcblxuICBpZiAoc3RhdGUuZWxlbWVudHMuYXJyb3cpIHtcbiAgICBPYmplY3QuYXNzaWduKHN0YXRlLmVsZW1lbnRzLmFycm93LnN0eWxlLCBpbml0aWFsU3R5bGVzLmFycm93KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgT2JqZWN0LmtleXMoc3RhdGUuZWxlbWVudHMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gc3RhdGUuZWxlbWVudHNbbmFtZV07XG4gICAgICB2YXIgYXR0cmlidXRlcyA9IHN0YXRlLmF0dHJpYnV0ZXNbbmFtZV0gfHwge307XG4gICAgICB2YXIgc3R5bGVQcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoc3RhdGUuc3R5bGVzLmhhc093blByb3BlcnR5KG5hbWUpID8gc3RhdGUuc3R5bGVzW25hbWVdIDogaW5pdGlhbFN0eWxlc1tuYW1lXSk7IC8vIFNldCBhbGwgdmFsdWVzIHRvIGFuIGVtcHR5IHN0cmluZyB0byB1bnNldCB0aGVtXG5cbiAgICAgIHZhciBzdHlsZSA9IHN0eWxlUHJvcGVydGllcy5yZWR1Y2UoZnVuY3Rpb24gKHN0eWxlLCBwcm9wZXJ0eSkge1xuICAgICAgICBzdHlsZVtwcm9wZXJ0eV0gPSAnJztcbiAgICAgICAgcmV0dXJuIHN0eWxlO1xuICAgICAgfSwge30pOyAvLyBhcnJvdyBpcyBvcHRpb25hbCArIHZpcnR1YWwgZWxlbWVudHNcblxuICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KGVsZW1lbnQpIHx8ICFnZXROb2RlTmFtZShlbGVtZW50KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgc3R5bGUpO1xuICAgICAgT2JqZWN0LmtleXMoYXR0cmlidXRlcykuZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2FwcGx5U3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBhcHBseVN0eWxlcyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ2NvbXB1dGVTdHlsZXMnXVxufTsiLCAiaW1wb3J0IHsgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xufSIsICJleHBvcnQgdmFyIG1heCA9IE1hdGgubWF4O1xuZXhwb3J0IHZhciBtaW4gPSBNYXRoLm1pbjtcbmV4cG9ydCB2YXIgcm91bmQgPSBNYXRoLnJvdW5kOyIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRVQVN0cmluZygpIHtcbiAgdmFyIHVhRGF0YSA9IG5hdmlnYXRvci51c2VyQWdlbnREYXRhO1xuXG4gIGlmICh1YURhdGEgIT0gbnVsbCAmJiB1YURhdGEuYnJhbmRzICYmIEFycmF5LmlzQXJyYXkodWFEYXRhLmJyYW5kcykpIHtcbiAgICByZXR1cm4gdWFEYXRhLmJyYW5kcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBpdGVtLmJyYW5kICsgXCIvXCIgKyBpdGVtLnZlcnNpb247XG4gICAgfSkuam9pbignICcpO1xuICB9XG5cbiAgcmV0dXJuIG5hdmlnYXRvci51c2VyQWdlbnQ7XG59IiwgImltcG9ydCBnZXRVQVN0cmluZyBmcm9tIFwiLi4vdXRpbHMvdXNlckFnZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0xheW91dFZpZXdwb3J0KCkge1xuICByZXR1cm4gIS9eKCg/IWNocm9tZXxhbmRyb2lkKS4pKnNhZmFyaS9pLnRlc3QoZ2V0VUFTdHJpbmcoKSk7XG59IiwgImltcG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcbmltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCwgaW5jbHVkZVNjYWxlLCBpc0ZpeGVkU3RyYXRlZ3kpIHtcbiAgaWYgKGluY2x1ZGVTY2FsZSA9PT0gdm9pZCAwKSB7XG4gICAgaW5jbHVkZVNjYWxlID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaXNGaXhlZFN0cmF0ZWd5ID09PSB2b2lkIDApIHtcbiAgICBpc0ZpeGVkU3RyYXRlZ3kgPSBmYWxzZTtcbiAgfVxuXG4gIHZhciBjbGllbnRSZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgdmFyIHNjYWxlWCA9IDE7XG4gIHZhciBzY2FsZVkgPSAxO1xuXG4gIGlmIChpbmNsdWRlU2NhbGUgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSkge1xuICAgIHNjYWxlWCA9IGVsZW1lbnQub2Zmc2V0V2lkdGggPiAwID8gcm91bmQoY2xpZW50UmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDEgOiAxO1xuICAgIHNjYWxlWSA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0ID4gMCA/IHJvdW5kKGNsaWVudFJlY3QuaGVpZ2h0KSAvIGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDEgOiAxO1xuICB9XG5cbiAgdmFyIF9yZWYgPSBpc0VsZW1lbnQoZWxlbWVudCkgPyBnZXRXaW5kb3coZWxlbWVudCkgOiB3aW5kb3csXG4gICAgICB2aXN1YWxWaWV3cG9ydCA9IF9yZWYudmlzdWFsVmlld3BvcnQ7XG5cbiAgdmFyIGFkZFZpc3VhbE9mZnNldHMgPSAhaXNMYXlvdXRWaWV3cG9ydCgpICYmIGlzRml4ZWRTdHJhdGVneTtcbiAgdmFyIHggPSAoY2xpZW50UmVjdC5sZWZ0ICsgKGFkZFZpc3VhbE9mZnNldHMgJiYgdmlzdWFsVmlld3BvcnQgPyB2aXN1YWxWaWV3cG9ydC5vZmZzZXRMZWZ0IDogMCkpIC8gc2NhbGVYO1xuICB2YXIgeSA9IChjbGllbnRSZWN0LnRvcCArIChhZGRWaXN1YWxPZmZzZXRzICYmIHZpc3VhbFZpZXdwb3J0ID8gdmlzdWFsVmlld3BvcnQub2Zmc2V0VG9wIDogMCkpIC8gc2NhbGVZO1xuICB2YXIgd2lkdGggPSBjbGllbnRSZWN0LndpZHRoIC8gc2NhbGVYO1xuICB2YXIgaGVpZ2h0ID0gY2xpZW50UmVjdC5oZWlnaHQgLyBzY2FsZVk7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHRvcDogeSxcbiAgICByaWdodDogeCArIHdpZHRoLFxuICAgIGJvdHRvbTogeSArIGhlaWdodCxcbiAgICBsZWZ0OiB4LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiOyAvLyBSZXR1cm5zIHRoZSBsYXlvdXQgcmVjdCBvZiBhbiBlbGVtZW50IHJlbGF0aXZlIHRvIGl0cyBvZmZzZXRQYXJlbnQuIExheW91dFxuLy8gbWVhbnMgaXQgZG9lc24ndCB0YWtlIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zLlxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRMYXlvdXRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIGNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCk7IC8vIFVzZSB0aGUgY2xpZW50UmVjdCBzaXplcyBpZiBpdCdzIG5vdCBiZWVuIHRyYW5zZm9ybWVkLlxuICAvLyBGaXhlcyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEyMjNcblxuICB2YXIgd2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG5cbiAgaWYgKE1hdGguYWJzKGNsaWVudFJlY3Qud2lkdGggLSB3aWR0aCkgPD0gMSkge1xuICAgIHdpZHRoID0gY2xpZW50UmVjdC53aWR0aDtcbiAgfVxuXG4gIGlmIChNYXRoLmFicyhjbGllbnRSZWN0LmhlaWdodCAtIGhlaWdodCkgPD0gMSkge1xuICAgIGhlaWdodCA9IGNsaWVudFJlY3QuaGVpZ2h0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBlbGVtZW50Lm9mZnNldExlZnQsXG4gICAgeTogZWxlbWVudC5vZmZzZXRUb3AsXG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRhaW5zKHBhcmVudCwgY2hpbGQpIHtcbiAgdmFyIHJvb3ROb2RlID0gY2hpbGQuZ2V0Um9vdE5vZGUgJiYgY2hpbGQuZ2V0Um9vdE5vZGUoKTsgLy8gRmlyc3QsIGF0dGVtcHQgd2l0aCBmYXN0ZXIgbmF0aXZlIG1ldGhvZFxuXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gLy8gdGhlbiBmYWxsYmFjayB0byBjdXN0b20gaW1wbGVtZW50YXRpb24gd2l0aCBTaGFkb3cgRE9NIHN1cHBvcnRcbiAgZWxzZSBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgICAgdmFyIG5leHQgPSBjaGlsZDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAobmV4dCAmJiBwYXJlbnQuaXNTYW1lTm9kZShuZXh0KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXTogbmVlZCBhIGJldHRlciB3YXkgdG8gaGFuZGxlIHRoaXMuLi5cblxuXG4gICAgICAgIG5leHQgPSBuZXh0LnBhcmVudE5vZGUgfHwgbmV4dC5ob3N0O1xuICAgICAgfSB3aGlsZSAobmV4dCk7XG4gICAgfSAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG5cblxuICByZXR1cm4gZmFsc2U7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFdpbmRvdyhlbGVtZW50KS5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xufSIsICJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGlzVGFibGVFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIFsndGFibGUnLCAndGQnLCAndGgnXS5pbmRleE9mKGdldE5vZGVOYW1lKGVsZW1lbnQpKSA+PSAwO1xufSIsICJpbXBvcnQgeyBpc0VsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkge1xuICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gIHJldHVybiAoKGlzRWxlbWVudChlbGVtZW50KSA/IGVsZW1lbnQub3duZXJEb2N1bWVudCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICBlbGVtZW50LmRvY3VtZW50KSB8fCB3aW5kb3cuZG9jdW1lbnQpLmRvY3VtZW50RWxlbWVudDtcbn0iLCAiaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IHsgaXNTaGFkb3dSb290IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0UGFyZW50Tm9kZShlbGVtZW50KSB7XG4gIGlmIChnZXROb2RlTmFtZShlbGVtZW50KSA9PT0gJ2h0bWwnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gKC8vIHRoaXMgaXMgYSBxdWlja2VyIChidXQgbGVzcyB0eXBlIHNhZmUpIHdheSB0byBzYXZlIHF1aXRlIHNvbWUgYnl0ZXMgZnJvbSB0aGUgYnVuZGxlXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXVxuICAgIC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgIGVsZW1lbnQuYXNzaWduZWRTbG90IHx8IC8vIHN0ZXAgaW50byB0aGUgc2hhZG93IERPTSBvZiB0aGUgcGFyZW50IG9mIGEgc2xvdHRlZCBub2RlXG4gICAgZWxlbWVudC5wYXJlbnROb2RlIHx8ICggLy8gRE9NIEVsZW1lbnQgZGV0ZWN0ZWRcbiAgICBpc1NoYWRvd1Jvb3QoZWxlbWVudCkgPyBlbGVtZW50Lmhvc3QgOiBudWxsKSB8fCAvLyBTaGFkb3dSb290IGRldGVjdGVkXG4gICAgLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IEhUTUxFbGVtZW50IGlzIGEgTm9kZVxuICAgIGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KSAvLyBmYWxsYmFja1xuXG4gICk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQsIGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBpc1RhYmxlRWxlbWVudCBmcm9tIFwiLi9pc1RhYmxlRWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGdldFVBU3RyaW5nIGZyb20gXCIuLi91dGlscy91c2VyQWdlbnQuanNcIjtcblxuZnVuY3Rpb24gZ2V0VHJ1ZU9mZnNldFBhcmVudChlbGVtZW50KSB7XG4gIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzgzN1xuICBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG59IC8vIGAub2Zmc2V0UGFyZW50YCByZXBvcnRzIGBudWxsYCBmb3IgZml4ZWQgZWxlbWVudHMsIHdoaWxlIGFic29sdXRlIGVsZW1lbnRzXG4vLyByZXR1cm4gdGhlIGNvbnRhaW5pbmcgYmxvY2tcblxuXG5mdW5jdGlvbiBnZXRDb250YWluaW5nQmxvY2soZWxlbWVudCkge1xuICB2YXIgaXNGaXJlZm94ID0gL2ZpcmVmb3gvaS50ZXN0KGdldFVBU3RyaW5nKCkpO1xuICB2YXIgaXNJRSA9IC9UcmlkZW50L2kudGVzdChnZXRVQVN0cmluZygpKTtcblxuICBpZiAoaXNJRSAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgLy8gSW4gSUUgOSwgMTAgYW5kIDExIGZpeGVkIGVsZW1lbnRzIGNvbnRhaW5pbmcgYmxvY2sgaXMgYWx3YXlzIGVzdGFibGlzaGVkIGJ5IHRoZSB2aWV3cG9ydFxuICAgIHZhciBlbGVtZW50Q3NzID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50Q3NzLnBvc2l0aW9uID09PSAnZml4ZWQnKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICB2YXIgY3VycmVudE5vZGUgPSBnZXRQYXJlbnROb2RlKGVsZW1lbnQpO1xuXG4gIGlmIChpc1NoYWRvd1Jvb3QoY3VycmVudE5vZGUpKSB7XG4gICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5ob3N0O1xuICB9XG5cbiAgd2hpbGUgKGlzSFRNTEVsZW1lbnQoY3VycmVudE5vZGUpICYmIFsnaHRtbCcsICdib2R5J10uaW5kZXhPZihnZXROb2RlTmFtZShjdXJyZW50Tm9kZSkpIDwgMCkge1xuICAgIHZhciBjc3MgPSBnZXRDb21wdXRlZFN0eWxlKGN1cnJlbnROb2RlKTsgLy8gVGhpcyBpcyBub24tZXhoYXVzdGl2ZSBidXQgY292ZXJzIHRoZSBtb3N0IGNvbW1vbiBDU1MgcHJvcGVydGllcyB0aGF0XG4gICAgLy8gY3JlYXRlIGEgY29udGFpbmluZyBibG9jay5cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9DU1MvQ29udGFpbmluZ19ibG9jayNpZGVudGlmeWluZ190aGVfY29udGFpbmluZ19ibG9ja1xuXG4gICAgaWYgKGNzcy50cmFuc2Zvcm0gIT09ICdub25lJyB8fCBjc3MucGVyc3BlY3RpdmUgIT09ICdub25lJyB8fCBjc3MuY29udGFpbiA9PT0gJ3BhaW50JyB8fCBbJ3RyYW5zZm9ybScsICdwZXJzcGVjdGl2ZSddLmluZGV4T2YoY3NzLndpbGxDaGFuZ2UpICE9PSAtMSB8fCBpc0ZpcmVmb3ggJiYgY3NzLndpbGxDaGFuZ2UgPT09ICdmaWx0ZXInIHx8IGlzRmlyZWZveCAmJiBjc3MuZmlsdGVyICYmIGNzcy5maWx0ZXIgIT09ICdub25lJykge1xuICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59IC8vIEdldHMgdGhlIGNsb3Nlc3QgYW5jZXN0b3IgcG9zaXRpb25lZCBlbGVtZW50LiBIYW5kbGVzIHNvbWUgZWRnZSBjYXNlcyxcbi8vIHN1Y2ggYXMgdGFibGUgYW5jZXN0b3JzIGFuZCBjcm9zcyBicm93c2VyIGJ1Z3MuXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIHtcbiAgdmFyIHdpbmRvdyA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIG9mZnNldFBhcmVudCA9IGdldFRydWVPZmZzZXRQYXJlbnQoZWxlbWVudCk7XG5cbiAgd2hpbGUgKG9mZnNldFBhcmVudCAmJiBpc1RhYmxlRWxlbWVudChvZmZzZXRQYXJlbnQpICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpIHtcbiAgICBvZmZzZXRQYXJlbnQgPSBnZXRUcnVlT2Zmc2V0UGFyZW50KG9mZnNldFBhcmVudCk7XG4gIH1cblxuICBpZiAob2Zmc2V0UGFyZW50ICYmIChnZXROb2RlTmFtZShvZmZzZXRQYXJlbnQpID09PSAnaHRtbCcgfHwgZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSA9PT0gJ2JvZHknICYmIGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpKSB7XG4gICAgcmV0dXJuIHdpbmRvdztcbiAgfVxuXG4gIHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZ2V0Q29udGFpbmluZ0Jsb2NrKGVsZW1lbnQpIHx8IHdpbmRvdztcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gWyd0b3AnLCAnYm90dG9tJ10uaW5kZXhPZihwbGFjZW1lbnQpID49IDAgPyAneCcgOiAneSc7XG59IiwgImltcG9ydCB7IG1heCBhcyBtYXRoTWF4LCBtaW4gYXMgbWF0aE1pbiB9IGZyb20gXCIuL21hdGguanNcIjtcbmV4cG9ydCBmdW5jdGlvbiB3aXRoaW4obWluLCB2YWx1ZSwgbWF4KSB7XG4gIHJldHVybiBtYXRoTWF4KG1pbiwgbWF0aE1pbih2YWx1ZSwgbWF4KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gd2l0aGluTWF4Q2xhbXAobWluLCB2YWx1ZSwgbWF4KSB7XG4gIHZhciB2ID0gd2l0aGluKG1pbiwgdmFsdWUsIG1heCk7XG4gIHJldHVybiB2ID4gbWF4ID8gbWF4IDogdjtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RnJlc2hTaWRlT2JqZWN0KCkge1xuICByZXR1cm4ge1xuICAgIHRvcDogMCxcbiAgICByaWdodDogMCxcbiAgICBib3R0b206IDAsXG4gICAgbGVmdDogMFxuICB9O1xufSIsICJpbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbWVyZ2VQYWRkaW5nT2JqZWN0KHBhZGRpbmdPYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGdldEZyZXNoU2lkZU9iamVjdCgpLCBwYWRkaW5nT2JqZWN0KTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZXhwYW5kVG9IYXNoTWFwKHZhbHVlLCBrZXlzKSB7XG4gIHJldHVybiBrZXlzLnJlZHVjZShmdW5jdGlvbiAoaGFzaE1hcCwga2V5KSB7XG4gICAgaGFzaE1hcFtrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIGhhc2hNYXA7XG4gIH0sIHt9KTtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuLi9kb20tdXRpbHMvY29udGFpbnMuanNcIjtcbmltcG9ydCBnZXRPZmZzZXRQYXJlbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgd2l0aGluIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGhpbi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi4vdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzXCI7XG5pbXBvcnQgZXhwYW5kVG9IYXNoTWFwIGZyb20gXCIuLi91dGlscy9leHBhbmRUb0hhc2hNYXAuanNcIjtcbmltcG9ydCB7IGxlZnQsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdG9wLCBib3R0b20gfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdG9QYWRkaW5nT2JqZWN0ID0gZnVuY3Rpb24gdG9QYWRkaW5nT2JqZWN0KHBhZGRpbmcsIHN0YXRlKSB7XG4gIHBhZGRpbmcgPSB0eXBlb2YgcGFkZGluZyA9PT0gJ2Z1bmN0aW9uJyA/IHBhZGRpbmcoT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KSkgOiBwYWRkaW5nO1xuICByZXR1cm4gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbn07XG5cbmZ1bmN0aW9uIGFycm93KF9yZWYpIHtcbiAgdmFyIF9zdGF0ZSRtb2RpZmllcnNEYXRhJDtcblxuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XG4gIHZhciBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdztcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHM7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgYXhpcyA9IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChiYXNlUGxhY2VtZW50KTtcbiAgdmFyIGlzVmVydGljYWwgPSBbbGVmdCwgcmlnaHRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgPj0gMDtcbiAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgaWYgKCFhcnJvd0VsZW1lbnQgfHwgIXBvcHBlck9mZnNldHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFkZGluZ09iamVjdCA9IHRvUGFkZGluZ09iamVjdChvcHRpb25zLnBhZGRpbmcsIHN0YXRlKTtcbiAgdmFyIGFycm93UmVjdCA9IGdldExheW91dFJlY3QoYXJyb3dFbGVtZW50KTtcbiAgdmFyIG1pblByb3AgPSBheGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICB2YXIgbWF4UHJvcCA9IGF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICB2YXIgZW5kRGlmZiA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtsZW5dICsgc3RhdGUucmVjdHMucmVmZXJlbmNlW2F4aXNdIC0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnBvcHBlcltsZW5dO1xuICB2YXIgc3RhcnREaWZmID0gcG9wcGVyT2Zmc2V0c1theGlzXSAtIHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtheGlzXTtcbiAgdmFyIGFycm93T2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KGFycm93RWxlbWVudCk7XG4gIHZhciBjbGllbnRTaXplID0gYXJyb3dPZmZzZXRQYXJlbnQgPyBheGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRIZWlnaHQgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudFdpZHRoIHx8IDAgOiAwO1xuICB2YXIgY2VudGVyVG9SZWZlcmVuY2UgPSBlbmREaWZmIC8gMiAtIHN0YXJ0RGlmZiAvIDI7IC8vIE1ha2Ugc3VyZSB0aGUgYXJyb3cgZG9lc24ndCBvdmVyZmxvdyB0aGUgcG9wcGVyIGlmIHRoZSBjZW50ZXIgcG9pbnQgaXNcbiAgLy8gb3V0c2lkZSBvZiB0aGUgcG9wcGVyIGJvdW5kc1xuXG4gIHZhciBtaW4gPSBwYWRkaW5nT2JqZWN0W21pblByb3BdO1xuICB2YXIgbWF4ID0gY2xpZW50U2l6ZSAtIGFycm93UmVjdFtsZW5dIC0gcGFkZGluZ09iamVjdFttYXhQcm9wXTtcbiAgdmFyIGNlbnRlciA9IGNsaWVudFNpemUgLyAyIC0gYXJyb3dSZWN0W2xlbl0gLyAyICsgY2VudGVyVG9SZWZlcmVuY2U7XG4gIHZhciBvZmZzZXQgPSB3aXRoaW4obWluLCBjZW50ZXIsIG1heCk7IC8vIFByZXZlbnRzIGJyZWFraW5nIHN5bnRheCBoaWdobGlnaHRpbmcuLi5cblxuICB2YXIgYXhpc1Byb3AgPSBheGlzO1xuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gKF9zdGF0ZSRtb2RpZmllcnNEYXRhJCA9IHt9LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSRbYXhpc1Byb3BdID0gb2Zmc2V0LCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQuY2VudGVyT2Zmc2V0ID0gb2Zmc2V0IC0gY2VudGVyLCBfc3RhdGUkbW9kaWZpZXJzRGF0YSQpO1xufVxuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJGVsZW1lbnQgPSBvcHRpb25zLmVsZW1lbnQsXG4gICAgICBhcnJvd0VsZW1lbnQgPSBfb3B0aW9ucyRlbGVtZW50ID09PSB2b2lkIDAgPyAnW2RhdGEtcG9wcGVyLWFycm93XScgOiBfb3B0aW9ucyRlbGVtZW50O1xuXG4gIGlmIChhcnJvd0VsZW1lbnQgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfSAvLyBDU1Mgc2VsZWN0b3JcblxuXG4gIGlmICh0eXBlb2YgYXJyb3dFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgIGFycm93RWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzLnBvcHBlci5xdWVyeVNlbGVjdG9yKGFycm93RWxlbWVudCk7XG5cbiAgICBpZiAoIWFycm93RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmICghY29udGFpbnMoc3RhdGUuZWxlbWVudHMucG9wcGVyLCBhcnJvd0VsZW1lbnQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgc3RhdGUuZWxlbWVudHMuYXJyb3cgPSBhcnJvd0VsZW1lbnQ7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcnJvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBhcnJvdyxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydwcmV2ZW50T3ZlcmZsb3cnXVxufTsiLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnNwbGl0KCctJylbMV07XG59IiwgImltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgZW5kIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0V2luZG93LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgdW5zZXRTaWRlcyA9IHtcbiAgdG9wOiAnYXV0bycsXG4gIHJpZ2h0OiAnYXV0bycsXG4gIGJvdHRvbTogJ2F1dG8nLFxuICBsZWZ0OiAnYXV0bydcbn07IC8vIFJvdW5kIHRoZSBvZmZzZXRzIHRvIHRoZSBuZWFyZXN0IHN1aXRhYmxlIHN1YnBpeGVsIGJhc2VkIG9uIHRoZSBEUFIuXG4vLyBab29taW5nIGNhbiBjaGFuZ2UgdGhlIERQUiwgYnV0IGl0IHNlZW1zIHRvIHJlcG9ydCBhIHZhbHVlIHRoYXQgd2lsbFxuLy8gY2xlYW5seSBkaXZpZGUgdGhlIHZhbHVlcyBpbnRvIHRoZSBhcHByb3ByaWF0ZSBzdWJwaXhlbHMuXG5cbmZ1bmN0aW9uIHJvdW5kT2Zmc2V0c0J5RFBSKF9yZWYsIHdpbikge1xuICB2YXIgeCA9IF9yZWYueCxcbiAgICAgIHkgPSBfcmVmLnk7XG4gIHZhciBkcHIgPSB3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICByZXR1cm4ge1xuICAgIHg6IHJvdW5kKHggKiBkcHIpIC8gZHByIHx8IDAsXG4gICAgeTogcm91bmQoeSAqIGRwcikgLyBkcHIgfHwgMFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFwVG9TdHlsZXMoX3JlZjIpIHtcbiAgdmFyIF9PYmplY3QkYXNzaWduMjtcblxuICB2YXIgcG9wcGVyID0gX3JlZjIucG9wcGVyLFxuICAgICAgcG9wcGVyUmVjdCA9IF9yZWYyLnBvcHBlclJlY3QsXG4gICAgICBwbGFjZW1lbnQgPSBfcmVmMi5wbGFjZW1lbnQsXG4gICAgICB2YXJpYXRpb24gPSBfcmVmMi52YXJpYXRpb24sXG4gICAgICBvZmZzZXRzID0gX3JlZjIub2Zmc2V0cyxcbiAgICAgIHBvc2l0aW9uID0gX3JlZjIucG9zaXRpb24sXG4gICAgICBncHVBY2NlbGVyYXRpb24gPSBfcmVmMi5ncHVBY2NlbGVyYXRpb24sXG4gICAgICBhZGFwdGl2ZSA9IF9yZWYyLmFkYXB0aXZlLFxuICAgICAgcm91bmRPZmZzZXRzID0gX3JlZjIucm91bmRPZmZzZXRzLFxuICAgICAgaXNGaXhlZCA9IF9yZWYyLmlzRml4ZWQ7XG4gIHZhciBfb2Zmc2V0cyR4ID0gb2Zmc2V0cy54LFxuICAgICAgeCA9IF9vZmZzZXRzJHggPT09IHZvaWQgMCA/IDAgOiBfb2Zmc2V0cyR4LFxuICAgICAgX29mZnNldHMkeSA9IG9mZnNldHMueSxcbiAgICAgIHkgPSBfb2Zmc2V0cyR5ID09PSB2b2lkIDAgPyAwIDogX29mZnNldHMkeTtcblxuICB2YXIgX3JlZjMgPSB0eXBlb2Ygcm91bmRPZmZzZXRzID09PSAnZnVuY3Rpb24nID8gcm91bmRPZmZzZXRzKHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWYzLng7XG4gIHkgPSBfcmVmMy55O1xuICB2YXIgaGFzWCA9IG9mZnNldHMuaGFzT3duUHJvcGVydHkoJ3gnKTtcbiAgdmFyIGhhc1kgPSBvZmZzZXRzLmhhc093blByb3BlcnR5KCd5Jyk7XG4gIHZhciBzaWRlWCA9IGxlZnQ7XG4gIHZhciBzaWRlWSA9IHRvcDtcbiAgdmFyIHdpbiA9IHdpbmRvdztcblxuICBpZiAoYWRhcHRpdmUpIHtcbiAgICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KHBvcHBlcik7XG4gICAgdmFyIGhlaWdodFByb3AgPSAnY2xpZW50SGVpZ2h0JztcbiAgICB2YXIgd2lkdGhQcm9wID0gJ2NsaWVudFdpZHRoJztcblxuICAgIGlmIChvZmZzZXRQYXJlbnQgPT09IGdldFdpbmRvdyhwb3BwZXIpKSB7XG4gICAgICBvZmZzZXRQYXJlbnQgPSBnZXREb2N1bWVudEVsZW1lbnQocG9wcGVyKTtcblxuICAgICAgaWYgKGdldENvbXB1dGVkU3R5bGUob2Zmc2V0UGFyZW50KS5wb3NpdGlvbiAhPT0gJ3N0YXRpYycgJiYgcG9zaXRpb24gPT09ICdhYnNvbHV0ZScpIHtcbiAgICAgICAgaGVpZ2h0UHJvcCA9ICdzY3JvbGxIZWlnaHQnO1xuICAgICAgICB3aWR0aFByb3AgPSAnc2Nyb2xsV2lkdGgnO1xuICAgICAgfVxuICAgIH0gLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FzdF06IGZvcmNlIHR5cGUgcmVmaW5lbWVudCwgd2UgY29tcGFyZSBvZmZzZXRQYXJlbnQgd2l0aCB3aW5kb3cgYWJvdmUsIGJ1dCBGbG93IGRvZXNuJ3QgZGV0ZWN0IGl0XG5cblxuICAgIG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudDtcblxuICAgIGlmIChwbGFjZW1lbnQgPT09IHRvcCB8fCAocGxhY2VtZW50ID09PSBsZWZ0IHx8IHBsYWNlbWVudCA9PT0gcmlnaHQpICYmIHZhcmlhdGlvbiA9PT0gZW5kKSB7XG4gICAgICBzaWRlWSA9IGJvdHRvbTtcbiAgICAgIHZhciBvZmZzZXRZID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQuaGVpZ2h0IDogLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgICBvZmZzZXRQYXJlbnRbaGVpZ2h0UHJvcF07XG4gICAgICB5IC09IG9mZnNldFkgLSBwb3BwZXJSZWN0LmhlaWdodDtcbiAgICAgIHkgKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cblxuICAgIGlmIChwbGFjZW1lbnQgPT09IGxlZnQgfHwgKHBsYWNlbWVudCA9PT0gdG9wIHx8IHBsYWNlbWVudCA9PT0gYm90dG9tKSAmJiB2YXJpYXRpb24gPT09IGVuZCkge1xuICAgICAgc2lkZVggPSByaWdodDtcbiAgICAgIHZhciBvZmZzZXRYID0gaXNGaXhlZCAmJiBvZmZzZXRQYXJlbnQgPT09IHdpbiAmJiB3aW4udmlzdWFsVmlld3BvcnQgPyB3aW4udmlzdWFsVmlld3BvcnQud2lkdGggOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgIG9mZnNldFBhcmVudFt3aWR0aFByb3BdO1xuICAgICAgeCAtPSBvZmZzZXRYIC0gcG9wcGVyUmVjdC53aWR0aDtcbiAgICAgIHggKj0gZ3B1QWNjZWxlcmF0aW9uID8gMSA6IC0xO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjb21tb25TdHlsZXMgPSBPYmplY3QuYXNzaWduKHtcbiAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgfSwgYWRhcHRpdmUgJiYgdW5zZXRTaWRlcyk7XG5cbiAgdmFyIF9yZWY0ID0gcm91bmRPZmZzZXRzID09PSB0cnVlID8gcm91bmRPZmZzZXRzQnlEUFIoe1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9LCBnZXRXaW5kb3cocG9wcGVyKSkgOiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG5cbiAgeCA9IF9yZWY0Lng7XG4gIHkgPSBfcmVmNC55O1xuXG4gIGlmIChncHVBY2NlbGVyYXRpb24pIHtcbiAgICB2YXIgX09iamVjdCRhc3NpZ247XG5cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCAoX09iamVjdCRhc3NpZ24gPSB7fSwgX09iamVjdCRhc3NpZ25bc2lkZVldID0gaGFzWSA/ICcwJyA6ICcnLCBfT2JqZWN0JGFzc2lnbltzaWRlWF0gPSBoYXNYID8gJzAnIDogJycsIF9PYmplY3QkYXNzaWduLnRyYW5zZm9ybSA9ICh3aW4uZGV2aWNlUGl4ZWxSYXRpbyB8fCAxKSA8PSAxID8gXCJ0cmFuc2xhdGUoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweClcIiA6IFwidHJhbnNsYXRlM2QoXCIgKyB4ICsgXCJweCwgXCIgKyB5ICsgXCJweCwgMClcIiwgX09iamVjdCRhc3NpZ24pKTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIChfT2JqZWN0JGFzc2lnbjIgPSB7fSwgX09iamVjdCRhc3NpZ24yW3NpZGVZXSA9IGhhc1kgPyB5ICsgXCJweFwiIDogJycsIF9PYmplY3QkYXNzaWduMltzaWRlWF0gPSBoYXNYID8geCArIFwicHhcIiA6ICcnLCBfT2JqZWN0JGFzc2lnbjIudHJhbnNmb3JtID0gJycsIF9PYmplY3QkYXNzaWduMikpO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlU3R5bGVzKF9yZWY1KSB7XG4gIHZhciBzdGF0ZSA9IF9yZWY1LnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWY1Lm9wdGlvbnM7XG4gIHZhciBfb3B0aW9ucyRncHVBY2NlbGVyYXQgPSBvcHRpb25zLmdwdUFjY2VsZXJhdGlvbixcbiAgICAgIGdwdUFjY2VsZXJhdGlvbiA9IF9vcHRpb25zJGdwdUFjY2VsZXJhdCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGdwdUFjY2VsZXJhdCxcbiAgICAgIF9vcHRpb25zJGFkYXB0aXZlID0gb3B0aW9ucy5hZGFwdGl2ZSxcbiAgICAgIGFkYXB0aXZlID0gX29wdGlvbnMkYWRhcHRpdmUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRhZGFwdGl2ZSxcbiAgICAgIF9vcHRpb25zJHJvdW5kT2Zmc2V0cyA9IG9wdGlvbnMucm91bmRPZmZzZXRzLFxuICAgICAgcm91bmRPZmZzZXRzID0gX29wdGlvbnMkcm91bmRPZmZzZXRzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkcm91bmRPZmZzZXRzO1xuICB2YXIgY29tbW9uU3R5bGVzID0ge1xuICAgIHBsYWNlbWVudDogZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpLFxuICAgIHZhcmlhdGlvbjogZ2V0VmFyaWF0aW9uKHN0YXRlLnBsYWNlbWVudCksXG4gICAgcG9wcGVyOiBzdGF0ZS5lbGVtZW50cy5wb3BwZXIsXG4gICAgcG9wcGVyUmVjdDogc3RhdGUucmVjdHMucG9wcGVyLFxuICAgIGdwdUFjY2VsZXJhdGlvbjogZ3B1QWNjZWxlcmF0aW9uLFxuICAgIGlzRml4ZWQ6IHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3kgPT09ICdmaXhlZCdcbiAgfTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuc3R5bGVzLnBvcHBlciwgbWFwVG9TdHlsZXMoT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCB7XG4gICAgICBvZmZzZXRzOiBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMsXG4gICAgICBwb3NpdGlvbjogc3RhdGUub3B0aW9ucy5zdHJhdGVneSxcbiAgICAgIGFkYXB0aXZlOiBhZGFwdGl2ZSxcbiAgICAgIHJvdW5kT2Zmc2V0czogcm91bmRPZmZzZXRzXG4gICAgfSkpKTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLmFycm93ICE9IG51bGwpIHtcbiAgICBzdGF0ZS5zdHlsZXMuYXJyb3cgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5zdHlsZXMuYXJyb3csIG1hcFRvU3R5bGVzKE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywge1xuICAgICAgb2Zmc2V0czogc3RhdGUubW9kaWZpZXJzRGF0YS5hcnJvdyxcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgYWRhcHRpdmU6IGZhbHNlLFxuICAgICAgcm91bmRPZmZzZXRzOiByb3VuZE9mZnNldHNcbiAgICB9KSkpO1xuICB9XG5cbiAgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5hdHRyaWJ1dGVzLnBvcHBlciwge1xuICAgICdkYXRhLXBvcHBlci1wbGFjZW1lbnQnOiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSk7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdjb21wdXRlU3R5bGVzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdiZWZvcmVXcml0ZScsXG4gIGZuOiBjb21wdXRlU3R5bGVzLFxuICBkYXRhOiB7fVxufTsiLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldFdpbmRvdy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciBwYXNzaXZlID0ge1xuICBwYXNzaXZlOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBlZmZlY3QoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgaW5zdGFuY2UgPSBfcmVmLmluc3RhbmNlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJHNjcm9sbCA9IG9wdGlvbnMuc2Nyb2xsLFxuICAgICAgc2Nyb2xsID0gX29wdGlvbnMkc2Nyb2xsID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc2Nyb2xsLFxuICAgICAgX29wdGlvbnMkcmVzaXplID0gb3B0aW9ucy5yZXNpemUsXG4gICAgICByZXNpemUgPSBfb3B0aW9ucyRyZXNpemUgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRyZXNpemU7XG4gIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coc3RhdGUuZWxlbWVudHMucG9wcGVyKTtcbiAgdmFyIHNjcm9sbFBhcmVudHMgPSBbXS5jb25jYXQoc3RhdGUuc2Nyb2xsUGFyZW50cy5yZWZlcmVuY2UsIHN0YXRlLnNjcm9sbFBhcmVudHMucG9wcGVyKTtcblxuICBpZiAoc2Nyb2xsKSB7XG4gICAgc2Nyb2xsUGFyZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzY3JvbGxQYXJlbnQpIHtcbiAgICAgIHNjcm9sbFBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJlc2l6ZSkge1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2Nyb2xsKSB7XG4gICAgICBzY3JvbGxQYXJlbnRzLmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbFBhcmVudCkge1xuICAgICAgICBzY3JvbGxQYXJlbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChyZXNpemUpIHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBpbnN0YW5jZS51cGRhdGUsIHBhc3NpdmUpO1xuICAgIH1cbiAgfTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2V2ZW50TGlzdGVuZXJzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICd3cml0ZScsXG4gIGZuOiBmdW5jdGlvbiBmbigpIHt9LFxuICBlZmZlY3Q6IGVmZmVjdCxcbiAgZGF0YToge31cbn07IiwgInZhciBoYXNoID0ge1xuICBsZWZ0OiAncmlnaHQnLFxuICByaWdodDogJ2xlZnQnLFxuICBib3R0b206ICd0b3AnLFxuICB0b3A6ICdib3R0b20nXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvbGVmdHxyaWdodHxib3R0b218dG9wL2csIGZ1bmN0aW9uIChtYXRjaGVkKSB7XG4gICAgcmV0dXJuIGhhc2hbbWF0Y2hlZF07XG4gIH0pO1xufSIsICJ2YXIgaGFzaCA9IHtcbiAgc3RhcnQ6ICdlbmQnLFxuICBlbmQ6ICdzdGFydCdcbn07XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5yZXBsYWNlKC9zdGFydHxlbmQvZywgZnVuY3Rpb24gKG1hdGNoZWQpIHtcbiAgICByZXR1cm4gaGFzaFttYXRjaGVkXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4vZ2V0V2luZG93LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRXaW5kb3dTY3JvbGwobm9kZSkge1xuICB2YXIgd2luID0gZ2V0V2luZG93KG5vZGUpO1xuICB2YXIgc2Nyb2xsTGVmdCA9IHdpbi5wYWdlWE9mZnNldDtcbiAgdmFyIHNjcm9sbFRvcCA9IHdpbi5wYWdlWU9mZnNldDtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBzY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogc2Nyb2xsVG9wXG4gIH07XG59IiwgImltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCkge1xuICAvLyBJZiA8aHRtbD4gaGFzIGEgQ1NTIHdpZHRoIGdyZWF0ZXIgdGhhbiB0aGUgdmlld3BvcnQsIHRoZW4gdGhpcyB3aWxsIGJlXG4gIC8vIGluY29ycmVjdCBmb3IgUlRMLlxuICAvLyBQb3BwZXIgMSBpcyBicm9rZW4gaW4gdGhpcyBjYXNlIGFuZCBuZXZlciBoYWQgYSBidWcgcmVwb3J0IHNvIGxldCdzIGFzc3VtZVxuICAvLyBpdCdzIG5vdCBhbiBpc3N1ZS4gSSBkb24ndCB0aGluayBhbnlvbmUgZXZlciBzcGVjaWZpZXMgd2lkdGggb24gPGh0bWw+XG4gIC8vIGFueXdheS5cbiAgLy8gQnJvd3NlcnMgd2hlcmUgdGhlIGxlZnQgc2Nyb2xsYmFyIGRvZXNuJ3QgY2F1c2UgYW4gaXNzdWUgcmVwb3J0IGAwYCBmb3JcbiAgLy8gdGhpcyAoZS5nLiBFZGdlIDIwMTksIElFMTEsIFNhZmFyaSlcbiAgcmV0dXJuIGdldEJvdW5kaW5nQ2xpZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpLmxlZnQgKyBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCkuc2Nyb2xsTGVmdDtcbn0iLCAiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93U2Nyb2xsQmFyWCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzXCI7XG5pbXBvcnQgaXNMYXlvdXRWaWV3cG9ydCBmcm9tIFwiLi9pc0xheW91dFZpZXdwb3J0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpIHtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhlbGVtZW50KTtcbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB2aXN1YWxWaWV3cG9ydCA9IHdpbi52aXN1YWxWaWV3cG9ydDtcbiAgdmFyIHdpZHRoID0gaHRtbC5jbGllbnRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IGh0bWwuY2xpZW50SGVpZ2h0O1xuICB2YXIgeCA9IDA7XG4gIHZhciB5ID0gMDtcblxuICBpZiAodmlzdWFsVmlld3BvcnQpIHtcbiAgICB3aWR0aCA9IHZpc3VhbFZpZXdwb3J0LndpZHRoO1xuICAgIGhlaWdodCA9IHZpc3VhbFZpZXdwb3J0LmhlaWdodDtcbiAgICB2YXIgbGF5b3V0Vmlld3BvcnQgPSBpc0xheW91dFZpZXdwb3J0KCk7XG5cbiAgICBpZiAobGF5b3V0Vmlld3BvcnQgfHwgIWxheW91dFZpZXdwb3J0ICYmIHN0cmF0ZWd5ID09PSAnZml4ZWQnKSB7XG4gICAgICB4ID0gdmlzdWFsVmlld3BvcnQub2Zmc2V0TGVmdDtcbiAgICAgIHkgPSB2aXN1YWxWaWV3cG9ydC5vZmZzZXRUb3A7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgeDogeCArIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCksXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldENvbXB1dGVkU3R5bGUgZnJvbSBcIi4vZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmltcG9ydCB7IG1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7IC8vIEdldHMgdGhlIGVudGlyZSBzaXplIG9mIHRoZSBzY3JvbGxhYmxlIGRvY3VtZW50IGFyZWEsIGV2ZW4gZXh0ZW5kaW5nIG91dHNpZGVcbi8vIG9mIHRoZSBgPGh0bWw+YCBhbmQgYDxib2R5PmAgcmVjdCBib3VuZHMgaWYgaG9yaXpvbnRhbGx5IHNjcm9sbGFibGVcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0RG9jdW1lbnRSZWN0KGVsZW1lbnQpIHtcbiAgdmFyIF9lbGVtZW50JG93bmVyRG9jdW1lbjtcblxuICB2YXIgaHRtbCA9IGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KTtcbiAgdmFyIHdpblNjcm9sbCA9IGdldFdpbmRvd1Njcm9sbChlbGVtZW50KTtcbiAgdmFyIGJvZHkgPSAoX2VsZW1lbnQkb3duZXJEb2N1bWVuID0gZWxlbWVudC5vd25lckRvY3VtZW50KSA9PSBudWxsID8gdm9pZCAwIDogX2VsZW1lbnQkb3duZXJEb2N1bWVuLmJvZHk7XG4gIHZhciB3aWR0aCA9IG1heChodG1sLnNjcm9sbFdpZHRoLCBodG1sLmNsaWVudFdpZHRoLCBib2R5ID8gYm9keS5zY3JvbGxXaWR0aCA6IDAsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCk7XG4gIHZhciBoZWlnaHQgPSBtYXgoaHRtbC5zY3JvbGxIZWlnaHQsIGh0bWwuY2xpZW50SGVpZ2h0LCBib2R5ID8gYm9keS5zY3JvbGxIZWlnaHQgOiAwLCBib2R5ID8gYm9keS5jbGllbnRIZWlnaHQgOiAwKTtcbiAgdmFyIHggPSAtd2luU2Nyb2xsLnNjcm9sbExlZnQgKyBnZXRXaW5kb3dTY3JvbGxCYXJYKGVsZW1lbnQpO1xuICB2YXIgeSA9IC13aW5TY3JvbGwuc2Nyb2xsVG9wO1xuXG4gIGlmIChnZXRDb21wdXRlZFN0eWxlKGJvZHkgfHwgaHRtbCkuZGlyZWN0aW9uID09PSAncnRsJykge1xuICAgIHggKz0gbWF4KGh0bWwuY2xpZW50V2lkdGgsIGJvZHkgPyBib2R5LmNsaWVudFdpZHRoIDogMCkgLSB3aWR0aDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHdpZHRoLFxuICAgIGhlaWdodDogaGVpZ2h0LFxuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufSIsICJpbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1Njcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIC8vIEZpcmVmb3ggd2FudHMgdXMgdG8gY2hlY2sgYC14YCBhbmQgYC15YCB2YXJpYXRpb25zIGFzIHdlbGxcbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcbiAgICAgIG92ZXJmbG93ID0gX2dldENvbXB1dGVkU3R5bGUub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1gsXG4gICAgICBvdmVyZmxvd1kgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1k7XG5cbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbi8udGVzdChvdmVyZmxvdyArIG92ZXJmbG93WSArIG92ZXJmbG93WCk7XG59IiwgImltcG9ydCBnZXRQYXJlbnROb2RlIGZyb20gXCIuL2dldFBhcmVudE5vZGUuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0U2Nyb2xsUGFyZW50KG5vZGUpIHtcbiAgaWYgKFsnaHRtbCcsICdib2R5JywgJyNkb2N1bWVudCddLmluZGV4T2YoZ2V0Tm9kZU5hbWUobm9kZSkpID49IDApIHtcbiAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gICAgcmV0dXJuIG5vZGUub3duZXJEb2N1bWVudC5ib2R5O1xuICB9XG5cbiAgaWYgKGlzSFRNTEVsZW1lbnQobm9kZSkgJiYgaXNTY3JvbGxQYXJlbnQobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHJldHVybiBnZXRTY3JvbGxQYXJlbnQoZ2V0UGFyZW50Tm9kZShub2RlKSk7XG59IiwgImltcG9ydCBnZXRTY3JvbGxQYXJlbnQgZnJvbSBcIi4vZ2V0U2Nyb2xsUGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0UGFyZW50Tm9kZSBmcm9tIFwiLi9nZXRQYXJlbnROb2RlLmpzXCI7XG5pbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGlzU2Nyb2xsUGFyZW50IGZyb20gXCIuL2lzU2Nyb2xsUGFyZW50LmpzXCI7XG4vKlxuZ2l2ZW4gYSBET00gZWxlbWVudCwgcmV0dXJuIHRoZSBsaXN0IG9mIGFsbCBzY3JvbGwgcGFyZW50cywgdXAgdGhlIGxpc3Qgb2YgYW5jZXNvcnNcbnVudGlsIHdlIGdldCB0byB0aGUgdG9wIHdpbmRvdyBvYmplY3QuIFRoaXMgbGlzdCBpcyB3aGF0IHdlIGF0dGFjaCBzY3JvbGwgbGlzdGVuZXJzXG50bywgYmVjYXVzZSBpZiBhbnkgb2YgdGhlc2UgcGFyZW50IGVsZW1lbnRzIHNjcm9sbCwgd2UnbGwgbmVlZCB0byByZS1jYWxjdWxhdGUgdGhlXG5yZWZlcmVuY2UgZWxlbWVudCdzIHBvc2l0aW9uLlxuKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGlzdFNjcm9sbFBhcmVudHMoZWxlbWVudCwgbGlzdCkge1xuICB2YXIgX2VsZW1lbnQkb3duZXJEb2N1bWVuO1xuXG4gIGlmIChsaXN0ID09PSB2b2lkIDApIHtcbiAgICBsaXN0ID0gW107XG4gIH1cblxuICB2YXIgc2Nyb2xsUGFyZW50ID0gZ2V0U2Nyb2xsUGFyZW50KGVsZW1lbnQpO1xuICB2YXIgaXNCb2R5ID0gc2Nyb2xsUGFyZW50ID09PSAoKF9lbGVtZW50JG93bmVyRG9jdW1lbiA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50JG93bmVyRG9jdW1lbi5ib2R5KTtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhzY3JvbGxQYXJlbnQpO1xuICB2YXIgdGFyZ2V0ID0gaXNCb2R5ID8gW3dpbl0uY29uY2F0KHdpbi52aXN1YWxWaWV3cG9ydCB8fCBbXSwgaXNTY3JvbGxQYXJlbnQoc2Nyb2xsUGFyZW50KSA/IHNjcm9sbFBhcmVudCA6IFtdKSA6IHNjcm9sbFBhcmVudDtcbiAgdmFyIHVwZGF0ZWRMaXN0ID0gbGlzdC5jb25jYXQodGFyZ2V0KTtcbiAgcmV0dXJuIGlzQm9keSA/IHVwZGF0ZWRMaXN0IDogLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtY2FsbF06IGlzQm9keSB0ZWxscyB1cyB0YXJnZXQgd2lsbCBiZSBhbiBIVE1MRWxlbWVudCBoZXJlXG4gIHVwZGF0ZWRMaXN0LmNvbmNhdChsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKHRhcmdldCkpKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZWN0LCB7XG4gICAgbGVmdDogcmVjdC54LFxuICAgIHRvcDogcmVjdC55LFxuICAgIHJpZ2h0OiByZWN0LnggKyByZWN0LndpZHRoLFxuICAgIGJvdHRvbTogcmVjdC55ICsgcmVjdC5oZWlnaHRcbiAgfSk7XG59IiwgImltcG9ydCB7IHZpZXdwb3J0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0Vmlld3BvcnRSZWN0IGZyb20gXCIuL2dldFZpZXdwb3J0UmVjdC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50UmVjdCBmcm9tIFwiLi9nZXREb2N1bWVudFJlY3QuanNcIjtcbmltcG9ydCBsaXN0U2Nyb2xsUGFyZW50cyBmcm9tIFwiLi9saXN0U2Nyb2xsUGFyZW50cy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5pbXBvcnQgeyBpc0VsZW1lbnQsIGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuL2NvbnRhaW5zLmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCByZWN0VG9DbGllbnRSZWN0IGZyb20gXCIuLi91dGlscy9yZWN0VG9DbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgeyBtYXgsIG1pbiB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIGdldElubmVyQm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIHN0cmF0ZWd5KSB7XG4gIHZhciByZWN0ID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQsIGZhbHNlLCBzdHJhdGVneSA9PT0gJ2ZpeGVkJyk7XG4gIHJlY3QudG9wID0gcmVjdC50b3AgKyBlbGVtZW50LmNsaWVudFRvcDtcbiAgcmVjdC5sZWZ0ID0gcmVjdC5sZWZ0ICsgZWxlbWVudC5jbGllbnRMZWZ0O1xuICByZWN0LmJvdHRvbSA9IHJlY3QudG9wICsgZWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gIHJlY3QucmlnaHQgPSByZWN0LmxlZnQgKyBlbGVtZW50LmNsaWVudFdpZHRoO1xuICByZWN0LndpZHRoID0gZWxlbWVudC5jbGllbnRXaWR0aDtcbiAgcmVjdC5oZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgcmVjdC54ID0gcmVjdC5sZWZ0O1xuICByZWN0LnkgPSByZWN0LnRvcDtcbiAgcmV0dXJuIHJlY3Q7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGNsaXBwaW5nUGFyZW50LCBzdHJhdGVneSkge1xuICByZXR1cm4gY2xpcHBpbmdQYXJlbnQgPT09IHZpZXdwb3J0ID8gcmVjdFRvQ2xpZW50UmVjdChnZXRWaWV3cG9ydFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpKSA6IGlzRWxlbWVudChjbGlwcGluZ1BhcmVudCkgPyBnZXRJbm5lckJvdW5kaW5nQ2xpZW50UmVjdChjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpIDogcmVjdFRvQ2xpZW50UmVjdChnZXREb2N1bWVudFJlY3QoZ2V0RG9jdW1lbnRFbGVtZW50KGVsZW1lbnQpKSk7XG59IC8vIEEgXCJjbGlwcGluZyBwYXJlbnRcIiBpcyBhbiBvdmVyZmxvd2FibGUgY29udGFpbmVyIHdpdGggdGhlIGNoYXJhY3RlcmlzdGljIG9mXG4vLyBjbGlwcGluZyAob3IgaGlkaW5nKSBvdmVyZmxvd2luZyBlbGVtZW50cyB3aXRoIGEgcG9zaXRpb24gZGlmZmVyZW50IGZyb21cbi8vIGBpbml0aWFsYFxuXG5cbmZ1bmN0aW9uIGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSB7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBsaXN0U2Nyb2xsUGFyZW50cyhnZXRQYXJlbnROb2RlKGVsZW1lbnQpKTtcbiAgdmFyIGNhbkVzY2FwZUNsaXBwaW5nID0gWydhYnNvbHV0ZScsICdmaXhlZCddLmluZGV4T2YoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbikgPj0gMDtcbiAgdmFyIGNsaXBwZXJFbGVtZW50ID0gY2FuRXNjYXBlQ2xpcHBpbmcgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSA/IGdldE9mZnNldFBhcmVudChlbGVtZW50KSA6IGVsZW1lbnQ7XG5cbiAgaWYgKCFpc0VsZW1lbnQoY2xpcHBlckVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXJldHVybl06IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8xNDE0XG5cblxuICByZXR1cm4gY2xpcHBpbmdQYXJlbnRzLmZpbHRlcihmdW5jdGlvbiAoY2xpcHBpbmdQYXJlbnQpIHtcbiAgICByZXR1cm4gaXNFbGVtZW50KGNsaXBwaW5nUGFyZW50KSAmJiBjb250YWlucyhjbGlwcGluZ1BhcmVudCwgY2xpcHBlckVsZW1lbnQpICYmIGdldE5vZGVOYW1lKGNsaXBwaW5nUGFyZW50KSAhPT0gJ2JvZHknO1xuICB9KTtcbn0gLy8gR2V0cyB0aGUgbWF4aW11bSBhcmVhIHRoYXQgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSBpbiBkdWUgdG8gYW55IG51bWJlciBvZlxuLy8gY2xpcHBpbmcgcGFyZW50c1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENsaXBwaW5nUmVjdChlbGVtZW50LCBib3VuZGFyeSwgcm9vdEJvdW5kYXJ5LCBzdHJhdGVneSkge1xuICB2YXIgbWFpbkNsaXBwaW5nUGFyZW50cyA9IGJvdW5kYXJ5ID09PSAnY2xpcHBpbmdQYXJlbnRzJyA/IGdldENsaXBwaW5nUGFyZW50cyhlbGVtZW50KSA6IFtdLmNvbmNhdChib3VuZGFyeSk7XG4gIHZhciBjbGlwcGluZ1BhcmVudHMgPSBbXS5jb25jYXQobWFpbkNsaXBwaW5nUGFyZW50cywgW3Jvb3RCb3VuZGFyeV0pO1xuICB2YXIgZmlyc3RDbGlwcGluZ1BhcmVudCA9IGNsaXBwaW5nUGFyZW50c1swXTtcbiAgdmFyIGNsaXBwaW5nUmVjdCA9IGNsaXBwaW5nUGFyZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjY1JlY3QsIGNsaXBwaW5nUGFyZW50KSB7XG4gICAgdmFyIHJlY3QgPSBnZXRDbGllbnRSZWN0RnJvbU1peGVkVHlwZShlbGVtZW50LCBjbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpO1xuICAgIGFjY1JlY3QudG9wID0gbWF4KHJlY3QudG9wLCBhY2NSZWN0LnRvcCk7XG4gICAgYWNjUmVjdC5yaWdodCA9IG1pbihyZWN0LnJpZ2h0LCBhY2NSZWN0LnJpZ2h0KTtcbiAgICBhY2NSZWN0LmJvdHRvbSA9IG1pbihyZWN0LmJvdHRvbSwgYWNjUmVjdC5ib3R0b20pO1xuICAgIGFjY1JlY3QubGVmdCA9IG1heChyZWN0LmxlZnQsIGFjY1JlY3QubGVmdCk7XG4gICAgcmV0dXJuIGFjY1JlY3Q7XG4gIH0sIGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGZpcnN0Q2xpcHBpbmdQYXJlbnQsIHN0cmF0ZWd5KSk7XG4gIGNsaXBwaW5nUmVjdC53aWR0aCA9IGNsaXBwaW5nUmVjdC5yaWdodCAtIGNsaXBwaW5nUmVjdC5sZWZ0O1xuICBjbGlwcGluZ1JlY3QuaGVpZ2h0ID0gY2xpcHBpbmdSZWN0LmJvdHRvbSAtIGNsaXBwaW5nUmVjdC50b3A7XG4gIGNsaXBwaW5nUmVjdC54ID0gY2xpcHBpbmdSZWN0LmxlZnQ7XG4gIGNsaXBwaW5nUmVjdC55ID0gY2xpcHBpbmdSZWN0LnRvcDtcbiAgcmV0dXJuIGNsaXBwaW5nUmVjdDtcbn0iLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQgZnJvbSBcIi4vZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQsIHN0YXJ0LCBlbmQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbXB1dGVPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHJlZmVyZW5jZSA9IF9yZWYucmVmZXJlbmNlLFxuICAgICAgZWxlbWVudCA9IF9yZWYuZWxlbWVudCxcbiAgICAgIHBsYWNlbWVudCA9IF9yZWYucGxhY2VtZW50O1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IHBsYWNlbWVudCA/IGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciB2YXJpYXRpb24gPSBwbGFjZW1lbnQgPyBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA6IG51bGw7XG4gIHZhciBjb21tb25YID0gcmVmZXJlbmNlLnggKyByZWZlcmVuY2Uud2lkdGggLyAyIC0gZWxlbWVudC53aWR0aCAvIDI7XG4gIHZhciBjb21tb25ZID0gcmVmZXJlbmNlLnkgKyByZWZlcmVuY2UuaGVpZ2h0IC8gMiAtIGVsZW1lbnQuaGVpZ2h0IC8gMjtcbiAgdmFyIG9mZnNldHM7XG5cbiAgc3dpdGNoIChiYXNlUGxhY2VtZW50KSB7XG4gICAgY2FzZSB0b3A6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiBjb21tb25YLFxuICAgICAgICB5OiByZWZlcmVuY2UueSAtIGVsZW1lbnQuaGVpZ2h0XG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGJvdHRvbTpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IGNvbW1vblgsXG4gICAgICAgIHk6IHJlZmVyZW5jZS55ICsgcmVmZXJlbmNlLmhlaWdodFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSByaWdodDpcbiAgICAgIG9mZnNldHMgPSB7XG4gICAgICAgIHg6IHJlZmVyZW5jZS54ICsgcmVmZXJlbmNlLndpZHRoLFxuICAgICAgICB5OiBjb21tb25ZXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIGxlZnQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCAtIGVsZW1lbnQud2lkdGgsXG4gICAgICAgIHk6IGNvbW1vbllcbiAgICAgIH07XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCxcbiAgICAgICAgeTogcmVmZXJlbmNlLnlcbiAgICAgIH07XG4gIH1cblxuICB2YXIgbWFpbkF4aXMgPSBiYXNlUGxhY2VtZW50ID8gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpIDogbnVsbDtcblxuICBpZiAobWFpbkF4aXMgIT0gbnVsbCkge1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuXG4gICAgc3dpdGNoICh2YXJpYXRpb24pIHtcbiAgICAgIGNhc2Ugc3RhcnQ6XG4gICAgICAgIG9mZnNldHNbbWFpbkF4aXNdID0gb2Zmc2V0c1ttYWluQXhpc10gLSAocmVmZXJlbmNlW2xlbl0gLyAyIC0gZWxlbWVudFtsZW5dIC8gMik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIGVuZDpcbiAgICAgICAgb2Zmc2V0c1ttYWluQXhpc10gPSBvZmZzZXRzW21haW5BeGlzXSArIChyZWZlcmVuY2VbbGVuXSAvIDIgLSBlbGVtZW50W2xlbl0gLyAyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9mZnNldHM7XG59IiwgImltcG9ydCBnZXRDbGlwcGluZ1JlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4vcmVjdFRvQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IHsgY2xpcHBpbmdQYXJlbnRzLCByZWZlcmVuY2UsIHBvcHBlciwgYm90dG9tLCB0b3AsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4vZXhwYW5kVG9IYXNoTWFwLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBfb3B0aW9ucyRwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/IHN0YXRlLnBsYWNlbWVudCA6IF9vcHRpb25zJHBsYWNlbWVudCxcbiAgICAgIF9vcHRpb25zJHN0cmF0ZWd5ID0gX29wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBzdHJhdGVneSA9IF9vcHRpb25zJHN0cmF0ZWd5ID09PSB2b2lkIDAgPyBzdGF0ZS5zdHJhdGVneSA6IF9vcHRpb25zJHN0cmF0ZWd5LFxuICAgICAgX29wdGlvbnMkYm91bmRhcnkgPSBfb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMkYm91bmRhcnkgPT09IHZvaWQgMCA/IGNsaXBwaW5nUGFyZW50cyA6IF9vcHRpb25zJGJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyB2aWV3cG9ydCA6IF9vcHRpb25zJHJvb3RCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGVsZW1lbnRDb250ZSA9IF9vcHRpb25zLmVsZW1lbnRDb250ZXh0LFxuICAgICAgZWxlbWVudENvbnRleHQgPSBfb3B0aW9ucyRlbGVtZW50Q29udGUgPT09IHZvaWQgMCA/IHBvcHBlciA6IF9vcHRpb25zJGVsZW1lbnRDb250ZSxcbiAgICAgIF9vcHRpb25zJGFsdEJvdW5kYXJ5ID0gX29wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IF9vcHRpb25zJGFsdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyBmYWxzZSA6IF9vcHRpb25zJGFsdEJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMkcGFkZGluZyA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHBhZGRpbmc7XG4gIHZhciBwYWRkaW5nT2JqZWN0ID0gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbiAgdmFyIGFsdENvbnRleHQgPSBlbGVtZW50Q29udGV4dCA9PT0gcG9wcGVyID8gcmVmZXJlbmNlIDogcG9wcGVyO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGVsZW1lbnQgPSBzdGF0ZS5lbGVtZW50c1thbHRCb3VuZGFyeSA/IGFsdENvbnRleHQgOiBlbGVtZW50Q29udGV4dF07XG4gIHZhciBjbGlwcGluZ0NsaWVudFJlY3QgPSBnZXRDbGlwcGluZ1JlY3QoaXNFbGVtZW50KGVsZW1lbnQpID8gZWxlbWVudCA6IGVsZW1lbnQuY29udGV4dEVsZW1lbnQgfHwgZ2V0RG9jdW1lbnRFbGVtZW50KHN0YXRlLmVsZW1lbnRzLnBvcHBlciksIGJvdW5kYXJ5LCByb290Qm91bmRhcnksIHN0cmF0ZWd5KTtcbiAgdmFyIHJlZmVyZW5jZUNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qoc3RhdGUuZWxlbWVudHMucmVmZXJlbmNlKTtcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyh7XG4gICAgcmVmZXJlbmNlOiByZWZlcmVuY2VDbGllbnRSZWN0LFxuICAgIGVsZW1lbnQ6IHBvcHBlclJlY3QsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSk7XG4gIHZhciBwb3BwZXJDbGllbnRSZWN0ID0gcmVjdFRvQ2xpZW50UmVjdChPYmplY3QuYXNzaWduKHt9LCBwb3BwZXJSZWN0LCBwb3BwZXJPZmZzZXRzKSk7XG4gIHZhciBlbGVtZW50Q2xpZW50UmVjdCA9IGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgPyBwb3BwZXJDbGllbnRSZWN0IDogcmVmZXJlbmNlQ2xpZW50UmVjdDsgLy8gcG9zaXRpdmUgPSBvdmVyZmxvd2luZyB0aGUgY2xpcHBpbmcgcmVjdFxuICAvLyAwIG9yIG5lZ2F0aXZlID0gd2l0aGluIHRoZSBjbGlwcGluZyByZWN0XG5cbiAgdmFyIG92ZXJmbG93T2Zmc2V0cyA9IHtcbiAgICB0b3A6IGNsaXBwaW5nQ2xpZW50UmVjdC50b3AgLSBlbGVtZW50Q2xpZW50UmVjdC50b3AgKyBwYWRkaW5nT2JqZWN0LnRvcCxcbiAgICBib3R0b206IGVsZW1lbnRDbGllbnRSZWN0LmJvdHRvbSAtIGNsaXBwaW5nQ2xpZW50UmVjdC5ib3R0b20gKyBwYWRkaW5nT2JqZWN0LmJvdHRvbSxcbiAgICBsZWZ0OiBjbGlwcGluZ0NsaWVudFJlY3QubGVmdCAtIGVsZW1lbnRDbGllbnRSZWN0LmxlZnQgKyBwYWRkaW5nT2JqZWN0LmxlZnQsXG4gICAgcmlnaHQ6IGVsZW1lbnRDbGllbnRSZWN0LnJpZ2h0IC0gY2xpcHBpbmdDbGllbnRSZWN0LnJpZ2h0ICsgcGFkZGluZ09iamVjdC5yaWdodFxuICB9O1xuICB2YXIgb2Zmc2V0RGF0YSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0OyAvLyBPZmZzZXRzIGNhbiBiZSBhcHBsaWVkIG9ubHkgdG8gdGhlIHBvcHBlciBlbGVtZW50XG5cbiAgaWYgKGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgJiYgb2Zmc2V0RGF0YSkge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXREYXRhW3BsYWNlbWVudF07XG4gICAgT2JqZWN0LmtleXMob3ZlcmZsb3dPZmZzZXRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciBtdWx0aXBseSA9IFtyaWdodCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/IDEgOiAtMTtcbiAgICAgIHZhciBheGlzID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/ICd5JyA6ICd4JztcbiAgICAgIG92ZXJmbG93T2Zmc2V0c1trZXldICs9IG9mZnNldFtheGlzXSAqIG11bHRpcGx5O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG92ZXJmbG93T2Zmc2V0cztcbn0iLCAiaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCB7IHZhcmlhdGlvblBsYWNlbWVudHMsIGJhc2VQbGFjZW1lbnRzLCBwbGFjZW1lbnRzIGFzIGFsbFBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4vZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29tcHV0ZUF1dG9QbGFjZW1lbnQoc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBib3VuZGFyeSA9IF9vcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zLmZsaXBWYXJpYXRpb25zLFxuICAgICAgX29wdGlvbnMkYWxsb3dlZEF1dG9QID0gX29wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzLFxuICAgICAgYWxsb3dlZEF1dG9QbGFjZW1lbnRzID0gX29wdGlvbnMkYWxsb3dlZEF1dG9QID09PSB2b2lkIDAgPyBhbGxQbGFjZW1lbnRzIDogX29wdGlvbnMkYWxsb3dlZEF1dG9QO1xuICB2YXIgdmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCk7XG4gIHZhciBwbGFjZW1lbnRzID0gdmFyaWF0aW9uID8gZmxpcFZhcmlhdGlvbnMgPyB2YXJpYXRpb25QbGFjZW1lbnRzIDogdmFyaWF0aW9uUGxhY2VtZW50cy5maWx0ZXIoZnVuY3Rpb24gKHBsYWNlbWVudCkge1xuICAgIHJldHVybiBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gdmFyaWF0aW9uO1xuICB9KSA6IGJhc2VQbGFjZW1lbnRzO1xuICB2YXIgYWxsb3dlZFBsYWNlbWVudHMgPSBwbGFjZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIGFsbG93ZWRBdXRvUGxhY2VtZW50cy5pbmRleE9mKHBsYWNlbWVudCkgPj0gMDtcbiAgfSk7XG5cbiAgaWYgKGFsbG93ZWRQbGFjZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIGFsbG93ZWRQbGFjZW1lbnRzID0gcGxhY2VtZW50cztcbiAgfSAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS10eXBlXTogRmxvdyBzZWVtcyB0byBoYXZlIHByb2JsZW1zIHdpdGggdHdvIGFycmF5IHVuaW9ucy4uLlxuXG5cbiAgdmFyIG92ZXJmbG93cyA9IGFsbG93ZWRQbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICBhY2NbcGxhY2VtZW50XSA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZ1xuICAgIH0pW2dldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KV07XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICByZXR1cm4gT2JqZWN0LmtleXMob3ZlcmZsb3dzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgcmV0dXJuIG92ZXJmbG93c1thXSAtIG92ZXJmbG93c1tiXTtcbiAgfSk7XG59IiwgImltcG9ydCBnZXRPcHBvc2l0ZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0T3Bwb3NpdGVQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgY29tcHV0ZUF1dG9QbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2NvbXB1dGVBdXRvUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgeyBib3R0b20sIHRvcCwgc3RhcnQsIHJpZ2h0LCBsZWZ0LCBhdXRvIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5mdW5jdGlvbiBnZXRFeHBhbmRlZEZhbGxiYWNrUGxhY2VtZW50cyhwbGFjZW1lbnQpIHtcbiAgaWYgKGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0bykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBvcHBvc2l0ZVBsYWNlbWVudCA9IGdldE9wcG9zaXRlUGxhY2VtZW50KHBsYWNlbWVudCk7XG4gIHJldHVybiBbZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQocGxhY2VtZW50KSwgb3Bwb3NpdGVQbGFjZW1lbnQsIGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KG9wcG9zaXRlUGxhY2VtZW50KV07XG59XG5cbmZ1bmN0aW9uIGZsaXAoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG5cbiAgaWYgKHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0uX3NraXApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgX29wdGlvbnMkbWFpbkF4aXMgPSBvcHRpb25zLm1haW5BeGlzLFxuICAgICAgY2hlY2tNYWluQXhpcyA9IF9vcHRpb25zJG1haW5BeGlzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkbWFpbkF4aXMsXG4gICAgICBfb3B0aW9ucyRhbHRBeGlzID0gb3B0aW9ucy5hbHRBeGlzLFxuICAgICAgY2hlY2tBbHRBeGlzID0gX29wdGlvbnMkYWx0QXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGFsdEF4aXMsXG4gICAgICBzcGVjaWZpZWRGYWxsYmFja1BsYWNlbWVudHMgPSBvcHRpb25zLmZhbGxiYWNrUGxhY2VtZW50cyxcbiAgICAgIHBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmcsXG4gICAgICBib3VuZGFyeSA9IG9wdGlvbnMuYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnkgPSBvcHRpb25zLnJvb3RCb3VuZGFyeSxcbiAgICAgIGFsdEJvdW5kYXJ5ID0gb3B0aW9ucy5hbHRCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9IG9wdGlvbnMuZmxpcFZhcmlhdGlvbnMsXG4gICAgICBmbGlwVmFyaWF0aW9ucyA9IF9vcHRpb25zJGZsaXBWYXJpYXRpbyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGZsaXBWYXJpYXRpbyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50cyA9IG9wdGlvbnMuYWxsb3dlZEF1dG9QbGFjZW1lbnRzO1xuICB2YXIgcHJlZmVycmVkUGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwcmVmZXJyZWRQbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gYmFzZVBsYWNlbWVudCA9PT0gcHJlZmVycmVkUGxhY2VtZW50O1xuICB2YXIgZmFsbGJhY2tQbGFjZW1lbnRzID0gc3BlY2lmaWVkRmFsbGJhY2tQbGFjZW1lbnRzIHx8IChpc0Jhc2VQbGFjZW1lbnQgfHwgIWZsaXBWYXJpYXRpb25zID8gW2dldE9wcG9zaXRlUGxhY2VtZW50KHByZWZlcnJlZFBsYWNlbWVudCldIDogZ2V0RXhwYW5kZWRGYWxsYmFja1BsYWNlbWVudHMocHJlZmVycmVkUGxhY2VtZW50KSk7XG4gIHZhciBwbGFjZW1lbnRzID0gW3ByZWZlcnJlZFBsYWNlbWVudF0uY29uY2F0KGZhbGxiYWNrUGxhY2VtZW50cykucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KSA9PT0gYXV0byA/IGNvbXB1dGVBdXRvUGxhY2VtZW50KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZyxcbiAgICAgIGZsaXBWYXJpYXRpb25zOiBmbGlwVmFyaWF0aW9ucyxcbiAgICAgIGFsbG93ZWRBdXRvUGxhY2VtZW50czogYWxsb3dlZEF1dG9QbGFjZW1lbnRzXG4gICAgfSkgOiBwbGFjZW1lbnQpO1xuICB9LCBbXSk7XG4gIHZhciByZWZlcmVuY2VSZWN0ID0gc3RhdGUucmVjdHMucmVmZXJlbmNlO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGNoZWNrc01hcCA9IG5ldyBNYXAoKTtcbiAgdmFyIG1ha2VGYWxsYmFja0NoZWNrcyA9IHRydWU7XG4gIHZhciBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBwbGFjZW1lbnRzWzBdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcGxhY2VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwbGFjZW1lbnQgPSBwbGFjZW1lbnRzW2ldO1xuXG4gICAgdmFyIF9iYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuXG4gICAgdmFyIGlzU3RhcnRWYXJpYXRpb24gPSBnZXRWYXJpYXRpb24ocGxhY2VtZW50KSA9PT0gc3RhcnQ7XG4gICAgdmFyIGlzVmVydGljYWwgPSBbdG9wLCBib3R0b21dLmluZGV4T2YoX2Jhc2VQbGFjZW1lbnQpID49IDA7XG4gICAgdmFyIGxlbiA9IGlzVmVydGljYWwgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG4gICAgdmFyIG92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICAgIHBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeTogYWx0Qm91bmRhcnksXG4gICAgICBwYWRkaW5nOiBwYWRkaW5nXG4gICAgfSk7XG4gICAgdmFyIG1haW5WYXJpYXRpb25TaWRlID0gaXNWZXJ0aWNhbCA/IGlzU3RhcnRWYXJpYXRpb24gPyByaWdodCA6IGxlZnQgOiBpc1N0YXJ0VmFyaWF0aW9uID8gYm90dG9tIDogdG9wO1xuXG4gICAgaWYgKHJlZmVyZW5jZVJlY3RbbGVuXSA+IHBvcHBlclJlY3RbbGVuXSkge1xuICAgICAgbWFpblZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgfVxuXG4gICAgdmFyIGFsdFZhcmlhdGlvblNpZGUgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChtYWluVmFyaWF0aW9uU2lkZSk7XG4gICAgdmFyIGNoZWNrcyA9IFtdO1xuXG4gICAgaWYgKGNoZWNrTWFpbkF4aXMpIHtcbiAgICAgIGNoZWNrcy5wdXNoKG92ZXJmbG93W19iYXNlUGxhY2VtZW50XSA8PSAwKTtcbiAgICB9XG5cbiAgICBpZiAoY2hlY2tBbHRBeGlzKSB7XG4gICAgICBjaGVja3MucHVzaChvdmVyZmxvd1ttYWluVmFyaWF0aW9uU2lkZV0gPD0gMCwgb3ZlcmZsb3dbYWx0VmFyaWF0aW9uU2lkZV0gPD0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrcy5ldmVyeShmdW5jdGlvbiAoY2hlY2spIHtcbiAgICAgIHJldHVybiBjaGVjaztcbiAgICB9KSkge1xuICAgICAgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50O1xuICAgICAgbWFrZUZhbGxiYWNrQ2hlY2tzID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjaGVja3NNYXAuc2V0KHBsYWNlbWVudCwgY2hlY2tzKTtcbiAgfVxuXG4gIGlmIChtYWtlRmFsbGJhY2tDaGVja3MpIHtcbiAgICAvLyBgMmAgbWF5IGJlIGRlc2lyZWQgaW4gc29tZSBjYXNlcyBcdTIwMTMgcmVzZWFyY2ggbGF0ZXJcbiAgICB2YXIgbnVtYmVyT2ZDaGVja3MgPSBmbGlwVmFyaWF0aW9ucyA/IDMgOiAxO1xuXG4gICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoX2kpIHtcbiAgICAgIHZhciBmaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50cy5maW5kKGZ1bmN0aW9uIChwbGFjZW1lbnQpIHtcbiAgICAgICAgdmFyIGNoZWNrcyA9IGNoZWNrc01hcC5nZXQocGxhY2VtZW50KTtcblxuICAgICAgICBpZiAoY2hlY2tzKSB7XG4gICAgICAgICAgcmV0dXJuIGNoZWNrcy5zbGljZSgwLCBfaSkuZXZlcnkoZnVuY3Rpb24gKGNoZWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gY2hlY2s7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZml0dGluZ1BsYWNlbWVudCkge1xuICAgICAgICBmaXJzdEZpdHRpbmdQbGFjZW1lbnQgPSBmaXR0aW5nUGxhY2VtZW50O1xuICAgICAgICByZXR1cm4gXCJicmVha1wiO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKHZhciBfaSA9IG51bWJlck9mQ2hlY2tzOyBfaSA+IDA7IF9pLS0pIHtcbiAgICAgIHZhciBfcmV0ID0gX2xvb3AoX2kpO1xuXG4gICAgICBpZiAoX3JldCA9PT0gXCJicmVha1wiKSBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUucGxhY2VtZW50ICE9PSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdLl9za2lwID0gdHJ1ZTtcbiAgICBzdGF0ZS5wbGFjZW1lbnQgPSBmaXJzdEZpdHRpbmdQbGFjZW1lbnQ7XG4gICAgc3RhdGUucmVzZXQgPSB0cnVlO1xuICB9XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdmbGlwJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgZm46IGZsaXAsXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J10sXG4gIGRhdGE6IHtcbiAgICBfc2tpcDogZmFsc2VcbiAgfVxufTsiLCAiaW1wb3J0IHsgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFNpZGVPZmZzZXRzKG92ZXJmbG93LCByZWN0LCBwcmV2ZW50ZWRPZmZzZXRzKSB7XG4gIGlmIChwcmV2ZW50ZWRPZmZzZXRzID09PSB2b2lkIDApIHtcbiAgICBwcmV2ZW50ZWRPZmZzZXRzID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IG92ZXJmbG93LnRvcCAtIHJlY3QuaGVpZ2h0IC0gcHJldmVudGVkT2Zmc2V0cy55LFxuICAgIHJpZ2h0OiBvdmVyZmxvdy5yaWdodCAtIHJlY3Qud2lkdGggKyBwcmV2ZW50ZWRPZmZzZXRzLngsXG4gICAgYm90dG9tOiBvdmVyZmxvdy5ib3R0b20gLSByZWN0LmhlaWdodCArIHByZXZlbnRlZE9mZnNldHMueSxcbiAgICBsZWZ0OiBvdmVyZmxvdy5sZWZ0IC0gcmVjdC53aWR0aCAtIHByZXZlbnRlZE9mZnNldHMueFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0FueVNpZGVGdWxseUNsaXBwZWQob3ZlcmZsb3cpIHtcbiAgcmV0dXJuIFt0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRdLnNvbWUoZnVuY3Rpb24gKHNpZGUpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dbc2lkZV0gPj0gMDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhpZGUoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgcHJldmVudGVkT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucHJldmVudE92ZXJmbG93O1xuICB2YXIgcmVmZXJlbmNlT3ZlcmZsb3cgPSBkZXRlY3RPdmVyZmxvdyhzdGF0ZSwge1xuICAgIGVsZW1lbnRDb250ZXh0OiAncmVmZXJlbmNlJ1xuICB9KTtcbiAgdmFyIHBvcHBlckFsdE92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBhbHRCb3VuZGFyeTogdHJ1ZVxuICB9KTtcbiAgdmFyIHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyA9IGdldFNpZGVPZmZzZXRzKHJlZmVyZW5jZU92ZXJmbG93LCByZWZlcmVuY2VSZWN0KTtcbiAgdmFyIHBvcHBlckVzY2FwZU9mZnNldHMgPSBnZXRTaWRlT2Zmc2V0cyhwb3BwZXJBbHRPdmVyZmxvdywgcG9wcGVyUmVjdCwgcHJldmVudGVkT2Zmc2V0cyk7XG4gIHZhciBpc1JlZmVyZW5jZUhpZGRlbiA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMpO1xuICB2YXIgaGFzUG9wcGVyRXNjYXBlZCA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChwb3BwZXJFc2NhcGVPZmZzZXRzKTtcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IHtcbiAgICByZWZlcmVuY2VDbGlwcGluZ09mZnNldHM6IHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyxcbiAgICBwb3BwZXJFc2NhcGVPZmZzZXRzOiBwb3BwZXJFc2NhcGVPZmZzZXRzLFxuICAgIGlzUmVmZXJlbmNlSGlkZGVuOiBpc1JlZmVyZW5jZUhpZGRlbixcbiAgICBoYXNQb3BwZXJFc2NhcGVkOiBoYXNQb3BwZXJFc2NhcGVkXG4gIH07XG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcmVmZXJlbmNlLWhpZGRlbic6IGlzUmVmZXJlbmNlSGlkZGVuLFxuICAgICdkYXRhLXBvcHBlci1lc2NhcGVkJzogaGFzUG9wcGVyRXNjYXBlZFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2hpZGUnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ3ByZXZlbnRPdmVyZmxvdyddLFxuICBmbjogaGlkZVxufTsiLCAiaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIHBsYWNlbWVudHMgfSBmcm9tIFwiLi4vZW51bXMuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2VBbmRTa2lkZGluZ1RvWFkocGxhY2VtZW50LCByZWN0cywgb2Zmc2V0KSB7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICB2YXIgaW52ZXJ0RGlzdGFuY2UgPSBbbGVmdCwgdG9wXS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDAgPyAtMSA6IDE7XG5cbiAgdmFyIF9yZWYgPSB0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gb2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSkpIDogb2Zmc2V0LFxuICAgICAgc2tpZGRpbmcgPSBfcmVmWzBdLFxuICAgICAgZGlzdGFuY2UgPSBfcmVmWzFdO1xuXG4gIHNraWRkaW5nID0gc2tpZGRpbmcgfHwgMDtcbiAgZGlzdGFuY2UgPSAoZGlzdGFuY2UgfHwgMCkgKiBpbnZlcnREaXN0YW5jZTtcbiAgcmV0dXJuIFtsZWZ0LCByaWdodF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSA+PSAwID8ge1xuICAgIHg6IGRpc3RhbmNlLFxuICAgIHk6IHNraWRkaW5nXG4gIH0gOiB7XG4gICAgeDogc2tpZGRpbmcsXG4gICAgeTogZGlzdGFuY2VcbiAgfTtcbn1cblxuZnVuY3Rpb24gb2Zmc2V0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZjIubmFtZTtcbiAgdmFyIF9vcHRpb25zJG9mZnNldCA9IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgb2Zmc2V0ID0gX29wdGlvbnMkb2Zmc2V0ID09PSB2b2lkIDAgPyBbMCwgMF0gOiBfb3B0aW9ucyRvZmZzZXQ7XG4gIHZhciBkYXRhID0gcGxhY2VtZW50cy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGxhY2VtZW50KSB7XG4gICAgYWNjW3BsYWNlbWVudF0gPSBkaXN0YW5jZUFuZFNraWRkaW5nVG9YWShwbGFjZW1lbnQsIHN0YXRlLnJlY3RzLCBvZmZzZXQpO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgdmFyIF9kYXRhJHN0YXRlJHBsYWNlbWVudCA9IGRhdGFbc3RhdGUucGxhY2VtZW50XSxcbiAgICAgIHggPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueCxcbiAgICAgIHkgPSBfZGF0YSRzdGF0ZSRwbGFjZW1lbnQueTtcblxuICBpZiAoc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzICE9IG51bGwpIHtcbiAgICBzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMueCArPSB4O1xuICAgIHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cy55ICs9IHk7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ29mZnNldCcsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIHJlcXVpcmVzOiBbJ3BvcHBlck9mZnNldHMnXSxcbiAgZm46IG9mZnNldFxufTsiLCAiaW1wb3J0IGNvbXB1dGVPZmZzZXRzIGZyb20gXCIuLi91dGlscy9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuXG5mdW5jdGlvbiBwb3BwZXJPZmZzZXRzKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWU7XG4gIC8vIE9mZnNldHMgYXJlIHRoZSBhY3R1YWwgcG9zaXRpb24gdGhlIHBvcHBlciBuZWVkcyB0byBoYXZlIHRvIGJlXG4gIC8vIHByb3Blcmx5IHBvc2l0aW9uZWQgbmVhciBpdHMgcmVmZXJlbmNlIGVsZW1lbnRcbiAgLy8gVGhpcyBpcyB0aGUgbW9zdCBiYXNpYyBwbGFjZW1lbnQsIGFuZCB3aWxsIGJlIGFkanVzdGVkIGJ5XG4gIC8vIHRoZSBtb2RpZmllcnMgaW4gdGhlIG5leHQgc3RlcFxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gY29tcHV0ZU9mZnNldHMoe1xuICAgIHJlZmVyZW5jZTogc3RhdGUucmVjdHMucmVmZXJlbmNlLFxuICAgIGVsZW1lbnQ6IHN0YXRlLnJlY3RzLnBvcHBlcixcbiAgICBzdHJhdGVneTogJ2Fic29sdXRlJyxcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3BvcHBlck9mZnNldHMnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ3JlYWQnLFxuICBmbjogcG9wcGVyT2Zmc2V0cyxcbiAgZGF0YToge31cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFsdEF4aXMoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xufSIsICJpbXBvcnQgeyB0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHN0YXJ0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0QWx0QXhpcyBmcm9tIFwiLi4vdXRpbHMvZ2V0QWx0QXhpcy5qc1wiO1xuaW1wb3J0IHsgd2l0aGluLCB3aXRoaW5NYXhDbGFtcCB9IGZyb20gXCIuLi91dGlscy93aXRoaW4uanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuLi91dGlscy9nZXRGcmVzaFNpZGVPYmplY3QuanNcIjtcbmltcG9ydCB7IG1pbiBhcyBtYXRoTWluLCBtYXggYXMgbWF0aE1heCB9IGZyb20gXCIuLi91dGlscy9tYXRoLmpzXCI7XG5cbmZ1bmN0aW9uIHByZXZlbnRPdmVyZmxvdyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZi5vcHRpb25zLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIF9vcHRpb25zJG1haW5BeGlzID0gb3B0aW9ucy5tYWluQXhpcyxcbiAgICAgIGNoZWNrTWFpbkF4aXMgPSBfb3B0aW9ucyRtYWluQXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJG1haW5BeGlzLFxuICAgICAgX29wdGlvbnMkYWx0QXhpcyA9IG9wdGlvbnMuYWx0QXhpcyxcbiAgICAgIGNoZWNrQWx0QXhpcyA9IF9vcHRpb25zJGFsdEF4aXMgPT09IHZvaWQgMCA/IGZhbHNlIDogX29wdGlvbnMkYWx0QXhpcyxcbiAgICAgIGJvdW5kYXJ5ID0gb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeSA9IG9wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnkgPSBvcHRpb25zLmFsdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZyA9IG9wdGlvbnMucGFkZGluZyxcbiAgICAgIF9vcHRpb25zJHRldGhlciA9IG9wdGlvbnMudGV0aGVyLFxuICAgICAgdGV0aGVyID0gX29wdGlvbnMkdGV0aGVyID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkdGV0aGVyLFxuICAgICAgX29wdGlvbnMkdGV0aGVyT2Zmc2V0ID0gb3B0aW9ucy50ZXRoZXJPZmZzZXQsXG4gICAgICB0ZXRoZXJPZmZzZXQgPSBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQgPT09IHZvaWQgMCA/IDAgOiBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQ7XG4gIHZhciBvdmVyZmxvdyA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgYWx0Qm91bmRhcnk6IGFsdEJvdW5kYXJ5XG4gIH0pO1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQoc3RhdGUucGxhY2VtZW50KTtcbiAgdmFyIHZhcmlhdGlvbiA9IGdldFZhcmlhdGlvbihzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgaXNCYXNlUGxhY2VtZW50ID0gIXZhcmlhdGlvbjtcbiAgdmFyIG1haW5BeGlzID0gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KGJhc2VQbGFjZW1lbnQpO1xuICB2YXIgYWx0QXhpcyA9IGdldEFsdEF4aXMobWFpbkF4aXMpO1xuICB2YXIgcG9wcGVyT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cztcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgdGV0aGVyT2Zmc2V0VmFsdWUgPSB0eXBlb2YgdGV0aGVyT2Zmc2V0ID09PSAnZnVuY3Rpb24nID8gdGV0aGVyT2Zmc2V0KE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSkpIDogdGV0aGVyT2Zmc2V0O1xuICB2YXIgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlID0gdHlwZW9mIHRldGhlck9mZnNldFZhbHVlID09PSAnbnVtYmVyJyA/IHtcbiAgICBtYWluQXhpczogdGV0aGVyT2Zmc2V0VmFsdWUsXG4gICAgYWx0QXhpczogdGV0aGVyT2Zmc2V0VmFsdWVcbiAgfSA6IE9iamVjdC5hc3NpZ24oe1xuICAgIG1haW5BeGlzOiAwLFxuICAgIGFsdEF4aXM6IDBcbiAgfSwgdGV0aGVyT2Zmc2V0VmFsdWUpO1xuICB2YXIgb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0ID8gc3RhdGUubW9kaWZpZXJzRGF0YS5vZmZzZXRbc3RhdGUucGxhY2VtZW50XSA6IG51bGw7XG4gIHZhciBkYXRhID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmICghcG9wcGVyT2Zmc2V0cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjaGVja01haW5BeGlzKSB7XG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclN0YXRlJDtcblxuICAgIHZhciBtYWluU2lkZSA9IG1haW5BeGlzID09PSAneScgPyB0b3AgOiBsZWZ0O1xuICAgIHZhciBhbHRTaWRlID0gbWFpbkF4aXMgPT09ICd5JyA/IGJvdHRvbSA6IHJpZ2h0O1xuICAgIHZhciBsZW4gPSBtYWluQXhpcyA9PT0gJ3knID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICAgIHZhciBvZmZzZXQgPSBwb3BwZXJPZmZzZXRzW21haW5BeGlzXTtcbiAgICB2YXIgbWluID0gb2Zmc2V0ICsgb3ZlcmZsb3dbbWFpblNpZGVdO1xuICAgIHZhciBtYXggPSBvZmZzZXQgLSBvdmVyZmxvd1thbHRTaWRlXTtcbiAgICB2YXIgYWRkaXRpdmUgPSB0ZXRoZXIgPyAtcG9wcGVyUmVjdFtsZW5dIC8gMiA6IDA7XG4gICAgdmFyIG1pbkxlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gOiBwb3BwZXJSZWN0W2xlbl07XG4gICAgdmFyIG1heExlbiA9IHZhcmlhdGlvbiA9PT0gc3RhcnQgPyAtcG9wcGVyUmVjdFtsZW5dIDogLXJlZmVyZW5jZVJlY3RbbGVuXTsgLy8gV2UgbmVlZCB0byBpbmNsdWRlIHRoZSBhcnJvdyBpbiB0aGUgY2FsY3VsYXRpb24gc28gdGhlIGFycm93IGRvZXNuJ3QgZ29cbiAgICAvLyBvdXRzaWRlIHRoZSByZWZlcmVuY2UgYm91bmRzXG5cbiAgICB2YXIgYXJyb3dFbGVtZW50ID0gc3RhdGUuZWxlbWVudHMuYXJyb3c7XG4gICAgdmFyIGFycm93UmVjdCA9IHRldGhlciAmJiBhcnJvd0VsZW1lbnQgPyBnZXRMYXlvdXRSZWN0KGFycm93RWxlbWVudCkgOiB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMFxuICAgIH07XG4gICAgdmFyIGFycm93UGFkZGluZ09iamVjdCA9IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXSA/IHN0YXRlLm1vZGlmaWVyc0RhdGFbJ2Fycm93I3BlcnNpc3RlbnQnXS5wYWRkaW5nIDogZ2V0RnJlc2hTaWRlT2JqZWN0KCk7XG4gICAgdmFyIGFycm93UGFkZGluZ01pbiA9IGFycm93UGFkZGluZ09iamVjdFttYWluU2lkZV07XG4gICAgdmFyIGFycm93UGFkZGluZ01heCA9IGFycm93UGFkZGluZ09iamVjdFthbHRTaWRlXTsgLy8gSWYgdGhlIHJlZmVyZW5jZSBsZW5ndGggaXMgc21hbGxlciB0aGFuIHRoZSBhcnJvdyBsZW5ndGgsIHdlIGRvbid0IHdhbnRcbiAgICAvLyB0byBpbmNsdWRlIGl0cyBmdWxsIHNpemUgaW4gdGhlIGNhbGN1bGF0aW9uLiBJZiB0aGUgcmVmZXJlbmNlIGlzIHNtYWxsXG4gICAgLy8gYW5kIG5lYXIgdGhlIGVkZ2Ugb2YgYSBib3VuZGFyeSwgdGhlIHBvcHBlciBjYW4gb3ZlcmZsb3cgZXZlbiBpZiB0aGVcbiAgICAvLyByZWZlcmVuY2UgaXMgbm90IG92ZXJmbG93aW5nIGFzIHdlbGwgKGUuZy4gdmlydHVhbCBlbGVtZW50cyB3aXRoIG5vXG4gICAgLy8gd2lkdGggb3IgaGVpZ2h0KVxuXG4gICAgdmFyIGFycm93TGVuID0gd2l0aGluKDAsIHJlZmVyZW5jZVJlY3RbbGVuXSwgYXJyb3dSZWN0W2xlbl0pO1xuICAgIHZhciBtaW5PZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyByZWZlcmVuY2VSZWN0W2xlbl0gLyAyIC0gYWRkaXRpdmUgLSBhcnJvd0xlbiAtIGFycm93UGFkZGluZ01pbiAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcyA6IG1pbkxlbiAtIGFycm93TGVuIC0gYXJyb3dQYWRkaW5nTWluIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzO1xuICAgIHZhciBtYXhPZmZzZXQgPSBpc0Jhc2VQbGFjZW1lbnQgPyAtcmVmZXJlbmNlUmVjdFtsZW5dIC8gMiArIGFkZGl0aXZlICsgYXJyb3dMZW4gKyBhcnJvd1BhZGRpbmdNYXggKyBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUubWFpbkF4aXMgOiBtYXhMZW4gKyBhcnJvd0xlbiArIGFycm93UGFkZGluZ01heCArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcztcbiAgICB2YXIgYXJyb3dPZmZzZXRQYXJlbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdyAmJiBnZXRPZmZzZXRQYXJlbnQoc3RhdGUuZWxlbWVudHMuYXJyb3cpO1xuICAgIHZhciBjbGllbnRPZmZzZXQgPSBhcnJvd09mZnNldFBhcmVudCA/IG1haW5BeGlzID09PSAneScgPyBhcnJvd09mZnNldFBhcmVudC5jbGllbnRUb3AgfHwgMCA6IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudExlZnQgfHwgMCA6IDA7XG4gICAgdmFyIG9mZnNldE1vZGlmaWVyVmFsdWUgPSAoX29mZnNldE1vZGlmaWVyU3RhdGUkID0gb2Zmc2V0TW9kaWZpZXJTdGF0ZSA9PSBudWxsID8gdm9pZCAwIDogb2Zmc2V0TW9kaWZpZXJTdGF0ZVttYWluQXhpc10pICE9IG51bGwgPyBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQgOiAwO1xuICAgIHZhciB0ZXRoZXJNaW4gPSBvZmZzZXQgKyBtaW5PZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlIC0gY2xpZW50T2Zmc2V0O1xuICAgIHZhciB0ZXRoZXJNYXggPSBvZmZzZXQgKyBtYXhPZmZzZXQgLSBvZmZzZXRNb2RpZmllclZhbHVlO1xuICAgIHZhciBwcmV2ZW50ZWRPZmZzZXQgPSB3aXRoaW4odGV0aGVyID8gbWF0aE1pbihtaW4sIHRldGhlck1pbikgOiBtaW4sIG9mZnNldCwgdGV0aGVyID8gbWF0aE1heChtYXgsIHRldGhlck1heCkgOiBtYXgpO1xuICAgIHBvcHBlck9mZnNldHNbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0O1xuICAgIGRhdGFbbWFpbkF4aXNdID0gcHJldmVudGVkT2Zmc2V0IC0gb2Zmc2V0O1xuICB9XG5cbiAgaWYgKGNoZWNrQWx0QXhpcykge1xuICAgIHZhciBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyO1xuXG4gICAgdmFyIF9tYWluU2lkZSA9IG1haW5BeGlzID09PSAneCcgPyB0b3AgOiBsZWZ0O1xuXG4gICAgdmFyIF9hbHRTaWRlID0gbWFpbkF4aXMgPT09ICd4JyA/IGJvdHRvbSA6IHJpZ2h0O1xuXG4gICAgdmFyIF9vZmZzZXQgPSBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdO1xuXG4gICAgdmFyIF9sZW4gPSBhbHRBeGlzID09PSAneScgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG5cbiAgICB2YXIgX21pbiA9IF9vZmZzZXQgKyBvdmVyZmxvd1tfbWFpblNpZGVdO1xuXG4gICAgdmFyIF9tYXggPSBfb2Zmc2V0IC0gb3ZlcmZsb3dbX2FsdFNpZGVdO1xuXG4gICAgdmFyIGlzT3JpZ2luU2lkZSA9IFt0b3AsIGxlZnRdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgIT09IC0xO1xuXG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclZhbHVlID0gKF9vZmZzZXRNb2RpZmllclN0YXRlJDIgPSBvZmZzZXRNb2RpZmllclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBvZmZzZXRNb2RpZmllclN0YXRlW2FsdEF4aXNdKSAhPSBudWxsID8gX29mZnNldE1vZGlmaWVyU3RhdGUkMiA6IDA7XG5cbiAgICB2YXIgX3RldGhlck1pbiA9IGlzT3JpZ2luU2lkZSA/IF9taW4gOiBfb2Zmc2V0IC0gcmVmZXJlbmNlUmVjdFtfbGVuXSAtIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzO1xuXG4gICAgdmFyIF90ZXRoZXJNYXggPSBpc09yaWdpblNpZGUgPyBfb2Zmc2V0ICsgcmVmZXJlbmNlUmVjdFtfbGVuXSArIHBvcHBlclJlY3RbX2xlbl0gLSBfb2Zmc2V0TW9kaWZpZXJWYWx1ZSAtIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5hbHRBeGlzIDogX21heDtcblxuICAgIHZhciBfcHJldmVudGVkT2Zmc2V0ID0gdGV0aGVyICYmIGlzT3JpZ2luU2lkZSA/IHdpdGhpbk1heENsYW1wKF90ZXRoZXJNaW4sIF9vZmZzZXQsIF90ZXRoZXJNYXgpIDogd2l0aGluKHRldGhlciA/IF90ZXRoZXJNaW4gOiBfbWluLCBfb2Zmc2V0LCB0ZXRoZXIgPyBfdGV0aGVyTWF4IDogX21heCk7XG5cbiAgICBwb3BwZXJPZmZzZXRzW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldDtcbiAgICBkYXRhW2FsdEF4aXNdID0gX3ByZXZlbnRlZE9mZnNldCAtIF9vZmZzZXQ7XG4gIH1cblxuICBzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdID0gZGF0YTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBwcmV2ZW50T3ZlcmZsb3csXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsnb2Zmc2V0J11cbn07IiwgImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEhUTUxFbGVtZW50U2Nyb2xsKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHtcbiAgICBzY3JvbGxMZWZ0OiBlbGVtZW50LnNjcm9sbExlZnQsXG4gICAgc2Nyb2xsVG9wOiBlbGVtZW50LnNjcm9sbFRvcFxuICB9O1xufSIsICJpbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0SFRNTEVsZW1lbnRTY3JvbGwgZnJvbSBcIi4vZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVTY3JvbGwobm9kZSkge1xuICBpZiAobm9kZSA9PT0gZ2V0V2luZG93KG5vZGUpIHx8ICFpc0hUTUxFbGVtZW50KG5vZGUpKSB7XG4gICAgcmV0dXJuIGdldFdpbmRvd1Njcm9sbChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2V0SFRNTEVsZW1lbnRTY3JvbGwobm9kZSk7XG4gIH1cbn0iLCAiaW1wb3J0IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBmcm9tIFwiLi9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBnZXROb2RlU2Nyb2xsIGZyb20gXCIuL2dldE5vZGVTY3JvbGwuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgaXNTY3JvbGxQYXJlbnQgZnJvbSBcIi4vaXNTY3JvbGxQYXJlbnQuanNcIjtcbmltcG9ydCB7IHJvdW5kIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gaXNFbGVtZW50U2NhbGVkKGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB2YXIgc2NhbGVYID0gcm91bmQocmVjdC53aWR0aCkgLyBlbGVtZW50Lm9mZnNldFdpZHRoIHx8IDE7XG4gIHZhciBzY2FsZVkgPSByb3VuZChyZWN0LmhlaWdodCkgLyBlbGVtZW50Lm9mZnNldEhlaWdodCB8fCAxO1xuICByZXR1cm4gc2NhbGVYICE9PSAxIHx8IHNjYWxlWSAhPT0gMTtcbn0gLy8gUmV0dXJucyB0aGUgY29tcG9zaXRlIHJlY3Qgb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byBpdHMgb2Zmc2V0UGFyZW50LlxuLy8gQ29tcG9zaXRlIG1lYW5zIGl0IHRha2VzIGludG8gYWNjb3VudCB0cmFuc2Zvcm1zIGFzIHdlbGwgYXMgbGF5b3V0LlxuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbXBvc2l0ZVJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudCwgaXNGaXhlZCkge1xuICBpZiAoaXNGaXhlZCA9PT0gdm9pZCAwKSB7XG4gICAgaXNGaXhlZCA9IGZhbHNlO1xuICB9XG5cbiAgdmFyIGlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ID0gaXNIVE1MRWxlbWVudChvZmZzZXRQYXJlbnQpO1xuICB2YXIgb2Zmc2V0UGFyZW50SXNTY2FsZWQgPSBpc0hUTUxFbGVtZW50KG9mZnNldFBhcmVudCkgJiYgaXNFbGVtZW50U2NhbGVkKG9mZnNldFBhcmVudCk7XG4gIHZhciBkb2N1bWVudEVsZW1lbnQgPSBnZXREb2N1bWVudEVsZW1lbnQob2Zmc2V0UGFyZW50KTtcbiAgdmFyIHJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudE9yVmlydHVhbEVsZW1lbnQsIG9mZnNldFBhcmVudElzU2NhbGVkLCBpc0ZpeGVkKTtcbiAgdmFyIHNjcm9sbCA9IHtcbiAgICBzY3JvbGxMZWZ0OiAwLFxuICAgIHNjcm9sbFRvcDogMFxuICB9O1xuICB2YXIgb2Zmc2V0cyA9IHtcbiAgICB4OiAwLFxuICAgIHk6IDBcbiAgfTtcblxuICBpZiAoaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgfHwgIWlzT2Zmc2V0UGFyZW50QW5FbGVtZW50ICYmICFpc0ZpeGVkKSB7XG4gICAgaWYgKGdldE5vZGVOYW1lKG9mZnNldFBhcmVudCkgIT09ICdib2R5JyB8fCAvLyBodHRwczovL2dpdGh1Yi5jb20vcG9wcGVyanMvcG9wcGVyLWNvcmUvaXNzdWVzLzEwNzhcbiAgICBpc1Njcm9sbFBhcmVudChkb2N1bWVudEVsZW1lbnQpKSB7XG4gICAgICBzY3JvbGwgPSBnZXROb2RlU2Nyb2xsKG9mZnNldFBhcmVudCk7XG4gICAgfVxuXG4gICAgaWYgKGlzSFRNTEVsZW1lbnQob2Zmc2V0UGFyZW50KSkge1xuICAgICAgb2Zmc2V0cyA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChvZmZzZXRQYXJlbnQsIHRydWUpO1xuICAgICAgb2Zmc2V0cy54ICs9IG9mZnNldFBhcmVudC5jbGllbnRMZWZ0O1xuICAgICAgb2Zmc2V0cy55ICs9IG9mZnNldFBhcmVudC5jbGllbnRUb3A7XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIG9mZnNldHMueCA9IGdldFdpbmRvd1Njcm9sbEJhclgoZG9jdW1lbnRFbGVtZW50KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IHJlY3QubGVmdCArIHNjcm9sbC5zY3JvbGxMZWZ0IC0gb2Zmc2V0cy54LFxuICAgIHk6IHJlY3QudG9wICsgc2Nyb2xsLnNjcm9sbFRvcCAtIG9mZnNldHMueSxcbiAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0XG4gIH07XG59IiwgImltcG9ydCB7IG1vZGlmaWVyUGhhc2VzIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7IC8vIHNvdXJjZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDk4NzUyNTVcblxuZnVuY3Rpb24gb3JkZXIobW9kaWZpZXJzKSB7XG4gIHZhciBtYXAgPSBuZXcgTWFwKCk7XG4gIHZhciB2aXNpdGVkID0gbmV3IFNldCgpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIG1hcC5zZXQobW9kaWZpZXIubmFtZSwgbW9kaWZpZXIpO1xuICB9KTsgLy8gT24gdmlzaXRpbmcgb2JqZWN0LCBjaGVjayBmb3IgaXRzIGRlcGVuZGVuY2llcyBhbmQgdmlzaXQgdGhlbSByZWN1cnNpdmVseVxuXG4gIGZ1bmN0aW9uIHNvcnQobW9kaWZpZXIpIHtcbiAgICB2aXNpdGVkLmFkZChtb2RpZmllci5uYW1lKTtcbiAgICB2YXIgcmVxdWlyZXMgPSBbXS5jb25jYXQobW9kaWZpZXIucmVxdWlyZXMgfHwgW10sIG1vZGlmaWVyLnJlcXVpcmVzSWZFeGlzdHMgfHwgW10pO1xuICAgIHJlcXVpcmVzLmZvckVhY2goZnVuY3Rpb24gKGRlcCkge1xuICAgICAgaWYgKCF2aXNpdGVkLmhhcyhkZXApKSB7XG4gICAgICAgIHZhciBkZXBNb2RpZmllciA9IG1hcC5nZXQoZGVwKTtcblxuICAgICAgICBpZiAoZGVwTW9kaWZpZXIpIHtcbiAgICAgICAgICBzb3J0KGRlcE1vZGlmaWVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJlc3VsdC5wdXNoKG1vZGlmaWVyKTtcbiAgfVxuXG4gIG1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgIGlmICghdmlzaXRlZC5oYXMobW9kaWZpZXIubmFtZSkpIHtcbiAgICAgIC8vIGNoZWNrIGZvciB2aXNpdGVkIG9iamVjdFxuICAgICAgc29ydChtb2RpZmllcik7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb3JkZXJNb2RpZmllcnMobW9kaWZpZXJzKSB7XG4gIC8vIG9yZGVyIGJhc2VkIG9uIGRlcGVuZGVuY2llc1xuICB2YXIgb3JkZXJlZE1vZGlmaWVycyA9IG9yZGVyKG1vZGlmaWVycyk7IC8vIG9yZGVyIGJhc2VkIG9uIHBoYXNlXG5cbiAgcmV0dXJuIG1vZGlmaWVyUGhhc2VzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwaGFzZSkge1xuICAgIHJldHVybiBhY2MuY29uY2F0KG9yZGVyZWRNb2RpZmllcnMuZmlsdGVyKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgICAgcmV0dXJuIG1vZGlmaWVyLnBoYXNlID09PSBwaGFzZTtcbiAgICB9KSk7XG4gIH0sIFtdKTtcbn0iLCAiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVib3VuY2UoZm4pIHtcbiAgdmFyIHBlbmRpbmc7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcGVuZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXNvbHZlKGZuKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufSIsICJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBtZXJnZUJ5TmFtZShtb2RpZmllcnMpIHtcbiAgdmFyIG1lcmdlZCA9IG1vZGlmaWVycy5yZWR1Y2UoZnVuY3Rpb24gKG1lcmdlZCwgY3VycmVudCkge1xuICAgIHZhciBleGlzdGluZyA9IG1lcmdlZFtjdXJyZW50Lm5hbWVdO1xuICAgIG1lcmdlZFtjdXJyZW50Lm5hbWVdID0gZXhpc3RpbmcgPyBPYmplY3QuYXNzaWduKHt9LCBleGlzdGluZywgY3VycmVudCwge1xuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgZXhpc3Rpbmcub3B0aW9ucywgY3VycmVudC5vcHRpb25zKSxcbiAgICAgIGRhdGE6IE9iamVjdC5hc3NpZ24oe30sIGV4aXN0aW5nLmRhdGEsIGN1cnJlbnQuZGF0YSlcbiAgICB9KSA6IGN1cnJlbnQ7XG4gICAgcmV0dXJuIG1lcmdlZDtcbiAgfSwge30pOyAvLyBJRTExIGRvZXMgbm90IHN1cHBvcnQgT2JqZWN0LnZhbHVlc1xuXG4gIHJldHVybiBPYmplY3Qua2V5cyhtZXJnZWQpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIG1lcmdlZFtrZXldO1xuICB9KTtcbn0iLCAiaW1wb3J0IGdldENvbXBvc2l0ZVJlY3QgZnJvbSBcIi4vZG9tLXV0aWxzL2dldENvbXBvc2l0ZVJlY3QuanNcIjtcbmltcG9ydCBnZXRMYXlvdXRSZWN0IGZyb20gXCIuL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgbGlzdFNjcm9sbFBhcmVudHMgZnJvbSBcIi4vZG9tLXV0aWxzL2xpc3RTY3JvbGxQYXJlbnRzLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBvcmRlck1vZGlmaWVycyBmcm9tIFwiLi91dGlscy9vcmRlck1vZGlmaWVycy5qc1wiO1xuaW1wb3J0IGRlYm91bmNlIGZyb20gXCIuL3V0aWxzL2RlYm91bmNlLmpzXCI7XG5pbXBvcnQgbWVyZ2VCeU5hbWUgZnJvbSBcIi4vdXRpbHMvbWVyZ2VCeU5hbWUuanNcIjtcbmltcG9ydCBkZXRlY3RPdmVyZmxvdyBmcm9tIFwiLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IHsgaXNFbGVtZW50IH0gZnJvbSBcIi4vZG9tLXV0aWxzL2luc3RhbmNlT2YuanNcIjtcbnZhciBERUZBVUxUX09QVElPTlMgPSB7XG4gIHBsYWNlbWVudDogJ2JvdHRvbScsXG4gIG1vZGlmaWVyczogW10sXG4gIHN0cmF0ZWd5OiAnYWJzb2x1dGUnXG59O1xuXG5mdW5jdGlvbiBhcmVWYWxpZEVsZW1lbnRzKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuICFhcmdzLnNvbWUoZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gIShlbGVtZW50ICYmIHR5cGVvZiBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCA9PT0gJ2Z1bmN0aW9uJyk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcG9wcGVyR2VuZXJhdG9yKGdlbmVyYXRvck9wdGlvbnMpIHtcbiAgaWYgKGdlbmVyYXRvck9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIGdlbmVyYXRvck9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfZ2VuZXJhdG9yT3B0aW9ucyA9IGdlbmVyYXRvck9wdGlvbnMsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYgPSBfZ2VuZXJhdG9yT3B0aW9ucy5kZWZhdWx0TW9kaWZpZXJzLFxuICAgICAgZGVmYXVsdE1vZGlmaWVycyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZiA9PT0gdm9pZCAwID8gW10gOiBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYsXG4gICAgICBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyID0gX2dlbmVyYXRvck9wdGlvbnMuZGVmYXVsdE9wdGlvbnMsXG4gICAgICBkZWZhdWx0T3B0aW9ucyA9IF9nZW5lcmF0b3JPcHRpb25zJGRlZjIgPT09IHZvaWQgMCA/IERFRkFVTFRfT1BUSU9OUyA6IF9nZW5lcmF0b3JPcHRpb25zJGRlZjI7XG4gIHJldHVybiBmdW5jdGlvbiBjcmVhdGVQb3BwZXIocmVmZXJlbmNlLCBwb3BwZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgICBvcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG4gICAgfVxuXG4gICAgdmFyIHN0YXRlID0ge1xuICAgICAgcGxhY2VtZW50OiAnYm90dG9tJyxcbiAgICAgIG9yZGVyZWRNb2RpZmllcnM6IFtdLFxuICAgICAgb3B0aW9uczogT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBkZWZhdWx0T3B0aW9ucyksXG4gICAgICBtb2RpZmllcnNEYXRhOiB7fSxcbiAgICAgIGVsZW1lbnRzOiB7XG4gICAgICAgIHJlZmVyZW5jZTogcmVmZXJlbmNlLFxuICAgICAgICBwb3BwZXI6IHBvcHBlclxuICAgICAgfSxcbiAgICAgIGF0dHJpYnV0ZXM6IHt9LFxuICAgICAgc3R5bGVzOiB7fVxuICAgIH07XG4gICAgdmFyIGVmZmVjdENsZWFudXBGbnMgPSBbXTtcbiAgICB2YXIgaXNEZXN0cm95ZWQgPSBmYWxzZTtcbiAgICB2YXIgaW5zdGFuY2UgPSB7XG4gICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICBzZXRPcHRpb25zOiBmdW5jdGlvbiBzZXRPcHRpb25zKHNldE9wdGlvbnNBY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygc2V0T3B0aW9uc0FjdGlvbiA9PT0gJ2Z1bmN0aW9uJyA/IHNldE9wdGlvbnNBY3Rpb24oc3RhdGUub3B0aW9ucykgOiBzZXRPcHRpb25zQWN0aW9uO1xuICAgICAgICBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHN0YXRlLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0T3B0aW9ucywgc3RhdGUub3B0aW9ucywgb3B0aW9ucyk7XG4gICAgICAgIHN0YXRlLnNjcm9sbFBhcmVudHMgPSB7XG4gICAgICAgICAgcmVmZXJlbmNlOiBpc0VsZW1lbnQocmVmZXJlbmNlKSA/IGxpc3RTY3JvbGxQYXJlbnRzKHJlZmVyZW5jZSkgOiByZWZlcmVuY2UuY29udGV4dEVsZW1lbnQgPyBsaXN0U2Nyb2xsUGFyZW50cyhyZWZlcmVuY2UuY29udGV4dEVsZW1lbnQpIDogW10sXG4gICAgICAgICAgcG9wcGVyOiBsaXN0U2Nyb2xsUGFyZW50cyhwb3BwZXIpXG4gICAgICAgIH07IC8vIE9yZGVycyB0aGUgbW9kaWZpZXJzIGJhc2VkIG9uIHRoZWlyIGRlcGVuZGVuY2llcyBhbmQgYHBoYXNlYFxuICAgICAgICAvLyBwcm9wZXJ0aWVzXG5cbiAgICAgICAgdmFyIG9yZGVyZWRNb2RpZmllcnMgPSBvcmRlck1vZGlmaWVycyhtZXJnZUJ5TmFtZShbXS5jb25jYXQoZGVmYXVsdE1vZGlmaWVycywgc3RhdGUub3B0aW9ucy5tb2RpZmllcnMpKSk7IC8vIFN0cmlwIG91dCBkaXNhYmxlZCBtb2RpZmllcnNcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzID0gb3JkZXJlZE1vZGlmaWVycy5maWx0ZXIoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICByZXR1cm4gbS5lbmFibGVkO1xuICAgICAgICB9KTtcbiAgICAgICAgcnVuTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZS51cGRhdGUoKTtcbiAgICAgIH0sXG4gICAgICAvLyBTeW5jIHVwZGF0ZSBcdTIwMTMgaXQgd2lsbCBhbHdheXMgYmUgZXhlY3V0ZWQsIGV2ZW4gaWYgbm90IG5lY2Vzc2FyeS4gVGhpc1xuICAgICAgLy8gaXMgdXNlZnVsIGZvciBsb3cgZnJlcXVlbmN5IHVwZGF0ZXMgd2hlcmUgc3luYyBiZWhhdmlvciBzaW1wbGlmaWVzIHRoZVxuICAgICAgLy8gbG9naWMuXG4gICAgICAvLyBGb3IgaGlnaCBmcmVxdWVuY3kgdXBkYXRlcyAoZS5nLiBgcmVzaXplYCBhbmQgYHNjcm9sbGAgZXZlbnRzKSwgYWx3YXlzXG4gICAgICAvLyBwcmVmZXIgdGhlIGFzeW5jIFBvcHBlciN1cGRhdGUgbWV0aG9kXG4gICAgICBmb3JjZVVwZGF0ZTogZnVuY3Rpb24gZm9yY2VVcGRhdGUoKSB7XG4gICAgICAgIGlmIChpc0Rlc3Ryb3llZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfc3RhdGUkZWxlbWVudHMgPSBzdGF0ZS5lbGVtZW50cyxcbiAgICAgICAgICAgIHJlZmVyZW5jZSA9IF9zdGF0ZSRlbGVtZW50cy5yZWZlcmVuY2UsXG4gICAgICAgICAgICBwb3BwZXIgPSBfc3RhdGUkZWxlbWVudHMucG9wcGVyOyAvLyBEb24ndCBwcm9jZWVkIGlmIGByZWZlcmVuY2VgIG9yIGBwb3BwZXJgIGFyZSBub3QgdmFsaWQgZWxlbWVudHNcbiAgICAgICAgLy8gYW55bW9yZVxuXG4gICAgICAgIGlmICghYXJlVmFsaWRFbGVtZW50cyhyZWZlcmVuY2UsIHBvcHBlcikpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gU3RvcmUgdGhlIHJlZmVyZW5jZSBhbmQgcG9wcGVyIHJlY3RzIHRvIGJlIHJlYWQgYnkgbW9kaWZpZXJzXG5cblxuICAgICAgICBzdGF0ZS5yZWN0cyA9IHtcbiAgICAgICAgICByZWZlcmVuY2U6IGdldENvbXBvc2l0ZVJlY3QocmVmZXJlbmNlLCBnZXRPZmZzZXRQYXJlbnQocG9wcGVyKSwgc3RhdGUub3B0aW9ucy5zdHJhdGVneSA9PT0gJ2ZpeGVkJyksXG4gICAgICAgICAgcG9wcGVyOiBnZXRMYXlvdXRSZWN0KHBvcHBlcilcbiAgICAgICAgfTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gcmVzZXQgdGhlIGN1cnJlbnQgdXBkYXRlIGN5Y2xlLiBUaGVcbiAgICAgICAgLy8gbW9zdCBjb21tb24gdXNlIGNhc2UgZm9yIHRoaXMgaXMgdGhlIGBmbGlwYCBtb2RpZmllciBjaGFuZ2luZyB0aGVcbiAgICAgICAgLy8gcGxhY2VtZW50LCB3aGljaCB0aGVuIG5lZWRzIHRvIHJlLXJ1biBhbGwgdGhlIG1vZGlmaWVycywgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gbG9naWMgd2FzIHByZXZpb3VzbHkgcmFuIGZvciB0aGUgcHJldmlvdXMgcGxhY2VtZW50IGFuZCBpcyB0aGVyZWZvcmVcbiAgICAgICAgLy8gc3RhbGUvaW5jb3JyZWN0XG5cbiAgICAgICAgc3RhdGUucmVzZXQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucGxhY2VtZW50ID0gc3RhdGUub3B0aW9ucy5wbGFjZW1lbnQ7IC8vIE9uIGVhY2ggdXBkYXRlIGN5Y2xlLCB0aGUgYG1vZGlmaWVyc0RhdGFgIHByb3BlcnR5IGZvciBlYWNoIG1vZGlmaWVyXG4gICAgICAgIC8vIGlzIGZpbGxlZCB3aXRoIHRoZSBpbml0aWFsIGRhdGEgc3BlY2lmaWVkIGJ5IHRoZSBtb2RpZmllci4gVGhpcyBtZWFuc1xuICAgICAgICAvLyBpdCBkb2Vzbid0IHBlcnNpc3QgYW5kIGlzIGZyZXNoIG9uIGVhY2ggdXBkYXRlLlxuICAgICAgICAvLyBUbyBlbnN1cmUgcGVyc2lzdGVudCBkYXRhLCB1c2UgYCR7bmFtZX0jcGVyc2lzdGVudGBcblxuICAgICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKG1vZGlmaWVyKSB7XG4gICAgICAgICAgcmV0dXJuIHN0YXRlLm1vZGlmaWVyc0RhdGFbbW9kaWZpZXIubmFtZV0gPSBPYmplY3QuYXNzaWduKHt9LCBtb2RpZmllci5kYXRhKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCA8IHN0YXRlLm9yZGVyZWRNb2RpZmllcnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgaWYgKHN0YXRlLnJlc2V0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBzdGF0ZS5yZXNldCA9IGZhbHNlO1xuICAgICAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBfc3RhdGUkb3JkZXJlZE1vZGlmaWUgPSBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzW2luZGV4XSxcbiAgICAgICAgICAgICAgZm4gPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUuZm4sXG4gICAgICAgICAgICAgIF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUub3B0aW9ucyxcbiAgICAgICAgICAgICAgX29wdGlvbnMgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyID09PSB2b2lkIDAgPyB7fSA6IF9zdGF0ZSRvcmRlcmVkTW9kaWZpZTIsXG4gICAgICAgICAgICAgIG5hbWUgPSBfc3RhdGUkb3JkZXJlZE1vZGlmaWUubmFtZTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHN0YXRlID0gZm4oe1xuICAgICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICAgIG9wdGlvbnM6IF9vcHRpb25zLFxuICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBpbnN0YW5jZTogaW5zdGFuY2VcbiAgICAgICAgICAgIH0pIHx8IHN0YXRlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIEFzeW5jIGFuZCBvcHRpbWlzdGljYWxseSBvcHRpbWl6ZWQgdXBkYXRlIFx1MjAxMyBpdCB3aWxsIG5vdCBiZSBleGVjdXRlZCBpZlxuICAgICAgLy8gbm90IG5lY2Vzc2FyeSAoZGVib3VuY2VkIHRvIHJ1biBhdCBtb3N0IG9uY2UtcGVyLXRpY2spXG4gICAgICB1cGRhdGU6IGRlYm91bmNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgICAgaW5zdGFuY2UuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICByZXNvbHZlKHN0YXRlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIGNsZWFudXBNb2RpZmllckVmZmVjdHMoKTtcbiAgICAgICAgaXNEZXN0cm95ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgaW5zdGFuY2Uuc2V0T3B0aW9ucyhvcHRpb25zKS50aGVuKGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgICAgaWYgKCFpc0Rlc3Ryb3llZCAmJiBvcHRpb25zLm9uRmlyc3RVcGRhdGUpIHtcbiAgICAgICAgb3B0aW9ucy5vbkZpcnN0VXBkYXRlKHN0YXRlKTtcbiAgICAgIH1cbiAgICB9KTsgLy8gTW9kaWZpZXJzIGhhdmUgdGhlIGFiaWxpdHkgdG8gZXhlY3V0ZSBhcmJpdHJhcnkgY29kZSBiZWZvcmUgdGhlIGZpcnN0XG4gICAgLy8gdXBkYXRlIGN5Y2xlIHJ1bnMuIFRoZXkgd2lsbCBiZSBleGVjdXRlZCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGUgdXBkYXRlXG4gICAgLy8gY3ljbGUuIFRoaXMgaXMgdXNlZnVsIHdoZW4gYSBtb2RpZmllciBhZGRzIHNvbWUgcGVyc2lzdGVudCBkYXRhIHRoYXRcbiAgICAvLyBvdGhlciBtb2RpZmllcnMgbmVlZCB0byB1c2UsIGJ1dCB0aGUgbW9kaWZpZXIgaXMgcnVuIGFmdGVyIHRoZSBkZXBlbmRlbnRcbiAgICAvLyBvbmUuXG5cbiAgICBmdW5jdGlvbiBydW5Nb2RpZmllckVmZmVjdHMoKSB7XG4gICAgICBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgICAgdmFyIG5hbWUgPSBfcmVmLm5hbWUsXG4gICAgICAgICAgICBfcmVmJG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICAgICAgICBvcHRpb25zID0gX3JlZiRvcHRpb25zID09PSB2b2lkIDAgPyB7fSA6IF9yZWYkb3B0aW9ucyxcbiAgICAgICAgICAgIGVmZmVjdCA9IF9yZWYuZWZmZWN0O1xuXG4gICAgICAgIGlmICh0eXBlb2YgZWZmZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdmFyIGNsZWFudXBGbiA9IGVmZmVjdCh7XG4gICAgICAgICAgICBzdGF0ZTogc3RhdGUsXG4gICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgaW5zdGFuY2U6IGluc3RhbmNlLFxuICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgdmFyIG5vb3BGbiA9IGZ1bmN0aW9uIG5vb3BGbigpIHt9O1xuXG4gICAgICAgICAgZWZmZWN0Q2xlYW51cEZucy5wdXNoKGNsZWFudXBGbiB8fCBub29wRm4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCkge1xuICAgICAgZWZmZWN0Q2xlYW51cEZucy5mb3JFYWNoKGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgIH0pO1xuICAgICAgZWZmZWN0Q2xlYW51cEZucyA9IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfTtcbn1cbmV4cG9ydCB2YXIgY3JlYXRlUG9wcGVyID0gLyojX19QVVJFX18qL3BvcHBlckdlbmVyYXRvcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCB7IGRldGVjdE92ZXJmbG93IH07IiwgImltcG9ydCB7IHBvcHBlckdlbmVyYXRvciwgZGV0ZWN0T3ZlcmZsb3cgfSBmcm9tIFwiLi9jcmVhdGVQb3BwZXIuanNcIjtcbmltcG9ydCBldmVudExpc3RlbmVycyBmcm9tIFwiLi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanNcIjtcbmltcG9ydCBwb3BwZXJPZmZzZXRzIGZyb20gXCIuL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzXCI7XG5pbXBvcnQgY29tcHV0ZVN0eWxlcyBmcm9tIFwiLi9tb2RpZmllcnMvY29tcHV0ZVN0eWxlcy5qc1wiO1xuaW1wb3J0IGFwcGx5U3R5bGVzIGZyb20gXCIuL21vZGlmaWVycy9hcHBseVN0eWxlcy5qc1wiO1xuaW1wb3J0IG9mZnNldCBmcm9tIFwiLi9tb2RpZmllcnMvb2Zmc2V0LmpzXCI7XG5pbXBvcnQgZmxpcCBmcm9tIFwiLi9tb2RpZmllcnMvZmxpcC5qc1wiO1xuaW1wb3J0IHByZXZlbnRPdmVyZmxvdyBmcm9tIFwiLi9tb2RpZmllcnMvcHJldmVudE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgYXJyb3cgZnJvbSBcIi4vbW9kaWZpZXJzL2Fycm93LmpzXCI7XG5pbXBvcnQgaGlkZSBmcm9tIFwiLi9tb2RpZmllcnMvaGlkZS5qc1wiO1xudmFyIGRlZmF1bHRNb2RpZmllcnMgPSBbZXZlbnRMaXN0ZW5lcnMsIHBvcHBlck9mZnNldHMsIGNvbXB1dGVTdHlsZXMsIGFwcGx5U3R5bGVzLCBvZmZzZXQsIGZsaXAsIHByZXZlbnRPdmVyZmxvdywgYXJyb3csIGhpZGVdO1xudmFyIGNyZWF0ZVBvcHBlciA9IC8qI19fUFVSRV9fKi9wb3BwZXJHZW5lcmF0b3Ioe1xuICBkZWZhdWx0TW9kaWZpZXJzOiBkZWZhdWx0TW9kaWZpZXJzXG59KTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIsIHBvcHBlckdlbmVyYXRvciwgZGVmYXVsdE1vZGlmaWVycywgZGV0ZWN0T3ZlcmZsb3cgfTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBjcmVhdGVQb3BwZXIgYXMgY3JlYXRlUG9wcGVyTGl0ZSB9IGZyb20gXCIuL3BvcHBlci1saXRlLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0ICogZnJvbSBcIi4vbW9kaWZpZXJzL2luZGV4LmpzXCI7IiwgIi8vIFRoYW5rcyB0byBAbWdtZXllcnMgZm9yIHRoZSBjcmVhdGluZyB0aGUgb2JzaWRpYW4ga2FuYmFuIHBsdWdpbiBodHRwczovL2dpdGh1Yi5jb20vbWdtZXllcnMvb2JzaWRpYW4ta2FuYmFuXHJcbi8vIGZyb20gd2hlcmUgSSBnb3QgdGhlIHRlbXBsYXRlIGNvZGUgZm9yIHRoaXMgcGx1Z2luXHJcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tZ21leWVycy9vYnNpZGlhbi1rYW5iYW4vYmxvYi80OGU2YzI3OGNlOTE0MGI3ZTAzNGIxODE0MzIzMjFmNjk3ZDZlNDVlL3NyYy9jb21wb25lbnRzL2hlbHBlcnMudHNcclxuXHJcbmltcG9ydCB7IFRGaWxlLCBBcHAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwbHlUZW1wbGF0ZShcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLFxyXG5cdGZpbGU6IFRGaWxlLFxyXG5cdHRlbXBsYXRlUGF0aD86IHN0cmluZ1xyXG4pIHtcclxuXHRjb25zdCB0ZW1wbGF0ZUZpbGUgPSB0ZW1wbGF0ZVBhdGhcclxuXHRcdD8gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGVtcGxhdGVQYXRoKVxyXG5cdFx0OiBudWxsO1xyXG5cclxuXHRpZiAodGVtcGxhdGVGaWxlICYmIHRlbXBsYXRlRmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHR0cnkge1xyXG5cclxuXHRcdFx0Y29uc3Qge1xyXG5cdFx0XHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHRcdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdFx0XHR0ZW1wbGF0ZXNQbHVnaW4sXHJcblx0XHRcdFx0dGVtcGxhdGVyUGx1Z2luLFxyXG5cdFx0XHR9ID0gZ2V0VGVtcGxhdGVQbHVnaW5zKHBsdWdpbi5hcHApO1xyXG5cdFx0XHRjb25zdCB0ZW1wbGF0ZUNvbnRlbnQgPSBhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlYWQodGVtcGxhdGVGaWxlKTtcclxuXHJcblx0XHRcdC8vIElmIGJvdGggcGx1Z2lucyBhcmUgZW5hYmxlZCwgYXR0ZW1wdCB0byBkZXRlY3QgdGVtcGxhdGVyIGZpcnN0XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCAmJiB0ZW1wbGF0ZXJFbmFibGVkKSB7XHJcblx0XHRcdFx0aWYgKC88JS8udGVzdCh0ZW1wbGF0ZUNvbnRlbnQpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHRcdHRlbXBsYXRlRmlsZSxcclxuXHRcdFx0XHRcdFx0ZmlsZVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIGF3YWl0IHRlbXBsYXRlc1BsdWdpbi5pbnN0YW5jZS5pbnNlcnRUZW1wbGF0ZSh0ZW1wbGF0ZUZpbGUpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAodGVtcGxhdGVzRW5hYmxlZCkge1xyXG5cdFx0XHRcdHJldHVybiBhd2FpdCB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2UuaW5zZXJ0VGVtcGxhdGUodGVtcGxhdGVGaWxlKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKHRlbXBsYXRlckVuYWJsZWQpIHtcclxuXHRcdFx0XHRyZXR1cm4gYXdhaXQgdGVtcGxhdGVyUGx1Z2luLndyaXRlX3RlbXBsYXRlX3RvX2ZpbGUoXHJcblx0XHRcdFx0XHR0ZW1wbGF0ZUZpbGUsXHJcblx0XHRcdFx0XHRmaWxlXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdH0gY2F0Y2ggKGUpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcihlKTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW1wbGF0ZVBsdWdpbnMoYXBwOiBBcHApIHtcclxuXHRjb25zdCB0ZW1wbGF0ZXNQbHVnaW4gPSAoYXBwIGFzIGFueSkuaW50ZXJuYWxQbHVnaW5zLnBsdWdpbnMudGVtcGxhdGVzO1xyXG5cdGNvbnN0IHRlbXBsYXRlc0VuYWJsZWQgPSB0ZW1wbGF0ZXNQbHVnaW4uZW5hYmxlZDtcclxuXHRjb25zdCB0ZW1wbGF0ZXJQbHVnaW4gPSAoYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXTtcclxuXHRjb25zdCB0ZW1wbGF0ZXJFbmFibGVkID0gKGFwcCBhcyBhbnkpLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKFxyXG5cdFx0J3RlbXBsYXRlci1vYnNpZGlhbidcclxuXHQpO1xyXG5cdGNvbnN0IHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlID1cclxuXHRcdHRlbXBsYXRlclBsdWdpbiAmJlxyXG5cdFx0KHRoaXMuYXBwIGFzIGFueSkucGx1Z2lucy5wbHVnaW5zWyd0ZW1wbGF0ZXItb2JzaWRpYW4nXS5zZXR0aW5nc1xyXG5cdFx0XHQ/LmVtcHR5X2ZpbGVfdGVtcGxhdGU7XHJcblxyXG5cdGNvbnN0IHRlbXBsYXRlRm9sZGVyID0gdGVtcGxhdGVzRW5hYmxlZFxyXG5cdFx0PyB0ZW1wbGF0ZXNQbHVnaW4uaW5zdGFuY2Uub3B0aW9ucy5mb2xkZXJcclxuXHRcdDogdGVtcGxhdGVyUGx1Z2luXHJcblx0XHRcdD8gdGVtcGxhdGVyUGx1Z2luLnNldHRpbmdzLnRlbXBsYXRlX2ZvbGRlclxyXG5cdFx0XHQ6IHVuZGVmaW5lZDtcclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHRlbXBsYXRlc1BsdWdpbixcclxuXHRcdHRlbXBsYXRlc0VuYWJsZWQsXHJcblx0XHR0ZW1wbGF0ZXJQbHVnaW46IHRlbXBsYXRlclBsdWdpbj8udGVtcGxhdGVyLFxyXG5cdFx0dGVtcGxhdGVyRW5hYmxlZCxcclxuXHRcdHRlbXBsYXRlckVtcHR5RmlsZVRlbXBsYXRlLFxyXG5cdFx0dGVtcGxhdGVGb2xkZXIsXHJcblx0fTtcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgVEZpbGUsIFBsYXRmb3JtLCBURm9sZGVyLCBUQWJzdHJhY3RGaWxlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IHR1cm5JbnRvRm9sZGVyTm90ZSB9IGZyb20gJ3NyYy9mdW5jdGlvbnMvZm9sZGVyTm90ZUZ1bmN0aW9ucyc7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsIGV4dGVuZHMgTW9kYWwge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0ZmlsZTogVEZpbGU7XHJcblx0Zm9sZGVyOiBURm9sZGVyO1xyXG5cdGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGU7XHJcblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlLCBmb2xkZXI6IFRGb2xkZXIsIGZvbGRlck5vdGU6IFRBYnN0cmFjdEZpbGUpIHtcclxuXHRcdHN1cGVyKGFwcCk7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdFx0dGhpcy5maWxlID0gZmlsZTtcclxuXHRcdHRoaXMuZm9sZGVyID0gZm9sZGVyO1xyXG5cdFx0dGhpcy5mb2xkZXJOb3RlID0gZm9sZGVyTm90ZTtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnQSBmb2xkZXIgbm90ZSBmb3IgdGhpcyBmb2xkZXIgYWxyZWFkeSBleGlzdHMnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byB0dXJuIHRoZSBub3RlIGludG8gYSBmb2xkZXIgbm90ZSBhbmQgcmVuYW1lIHRoZSBleGlzdGluZyBmb2xkZXIgbm90ZT8nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dSZW5hbWVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0dHVybkludG9Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUsIHRoaXMuZm9sZGVyLCB0aGlzLmZvbGRlck5vdGUsIHRydWUpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGNvbnN0IGNoZWNrYm94ID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdpbnB1dCcsIHsgdHlwZTogJ2NoZWNrYm94JyB9KTtcclxuXHRcdFx0Y2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGUpID0+IHtcclxuXHRcdFx0XHRjb25zdCB0YXJnZXQgPSBlLnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG5cdFx0XHRcdGlmICh0YXJnZXQuY2hlY2tlZCkge1xyXG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiA9IGZhbHNlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93UmVuYW1lQ29uZmlybWF0aW9uID0gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRjb25zdCBjaGVja0JveFRleHQgPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ3NwYW4nLCB7IHRleHQ6ICdEb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNoZWNrQm94VGV4dC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcclxuXHRcdFx0XHRjaGVja2JveC5jbGljaygpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnUmVuYW1lJyB9KTtcclxuXHRcdGJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdtb2Qtd2FybmluZycsICdmbi1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9uJyk7XHJcblx0XHRidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdHR1cm5JbnRvRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgdGhpcy5maWxlLCB0aGlzLmZvbGRlciwgdGhpcy5mb2xkZXJOb3RlLCB0cnVlKTtcclxuXHRcdH0pO1xyXG5cdFx0YnV0dG9uLmZvY3VzKCk7XHJcblx0XHRjb25zdCBjYW5jZWxCdXR0b24gPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2J1dHRvbicsIHsgdGV4dDogJ0NhbmNlbCcgfSk7XHJcblx0XHRjYW5jZWxCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XHJcblx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdH0pO1xyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCBFeGlzdGluZ0ZvbGRlck5vdGVNb2RhbCBmcm9tICcuLi9tb2RhbHMvZXhpc3RpbmdOb3RlJztcclxuaW1wb3J0IHsgYXBwbHlUZW1wbGF0ZSB9IGZyb20gJy4uL3RlbXBsYXRlJztcclxuaW1wb3J0IHsgVEZvbGRlciwgVEZpbGUsIFRBYnN0cmFjdEZpbGUsIEtleW1hcCB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsIGZyb20gJy4uL21vZGFscy9kZWxldGVDb25maXJtYXRpb24nO1xyXG5pbXBvcnQgeyBhZGRFeGNsdWRlZEZvbGRlciwgZGVsZXRlRXhjbHVkZWRGb2xkZXIsIGdldEV4Y2x1ZGVkRm9sZGVyLCBFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuLi9leGNsdWRlZEZvbGRlcic7XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIG9wZW5GaWxlOiBib29sZWFuLCB1c2VNb2RhbD86IGJvb2xlYW4sIGV4aXN0aW5nTm90ZT86IFRGaWxlKSB7XHJcblx0Y29uc3QgbGVhZiA9IHBsdWdpbi5hcHAud29ya3NwYWNlLmdldExlYWYoZmFsc2UpO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBwbHVnaW4uZ2V0Rm9sZGVyTmFtZUZyb21QYXRoU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZvbGRlck5hbWUpO1xyXG5cdGxldCBwYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSB7XHJcblx0XHRjb25zdCBwYXJlbnRGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZvbGRlclBhdGgpO1xyXG5cdFx0aWYgKHBhcmVudEZvbGRlclBhdGgudHJpbSgpID09PSAnJykge1xyXG5cdFx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAndmF1bHRGb2xkZXInKSB7XHJcblx0XHRwYXRoID0gYCR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0cGF0aCA9IGAke2ZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9JHtwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGV9YDtcclxuXHR9XHJcblx0bGV0IGZpbGU6IFRGaWxlO1xyXG5cdGlmICghZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRmaWxlID0gYXdhaXQgcGx1Z2luLmFwcC52YXVsdC5jcmVhdGUocGF0aCwgJycpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRmaWxlID0gZXhpc3RpbmdOb3RlO1xyXG5cdFx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZXhpc3RpbmdOb3RlLCBwYXRoKTtcclxuXHR9XHJcblx0aWYgKG9wZW5GaWxlKSB7XHJcblx0XHRhd2FpdCBsZWFmLm9wZW5GaWxlKGZpbGUpO1xyXG5cdH1cclxuXHRpZiAoZmlsZSAmJiAhZXhpc3RpbmdOb3RlKSB7XHJcblx0XHRhcHBseVRlbXBsYXRlKHRoaXMsIGZpbGUsIHBsdWdpbi5zZXR0aW5ncy50ZW1wbGF0ZVBhdGgpO1xyXG5cdH1cclxuXHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0dXJuSW50b0ZvbGRlck5vdGUocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZmlsZTogVEZpbGUsIGZvbGRlcjogVEZvbGRlciwgZm9sZGVyTm90ZT86IFRGaWxlIHwgbnVsbCB8IFRBYnN0cmFjdEZpbGUsIHNraXBDb25maXJtYXRpb24/OiBib29sZWFuKSB7XHJcblx0aWYgKGZvbGRlck5vdGUpIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3Muc2hvd1JlbmFtZUNvbmZpcm1hdGlvbiAmJiAhc2tpcENvbmZpcm1hdGlvbikge1xyXG5cdFx0XHRyZXR1cm4gbmV3IEV4aXN0aW5nRm9sZGVyTm90ZU1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSwgZm9sZGVyLCBmb2xkZXJOb3RlKS5vcGVuKCk7XHJcblx0XHR9XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyTm90ZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdFx0bGV0IGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IHRydWU7XHJcblx0XHRsZXQgZGlzYWJsZWRTeW5jID0gZmFsc2U7XHJcblxyXG5cdFx0aWYgKCFleGNsdWRlZEZvbGRlcikge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlckV4aXN0ZWQgPSBmYWxzZTtcclxuXHRcdFx0ZXhjbHVkZWRGb2xkZXIgPSBuZXcgRXhjbHVkZWRGb2xkZXIoZm9sZGVyLnBhdGgsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdGNvbnN0IG5ld1BhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmb2xkZXIubmFtZX0gKCR7ZmlsZS5zdGF0LmN0aW1lLnRvU3RyaW5nKCkuc2xpY2UoMTApICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMCl9KSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHRwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmb2xkZXJOb3RlLCBuZXdQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVyLm5hbWU7XHJcblx0Y29uc3QgZmlsZU5hbWUgPSBwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUucmVwbGFjZSgne3tmb2xkZXJfbmFtZX19JywgZm9sZGVyTmFtZSk7XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdGlmIChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJykge1xyXG5cdFx0Y29uc3QgcGFyZW50Rm9sZGVyUGF0aCA9IGZvbGRlci5wYXJlbnQ/LnBhdGg7XHJcblx0XHRpZiAoIXBhcmVudEZvbGRlclBhdGgpIHJldHVybjtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0cGF0aCA9IGAke2ZpbGVOYW1lfSR7cGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVUeXBlfWA7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRwYXRoID0gYCR7cGFyZW50Rm9sZGVyUGF0aH0vJHtmaWxlTmFtZX0ke3BsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZX1gO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBwYXRoKTtcclxuXHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwocGF0aCwgJ2lzLWZvbGRlci1ub3RlJywgdHJ1ZSk7XHJcblx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuRm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBUQWJzdHJhY3RGaWxlLCBldnQ/OiBNb3VzZUV2ZW50KSB7XHJcblx0Y29uc3QgcGF0aCA9IGZpbGUucGF0aDtcclxuXHRpZiAocGx1Z2luLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpPy5wYXRoID09PSBwYXRoKSB7IHJldHVybjsgfVxyXG5cdGNvbnN0IGxlYWYgPSBwbHVnaW4uYXBwLndvcmtzcGFjZS5nZXRMZWFmKEtleW1hcC5pc01vZEV2ZW50KGV2dCkgfHwgcGx1Z2luLnNldHRpbmdzLm9wZW5Jbk5ld1RhYik7XHJcblx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0YXdhaXQgbGVhZi5vcGVuRmlsZShmaWxlKTtcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxldGVGb2xkZXJOb3RlKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIGZpbGU6IFRGaWxlKSB7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uKSB7XHJcblx0XHRyZXR1cm4gbmV3IERlbGV0ZUNvbmZpcm1hdGlvbk1vZGFsKHBsdWdpbi5hcHAsIHBsdWdpbiwgZmlsZSkub3BlbigpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIocGx1Z2luLCBmaWxlKTtcclxuXHRpZiAoIWZvbGRlcikgcmV0dXJuO1xyXG5cdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdGF3YWl0IHBsdWdpbi5hcHAudmF1bHQuZGVsZXRlKGZpbGUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEZvbGRlck5hbWUodGVtcGxhdGU6IHN0cmluZywgY2hhbmdlZEZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRjb25zdCBbcHJlZml4LCBzdWZmaXhdID0gdGVtcGxhdGUuc3BsaXQoJ3t7Zm9sZGVyX25hbWV9fScpO1xyXG5cdGlmIChwcmVmaXgudHJpbSgpID09PSAnJyAmJiBzdWZmaXgudHJpbSgpID09PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZTtcclxuXHR9XHJcblx0aWYgKCFjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpIHx8ICFjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cdGlmIChjaGFuZ2VkRmlsZU5hbWUuc3RhcnRzV2l0aChwcmVmaXgpICYmIHByZWZpeC50cmltKCkgIT09ICcnKSB7XHJcblx0XHRyZXR1cm4gY2hhbmdlZEZpbGVOYW1lLnNsaWNlKHByZWZpeC5sZW5ndGgpLnJlcGxhY2Uoc3VmZml4LCAnJyk7XHJcblx0fSBlbHNlIGlmIChjaGFuZ2VkRmlsZU5hbWUuZW5kc1dpdGgoc3VmZml4KSAmJiBzdWZmaXgudHJpbSgpICE9PSAnJykge1xyXG5cdFx0cmV0dXJuIGNoYW5nZWRGaWxlTmFtZS5zbGljZSgwLCAtc3VmZml4Lmxlbmd0aCk7XHJcblx0fVxyXG5cdHJldHVybiBudWxsO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9sZGVyTm90ZShwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmb2xkZXJQYXRoOiBzdHJpbmcsIHN0b3JhZ2VMb2NhdGlvbj86IHN0cmluZywgZmlsZT86IFRGaWxlKSB7XHJcblx0aWYgKCFmb2xkZXJQYXRoKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXIgPSB7XHJcblx0XHRwYXRoOiBmb2xkZXJQYXRoLFxyXG5cdFx0bmFtZTogcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhmb2xkZXJQYXRoKSxcclxuXHR9O1xyXG5cdGxldCBmaWxlTmFtZSA9IHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZS5yZXBsYWNlKCd7e2ZvbGRlcl9uYW1lfX0nLCBmb2xkZXIubmFtZSk7XHJcblx0aWYgKGZpbGUpIHtcclxuXHRcdGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdH1cclxuXHJcblx0aWYgKChwbHVnaW4uc2V0dGluZ3Muc3RvcmFnZUxvY2F0aW9uID09PSAncGFyZW50Rm9sZGVyJyB8fCBzdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInKSAmJiBzdG9yYWdlTG9jYXRpb24gIT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmb2xkZXJQYXRoKTtcclxuXHR9XHJcblx0bGV0IHBhdGggPSBgJHtmb2xkZXIucGF0aH0vJHtmaWxlTmFtZX1gO1xyXG5cdGlmIChmb2xkZXIucGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRmb2xkZXIucGF0aCA9IGZpbGVOYW1lO1xyXG5cdFx0cGF0aCA9IGAke2ZpbGVOYW1lfWA7XHJcblx0fVxyXG5cdGxldCBmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArIHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSk7XHJcblx0aWYgKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0cmV0dXJuIGZvbGRlck5vdGU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZVR5cGUgPT09ICcuY2FudmFzJykge1xyXG5cdFx0XHRmb2xkZXJOb3RlID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGF0aCArICcubWQnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoICsgJy5jYW52YXMnKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmb2xkZXJOb3RlO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSwgc3RvcmFnZUxvY2F0aW9uPzogc3RyaW5nKSB7XHJcblx0aWYgKCFmaWxlKSByZXR1cm4gbnVsbDtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBmaWxlLmJhc2VuYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCk7XHJcblx0bGV0IGZvbGRlcjogVEZvbGRlciB8IFRBYnN0cmFjdEZpbGUgfCBudWxsID0gbnVsbDtcclxuXHRpZiAoKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdwYXJlbnRGb2xkZXInIHx8IHN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpICYmIHN0b3JhZ2VMb2NhdGlvbiAhPT0gJ2luc2lkZUZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0XHRmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0Zm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCk7XHJcblx0fVxyXG5cdGlmICghZm9sZGVyKSB7IHJldHVybiBudWxsOyB9XHJcblx0cmV0dXJuIGZvbGRlcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTm90ZTogVEZpbGUgfCBzdHJpbmcsIGZpbGVOYW1lOiBzdHJpbmcpIHtcclxuXHRpZiAoIWZvbGRlck5vdGUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmaWxlUGF0aCA9ICcnO1xyXG5cdGlmICh0eXBlb2YgZm9sZGVyTm90ZSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdGZpbGVQYXRoID0gZm9sZGVyTm90ZTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0ZmlsZU5hbWUgPSBmb2xkZXJOb3RlLmJhc2VuYW1lO1xyXG5cdFx0ZmlsZVBhdGggPSBmb2xkZXJOb3RlLnBhdGg7XHJcblx0fVxyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIGZpbGVOYW1lKTtcclxuXHRpZiAoIWZvbGRlck5hbWUpIHJldHVybiBudWxsO1xyXG5cdGxldCBmb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGVQYXRoKTtcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGlmIChmb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0Zm9sZGVyUGF0aCA9IGZvbGRlck5hbWU7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb2xkZXJQYXRoID0gYCR7Zm9sZGVyUGF0aH0vJHtmb2xkZXJOYW1lfWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZVBhdGgpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXIgPSBwbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmb2xkZXJQYXRoKTtcclxuXHRpZiAoIWZvbGRlcikgeyByZXR1cm4gbnVsbDsgfVxyXG5cdHJldHVybiBmb2xkZXI7XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgTW9kYWwsIFNldHRpbmcsIFRGaWxlLCBQbGF0Zm9ybSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEZWxldGVDb25maXJtYXRpb25Nb2RhbCBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGZpbGU6IFRGaWxlO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBmaWxlOiBURmlsZSkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLmZpbGUgPSBmaWxlO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdEZWxldGUgZm9sZGVyIG5vdGUnIH0pO1xyXG5cdFx0Y29uc3Qgc2V0dGluZyA9IG5ldyBTZXR0aW5nKGNvbnRlbnRFbCk7XHJcblx0XHRzZXR0aW5nLmluZm9FbC5jcmVhdGVFbCgncCcsIHsgdGV4dDogYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhlIGZvbGRlciBub3RlIFwiJHt0aGlzLmZpbGUubmFtZX1cIiA/YCB9KTtcclxuXHRcdHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnSXQgd2lsbCBiZSBtb3ZlZCB0byB5b3VyIHN5c3RlbSB0cmFzaC4nIH0pO1xyXG5cclxuXHRcdHNldHRpbmcuaW5mb0VsLnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwnKTtcclxuXHJcblx0XHQvLyBDcmVhdGUgYSBjb250YWluZXIgZm9yIHRoZSBidXR0b25zIGFuZCB0aGUgY2hlY2tib3hcclxuXHRcdGNvbnN0IGJ1dHRvbkNvbnRhaW5lciA9IHNldHRpbmcuaW5mb0VsLmNyZWF0ZUVsKCdkaXYnLCB7IGNsczogJ2ZuLWRlbGV0ZS1jb25maXJtYXRpb24tbW9kYWwtYnV0dG9ucycgfSk7XHJcblx0XHRpZiAoUGxhdGZvcm0uaXNNb2JpbGVBcHApIHtcclxuXHRcdFx0Y29uc3QgY29uZmlybUJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnRGVsZXRlIGFuZCBkb25cXCd0IGFzayBhZ2FpbicgfSk7XHJcblx0XHRcdGNvbmZpcm1CdXR0b24uY2xhc3NMaXN0LmFkZCgnbW9kLXdhcm5pbmcnLCAnZm4tY29uZmlybWF0aW9uLW1vZGFsLWJ1dHRvbicpO1xyXG5cdFx0XHRjb25maXJtQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSBmYWxzZTtcclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHR0aGlzLmNsb3NlKCk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyKHRoaXMucGx1Z2luLCB0aGlzLmZpbGUpO1xyXG5cdFx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdFx0dGhpcy5wbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwoZm9sZGVyPy5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdFx0dGhpcy5hcHAudmF1bHQuZGVsZXRlKHRoaXMuZmlsZSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y29uc3QgY2hlY2tib3ggPSBidXR0b25Db250YWluZXIuY3JlYXRlRWwoJ2lucHV0JywgeyB0eXBlOiAnY2hlY2tib3gnIH0pO1xyXG5cdFx0XHRjaGVja2JveC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZSkgPT4ge1xyXG5cdFx0XHRcdGNvbnN0IHRhcmdldCA9IGUudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcblx0XHRcdFx0aWYgKHRhcmdldC5jaGVja2VkKSB7XHJcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93RGVsZXRlQ29uZmlybWF0aW9uID0gZmFsc2U7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dEZWxldGVDb25maXJtYXRpb24gPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0fSk7XHJcblx0XHRcdGNvbnN0IGNoZWNrQm94VGV4dCA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnc3BhbicsIHsgdGV4dDogJ0RvblxcJ3QgYXNrIGFnYWluJyB9KTtcclxuXHRcdFx0Y2hlY2tCb3hUZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG5cdFx0XHRcdGNoZWNrYm94LmNsaWNrKCk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdFx0Y29uc3QgYnV0dG9uID0gYnV0dG9uQ29udGFpbmVyLmNyZWF0ZUVsKCdidXR0b24nLCB7IHRleHQ6ICdEZWxldGUnIH0pO1xyXG5cdFx0YnV0dG9uLmNsYXNzTGlzdC5hZGQoJ21vZC13YXJuaW5nJywgJ2ZuLWNvbmZpcm1hdGlvbi1tb2RhbC1idXR0b24nKTtcclxuXHRcdGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXIodGhpcy5wbHVnaW4sIHRoaXMuZmlsZSk7XHJcblx0XHRcdGlmICghZm9sZGVyKSByZXR1cm47XHJcblx0XHRcdHRoaXMucGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlci5wYXRoLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmRlbGV0ZSh0aGlzLmZpbGUpO1xyXG5cdFx0fSk7XHJcblx0XHRidXR0b24uZm9jdXMoKTtcclxuXHRcdGNvbnN0IGNhbmNlbEJ1dHRvbiA9IGJ1dHRvbkNvbnRhaW5lci5jcmVhdGVFbCgnYnV0dG9uJywgeyB0ZXh0OiAnQ2FuY2VsJyB9KTtcclxuXHRcdGNhbmNlbEJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGFzeW5jICgpID0+IHtcclxuXHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0fSk7XHJcblxyXG5cdH1cclxuXHRvbkNsb3NlKCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IFNldHRpbmcgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuL21haW4nO1xyXG5pbXBvcnQgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBmcm9tICcuL21vZGFscy9leGNsdWRlRm9sZGVyU2V0dGluZ3MnO1xyXG5pbXBvcnQgeyBGb2xkZXJTdWdnZXN0IH0gZnJvbSAnLi9zdWdnZXN0ZXJzL0ZvbGRlclN1Z2dlc3Rlcic7XHJcbmltcG9ydCB7IFNldHRpbmdzVGFiIH0gZnJvbSAnLi9zZXR0aW5ncyc7XHJcbmltcG9ydCBQYXR0ZXJuU2V0dGluZ3MgZnJvbSAnLi9tb2RhbHMvcGF0dGVyblNldHRpbmdzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFeGNsdWRlZEZvbGRlciB7XHJcblx0dHlwZTogc3RyaW5nO1xyXG5cdHBhdGg6IHN0cmluZztcclxuXHRzdHJpbmc6IHN0cmluZztcclxuXHRzdWJGb2xkZXJzOiBib29sZWFuO1xyXG5cdGRpc2FibGVTeW5jOiBib29sZWFuO1xyXG5cdGRpc2FibGVBdXRvQ3JlYXRlOiBib29sZWFuO1xyXG5cdGRpc2FibGVGb2xkZXJOb3RlOiBib29sZWFuO1xyXG5cdGVuYWJsZUNvbGxhcHNpbmc6IGJvb2xlYW47XHJcblx0cG9zaXRpb246IG51bWJlcjtcclxuXHRjb25zdHJ1Y3RvcihwYXRoOiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIpIHtcclxuXHRcdHRoaXMudHlwZSA9ICdmb2xkZXInO1xyXG5cdFx0dGhpcy5wYXRoID0gcGF0aDtcclxuXHRcdHRoaXMuc3ViRm9sZGVycyA9IHRydWU7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247XHJcblx0XHR0aGlzLnN0cmluZyA9ICcnO1xyXG5cdH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIEV4Y2x1ZGVQYXR0ZXJuIHtcclxuXHR0eXBlOiBzdHJpbmc7XHJcblx0c3RyaW5nOiBzdHJpbmc7XHJcblx0cGF0aDogc3RyaW5nO1xyXG5cdHBvc2l0aW9uOiBudW1iZXI7XHJcblx0c3ViRm9sZGVyczogYm9vbGVhbjtcclxuXHRkaXNhYmxlU3luYzogYm9vbGVhbjtcclxuXHRkaXNhYmxlQXV0b0NyZWF0ZTogYm9vbGVhbjtcclxuXHRkaXNhYmxlRm9sZGVyTm90ZTogYm9vbGVhbjtcclxuXHRlbmFibGVDb2xsYXBzaW5nOiBib29sZWFuO1xyXG5cdGNvbnN0cnVjdG9yKHBhdHRlcm46IHN0cmluZywgcG9zaXRpb246IG51bWJlcikge1xyXG5cdFx0dGhpcy50eXBlID0gJ3BhdHRlcm4nO1xyXG5cdFx0dGhpcy5zdHJpbmcgPSBwYXR0ZXJuO1xyXG5cdFx0dGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uO1xyXG5cdFx0dGhpcy5zdWJGb2xkZXJzID0gZmFsc2U7XHJcblx0XHR0aGlzLmRpc2FibGVTeW5jID0gdHJ1ZTtcclxuXHRcdHRoaXMuZGlzYWJsZUF1dG9DcmVhdGUgPSB0cnVlO1xyXG5cdFx0dGhpcy5kaXNhYmxlRm9sZGVyTm90ZSA9IGZhbHNlO1xyXG5cdFx0dGhpcy5lbmFibGVDb2xsYXBzaW5nID0gZmFsc2U7XHJcblx0XHR0aGlzLnBhdGggPSAnJztcclxuXHR9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXRoOiBzdHJpbmcpIHtcclxuXHRjb25zdCBmb2xkZXJOYW1lID0gcGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhwYXRoKTtcclxuXHRjb25zdCBtYXRjaGVkUGF0dGVybiA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXR0ZXJuKHBsdWdpbiwgZm9sZGVyTmFtZSk7XHJcblx0aWYgKG1hdGNoZWRQYXR0ZXJuKSB7IHJldHVybiBtYXRjaGVkUGF0dGVybjsgfVxyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbiwgcGF0aCk7XHJcblx0cmV0dXJuIGV4Y2x1ZGVkRm9sZGVyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXhjbHVkZWRGb2xkZXJCeVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZm9sZGVyTmFtZTogc3RyaW5nKSB7XHJcblx0cmV0dXJuIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maWx0ZXIoKHMpID0+IHMucGF0aCA9PT0gJycpLmZpbmQoKHBhdHRlcm4pID0+IHtcclxuXHRcdGlmICghcGF0dGVybi5zdHJpbmcpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAocGF0dGVybi5zdHJpbmcudG9Mb2NhbGVMb3dlckNhc2UoKS5zdGFydHNXaXRoKCd7cmVnZXh9JykgJiYgcGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpICE9PSAnJykge1xyXG5cdFx0XHRjb25zdCBtYXRjaCA9IG5ldyBSZWdFeHAocGF0dGVybi5zdHJpbmcuc2xpY2UoNykudHJpbSgpKS5leGVjKGZvbGRlck5hbWUpO1xyXG5cdFx0XHRpZiAobWF0Y2gpIHtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmIChwYXR0ZXJuLnN0cmluZy5zdGFydHNXaXRoKCcqJykgJiYgcGF0dGVybi5zdHJpbmcuZW5kc1dpdGgoJyonKSkge1xyXG5cdFx0XHRpZiAoZm9sZGVyTmFtZS5pbmNsdWRlcyhwYXR0ZXJuLnN0cmluZy5zbGljZSgxLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSBpZiAocGF0dGVybi5zdHJpbmcuc3RhcnRzV2l0aCgnKicpKSB7XHJcblx0XHRcdGlmIChmb2xkZXJOYW1lLmVuZHNXaXRoKHBhdHRlcm4uc3RyaW5nLnNsaWNlKDEpKSkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHBhdHRlcm4uc3RyaW5nLmVuZHNXaXRoKCcqJykpIHtcclxuXHRcdFx0aWYgKGZvbGRlck5hbWUuc3RhcnRzV2l0aChwYXR0ZXJuLnN0cmluZy5zbGljZSgwLCAtMSkpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEV4Y2x1ZGVkRm9sZGVyQnlQYXRoKHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4sIHBhdGg6IHN0cmluZykge1xyXG5cdHJldHVybiBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZXhjbHVkZWRGb2xkZXIpID0+IHtcclxuXHRcdGlmIChleGNsdWRlZEZvbGRlci5wYXRoID09PSBwYXRoKSB7IHJldHVybiB0cnVlOyB9XHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRyZXR1cm4gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKHBhdGgpLnN0YXJ0c1dpdGgoZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0fSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlcik7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCB8fCBmb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKTtcclxuXHRwbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0cmVzeW5jQXJyYXkocGx1Z2luKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4pIHtcclxuXHRwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKChmb2xkZXIpID0+IGZvbGRlci5zdHJpbmcgIT09IHBhdHRlcm4uc3RyaW5nIHx8IGZvbGRlci50eXBlID09PSAnZm9sZGVyJyk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cdHJlc3luY0FycmF5KHBsdWdpbik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZVBhdHRlcm4sIG5ld0V4Y2x1ZGVGb2xkZXI6IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIucGF0aCAhPT0gZXhjbHVkZWRGb2xkZXIucGF0aCk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdFeGNsdWRlRm9sZGVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVBhdHRlcm4ocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgcGF0dGVybjogRXhjbHVkZVBhdHRlcm4sIG5ld1BhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzID0gcGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcigoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nICE9PSBwYXR0ZXJuLnN0cmluZyk7XHJcblx0YWRkRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBuZXdQYXR0ZXJuKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVzeW5jQXJyYXkocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5zb3J0KChhLCBiKSA9PiBhLnBvc2l0aW9uIC0gYi5wb3NpdGlvbik7XHJcblx0cGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZvckVhY2goKGZvbGRlciwgaW5kZXgpID0+IHtcclxuXHRcdGZvbGRlci5wb3NpdGlvbiA9IGluZGV4O1xyXG5cdH0pO1xyXG5cdHBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZEV4Y2x1ZGVQYXR0ZXJuTGlzdEl0ZW0oc2V0dGluZ3M6IFNldHRpbmdzVGFiLCBjb250YWluZXJFbDogSFRNTEVsZW1lbnQsIHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuKSB7XHJcblx0Y29uc3QgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiA9IHNldHRpbmdzLnBsdWdpbjtcclxuXHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpO1xyXG5cdHNldHRpbmcuc2V0Q2xhc3MoJ2ZuLWV4Y2x1ZGUtZm9sZGVyLWxpc3QnKTtcclxuXHRzZXR0aW5nLmFkZFNlYXJjaCgoY2IpID0+IHtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignUGF0dGVybicpO1xyXG5cdFx0Y2Iuc2V0VmFsdWUocGF0dGVybi5zdHJpbmcpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmIChwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIuc3RyaW5nID09PSB2YWx1ZSkpIHsgcmV0dXJuOyB9XHJcblx0XHRcdHBhdHRlcm4uc3RyaW5nID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuLCBwYXR0ZXJuKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBwYXR0ZXJuJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0bmV3IFBhdHRlcm5TZXR0aW5ncyhwbHVnaW4uYXBwLCBwbHVnaW4sIHBhdHRlcm4pLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAocGF0dGVybi5wb3NpdGlvbiA9PT0gMCkgeyByZXR1cm47IH1cclxuXHRcdFx0cGF0dGVybi5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCdkb3duLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgZG93bicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGlmIChwYXR0ZXJuLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRwYXR0ZXJuLnBvc2l0aW9uICs9IDE7XHJcblxyXG5cdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgcGF0dGVybiwgcGF0dGVybik7XHJcblx0XHRcdGNvbnN0IG9sZFBhdHRlcm4gPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IHBhdHRlcm4ucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkUGF0dGVybikge1xyXG5cdFx0XHRcdG9sZFBhdHRlcm4ucG9zaXRpb24gLT0gMTtcclxuXHRcdFx0XHRpZiAob2xkUGF0dGVybi50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRQYXR0ZXJuLCBvbGRQYXR0ZXJuKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0c2V0dGluZ3MuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0fSk7XHJcblx0c2V0dGluZy5hZGRCdXR0b24oKGNiKSA9PiB7XHJcblx0XHRjYi5zZXRJY29uKCd0cmFzaC0yJyk7XHJcblx0XHRjYi5zZXRUb29sdGlwKCdEZWxldGUgcGF0dGVybicpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdGRlbGV0ZVBhdHRlcm4ocGx1Z2luLCBwYXR0ZXJuKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gYWRkRXhjbHVkZUZvbGRlckxpc3RJdGVtKHNldHRpbmdzOiBTZXR0aW5nc1RhYiwgY29udGFpbmVyRWw6IEhUTUxFbGVtZW50LCBleGNsdWRlZEZvbGRlcjogRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRjb25zdCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luID0gc2V0dGluZ3MucGx1Z2luO1xyXG5cdGNvbnN0IHNldHRpbmcgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbCk7XHJcblx0c2V0dGluZy5zZXRDbGFzcygnZm4tZXhjbHVkZS1mb2xkZXItbGlzdCcpO1xyXG5cdHNldHRpbmcuYWRkU2VhcmNoKChjYikgPT4ge1xyXG5cdFx0bmV3IEZvbGRlclN1Z2dlc3QoXHJcblx0XHRcdGNiLmlucHV0RWwsXHJcblx0XHRcdHBsdWdpblxyXG5cdFx0KTtcclxuXHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdGNiLmNvbnRhaW5lckVsLmFkZENsYXNzKCdmbi1leGNsdWRlLWZvbGRlci1wYXRoJyk7XHJcblx0XHRjYi5zZXRQbGFjZWhvbGRlcignRm9sZGVyIHBhdGgnKTtcclxuXHRcdGNiLnNldFZhbHVlKGV4Y2x1ZGVkRm9sZGVyLnBhdGgpO1xyXG5cdFx0Y2Iub25DaGFuZ2UoKHZhbHVlKSA9PiB7XHJcblx0XHRcdGlmICh2YWx1ZS5zdGFydHNXaXRoKCd7cmVnZXh9JykgfHwgdmFsdWUuaW5jbHVkZXMoJyonKSkge1xyXG5cdFx0XHRcdGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdGNvbnN0IHBhdHRlcm4gPSBuZXcgRXhjbHVkZVBhdHRlcm4odmFsdWUsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRcdGFkZEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgcGF0dGVybik7XHJcblx0XHRcdFx0YWRkRXhjbHVkZVBhdHRlcm5MaXN0SXRlbShzZXR0aW5ncywgY29udGFpbmVyRWwsIHBhdHRlcm4pO1xyXG5cdFx0XHRcdHNldHRpbmcuY2xlYXIoKTtcclxuXHRcdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIXBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKHZhbHVlKSkgcmV0dXJuO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gdmFsdWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cdHNldHRpbmcuYWRkQnV0dG9uKChjYikgPT4ge1xyXG5cdFx0Y2Iuc2V0SWNvbignZWRpdCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnRWRpdCBmb2xkZXIgbm90ZScpO1xyXG5cdFx0Y2Iub25DbGljaygoKSA9PiB7XHJcblx0XHRcdG5ldyBFeGNsdWRlZEZvbGRlclNldHRpbmdzKHBsdWdpbi5hcHAsIHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIpLm9wZW4oKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG5cclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3VwLWNoZXZyb24tZ2x5cGgnKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ01vdmUgdXAnKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucG9zaXRpb24gPT09IDApIHsgcmV0dXJuOyB9XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uIC09IDE7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0Y29uc3Qgb2xkRXhjbHVkZWRGb2xkZXIgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmluZCgoZm9sZGVyKSA9PiBmb2xkZXIucG9zaXRpb24gPT09IGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uKTtcclxuXHRcdFx0aWYgKG9sZEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdFx0b2xkRXhjbHVkZWRGb2xkZXIucG9zaXRpb24gKz0gMTtcclxuXHRcdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIudHlwZSA9PT0gJ3BhdHRlcm4nKSB7XHJcblx0XHRcdFx0XHR1cGRhdGVQYXR0ZXJuKHBsdWdpbiwgb2xkRXhjbHVkZWRGb2xkZXIsIG9sZEV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ2Rvd24tY2hldnJvbi1nbHlwaCcpO1xyXG5cdFx0Y2Iuc2V0VG9vbHRpcCgnTW92ZSBkb3duJyk7XHJcblx0XHRjYi5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0aWYgKGV4Y2x1ZGVkRm9sZGVyLnBvc2l0aW9uID09PSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wb3NpdGlvbiArPSAxO1xyXG5cclxuXHRcdFx0dXBkYXRlRXhjbHVkZWRGb2xkZXIocGx1Z2luLCBleGNsdWRlZEZvbGRlciwgZXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRjb25zdCBvbGRFeGNsdWRlZEZvbGRlciA9IHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmb2xkZXIpID0+IGZvbGRlci5wb3NpdGlvbiA9PT0gZXhjbHVkZWRGb2xkZXIucG9zaXRpb24pO1xyXG5cdFx0XHRpZiAob2xkRXhjbHVkZWRGb2xkZXIpIHtcclxuXHRcdFx0XHRvbGRFeGNsdWRlZEZvbGRlci5wb3NpdGlvbiAtPSAxO1xyXG5cdFx0XHRcdGlmIChvbGRFeGNsdWRlZEZvbGRlci50eXBlID09PSAncGF0dGVybicpIHtcclxuXHRcdFx0XHRcdHVwZGF0ZVBhdHRlcm4ocGx1Z2luLCBvbGRFeGNsdWRlZEZvbGRlciwgb2xkRXhjbHVkZWRGb2xkZXIpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIG9sZEV4Y2x1ZGVkRm9sZGVyLCBvbGRFeGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzZXR0aW5ncy5kaXNwbGF5KCk7XHJcblx0XHR9KTtcclxuXHR9KTtcclxuXHRzZXR0aW5nLmFkZEJ1dHRvbigoY2IpID0+IHtcclxuXHRcdGNiLnNldEljb24oJ3RyYXNoLTInKTtcclxuXHRcdGNiLnNldFRvb2x0aXAoJ0RlbGV0ZSBleGNsdWRlZCBmb2xkZXInKTtcclxuXHRcdGNiLm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0c2V0dGluZy5jbGVhcigpO1xyXG5cdFx0XHRzZXR0aW5nLnNldHRpbmdFbC5yZW1vdmUoKTtcclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcbiIsICJpbXBvcnQgeyBBcHAsIE1vZGFsLCBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmltcG9ydCB7IEV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnc3JjL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhjbHVkZWRGb2xkZXJTZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGV4Y2x1ZGVkRm9sZGVyOiBFeGNsdWRlZEZvbGRlcjtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgZXhjbHVkZWRGb2xkZXI6IEV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRzdXBlcihhcHApO1xyXG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XHJcblx0XHR0aGlzLmFwcCA9IGFwcDtcclxuXHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIgPSBleGNsdWRlZEZvbGRlcjtcclxuXHR9XHJcblx0b25PcGVuKCkge1xyXG5cdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0fVxyXG5cdGRpc3BsYXkoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKCdoMicsIHsgdGV4dDogJ0V4Y2x1ZGVkIGZvbGRlciBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdJbmNsdWRlIHN1YmZvbGRlcnMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBzdWJmb2xkZXJzIG9mIHRoZSBmb2xkZXIgc2hvdWxkIGFsc28gYmUgZXhjbHVkZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5zdWJGb2xkZXJzKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLnN1YkZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgZm9sZGVyIG5hbWUgc3luYycpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBub3RlIHNob3VsZCBiZSByZW5hbWVkIHdoZW4gdGhlIGZvbGRlciBuYW1lIGlzIGNoYW5nZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYylcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMuZXhjbHVkZWRGb2xkZXIuZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSlcclxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0dGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHRcdGlmICghdGhpcy5leGNsdWRlZEZvbGRlci5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcpXHJcblx0XHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLmV4Y2x1ZGVkRm9sZGVyLmVuYWJsZUNvbGxhcHNpbmcgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0fSlcclxuXHRcdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcbiIsICIvLyBDcmVkaXRzIGdvIHRvIExpYW0ncyBQZXJpb2RpYyBOb3RlcyBQbHVnaW46IGh0dHBzOi8vZ2l0aHViLmNvbS9saWFtY2Fpbi9vYnNpZGlhbi1wZXJpb2RpYy1ub3RlcyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL1NpbGVudFZvaWQxMy9UZW1wbGF0ZXJcclxuXHJcbmltcG9ydCB7IFRBYnN0cmFjdEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IFRleHRJbnB1dFN1Z2dlc3QgfSBmcm9tICcuL3N1Z2dlc3QnO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi4vbWFpbic7XHJcbmV4cG9ydCBlbnVtIEZpbGVTdWdnZXN0TW9kZSB7XHJcbiAgICBUZW1wbGF0ZUZpbGVzLFxyXG4gICAgU2NyaXB0RmlsZXMsXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBGb2xkZXJTdWdnZXN0IGV4dGVuZHMgVGV4dElucHV0U3VnZ2VzdDxURm9sZGVyPiB7XHJcblx0Y29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGlucHV0RWw6IEhUTUxJbnB1dEVsZW1lbnQsXHJcbiAgICAgICAgcHJpdmF0ZSBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luXHJcblx0KSB7XHJcblx0XHRzdXBlcihpbnB1dEVsKTtcclxuXHR9XHJcblxyXG5cclxuXHRnZXRfZXJyb3JfbXNnKG1vZGU6IEZpbGVTdWdnZXN0TW9kZSk6IHN0cmluZyB7XHJcblx0XHRzd2l0Y2ggKG1vZGUpIHtcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuVGVtcGxhdGVGaWxlczpcclxuXHRcdFx0XHRyZXR1cm4gJ1RlbXBsYXRlcyBmb2xkZXIgZG9lc25cXCd0IGV4aXN0JztcclxuXHRcdFx0Y2FzZSBGaWxlU3VnZ2VzdE1vZGUuU2NyaXB0RmlsZXM6XHJcblx0XHRcdFx0cmV0dXJuICdVc2VyIFNjcmlwdHMgZm9sZGVyIGRvZXNuXFwndCBleGlzdCc7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRnZXRTdWdnZXN0aW9ucyhpbnB1dF9zdHI6IHN0cmluZyk6IFRGb2xkZXJbXSB7XHJcblx0XHRjb25zdCBmb2xkZXJzOiBURm9sZGVyW10gPSBbXTtcclxuXHRcdGNvbnN0IGxvd2VyX2lucHV0X3N0ciA9IGlucHV0X3N0ci50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFsbExvYWRlZEZpbGVzKCkuZm9yRWFjaCgoZm9sZGVyOiBUQWJzdHJhY3RGaWxlKSA9PiB7XHJcblx0XHRcdGlmIChcclxuXHRcdFx0XHRmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyICYmXHJcbiAgICAgICAgICAgICAgICBmb2xkZXIucGF0aC50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKGxvd2VyX2lucHV0X3N0cikgJiZcclxuICAgICAgICAgICAgICAgICF0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5maW5kKChmKSA9PiBmLnBhdGggPT09IGZvbGRlci5wYXRoKVxyXG5cdFx0XHQpIHtcclxuXHRcdFx0XHRmb2xkZXJzLnB1c2goZm9sZGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIGZvbGRlcnM7XHJcblx0fVxyXG5cclxuXHRyZW5kZXJTdWdnZXN0aW9uKGZvbGRlcjogVEZvbGRlciwgZWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcblx0XHRlbC5zZXRUZXh0KGZvbGRlci5wYXRoKTtcclxuXHR9XHJcblxyXG5cdHNlbGVjdFN1Z2dlc3Rpb24oZm9sZGVyOiBURm9sZGVyKTogdm9pZCB7XHJcblx0XHR0aGlzLmlucHV0RWwudmFsdWUgPSBmb2xkZXIucGF0aDtcclxuXHRcdHRoaXMuaW5wdXRFbC50cmlnZ2VyKCdpbnB1dCcpO1xyXG5cdFx0dGhpcy5jbG9zZSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4uL21haW4nO1xyXG5pbXBvcnQgeyBFeGNsdWRlUGF0dGVybiB9IGZyb20gJ3NyYy9leGNsdWRlZEZvbGRlcic7XHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhdHRlcm5TZXR0aW5ncyBleHRlbmRzIE1vZGFsIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdHBhdHRlcm46IEV4Y2x1ZGVQYXR0ZXJuO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBwYXR0ZXJuOiBFeGNsdWRlUGF0dGVybikge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuO1xyXG5cdH1cclxuXHRvbk9wZW4oKSB7XHJcblx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHR9XHJcblx0ZGlzcGxheSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnUGF0dGVybiBzZXR0aW5ncycgfSk7XHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIGZvbGRlciBuYW1lIHN5bmMnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbmFtZSBzaG91bGQgYmUgcmVuYW1lZCB3aGVuIHRoZSBmaWxlIG5hbWUgaGFzIGJlZW4gY2hhbmdlZCcpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cclxuXHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZGlzYWJsZVN5bmMpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5kaXNhYmxlU3luYyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBhdXRvIGNyZWF0aW9uIG9mIGZvbGRlciBub3RlcyBpbiB0aGlzIGZvbGRlcicpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgYSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgY3JlYXRlZCB3aGVuIGEgbmV3IGZvbGRlciBpcyBjcmVhdGVkIHRoYXQgbWF0Y2hlcyB0aGlzIHBhdHRlcm4nKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVBdXRvQ3JlYXRlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUF1dG9DcmVhdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdEaXNhYmxlIG9wZW4gZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIGlmIHRoZSBmb2xkZXIgbm90ZSBzaG91bGQgYmUgb3BlbmVkIHdoZW4gdGhlIGZvbGRlciBpcyBvcGVuZWQnKVxyXG5cdFx0XHQuYWRkVG9nZ2xlKCh0b2dnbGUpID0+XHJcblx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wYXR0ZXJuLmRpc2FibGVGb2xkZXJOb3RlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnBhdHRlcm4uZGlzYWJsZUZvbGRlck5vdGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRpZiAoIXRoaXMucGF0dGVybi5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ0NvbGxhcHNlIGZvbGRlciB3aGVuIG9wZW5pbmcgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaWYgdGhlIGZvbGRlciBzaG91bGQgYmUgY29sbGFwc2VkIHdoZW4gdGhlIGZvbGRlciBub3RlIGlzIG9wZW5lZCcpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBhdHRlcm4uZW5hYmxlQ29sbGFwc2luZylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMucGF0dGVybi5lbmFibGVDb2xsYXBzaW5nID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XHJcblx0XHRcdFx0XHRcdH0pXHJcblx0XHRcdFx0KTtcclxuXHRcdH1cclxuXHJcblx0fVxyXG5cdG9uQ2xvc2UoKSB7XHJcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcclxuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xyXG5cdH1cclxufVxyXG4iLCAiaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJ3NyYy9tYWluJztcclxuaW1wb3J0IHsgZ2V0RGVmZXIsIExpc3RlbmVyLCBFdmVudHMsIEFwaUludGVyZmFjZSwgRGVmZXJJbnRlcmZhY2UsIExpc3RlbmVyUmVmLCBFdmVudERpc3BhdGNoZXJJbnRlcmZhY2UgfSBmcm9tICdmcm9udC1tYXR0ZXItcGx1Z2luLWFwaS1wcm92aWRlcic7XHJcbmltcG9ydCB7IEFwcCwgVEZpbGUsIFRGb2xkZXIgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IGV4dHJhY3RGb2xkZXJOYW1lLCBnZXRGb2xkZXIgfSBmcm9tICdzcmMvZnVuY3Rpb25zL2ZvbGRlck5vdGVGdW5jdGlvbnMnO1xyXG5leHBvcnQgY2xhc3MgRnJvbnRNYXR0ZXJUaXRsZVBsdWdpbkhhbmRsZXIge1xyXG5cdHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW47XHJcblx0YXBwOiBBcHA7XHJcblx0YXBpOiBBcGlJbnRlcmZhY2UgfCBudWxsID0gbnVsbDtcclxuXHRkZWZmZXI6IERlZmVySW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XHJcblx0bW9kaWZpZWRGb2xkZXJzOiBNYXA8c3RyaW5nLCBURm9sZGVyPiA9IG5ldyBNYXAoKTtcclxuXHRldmVudFJlZjogTGlzdGVuZXJSZWY8J21hbmFnZXI6dXBkYXRlJz47XHJcblx0ZGlzcGF0Y2hlcjogRXZlbnREaXNwYXRjaGVySW50ZXJmYWNlPEV2ZW50cz5cclxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gcGx1Z2luLmFwcDtcclxuXHJcblx0XHQoYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHR0aGlzLmRlZmZlciA9IGdldERlZmVyKHRoaXMuYXBwKTtcclxuXHRcdFx0aWYgKHRoaXMuZGVmZmVyLmlzUGx1Z2luUmVhZHkoKSkge1xyXG5cdFx0XHRcdHRoaXMuYXBpID0gdGhpcy5kZWZmZXIuZ2V0QXBpKCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0YXdhaXQgdGhpcy5kZWZmZXIuYXdhaXRQbHVnaW4oKTtcclxuXHRcdFx0XHR0aGlzLmFwaSA9IHRoaXMuZGVmZmVyLmdldEFwaSgpO1xyXG5cdFx0XHRcdC8vIGlmIHlvdSB3YW50IHRvIHdhaXQgZmVhdHVyZXMgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjaGFpblxyXG5cdFx0XHRcdGlmICghdGhpcy5kZWZmZXIuaXNGZWF0dXJlc1JlYWR5KCkpIHtcclxuXHRcdFx0XHRcdGF3YWl0IHRoaXMuZGVmZmVyLmF3YWl0RmVhdHVyZXMoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0Y29uc3QgZGlzcGF0Y2hlciA9IHRoaXMuYXBpPy5nZXRFdmVudERpc3BhdGNoZXIoKTtcclxuXHRcdFx0aWYgKGRpc3BhdGNoZXIpIHtcclxuXHRcdFx0XHR0aGlzLmRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbnN0IGV2ZW50OiBMaXN0ZW5lcjxFdmVudHMsICdtYW5hZ2VyOnVwZGF0ZSc+ID0ge1xyXG5cdFx0XHRcdG5hbWU6ICdtYW5hZ2VyOnVwZGF0ZScsXHJcblx0XHRcdFx0Y2I6IChkYXRhKSA9PiB7XHJcblx0XHRcdFx0XHR0aGlzLmhhbmRsZVJlbmFtZShkYXRhIGFzIGFueSwgdHJ1ZSk7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0fTtcclxuXHRcdFx0Ly8gS2VlcCByZWYgdG8gcmVtb3ZlIGxpc3RlbmVyXHJcblx0XHRcdGNvbnN0IHJlZiA9IGRpc3BhdGNoZXI/LmFkZExpc3RlbmVyKGV2ZW50KTtcclxuXHRcdFx0aWYgKHJlZikge1xyXG5cdFx0XHRcdHRoaXMuZXZlbnRSZWYgPSByZWY7XHJcblx0XHRcdH1cclxuXHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEZpbGVzKCkuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRcdHRoaXMuaGFuZGxlUmVuYW1lKHsgaWQ6ICcnLCByZXN1bHQ6IGZhbHNlLCBwYXRoOiBmaWxlLnBhdGggfSwgZmFsc2UpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0dGhpcy5wbHVnaW4udXBkYXRlQnJlYWRjcnVtYnMoKTtcclxuXHRcdH0pKCk7XHJcblx0fVxyXG5cdGRlbGV0ZUV2ZW50KCkge1xyXG5cdFx0aWYgKHRoaXMuZXZlbnRSZWYpIHtcclxuXHRcdFx0dGhpcy5kaXNwYXRjaGVyLnJlbW92ZUxpc3RlbmVyKHRoaXMuZXZlbnRSZWYpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRhc3luYyBoYW5kbGVSZW5hbWUoZGF0YToge1xyXG5cdFx0aWQ6IHN0cmluZztcclxuXHRcdHJlc3VsdDogYm9vbGVhbjtcclxuXHRcdHBhdGg6IHN0cmluZztcclxuXHR9LCBpc0V2ZW50OiBib29sZWFuKSB7XHJcblx0XHRpZiAoKGRhdGEgYXMgYW55KS5kYXRhKSBkYXRhID0gKGRhdGEgYXMgYW55KS5kYXRhXHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGRhdGEucGF0aCk7XHJcblx0XHRpZiAoIShmaWxlIGluc3RhbmNlb2YgVEZpbGUpKSB7IHJldHVybjsgfVxyXG5cclxuXHRcdGNvbnN0IHJlc29sdmVyID0gdGhpcy5hcGk/LmdldFJlc29sdmVyRmFjdG9yeSgpPy5jcmVhdGVSZXNvbHZlcignI2ZlYXR1cmUtaWQjJyk7XHJcblx0XHRjb25zdCBuZXdOYW1lID0gcmVzb2x2ZXI/LnJlc29sdmUoZmlsZT8ucGF0aCA/PyAnJylcclxuXHRcdGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcih0aGlzLnBsdWdpbiwgZmlsZSk7XHJcblxyXG5cdFx0aWYgKChleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZSkgIT09IGZvbGRlcj8ubmFtZSkgeyByZXR1cm47IH1cclxuXHRcdGlmICghKGZvbGRlciBpbnN0YW5jZW9mIFRGb2xkZXIpKSB7IHJldHVybjsgfVxyXG5cdFx0aWYgKGlzRXZlbnQpIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIHRydWUpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5wbHVnaW4uY2hhbmdlTmFtZShmb2xkZXIsIG5ld05hbWUsIGZhbHNlKTtcclxuXHRcdH1cclxuXHRcdGlmIChuZXdOYW1lKSB7XHJcblx0XHRcdGZvbGRlci5uZXdOYW1lID0gbmV3TmFtZTtcclxuXHRcdFx0dGhpcy5tb2RpZmllZEZvbGRlcnMuc2V0KGZvbGRlci5wYXRoLCBmb2xkZXIpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Zm9sZGVyLm5ld05hbWUgPSBudWxsO1xyXG5cdFx0XHR0aGlzLm1vZGlmaWVkRm9sZGVycy5kZWxldGUoZm9sZGVyLnBhdGgpO1xyXG5cdFx0fVxyXG5cclxuXHR9XHJcbn1cclxuIiwgImltcG9ydCB7IEFwcCwgVEZvbGRlciwgTWVudSwgVEFic3RyYWN0RmlsZSwgTm90aWNlLCBURmlsZSwgRWRpdG9yLCBNYXJrZG93blZpZXcsIFBsYXRmb3JtIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnLi9tYWluJztcclxuaW1wb3J0IHsgZ2V0Rm9sZGVyTm90ZSwgY3JlYXRlRm9sZGVyTm90ZSwgZGVsZXRlRm9sZGVyTm90ZSwgdHVybkludG9Gb2xkZXJOb3RlLCBvcGVuRm9sZGVyTm90ZSwgZXh0cmFjdEZvbGRlck5hbWUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgRXhjbHVkZWRGb2xkZXIgfSBmcm9tICcuL2V4Y2x1ZGVkRm9sZGVyJztcclxuZXhwb3J0IGNsYXNzIENvbW1hbmRzIHtcclxuXHRwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luO1xyXG5cdGFwcDogQXBwO1xyXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcclxuXHRcdHRoaXMuYXBwID0gYXBwO1xyXG5cdH1cclxuXHRyZWdpc3RlckNvbW1hbmRzKCkge1xyXG5cdFx0dGhpcy5wbHVnaW4ucmVnaXN0ZXJFdmVudCh0aGlzLnBsdWdpbi5hcHAud29ya3NwYWNlLm9uKCdlZGl0b3ItbWVudScsIChtZW51OiBNZW51LCBlZGl0b3I6IEVkaXRvciwgdmlldzogTWFya2Rvd25WaWV3KSA9PiB7XHJcblx0XHRcdGNvbnN0IHRleHQgPSBlZGl0b3IuZ2V0U2VsZWN0aW9uKCkudHJpbSgpO1xyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpdGVtLnNldFRpdGxlKCdDcmVhdGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdC5zZXRJY29uKCdlZGl0JylcclxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oJ2BgYGZvbGRlci1vdmVydmlld1xcbmBgYFxcbicpO1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHRpZiAoIXRleHQgfHwgdGV4dC50cmltKCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdG1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0NyZWF0ZSBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdGNvbnN0IGZpbGUgPSB2aWV3LmZpbGU7XHJcblx0XHRcdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0Y29uc3QgYmxhY2tsaXN0ID0gWycqJywgJ1xcXFwnLCAnXCInLCAnLycsICc8JywgJz4nLCAnPycsICd8JywgJzonXTtcclxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCBjaGFyIG9mIGJsYWNrbGlzdCkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICh0ZXh0LmluY2x1ZGVzKGNoYXIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGNvbnRhaW4gYW55IG9mIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogKiBcIiBcXFxcIC8gPCA+IDogfCA/Jyk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGlmICh0ZXh0LmVuZHNXaXRoKCcuJykpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdGaWxlIG5hbWUgY2Fubm90IGVuZCB3aXRoIGEgZG90Jyk7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGxldCBmb2xkZXI6IFRBYnN0cmFjdEZpbGUgfCBudWxsO1xyXG5cdFx0XHRcdFx0XHRjb25zdCBmb2xkZXJQYXRoID0gdGhpcy5wbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdFx0XHRcdFx0aWYgKGZvbGRlclBhdGggPT09ICcnKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0ZXh0KTtcclxuXHRcdFx0XHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBub3RlIGFscmVhZHkgZXhpc3RzJyk7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5jcmVhdGVGb2xkZXIodGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0XHRjcmVhdGVGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCB0ZXh0LCBmYWxzZSk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdGZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gbmV3IE5vdGljZSgnRm9sZGVyIG5vdGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICh0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZm9sZGVyUGF0aCArICcvJyArIHRleHQgKyB0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlVHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZpbGUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihmb2xkZXJQYXRoICsgJy8nICsgdGV4dCk7XHJcblx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyUGF0aCArICcvJyArIHRleHQsIGZhbHNlKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlTmFtZSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIHRleHQpO1xyXG5cdFx0XHRcdFx0XHRpZiAoZmlsZU5hbWUgPT09IHRleHQpIHtcclxuXHRcdFx0XHRcdFx0XHRlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgW1ske2ZpbGVOYW1lfV1dYCk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFtbJHtmaWxlTmFtZX18JHt0ZXh0fV1dYCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pKTtcclxuXHRcdHRoaXMucGx1Z2luLnJlZ2lzdGVyRXZlbnQodGhpcy5hcHAud29ya3NwYWNlLm9uKCdmaWxlLW1lbnUnLCAobWVudTogTWVudSwgZmlsZTogVEFic3RyYWN0RmlsZSkgPT4ge1xyXG5cdFx0XHRsZXQgZm9sZGVyOiBUQWJzdHJhY3RGaWxlIHwgVEZvbGRlciB8IG51bGwgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRcdGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRcdFx0XHRmb2xkZXIgPSBmaWxlLnBhcmVudDtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0XHRcdFx0XHRpZiAoZmlsZU5hbWUpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGZpbGUucGFyZW50Py5wYXRoID09PSAnJyB8fCBmaWxlLnBhcmVudD8ucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlTmFtZSk7XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0Zm9sZGVyID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlLnBhcmVudD8ucGF0aCArICcvJyArIGZpbGVOYW1lKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdFx0Y29uc3QgZm9sZGVyTm90ZSA9IGdldEZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZvbGRlci5wYXRoKTtcclxuXHRcdFx0XHRcdGlmIChmb2xkZXJOb3RlPy5wYXRoID09PSBmaWxlLnBhdGgpIHsgcmV0dXJuOyB9XHJcblx0XHRcdFx0fSBlbHNlIGlmIChmaWxlLnBhcmVudCBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRcdGZvbGRlciA9IGZpbGUucGFyZW50O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRpZiAoUGxhdGZvcm0uaXNEZXNrdG9wICYmICFQbGF0Zm9ybS5pc1RhYmxldCAmJiB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VTdWJtZW51cykge1xyXG5cdFx0XHRcdFx0aXRlbVxyXG5cdFx0XHRcdFx0XHQuc2V0VGl0bGUoJ0ZvbGRlciBOb3RlIENvbW1hbmRzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ2ZvbGRlci1lZGl0Jyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxldCBzdWJNZW51OiBNZW51O1xyXG5cdFx0XHRcdGlmICghUGxhdGZvcm0uaXNEZXNrdG9wQXBwIHx8ICFQbGF0Zm9ybS5pc0Rlc2t0b3AgfHwgUGxhdGZvcm0uaXNUYWJsZXQgfHwgIXRoaXMucGx1Z2luLnNldHRpbmdzLnVzZVN1Ym1lbnVzKSB7XHJcblx0XHRcdFx0XHRzdWJNZW51ID0gbWVudTtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0RGlzYWJsZWQodHJ1ZSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdHN1Yk1lbnUgPSBpdGVtLnNldFN1Ym1lbnUoKSBhcyBNZW51O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCFmb2xkZXIpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGxldCBuZXdQYXRoID0gZm9sZGVyLnBhdGggKyAnLycgKyBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKGZvbGRlci5wYXRoID09PSAnJyB8fCBmb2xkZXIucGF0aCA9PT0gJy8nKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdG5ld1BhdGggPSBmaWxlLmJhc2VuYW1lO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG5ldyBOb3RpY2UoJ0ZvbGRlciBhbHJlYWR5IGV4aXN0cycpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihuZXdQYXRoKTtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG5ld0ZvbGRlciA9IHRoaXMucGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobmV3UGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIShuZXdGb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgbmV3Rm9sZGVyLnBhdGgsIHRydWUsIGZhbHNlLCBmaWxlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGZpbGUucGF0aCkgPT09ICcnKSByZXR1cm47XHJcblx0XHRcdFx0XHRpZiAoIShmb2xkZXIgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdFx0c3ViTWVudS5hZGRJdGVtKChpdGVtKSA9PiB7XHJcblx0XHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ1R1cm4gaW50byBmb2xkZXIgbm90ZScpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ2VkaXQnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghZm9sZGVyIHx8ICEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXIucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0dXJuSW50b0ZvbGRlck5vdGUodGhpcy5wbHVnaW4sIGZpbGUsIGZvbGRlciwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpKSByZXR1cm47XHJcblx0XHRcdFx0aWYgKHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbmQoKGZvbGRlcikgPT4gZm9sZGVyLnBhdGggPT09IGZpbGUucGF0aCkpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdSZW1vdmUgZm9sZGVyIGZyb20gZXhjbHVkZWQgZm9sZGVycycpXHJcblx0XHRcdFx0XHRcdFx0LnNldEljb24oJ3RyYXNoJylcclxuXHRcdFx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmV4Y2x1ZGVGb2xkZXJzLmZpbHRlcihcclxuXHRcdFx0XHRcdFx0XHRcdFx0KGZvbGRlcikgPT4gZm9sZGVyLnBhdGggIT09IGZpbGUucGF0aCk7XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoJ1N1Y2Nlc3NmdWxseSByZW1vdmVkIGZvbGRlciBmcm9tIGV4Y2x1ZGVkIGZvbGRlcnMnKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdGl0ZW0uc2V0VGl0bGUoJ0V4Y2x1ZGUgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJylcclxuXHRcdFx0XHRcdFx0LnNldEljb24oJ3gtY2lyY2xlJylcclxuXHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdGNvbnN0IGV4Y2x1ZGVkRm9sZGVyID0gbmV3IEV4Y2x1ZGVkRm9sZGVyKGZpbGUucGF0aCwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMubGVuZ3RoKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5wdXNoKGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKCdTdWNjZXNzZnVsbHkgZXhjbHVkZWQgZm9sZGVyIGZyb20gZm9sZGVyIG5vdGVzJyk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSkgcmV0dXJuO1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmaWxlLnBhdGgpO1xyXG5cdFx0XHRcdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdEZWxldGUgZm9sZGVyIG5vdGUnKVxyXG5cdFx0XHRcdFx0XHRcdC5zZXRJY29uKCd0cmFzaCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGVsZXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZm9sZGVyTm90ZSk7XHJcblx0XHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdHN1Yk1lbnUuYWRkSXRlbSgoaXRlbSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpdGVtLnNldFRpdGxlKCdPcGVuIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignY2hldnJvbi1yaWdodC1zcXVhcmUnKVxyXG5cdFx0XHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRcdFx0XHRcdG9wZW5Gb2xkZXJOb3RlKHRoaXMucGx1Z2luLCBmb2xkZXJOb3RlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRzdWJNZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcclxuXHRcdFx0XHRcdFx0aXRlbS5zZXRUaXRsZSgnQ3JlYXRlIGZvbGRlciBub3RlJylcclxuXHRcdFx0XHRcdFx0XHQuc2V0SWNvbignZWRpdCcpXHJcblx0XHRcdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdFx0Y3JlYXRlRm9sZGVyTm90ZSh0aGlzLnBsdWdpbiwgZmlsZS5wYXRoLCB0cnVlKTtcclxuXHRcdFx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHR9KSk7XHJcblx0fVxyXG59XHJcbiIsICJpbXBvcnQgeyBLZXltYXAgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICdzcmMvbWFpbic7XHJcbmltcG9ydCB7IG9wZW5Gb2xkZXJOb3RlLCBjcmVhdGVGb2xkZXJOb3RlLCBnZXRGb2xkZXJOb3RlIH0gZnJvbSAnc3JjL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIgfSBmcm9tICdzcmMvZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlVmlld0hlYWRlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50LCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0aWYgKCEoZXZlbnQudGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSByZXR1cm47XHJcblx0aWYgKCFwbHVnaW4uc2V0dGluZ3Mub3BlbkZvbGRlck5vdGVPbkNsaWNrSW5QYXRoKSByZXR1cm47XHJcblxyXG5cdGNvbnN0IGZvbGRlclBhdGggPSBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXBhdGgnKTtcclxuXHRpZiAoIWZvbGRlclBhdGgpIHsgcmV0dXJuOyB9XHJcblx0Y29uc3QgZXhjbHVkZWRGb2xkZXIgPSBnZXRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChleGNsdWRlZEZvbGRlcj8uZGlzYWJsZUZvbGRlck5vdGUpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAoZXhjbHVkZWRGb2xkZXI/LmVuYWJsZUNvbGxhcHNpbmcgfHwgcGx1Z2luLnNldHRpbmdzLmVuYWJsZUNvbGxhcHNpbmcpIHtcclxuXHRcdGV2ZW50LnRhcmdldC5vbmNsaWNrID0gbnVsbDtcclxuXHRcdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG5cdH1cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlRm9sZGVyQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRpZiAoIShldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHJldHVybjtcclxuXHRldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuXHJcblx0Y29uc3QgZm9sZGVyUGF0aCA9IGV2ZW50LnRhcmdldC5wYXJlbnRFbGVtZW50Py5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGF0aCcpO1xyXG5cdGlmICghZm9sZGVyUGF0aCkgeyByZXR1cm47IH1cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZm9sZGVyUGF0aCk7XHJcblx0aWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlRm9sZGVyTm90ZSkge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0XHRyZXR1cm47XHJcblx0fSBlbHNlIGlmIChleGNsdWRlZEZvbGRlcj8uZW5hYmxlQ29sbGFwc2luZyB8fCBwbHVnaW4uc2V0dGluZ3MuZW5hYmxlQ29sbGFwc2luZykge1xyXG5cdFx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdFx0ZXZlbnQudGFyZ2V0LmNsaWNrKCk7XHJcblx0fVxyXG5cclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIGZvbGRlclBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gb3BlbkZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJOb3RlLCBldmVudCk7XHJcblx0fSBlbHNlIGlmIChldmVudC5hbHRLZXkgfHwgS2V5bWFwLmlzTW9kRXZlbnQoZXZlbnQpID09PSAndGFiJykge1xyXG5cdFx0aWYgKChwbHVnaW4uc2V0dGluZ3MuYWx0S2V5ICYmIGV2ZW50LmFsdEtleSkgfHwgKHBsdWdpbi5zZXR0aW5ncy5jdHJsS2V5ICYmIEtleW1hcC5pc01vZEV2ZW50KGV2ZW50KSA9PT0gJ3RhYicpKSB7XHJcblx0XHRcdGF3YWl0IGNyZWF0ZUZvbGRlck5vdGUocGx1Z2luLCBmb2xkZXJQYXRoLCB0cnVlLCB0cnVlKTtcclxuXHRcdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZvbGRlclBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZvbGRlclBhdGgsICdoYXMtbm90LWZvbGRlci1ub3RlJyk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHR9XHJcblx0ZXZlbnQudGFyZ2V0Lm9uY2xpY2sgPSBudWxsO1xyXG5cdGV2ZW50LnRhcmdldC5jbGljaygpO1xyXG59XHJcbiIsICJpbXBvcnQgeyBURmlsZSwgVEZvbGRlciwgVEFic3RyYWN0RmlsZSwgTm90aWNlIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgRm9sZGVyTm90ZXNQbHVnaW4gZnJvbSAnc3JjL21haW4nO1xyXG5pbXBvcnQgeyBleHRyYWN0Rm9sZGVyTmFtZSwgZ2V0Rm9sZGVyTm90ZSwgZ2V0Rm9sZGVyTm90ZUZvbGRlciB9IGZyb20gJy4uL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IHsgZ2V0RXhjbHVkZWRGb2xkZXIsIEV4Y2x1ZGVkRm9sZGVyLCBhZGRFeGNsdWRlZEZvbGRlciwgdXBkYXRlRXhjbHVkZWRGb2xkZXIsIGRlbGV0ZUV4Y2x1ZGVkRm9sZGVyIH0gZnJvbSAnLi4vZXhjbHVkZWRGb2xkZXInO1xyXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRm9sZGVyUmVuYW1lKGZpbGU6IFRGb2xkZXIsIG9sZFBhdGg6IHN0cmluZywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGNvbnN0IGZpbGVOYW1lID0gcGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLnJlcGxhY2UoJ3t7Zm9sZGVyX25hbWV9fScsIGZpbGUubmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoZmlsZS5wYXRoKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgpO1xyXG5cdGlmICghKGZvbGRlck5vdGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHJcblx0aWYgKCEoZm9sZGVyIGluc3RhbmNlb2YgVEZvbGRlcikpIHJldHVybjtcclxuXHRjb25zdCBleGNsdWRlZEZvbGRlcnMgPSBwbHVnaW4uc2V0dGluZ3MuZXhjbHVkZUZvbGRlcnMuZmlsdGVyKFxyXG5cdFx0KGV4Y2x1ZGVkRm9sZGVyKSA9PiBleGNsdWRlZEZvbGRlci5wYXRoLmluY2x1ZGVzKG9sZFBhdGgpXHJcblx0KTtcclxuXHJcblx0ZXhjbHVkZWRGb2xkZXJzLmZvckVhY2goKGV4Y2x1ZGVkRm9sZGVyKSA9PiB7XHJcblx0XHRpZiAoZXhjbHVkZWRGb2xkZXIucGF0aCA9PT0gb2xkUGF0aCkge1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVyLnBhdGg7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdGNvbnN0IGZvbGRlcnMgPSBleGNsdWRlZEZvbGRlci5wYXRoLnNwbGl0KCcvJyk7XHJcblx0XHRpZiAoZm9sZGVycy5sZW5ndGggPCAxKSB7XHJcblx0XHRcdGZvbGRlcnMucHVzaChleGNsdWRlZEZvbGRlci5wYXRoKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb2xkZXJzW2ZvbGRlcnMuaW5kZXhPZihmb2xkZXIubmFtZSldID0gZm9sZGVyLm5hbWU7XHJcblx0XHRleGNsdWRlZEZvbGRlci5wYXRoID0gZm9sZGVycy5qb2luKCcvJyk7XHJcblx0fSk7XHJcblx0cGx1Z2luLnNhdmVTZXR0aW5ncygpO1xyXG5cclxuXHRjb25zdCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZmlsZS5wYXRoKTtcclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmICFmb2xkZXJOb3RlKSB7XHJcblx0XHRyZXR1cm4gcGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdH1cclxuXHJcblx0bGV0IG5ld1BhdGggPSAnJztcclxuXHRpZiAocGx1Z2luLnNldHRpbmdzLnN0b3JhZ2VMb2NhdGlvbiA9PT0gJ3BhcmVudEZvbGRlcicpIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGNvbnN0IG9sZFBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcob2xkUGF0aCk7XHJcblx0XHRpZiAocGFyZW50Rm9sZGVyUGF0aCAhPT0gb2xkUGFyZW50Rm9sZGVyUGF0aCkge1xyXG5cdFx0XHRpZiAoIXBsdWdpbi5zZXR0aW5ncy5zeW5jTW92ZSkgeyByZXR1cm47IH1cclxuXHRcdFx0bmV3UGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSBpZiAocGFyZW50Rm9sZGVyUGF0aC50cmltKCkgPT09ICcnKSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZvbGRlck5vdGUubmFtZX1gO1xyXG5cdFx0XHRuZXdQYXRoID0gYCR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvbGRlck5vdGUucGF0aCA9IGAke3BhcmVudEZvbGRlclBhdGh9LyR7Zm9sZGVyTm90ZS5uYW1lfWA7XHJcblx0XHRcdG5ld1BhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke2ZpbGVOYW1lfS4ke2ZvbGRlck5vdGUuZXh0ZW5zaW9ufWA7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGZvbGRlck5vdGUucGF0aCA9IGAke2ZpbGUucGF0aH0vJHtmb2xkZXJOb3RlLm5hbWV9YDtcclxuXHRcdG5ld1BhdGggPSBgJHtmaWxlLnBhdGh9LyR7ZmlsZU5hbWV9LiR7Zm9sZGVyTm90ZS5leHRlbnNpb259YDtcclxuXHR9XHJcblx0cGx1Z2luLmFwcC52YXVsdC5yZW5hbWUoZm9sZGVyTm90ZSwgbmV3UGF0aCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVGaWxlUmVuYW1lKGZpbGU6IFRGaWxlLCBvbGRQYXRoOiBzdHJpbmcsIHBsdWdpbjogRm9sZGVyTm90ZXNQbHVnaW4pIHtcclxuXHRjb25zdCBvbGRGaWxlTmFtZSA9IHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZpbGVOYW1lRnJvbVBhdGhTdHJpbmcob2xkUGF0aCkpO1xyXG5cdGNvbnN0IG9sZEZvbGRlciA9IGdldEZvbGRlck5vdGVGb2xkZXIocGx1Z2luLCBvbGRQYXRoLCBvbGRGaWxlTmFtZSk7XHJcblx0Y29uc3QgZm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSkgfHwgZmlsZS5iYXNlbmFtZTtcclxuXHRjb25zdCBvbGRGb2xkZXJOYW1lID0gZXh0cmFjdEZvbGRlck5hbWUocGx1Z2luLnNldHRpbmdzLmZvbGRlck5vdGVOYW1lLCBvbGRGaWxlTmFtZSkgfHwgb2xkRmlsZU5hbWU7XHJcblx0Y29uc3QgbmV3Rm9sZGVyID0gZ2V0Rm9sZGVyTm90ZUZvbGRlcihwbHVnaW4sIGZpbGUsIGZpbGUuYmFzZW5hbWUpO1xyXG5cdGxldCBleGNsdWRlZEZvbGRlciA9IGdldEV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgbmV3Rm9sZGVyPy5wYXRoIHx8ICcnKTtcclxuXHRjb25zdCBmb2xkZXJOb3RlID0gZ2V0Rm9sZGVyTm90ZShwbHVnaW4sIG9sZFBhdGgsIHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24sIGZpbGUpO1xyXG5cclxuXHRpZiAoZXhjbHVkZWRGb2xkZXI/LmRpc2FibGVTeW5jICYmIGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSkge1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwobmV3Rm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHJldHVybjtcclxuXHR9IGVsc2UgaWYgKGV4Y2x1ZGVkRm9sZGVyPy5kaXNhYmxlU3luYykge1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwobmV3Rm9sZGVyPy5wYXRoIHx8ICcnLCAnaGFzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyBmaWxlIGhhcyBiZWVuIG1vdmVkIGludG8gcG9zaXRpb24gd2hlcmUgaXQgY2FuIGJlIGEgZm9sZGVyIG5vdGUhXHJcblx0aWYgKGZvbGRlck5hbWUgPT09IG5ld0ZvbGRlcj8ubmFtZSAmJiBmb2xkZXJOb3RlKSB7XHJcblx0XHRuZXcgTm90aWNlKCdGb2xkZXIgd2l0aCBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMhJyk7XHJcblx0XHRsZXQgZXhjbHVkZWRGb2xkZXJFeGlzdGVkID0gdHJ1ZTtcclxuXHRcdGxldCBkaXNhYmxlZFN5bmMgPSBmYWxzZTtcclxuXHJcblx0XHRpZiAoIWV4Y2x1ZGVkRm9sZGVyKSB7XHJcblx0XHRcdGV4Y2x1ZGVkRm9sZGVyRXhpc3RlZCA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlciA9IG5ldyBFeGNsdWRlZEZvbGRlcihvbGRGb2xkZXI/LnBhdGggfHwgJycsIHBsdWdpbi5zZXR0aW5ncy5leGNsdWRlRm9sZGVycy5sZW5ndGgpO1xyXG5cdFx0XHRhZGRFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH0gZWxzZSBpZiAoIWV4Y2x1ZGVkRm9sZGVyLmRpc2FibGVTeW5jKSB7XHJcblx0XHRcdGRpc2FibGVkU3luYyA9IGZhbHNlO1xyXG5cdFx0XHRleGNsdWRlZEZvbGRlci5kaXNhYmxlU3luYyA9IHRydWU7XHJcblx0XHRcdHVwZGF0ZUV4Y2x1ZGVkRm9sZGVyKHBsdWdpbiwgZXhjbHVkZWRGb2xkZXIsIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKS50aGVuKCgpID0+IHtcclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlcikgeyByZXR1cm47IH1cclxuXHRcdFx0aWYgKCFleGNsdWRlZEZvbGRlckV4aXN0ZWQpIHtcclxuXHRcdFx0XHRkZWxldGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyKTtcclxuXHRcdFx0fSBlbHNlIGlmICghZGlzYWJsZWRTeW5jKSB7XHJcblx0XHRcdFx0ZXhjbHVkZWRGb2xkZXIuZGlzYWJsZVN5bmMgPSBmYWxzZTtcclxuXHRcdFx0XHR1cGRhdGVFeGNsdWRlZEZvbGRlcihwbHVnaW4sIGV4Y2x1ZGVkRm9sZGVyLCBleGNsdWRlZEZvbGRlcik7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH1cclxuXHRpZiAoZm9sZGVyTmFtZSA9PT0gbmV3Rm9sZGVyPy5uYW1lKSB7XHJcblx0XHRwbHVnaW4uYWRkQ1NTQ2xhc3NUb1RpdGxlRUwoZmlsZS5wYXRoLCAnaXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChuZXdGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKG9sZEZvbGRlcj8ucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gZmlsZSBtYXRjaGVkIGZvbGRlciBuYW1lIGJlZm9yZSByZW5hbWVcclxuXHQvLyBmaWxlIGhhc250IG1vdmVkIGp1c3QgcmVuYW1lZFxyXG5cdC8vIE5lZWQgdG8gcmVuYW1lIHRoZSBmb2xkZXJcclxuXHRpZiAoIW9sZEZvbGRlcikgcmV0dXJuO1xyXG5cdGlmIChvbGRGb2xkZXJOYW1lID09PSBvbGRGb2xkZXIubmFtZSAmJiBuZXdGb2xkZXI/LnBhdGggPT09IG9sZEZvbGRlci5wYXRoKSB7XHJcblx0XHRyZXR1cm4gcmVuYW1lRm9sZGVyT25GaWxlUmVuYW1lKGZpbGUsIG9sZFBhdGgsIG9sZEZvbGRlciwgcGx1Z2luKTtcclxuXHR9IGVsc2UgaWYgKGZvbGRlck5vdGUgJiYgb2xkRm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHJldHVybiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZSwgb2xkUGF0aCwgb2xkRm9sZGVyLCBwbHVnaW4pO1xyXG5cdH1cclxuXHJcblx0Ly8gdGhlIG5vdGUgaGFzIGJlZW4gbW92ZWQgc29tZXdoZXJlIGFuZCBpcyBubyBsb25nZXIgYSBmb2xkZXIgbm90ZVxyXG5cdC8vIGNsZWFudXAgY3NzIG9uIHRoZSBmb2xkZXIgYW5kIG5vdGVcclxuXHRpZiAob2xkRm9sZGVyLm5hbWUgPT09IG9sZEZpbGVOYW1lICYmIG5ld0ZvbGRlcj8ucGF0aCAhPT0gb2xkRm9sZGVyLnBhdGgpIHtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLnJlbW92ZUNTU0NsYXNzRnJvbUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkUGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0fVxyXG59XHJcblxyXG5hc3luYyBmdW5jdGlvbiByZW5hbWVGb2xkZXJPbkZpbGVSZW5hbWUoZmlsZTogVEZpbGUsIG9sZFBhdGg6IHN0cmluZywgb2xkRm9sZGVyOiBUQWJzdHJhY3RGaWxlLCBwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luKSB7XHJcblx0Y29uc3QgbmV3Rm9sZGVyTmFtZSA9IGV4dHJhY3RGb2xkZXJOYW1lKHBsdWdpbi5zZXR0aW5ncy5mb2xkZXJOb3RlTmFtZSwgZmlsZS5iYXNlbmFtZSk7XHJcblx0aWYgKCFuZXdGb2xkZXJOYW1lKSB7XHJcblx0XHRwbHVnaW4ucmVtb3ZlQ1NTQ2xhc3NGcm9tRUwob2xkRm9sZGVyLnBhdGgsICdoYXMtZm9sZGVyLW5vdGUnKTtcclxuXHRcdHBsdWdpbi5yZW1vdmVDU1NDbGFzc0Zyb21FTChmaWxlLnBhdGgsICdpcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH0gZWxzZSBpZiAobmV3Rm9sZGVyTmFtZSA9PT0gb2xkRm9sZGVyLm5hbWUpIHtcclxuXHRcdHBsdWdpbi5hZGRDU1NDbGFzc1RvVGl0bGVFTChvbGRGb2xkZXIucGF0aCwgJ2hhcy1mb2xkZXItbm90ZScpO1xyXG5cdFx0cGx1Z2luLmFkZENTU0NsYXNzVG9UaXRsZUVMKGZpbGUucGF0aCwgJ2lzLWZvbGRlci1ub3RlJyk7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cdGxldCBuZXdGb2xkZXJQYXRoID0gJyc7XHJcblx0aWYgKHBsdWdpbi5zZXR0aW5ncy5zdG9yYWdlTG9jYXRpb24gPT09ICdpbnNpZGVGb2xkZXInKSB7XHJcblx0XHRuZXdGb2xkZXJQYXRoID0gb2xkRm9sZGVyLnBhcmVudD8ucGF0aCArICcvJyArIG5ld0ZvbGRlck5hbWU7XHJcblx0fSBlbHNlIHtcclxuXHRcdGNvbnN0IHBhcmVudEZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmIChwYXJlbnRGb2xkZXJQYXRoLnRyaW0oKSA9PT0gJycpIHtcclxuXHRcdFx0bmV3Rm9sZGVyUGF0aCA9IGAke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG5ld0ZvbGRlclBhdGggPSBgJHtwYXJlbnRGb2xkZXJQYXRofS8ke25ld0ZvbGRlck5hbWV9YDtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlclBhdGgpIHx8IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKG5ld0ZvbGRlck5hbWUgfHwgJycpKSB7XHJcblx0XHRhd2FpdCBwbHVnaW4uYXBwLnZhdWx0LnJlbmFtZShmaWxlLCBvbGRQYXRoKTtcclxuXHRcdHJldHVybiBuZXcgTm90aWNlKCdBIGZvbGRlciB3aXRoIHRoZSBzYW1lIG5hbWUgYWxyZWFkeSBleGlzdHMnKTtcclxuXHR9XHJcblx0YXdhaXQgcGx1Z2luLmFwcC52YXVsdC5yZW5hbWUob2xkRm9sZGVyLCBuZXdGb2xkZXJQYXRoKTtcclxufVxyXG4iLCAiaW1wb3J0IHsgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgcGFyc2VZYW1sLCBUQWJzdHJhY3RGaWxlLCBURm9sZGVyLCBURmlsZSB9IGZyb20gJ29ic2lkaWFuJztcclxuaW1wb3J0IHsgZXh0cmFjdEZvbGRlck5hbWUsIGdldEZvbGRlck5vdGUgfSBmcm9tICcuL2Z1bmN0aW9ucy9mb2xkZXJOb3RlRnVuY3Rpb25zJztcclxuaW1wb3J0IEZvbGRlck5vdGVzUGx1Z2luIGZyb20gJy4vbWFpbic7XHJcbmV4cG9ydCB0eXBlIHlhbWxTZXR0aW5ncyA9IHtcclxuXHR0aXRsZT86IHN0cmluZztcclxuXHRkaXNhYmxlVGl0bGU/OiBib29sZWFuO1xyXG5cdGRlcHRoPzogbnVtYmVyO1xyXG5cdHR5cGU/OiAnZm9sZGVyJyB8ICdtYXJrZG93bicgfCAnY2FudmFzJyB8ICdvdGhlcicgfCAncGRmJyB8ICdpbWFnZXMnIHwgJ2F1ZGlvJyB8ICd2aWRlbycgfCAnYWxsJztcclxuXHRpbmNsdWRlVHlwZXM/OiBzdHJpbmdbXTtcclxuXHRzdHlsZT86ICdsaXN0JyB8ICdncmlkJztcclxuXHRkaXNhYmxlRmlsZVRhZz86IGJvb2xlYW47XHJcblx0c29ydEJ5PzogJ25hbWUnIHwgJ2NyZWF0ZWQnIHwgJ21vZGlmaWVkJyB8ICduYW1lQXNjJyB8ICdjcmVhdGVkQXNjJyB8ICdtb2RpZmllZEFzYyc7XHJcblx0c2hvd0VtcHR5Rm9sZGVycz86IGJvb2xlYW47XHJcblx0b25seUluY2x1ZGVTdWJmb2xkZXJzPzogYm9vbGVhbjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYW52YXNPdmVydmlldygpIHtcclxuXHQvLyBjb25zb2xlLmxvZygndGVzdCcpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3ZlcnZpZXcocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgc291cmNlOiBzdHJpbmcsIGVsOiBIVE1MRWxlbWVudCwgY3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0KSB7XHJcblx0Ly8gcGFyc2Ugc291cmNlIHRvIHlhbWxcclxuXHRsZXQgeWFtbDogeWFtbFNldHRpbmdzID0gcGFyc2VZYW1sKHNvdXJjZSk7XHJcblx0aWYgKCF5YW1sKSB7XHJcblx0XHR5YW1sID0ge1xyXG5cdFx0XHR0aXRsZTogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0ZGlzYWJsZVRpdGxlOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVUaXRsZSxcclxuXHRcdFx0ZGVwdGg6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGVwdGgsXHJcblx0XHRcdHR5cGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0aW5jbHVkZVR5cGVzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyxcclxuXHRcdFx0c3R5bGU6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc3R5bGUsXHJcblx0XHRcdGRpc2FibGVGaWxlVGFnOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRzb3J0Qnk6IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5LFxyXG5cdFx0XHRzaG93RW1wdHlGb2xkZXJzOiBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMsXHJcblx0XHRcdG9ubHlJbmNsdWRlU3ViZm9sZGVyczogcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHR9O1xyXG5cdH1cclxuXHRjb25zdCBkZXB0aCA9IHlhbWw/LmRlcHRoIHx8IDE7XHJcblx0bGV0IHRpdGxlID0geWFtbD8udGl0bGUgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSB8fCAne3tmb2xkZXJOYW1lfX0gb3ZlcnZpZXcnO1xyXG5cdGNvbnN0IGZvbGRlck5hbWUgPSBleHRyYWN0Rm9sZGVyTmFtZShwbHVnaW4uc2V0dGluZ3MuZm9sZGVyTm90ZU5hbWUsIHBsdWdpbi5yZW1vdmVFeHRlbnNpb24ocGx1Z2luLmdldEZvbGRlck5hbWVGcm9tUGF0aFN0cmluZyhjdHguc291cmNlUGF0aCkpKTtcclxuXHR0aXRsZSA9IHRpdGxlLnJlcGxhY2VBbGwoJ3t7Zm9sZGVyTmFtZX19JywgZm9sZGVyTmFtZSB8fCAnJyk7XHJcblx0Y29uc3QgZGlzYWJsZVRpdGxlID0geWFtbD8uZGlzYWJsZVRpdGxlIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuZGlzYWJsZVRpdGxlIHx8IGZhbHNlO1xyXG5cdGxldCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdID0geWFtbD8uaW5jbHVkZVR5cGVzIHx8IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuaW5jbHVkZVR5cGVzIHx8IFsnZm9sZGVyJywgJ21hcmtkb3duJ107XHJcblx0aW5jbHVkZVR5cGVzID0gaW5jbHVkZVR5cGVzLm1hcCgodHlwZSkgPT4gdHlwZS50b0xvd2VyQ2FzZSgpKTtcclxuXHRjb25zdCBzdHlsZTogJ2xpc3QnIHwgJ2dyaWQnID0geWFtbD8uc3R5bGUgfHwgJ2xpc3QnO1xyXG5cdGNvbnN0IGRpc2FibGVGaWxlVGFnID0geWFtbD8uZGlzYWJsZUZpbGVUYWcgfHwgcGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlRmlsZVRhZyB8fCBmYWxzZTtcclxuXHRjb25zdCBzaG93RW1wdHlGb2xkZXJzID0geWFtbD8uc2hvd0VtcHR5Rm9sZGVycyB8fCBwbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNob3dFbXB0eUZvbGRlcnMgfHwgZmFsc2U7XHJcblxyXG5cdGNvbnN0IHJvb3QgPSBlbC5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXcnIH0pO1xyXG5cdGNvbnN0IHRpdGxlRWwgPSByb290LmNyZWF0ZUVsKCdoMScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LXRpdGxlJyB9KTtcclxuXHRjb25zdCB1bCA9IHJvb3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0aWYgKCFkaXNhYmxlVGl0bGUpIHtcclxuXHRcdHRpdGxlRWwuaW5uZXJUZXh0ID0gdGl0bGU7XHJcblx0fVxyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID09PSAwKSB7IHJldHVybjsgfVxyXG5cdGxldCBmaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0Y29uc3Qgc291cmNlRmlsZSA9IHBsdWdpbi5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRpZiAoIXNvdXJjZUZpbGUpIHJldHVybjtcclxuXHRjb25zdCBzb3VyY2VGb2xkZXJQYXRoID0gcGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKTtcclxuXHRsZXQgc291cmNlRm9sZGVyOiBURm9sZGVyIHwgdW5kZWZpbmVkO1xyXG5cclxuXHRpZiAoc291cmNlRmlsZS5wYXJlbnQgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRzb3VyY2VGb2xkZXIgPSBzb3VyY2VGaWxlLnBhcmVudDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0c291cmNlRm9sZGVyID0gcGx1Z2luLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSkgYXMgVEZvbGRlcjtcclxuXHR9XHJcblxyXG5cdGZpbGVzID0gc291cmNlRm9sZGVyLmNoaWxkcmVuO1xyXG5cclxuXHRmaWxlcyA9IGZpbGVzLmZpbHRlcigoZmlsZSkgPT4ge1xyXG5cdFx0Y29uc3QgZm9sZGVyUGF0aCA9IHBsdWdpbi5nZXRGb2xkZXJQYXRoRnJvbVN0cmluZyhmaWxlLnBhdGgpO1xyXG5cdFx0aWYgKCFmb2xkZXJQYXRoLnN0YXJ0c1dpdGgoc291cmNlRm9sZGVyUGF0aCkpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblx0XHRpZiAoZmlsZS5wYXRoID09PSBjdHguc291cmNlUGF0aCkgeyByZXR1cm4gZmFsc2U7IH1cclxuXHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGgpIHtcclxuXHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHR9XHJcblx0fSk7XHJcblx0aWYgKCFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ2ZvbGRlcicpKSB7XHJcblx0XHRmaWxlcyA9IGdldEFsbEZpbGVzKGZpbGVzLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCk7XHJcblx0fVxyXG5cdGZpbGVzID0gc29ydEZpbGVzKGZpbGVzLCB5YW1sLCBwbHVnaW4pO1xyXG5cclxuXHRpZiAoc3R5bGUgPT09ICdncmlkJykge1xyXG5cdFx0Y29uc3QgZ3JpZCA9IHJvb3QuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQnIH0pO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaChhc3luYyAoZmlsZSkgPT4ge1xyXG5cdFx0XHRjb25zdCBncmlkSXRlbSA9IGdyaWQuY3JlYXRlRWwoJ2RpdicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbScgfSk7XHJcblx0XHRcdGNvbnN0IGdyaWRBcnRpY2xlID0gZ3JpZEl0ZW0uY3JlYXRlRWwoJ2FydGljbGUnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tYXJ0aWNsZScgfSk7XHJcblx0XHRcdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdFx0XHRjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IHBsdWdpbi5hcHAudmF1bHQucmVhZChmaWxlKTtcclxuXHRcdFx0XHQvLyBza2lwIC0tLSB5YW1sXHJcblx0XHRcdFx0Y29uc3QgZGVzY3JpcHRpb25FbCA9IGdyaWRBcnRpY2xlLmNyZWF0ZUVsKCdwJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWRlc2NyaXB0aW9uJyB9KTtcclxuXHRcdFx0XHRsZXQgZGVzY3JpcHRpb24gPSBmaWxlQ29udGVudC5zcGxpdCgnXFxuJylbMF07XHJcblx0XHRcdFx0aWYgKGRlc2NyaXB0aW9uLmxlbmd0aCA+IDY0KSB7XHJcblx0XHRcdFx0XHRkZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLnNsaWNlKDAsIDY0KSArICcuLi4nO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRkZXNjcmlwdGlvbkVsLmlubmVyVGV4dCA9IGRlc2NyaXB0aW9uO1xyXG5cdFx0XHRcdGNvbnN0IGxpbmsgPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWdyaWQtaXRlbS1saW5rIGludGVybmFsLWxpbmsnIH0pO1xyXG5cdFx0XHRcdGNvbnN0IHRpdGxlID0gbGluay5jcmVhdGVFbCgnaDEnLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1ncmlkLWl0ZW0tbGluay10aXRsZScgfSk7XHJcblx0XHRcdFx0dGl0bGUuaW5uZXJUZXh0ID0gZmlsZS5uYW1lLnJlcGxhY2UoJy5tZCcsICcnKS5yZXBsYWNlKCcuY2FudmFzJywgJycpO1xyXG5cdFx0XHRcdGxpbmsuaHJlZiA9IGZpbGUucGF0aDtcclxuXHRcdFx0fSBlbHNlIGlmIChmaWxlIGluc3RhbmNlb2YgVEZvbGRlcikge1xyXG5cdFx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBncmlkQXJ0aWNsZS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlcicgfSk7XHJcblx0XHRcdFx0Y29uc3QgZm9sZGVyTmFtZSA9IGZvbGRlckl0ZW0uY3JlYXRlRWwoJ2gxJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctZ3JpZC1pdGVtLWZvbGRlci1uYW1lJyB9KTtcclxuXHRcdFx0XHRmb2xkZXJOYW1lLmlubmVyVGV4dCA9IGZpbGUubmFtZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSBlbHNlIGlmIChzdHlsZSA9PT0gJ2xpc3QnKSB7XHJcblx0XHRjb25zdCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSA9IFtdO1xyXG5cdFx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0XHRpZiAoZmlsZSBpbnN0YW5jZW9mIFRGb2xkZXIpIHtcclxuXHRcdFx0XHRjb25zdCBmb2xkZXJJdGVtID0gYWRkRm9sZGVyTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlKTtcclxuXHRcdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH0gZWxzZSBpZiAoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB7XHJcblx0XHRcdFx0YWRkRmlsZUxpc3QocGx1Z2luLCB1bCwgcGF0aEJsYWNrbGlzdCwgZmlsZSwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0gZWxzZSBpZiAoc3R5bGUgPT09ICdleHBsb3JlcicpIHtcclxuXHRcdC8qXHJcblx0XHRjb25zdCB2aWV3ID0gcGx1Z2luLmdldEZpbGVFeHBsb3JlclZpZXcoKTtcclxuXHRcdGNvbnN0IGZvbGRlckVsZW1lbnQgPSBwbHVnaW4uZ2V0RUwocGx1Z2luLmdldEZvbGRlclBhdGhGcm9tU3RyaW5nKGN0eC5zb3VyY2VQYXRoKSk/LnBhcmVudEVsZW1lbnQ7XHJcblx0XHRpZiAoIWZvbGRlckVsZW1lbnQpIHJldHVybjtcclxuXHRcdC8vIGNvcHkgZm9sZGVyRWxlbWVudFxyXG5cdFx0Y29uc3QgbmV3Rm9sZGVyRWxlbWVudCA9IGZvbGRlckVsZW1lbnQuY2xvbmVOb2RlKHRydWUpIGFzIEhUTUxFbGVtZW50O1xyXG5cdFx0bmV3Rm9sZGVyRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmF2LWZvbGRlcicpLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRcdGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2lzLWNvbGxhcHNlZCcpO1xyXG5cdFx0fSk7XHJcblx0XHRyb290LmFwcGVuZENoaWxkKGZvbGRlckVsZW1lbnQpO1xyXG5cdFx0Ki9cclxuXHR9XHJcblx0aWYgKGluY2x1ZGVUeXBlcy5sZW5ndGggPiAxICYmIHN0eWxlICE9PSAnZ3JpZCcgJiYgKCFzaG93RW1wdHlGb2xkZXJzIHx8IHlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzKSkge1xyXG5cdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKHVsLCAxLCB5YW1sKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdvVGhyb3VnaEZvbGRlcnMocGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgbGlzdDogSFRNTExJRWxlbWVudCB8IEhUTUxVTGlzdEVsZW1lbnQsIGZvbGRlcjogVEZvbGRlcixcclxuXHRkZXB0aDogbnVtYmVyLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGN0eDogTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgeWFtbDogeWFtbFNldHRpbmdzLCBwYXRoQmxhY2tsaXN0OiBzdHJpbmdbXSwgaW5jbHVkZVR5cGVzOiBzdHJpbmdbXSwgZGlzYWJsZUZpbGVUYWc6IGJvb2xlYW4pIHtcclxuXHRpZiAoc291cmNlRm9sZGVyUGF0aCA9PT0gJycpIHtcclxuXHRcdGRlcHRoLS07XHJcblx0fVxyXG5cdGxldCBmaWxlcyA9IGZvbGRlci5jaGlsZHJlbi5maWx0ZXIoKGZpbGUpID0+IHtcclxuXHRcdGNvbnN0IGZvbGRlclBhdGggPSBwbHVnaW4uZ2V0Rm9sZGVyUGF0aEZyb21TdHJpbmcoZmlsZS5wYXRoKTtcclxuXHRcdGlmICghZm9sZGVyUGF0aC5zdGFydHNXaXRoKHNvdXJjZUZvbGRlclBhdGgpKSB7IHJldHVybiBmYWxzZTsgfVxyXG5cdFx0aWYgKChmaWxlLnBhdGguc3BsaXQoJy8nKS5sZW5ndGggLSBzb3VyY2VGb2xkZXJQYXRoLnNwbGl0KCcvJykubGVuZ3RoKSAtIDEgPCBkZXB0aCkge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHRmaWxlcyA9IHNvcnRGaWxlcyhmaWxlcywgeWFtbCwgcGx1Z2luKTtcclxuXHRjb25zdCB1bCA9IGxpc3QuY3JlYXRlRWwoJ3VsJywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdCcgfSk7XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGNvbnN0IGZvbGRlckl0ZW0gPSBhZGRGb2xkZXJMaXN0KHBsdWdpbiwgdWwsIHBhdGhCbGFja2xpc3QsIGZpbGUpO1xyXG5cdFx0XHRnb1Rocm91Z2hGb2xkZXJzKHBsdWdpbiwgZm9sZGVySXRlbSwgZmlsZSwgZGVwdGgsIHNvdXJjZUZvbGRlclBhdGgsIGN0eCwgeWFtbCwgcGF0aEJsYWNrbGlzdCwgaW5jbHVkZVR5cGVzLCBkaXNhYmxlRmlsZVRhZyk7XHJcblx0XHR9IGVsc2UgaWYgKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkge1xyXG5cdFx0XHRhZGRGaWxlTGlzdChwbHVnaW4sIHVsLCBwYXRoQmxhY2tsaXN0LCBmaWxlLCBpbmNsdWRlVHlwZXMsIGRpc2FibGVGaWxlVGFnKTtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gc29ydEZpbGVzKGZpbGVzOiBUQWJzdHJhY3RGaWxlW10sIHlhbWw6IHlhbWxTZXR0aW5ncywgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbikge1xyXG5cdGlmICgheWFtbD8uc29ydEJ5KSB7XHJcblx0XHR5YW1sLnNvcnRCeSA9IHBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc29ydEJ5IHx8ICduYW1lJztcclxuXHR9XHJcblx0cmV0dXJuIGZpbGVzLnNvcnQoKGEsIGIpID0+IHtcclxuXHRcdC8vIHNvcnQgYnkgZm9sZGVyIGZpcnN0XHJcblx0XHRpZiAoYSBpbnN0YW5jZW9mIFRGb2xkZXIgJiYgIShiIGluc3RhbmNlb2YgVEZvbGRlcikpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGb2xkZXIpICYmIGIgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCEoYSBpbnN0YW5jZW9mIFRGaWxlKSB8fCAhKGIgaW5zdGFuY2VvZiBURmlsZSkpIHsgcmV0dXJuIC0xOyB9XHJcblx0XHRpZiAoeWFtbC5zb3J0QnkgPT09ICdjcmVhdGVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0LmN0aW1lID4gYi5zdGF0LmN0aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnY3JlYXRlZEFzYycpIHtcclxuXHRcdFx0aWYgKGEuc3RhdC5jdGltZSA8IGIuc3RhdC5jdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAtMTtcclxuXHRcdFx0fSBlbHNlIGlmIChhLnN0YXQuY3RpbWUgPiBiLnN0YXQuY3RpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gMTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIGlmICh5YW1sLnNvcnRCeSA9PT0gJ21vZGlmaWVkJykge1xyXG5cdFx0XHRpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGEuc3RhdC5tdGltZSA8IGIuc3RhdC5tdGltZSkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHlhbWwuc29ydEJ5ID09PSAnbW9kaWZpZWRBc2MnKSB7XHJcblx0XHRcdGlmIChhLnN0YXQubXRpbWUgPCBiLnN0YXQubXRpbWUpIHtcclxuXHRcdFx0XHRyZXR1cm4gLTE7XHJcblx0XHRcdH0gZWxzZSBpZiAoYS5zdGF0Lm10aW1lID4gYi5zdGF0Lm10aW1lKSB7XHJcblx0XHRcdFx0cmV0dXJuIDE7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdC8vIHNvcnQgYnkgbmFtZVxyXG5cdFx0aWYgKGEubmFtZSA8IGIubmFtZSAmJiB5YW1sLnNvcnRCeSA9PT0gJ25hbWUnKSB7XHJcblx0XHRcdHJldHVybiAtMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lID4gYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChhLm5hbWUgPiBiLm5hbWUgJiYgeWFtbC5zb3J0QnkgPT09ICduYW1lJykge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH0gZWxzZSBpZiAoYS5uYW1lIDwgYi5uYW1lICYmIHlhbWwuc29ydEJ5ID09PSAnbmFtZUFzYycpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gMDtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVtb3ZlRW1wdHlGb2xkZXJzKHVsOiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgZGVwdGg6IG51bWJlciwgeWFtbDogeWFtbFNldHRpbmdzKSB7XHJcblx0Y29uc3QgY2hpbGRyZW5zVG9SZW1vdmU6IENoaWxkTm9kZVtdID0gW107XHJcblx0dWwuY2hpbGROb2Rlcy5mb3JFYWNoKChlbCkgPT4ge1xyXG5cdFx0Y29uc3QgY2hpbGRyZW5zID0gKGVsIGFzIEVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3IoJ3VsJyk7XHJcblx0XHRpZiAoIWNoaWxkcmVucyB8fCBjaGlsZHJlbnMgPT09IG51bGwpIHsgcmV0dXJuOyB9XHJcblx0XHRpZiAoY2hpbGRyZW5zICYmICFjaGlsZHJlbnM/Lmhhc0NoaWxkTm9kZXMoKSAmJiAhKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCkpIHtcclxuXHRcdFx0Y2hpbGRyZW5zVG9SZW1vdmUucHVzaChlbCk7XHJcblx0XHR9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgSFRNTFVMaXN0RWxlbWVudCB8fCBlbCBpbnN0YW5jZW9mIEhUTUxMSUVsZW1lbnQpIHtcclxuXHRcdFx0cmVtb3ZlRW1wdHlGb2xkZXJzKGVsLCBkZXB0aCArIDEsIHlhbWwpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdGNoaWxkcmVuc1RvUmVtb3ZlLmZvckVhY2goKGVsKSA9PiB7XHJcblx0XHRpZiAoeWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgJiYgZGVwdGggPT09IDEpIHsgcmV0dXJuOyB9XHJcblx0XHRlbC5yZW1vdmUoKTtcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkRm9sZGVyTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZvbGRlcjogVEZvbGRlcikge1xyXG5cdGNvbnN0IGZvbGRlckl0ZW0gPSBsaXN0LmNyZWF0ZUVsKCdsaScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QgZm9sZGVyLWxpc3QnIH0pO1xyXG5cdGNvbnN0IGZvbGRlck5vdGUgPSBnZXRGb2xkZXJOb3RlKHBsdWdpbiwgZm9sZGVyLnBhdGgpO1xyXG5cdGlmIChmb2xkZXJOb3RlIGluc3RhbmNlb2YgVEZpbGUpIHtcclxuXHRcdGNvbnN0IGZvbGRlck5vdGVMaW5rID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnYScsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtIGludGVybmFsLWxpbmsnLCBocmVmOiBmb2xkZXJOb3RlLnBhdGggfSk7XHJcblx0XHRmb2xkZXJOb3RlTGluay5pbm5lclRleHQgPSBmb2xkZXIubmFtZTtcclxuXHRcdHBhdGhCbGFja2xpc3QucHVzaChmb2xkZXJOb3RlLnBhdGgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRjb25zdCBmb2xkZXJOYW1lID0gZm9sZGVySXRlbS5jcmVhdGVFbCgnc3BhbicsIHsgY2xzOiAnZm9sZGVyLW92ZXJ2aWV3LWxpc3QtaXRlbSBmb2xkZXItbmFtZS1pdGVtJyB9KTtcclxuXHRcdGZvbGRlck5hbWUuaW5uZXJUZXh0ID0gZm9sZGVyLm5hbWU7XHJcblx0fVxyXG5cdHJldHVybiBmb2xkZXJJdGVtO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRGaWxlTGlzdChwbHVnaW46IEZvbGRlck5vdGVzUGx1Z2luLCBsaXN0OiBIVE1MVUxpc3RFbGVtZW50IHwgSFRNTExJRWxlbWVudCwgcGF0aEJsYWNrbGlzdDogc3RyaW5nW10sIGZpbGU6IFRGaWxlLCBpbmNsdWRlVHlwZXM6IHN0cmluZ1tdLCBkaXNhYmxlRmlsZVRhZzogYm9vbGVhbikge1xyXG5cdGlmIChpbmNsdWRlVHlwZXMubGVuZ3RoID4gMCAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0aWYgKGZpbGUuZXh0ZW5zaW9uID09PSAnbWQnICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ21hcmtkb3duJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ2NhbnZhcycgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygnY2FudmFzJykpIHJldHVybjtcclxuXHRcdGlmIChmaWxlLmV4dGVuc2lvbiA9PT0gJ3BkZicgJiYgIWluY2x1ZGVUeXBlcy5pbmNsdWRlcygncGRmJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGltYWdlVHlwZXMgPSBbJ2pwZycsICdqcGVnJywgJ3BuZycsICdnaWYnLCAnc3ZnJywgJ3dlYnAnXTtcclxuXHRcdGlmIChpbWFnZVR5cGVzLmluY2x1ZGVzKGZpbGUuZXh0ZW5zaW9uKSAmJiAhaW5jbHVkZVR5cGVzLmluY2x1ZGVzKCdpbWFnZScpKSByZXR1cm47XHJcblx0XHRjb25zdCB2aWRlb1R5cGVzID0gWydtcDQnLCAnd2VibScsICdvZ3YnLCAnbW92JywgJ21rdiddO1xyXG5cdFx0aWYgKHZpZGVvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ3ZpZGVvJykpIHJldHVybjtcclxuXHRcdGNvbnN0IGF1ZGlvVHlwZXMgPSBbJ21wMycsICd3YXYnLCAnbTRhJywgJzNncCcsICdmbGFjJywgJ29nZycsICdvZ2EnLCAnb3B1cyddO1xyXG5cdFx0aWYgKGF1ZGlvVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmIGluY2x1ZGVUeXBlcy5pbmNsdWRlcygnYXVkaW8nKSkgcmV0dXJuO1xyXG5cdFx0Y29uc3QgYWxsVHlwZXMgPSBbJ21kJywgJ2NhbnZhcycsICdwZGYnLCAuLi5pbWFnZVR5cGVzLCAuLi52aWRlb1R5cGVzLCAuLi5hdWRpb1R5cGVzXTtcclxuXHRcdGlmICghYWxsVHlwZXMuaW5jbHVkZXMoZmlsZS5leHRlbnNpb24pICYmICFpbmNsdWRlVHlwZXMuaW5jbHVkZXMoJ290aGVyJykpIHJldHVybjtcclxuXHR9XHJcblx0aWYgKHBhdGhCbGFja2xpc3QuaW5jbHVkZXMoZmlsZS5wYXRoKSkgcmV0dXJuO1xyXG5cdGNvbnN0IGxpc3RJdGVtID0gbGlzdC5jcmVhdGVFbCgnbGknLCB7IGNsczogJ2ZvbGRlci1vdmVydmlldy1saXN0IGZpbGUtbGluaycgfSk7XHJcblx0Y29uc3QgbmFtZUl0ZW0gPSBsaXN0SXRlbS5jcmVhdGVFbCgnZGl2JywgeyBjbHM6ICdmb2xkZXItb3ZlcnZpZXctbGlzdC1pdGVtJyB9KTtcclxuXHRjb25zdCBsaW5rID0gbmFtZUl0ZW0uY3JlYXRlRWwoJ2EnLCB7IGNsczogJ2ludGVybmFsLWxpbmsnLCBocmVmOiBmaWxlLnBhdGggfSk7XHJcblx0bGluay5pbm5lclRleHQgPSBmaWxlLmJhc2VuYW1lO1xyXG5cdGlmIChmaWxlLmV4dGVuc2lvbiAhPT0gJ21kJyAmJiAhZGlzYWJsZUZpbGVUYWcpIHtcclxuXHRcdG5hbWVJdGVtLmNyZWF0ZURpdih7IGNsczogJ25hdi1maWxlLXRhZycgfSkuaW5uZXJUZXh0ID0gZmlsZS5leHRlbnNpb247XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRBbGxGaWxlcyhmaWxlczogVEFic3RyYWN0RmlsZVtdLCBzb3VyY2VGb2xkZXJQYXRoOiBzdHJpbmcsIGRlcHRoOiBudW1iZXIpIHtcclxuXHRjb25zdCBhbGxGaWxlczogVEFic3RyYWN0RmlsZVtdID0gW107XHJcblx0ZmlsZXMuZm9yRWFjaCgoZmlsZSkgPT4ge1xyXG5cdFx0aWYgKGZpbGUgaW5zdGFuY2VvZiBURm9sZGVyKSB7XHJcblx0XHRcdGlmICgoZmlsZS5wYXRoLnNwbGl0KCcvJykubGVuZ3RoIC0gc291cmNlRm9sZGVyUGF0aC5zcGxpdCgnLycpLmxlbmd0aCkgLSAxIDwgZGVwdGggLSAxKSB7XHJcblx0XHRcdFx0YWxsRmlsZXMucHVzaCguLi5nZXRBbGxGaWxlcyhmaWxlLmNoaWxkcmVuLCBzb3VyY2VGb2xkZXJQYXRoLCBkZXB0aCkpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRhbGxGaWxlcy5wdXNoKGZpbGUpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cdHJldHVybiBhbGxGaWxlcztcclxufVxyXG4iLCAiaW1wb3J0IHsgQXBwLCBNb2RhbCwgU2V0dGluZywgTWFya2Rvd25Qb3N0UHJvY2Vzc29yQ29udGV4dCwgc3RyaW5naWZ5WWFtbCwgVEZpbGUgfSBmcm9tICdvYnNpZGlhbic7XHJcbmltcG9ydCB7IHlhbWxTZXR0aW5ncyB9IGZyb20gJ3NyYy9mb2xkZXJPdmVydmlldyc7XHJcbmltcG9ydCBGb2xkZXJOb3Rlc1BsdWdpbiBmcm9tICcuLi9tYWluJztcclxuaW1wb3J0IExpc3RDb21wb25lbnQgZnJvbSAnc3JjL2Z1bmN0aW9ucy9MaXN0Q29tcG9uZW50JztcclxuZXhwb3J0IGNsYXNzIEZvbGRlck92ZXJ2aWV3U2V0dGluZ3MgZXh0ZW5kcyBNb2RhbCB7XHJcblx0cGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbjtcclxuXHRhcHA6IEFwcDtcclxuXHR5YW1sOiB5YW1sU2V0dGluZ3M7XHJcblx0Y3R4OiBNYXJrZG93blBvc3RQcm9jZXNzb3JDb250ZXh0O1xyXG5cdGVsOiBIVE1MRWxlbWVudDtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBGb2xkZXJOb3Rlc1BsdWdpbiwgeWFtbDogeWFtbFNldHRpbmdzLCBjdHg6IE1hcmtkb3duUG9zdFByb2Nlc3NvckNvbnRleHQsIGVsOiBIVE1MRWxlbWVudCkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xyXG5cdFx0dGhpcy5hcHAgPSBhcHA7XHJcblx0XHR0aGlzLnlhbWwgPSB5YW1sO1xyXG5cdFx0dGhpcy5jdHggPSBjdHg7XHJcblx0XHR0aGlzLmVsID0gZWw7XHJcblx0XHRpZiAoIXRoaXMueWFtbCkge1xyXG5cdFx0XHR0aGlzLnlhbWwgPSB7XHJcblx0XHRcdFx0dGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy50aXRsZSxcclxuXHRcdFx0XHRkaXNhYmxlVGl0bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kaXNhYmxlVGl0bGUsXHJcblx0XHRcdFx0ZGVwdGg6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5kZXB0aCxcclxuXHRcdFx0XHR0eXBlOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcudHlwZSxcclxuXHRcdFx0XHRpbmNsdWRlVHlwZXM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMsXHJcblx0XHRcdFx0c3R5bGU6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zdHlsZSxcclxuXHRcdFx0XHRkaXNhYmxlRmlsZVRhZzogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnLFxyXG5cdFx0XHRcdHNvcnRCeTogdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LnNvcnRCeSxcclxuXHRcdFx0XHRzaG93RW1wdHlGb2xkZXJzOiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWZhdWx0T3ZlcnZpZXcuc2hvd0VtcHR5Rm9sZGVycyxcclxuXHRcdFx0XHRvbmx5SW5jbHVkZVN1YmZvbGRlcnM6IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5vbmx5SW5jbHVkZVN1YmZvbGRlcnMsXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0fVxyXG5cdG9uT3BlbigpIHtcclxuXHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdH1cclxuXHRkaXNwbGF5KCkge1xyXG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XHJcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcclxuXHRcdC8vIGNsb3NlIHdoZW4gdXNlciBwcmVzc2VzIGVudGVyXHJcblx0XHRjb250ZW50RWwuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XHJcblx0XHRcdGlmIChlLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdHRoaXMuY2xvc2UoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoJ2gyJywgeyB0ZXh0OiAnRm9sZGVyIG92ZXJ2aWV3IHNldHRpbmdzJyB9KTtcclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0Rpc2FibGUgdGhlIHRpdGxlJylcclxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgdGl0bGUgc2hvdWxkIGJlIHNob3duJylcclxuXHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgfHwgZmFsc2UpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kaXNhYmxlVGl0bGUgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0dGhpcy5kaXNwbGF5KCk7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHRcdGlmICghdGhpcy55YW1sLmRpc2FibGVUaXRsZSkge1xyXG5cdFx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdFx0LnNldE5hbWUoJ1RpdGxlJylcclxuXHRcdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSB0aXRsZSBvZiB0aGUgZm9sZGVyIG92ZXJ2aWV3JylcclxuXHRcdFx0XHQuYWRkVGV4dCgodGV4dCkgPT5cclxuXHRcdFx0XHRcdHRleHRcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8udGl0bGUgfHwgJ3t7Zm9sZGVyTmFtZX19IG92ZXJ2aWV3JylcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC50aXRsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0XHR9KVxyXG5cdFx0XHRcdCk7XHJcblx0XHR9XHJcblx0XHRjb25zdCBzZXR0aW5nID0gbmV3IFNldHRpbmcoY29udGVudEVsKTtcclxuXHRcdHNldHRpbmcuc2V0TmFtZSgnSW5jbHVkZSB0eXBlcycpO1xyXG5cdFx0Y29uc3QgbGlzdCA9IHNldHRpbmcuY3JlYXRlTGlzdCgobGlzdDogTGlzdENvbXBvbmVudCkgPT5cclxuXHRcdFx0bGlzdFxyXG5cdFx0XHRcdC5hZGRNb2RhbCh0aGlzKVxyXG5cdFx0XHRcdC5zZXRWYWx1ZXModGhpcy55YW1sPy5pbmNsdWRlVHlwZXMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSlcclxuXHRcdFx0XHQuYWRkUmVzZXRCdXR0b24oKVxyXG5cdFx0KTtcclxuXHRcdGlmICgodGhpcy55YW1sPy5pbmNsdWRlVHlwZXM/Lmxlbmd0aCB8fCAwKSA8IDggJiYgIXRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmluY2x1ZGVzKCdhbGwnKSkge1xyXG5cdFx0XHRzZXR0aW5nLmFkZERyb3Bkb3duKChkcm9wZG93bikgPT4ge1xyXG5cdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcykgdGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5pbmNsdWRlVHlwZXMgfHwgW107XHJcblx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXMubWFwKCh0eXBlOiBzdHJpbmcpID0+IHR5cGUudG9Mb3dlckNhc2UoKSk7XHJcblx0XHRcdFx0Y29uc3Qgb3B0aW9ucyA9IFtcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICdtYXJrZG93bicsIGxhYmVsOiAnTWFya2Rvd24nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnZm9sZGVyJywgbGFiZWw6ICdGb2xkZXInIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnY2FudmFzJywgbGFiZWw6ICdDYW52YXMnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAncGRmJywgbGFiZWw6ICdQREYnIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnaW1hZ2UnLCBsYWJlbDogJ0ltYWdlJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2F1ZGlvJywgbGFiZWw6ICdBdWRpbycgfSxcclxuXHRcdFx0XHRcdHsgdmFsdWU6ICd2aWRlbycsIGxhYmVsOiAnVmlkZW8nIH0sXHJcblx0XHRcdFx0XHR7IHZhbHVlOiAnb3RoZXInLCBsYWJlbDogJ0FsbCBvdGhlciBmaWxlIHR5cGVzJyB9LFxyXG5cdFx0XHRcdFx0eyB2YWx1ZTogJ2FsbCcsIGxhYmVsOiAnQWxsIGZpbGUgdHlwZXMnIH0sXHJcblx0XHRcdFx0XTtcclxuXHJcblx0XHRcdFx0b3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcclxuXHRcdFx0XHRcdGlmICghdGhpcy55YW1sLmluY2x1ZGVUeXBlcz8uaW5jbHVkZXMob3B0aW9uLnZhbHVlKSkge1xyXG5cdFx0XHRcdFx0XHRkcm9wZG93bi5hZGRPcHRpb24ob3B0aW9uLnZhbHVlLCBvcHRpb24ubGFiZWwpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdGRyb3Bkb3duLmFkZE9wdGlvbignKycsICcrJyk7XHJcblx0XHRcdFx0ZHJvcGRvd24uc2V0VmFsdWUoJysnKTtcclxuXHRcdFx0XHRkcm9wZG93bi5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcclxuXHRcdFx0XHRcdGlmICh2YWx1ZSA9PT0gJ2FsbCcpIHtcclxuXHRcdFx0XHRcdFx0dGhpcy55YW1sLmluY2x1ZGVUeXBlcyA9IHRoaXMueWFtbC5pbmNsdWRlVHlwZXM/LmZpbHRlcigodHlwZTogc3RyaW5nKSA9PiB0eXBlID09PSAnZm9sZGVyJyk7XHJcblx0XHRcdFx0XHRcdC8vIEB0cy1pZ25vcmVcclxuXHRcdFx0XHRcdFx0bGlzdC5zZXRWYWx1ZXModGhpcy55YW1sLmluY2x1ZGVUeXBlcyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQvLyBAdHMtaWdub3JlXHJcblx0XHRcdFx0XHRhd2FpdCBsaXN0LmFkZFZhbHVlKHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xyXG5cdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHR0aGlzLmRpc3BsYXkoKTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRsZXQgZGlzYWJsZUZpbGVUYWc7XHJcblx0XHR0aGlzLnlhbWwuaW5jbHVkZVR5cGVzPy5mb3JFYWNoKCh0eXBlOiBzdHJpbmcpID0+IHtcclxuXHRcdFx0dHlwZSA9PT0gJ2ZvbGRlcicgfHwgdHlwZSA9PT0gJ21hcmtkb3duJyA/IChkaXNhYmxlRmlsZVRhZyA9IHRydWUpIDogbnVsbDtcclxuXHRcdH0pO1xyXG5cdFx0aWYgKGRpc2FibGVGaWxlVGFnKSB7XHJcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0XHQuc2V0TmFtZSgnRGlzYWJsZSBmaWxlIHRhZycpXHJcblx0XHRcdFx0LnNldERlc2MoJ0Nob29zZSBpZiB0aGUgZmlsZSB0YWcgc2hvdWxkIGJlIHNob3duIGFmdGVyIHRoZSBmaWxlIG5hbWUnKVxyXG5cdFx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdFx0dG9nZ2xlXHJcblx0XHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWwuZGlzYWJsZUZpbGVUYWcgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmRpc2FibGVGaWxlVGFnIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdFx0dGhpcy55YW1sLmRpc2FibGVGaWxlVGFnID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy51cGRhdGVZYW1sKCk7XHJcblx0XHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcclxuXHRcdFx0LnNldE5hbWUoJ0ZpbGUgZGVwdGgnKVxyXG5cdFx0XHQuc2V0RGVzYygnRmlsZSAmIGZvbGRlciA9ICsxIGRlcHRoJylcclxuXHRcdFx0LmFkZFNsaWRlcigoc2xpZGVyKSA9PlxyXG5cdFx0XHRcdHNsaWRlclxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uZGVwdGggfHwgMilcclxuXHRcdFx0XHRcdC5zZXRMaW1pdHMoMSwgMTAsIDEpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5kZXB0aCA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnT3ZlcnZpZXcgc3R5bGUnKVxyXG5cdFx0XHQuc2V0RGVzYygnQ2hvb3NlIHRoZSBzdHlsZSBvZiB0aGUgb3ZlcnZpZXcgKGdyaWQgc3R5bGUgc29vbiknKVxyXG5cdFx0XHQuYWRkRHJvcGRvd24oKGRyb3Bkb3duKSA9PlxyXG5cdFx0XHRcdGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCdsaXN0JywgJ0xpc3QnKVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbD8uc3R5bGUgfHwgJ2xpc3QnKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZTogJ2xpc3QnKSA9PiB7XHJcblx0XHRcdFx0XHRcdHRoaXMueWFtbC5zdHlsZSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pXHJcblx0XHRcdCk7XHJcblxyXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHQuc2V0TmFtZSgnU29ydCBmaWxlcyBieScpXHJcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgaG93IHRoZSBmaWxlcyBzaG91bGQgYmUgc29ydGVkJylcclxuXHRcdFx0LmFkZERyb3Bkb3duKChkcm9wZG93bikgPT5cclxuXHRcdFx0XHRkcm9wZG93blxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbmFtZScsICdOYW1lIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignY3JlYXRlZCcsICdDcmVhdGVkIGRlc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWQnLCAnTW9kaWZpZWQgZGVzY2VuZGluZycpXHJcblx0XHRcdFx0XHQuYWRkT3B0aW9uKCduYW1lQXNjJywgJ05hbWUgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5hZGRPcHRpb24oJ2NyZWF0ZWRBc2MnLCAnQ3JlYXRlZCBhc2NlbmRpbmcnKVxyXG5cdFx0XHRcdFx0LmFkZE9wdGlvbignbW9kaWZpZWRBc2MnLCAnTW9kaWZpZWQgYXNjZW5kaW5nJylcclxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnlhbWw/LnNvcnRCeSB8fCAnbmFtZScpXHJcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlOiAnbmFtZScgfCAnY3JlYXRlZCcgfCAnbW9kaWZpZWQnIHwgJ25hbWVBc2MnIHwgJ2NyZWF0ZWRBc2MnIHwgJ21vZGlmaWVkQXNjJykgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc29ydEJ5ID0gdmFsdWU7XHJcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMudXBkYXRlWWFtbCgpO1xyXG5cdFx0XHRcdFx0fSlcclxuXHRcdFx0KTtcclxuXHJcblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXHJcblx0XHRcdC5zZXROYW1lKCdTaG93IGZvbGRlciBuYW1lcyBvZiBlbXB0eSBmb2xkZXJzJylcclxuXHRcdFx0LnNldERlc2MoJ1RoYXQgaW5jbHVkZXMgc3ViZm9sZGVycyBvZiB0aGUgY3VycmVudCBmb2xkZXIgd2hlbiB5b3UgYXJlIG9uIGZpbGUgZGVwdGggMScpXHJcblx0XHRcdC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT4ge1xyXG5cdFx0XHRcdHRvZ2dsZVxyXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5zaG93RW1wdHlGb2xkZXJzIHx8IHRoaXMucGx1Z2luLnNldHRpbmdzLmRlZmF1bHRPdmVydmlldy5zaG93RW1wdHlGb2xkZXJzIHx8IGZhbHNlKVxyXG5cdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwuc2hvd0VtcHR5Rm9sZGVycyA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0XHR0aGlzLnlhbWwub25seUluY2x1ZGVTdWJmb2xkZXJzID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdHRoaXMuZGlzcGxheSgpO1xyXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRpZiAodGhpcy55YW1sLnNob3dFbXB0eUZvbGRlcnMpIHtcclxuXHRcdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxyXG5cdFx0XHRcdC5zZXROYW1lKCdPbmx5IHNob3cgZmlyc3QgZW1wdHkgc3ViZm9sZGVycyBvZiBjdXJyZW50IGZvbGRlcicpXHJcblx0XHRcdFx0LmFkZFRvZ2dsZSgodG9nZ2xlKSA9PiB7XHJcblx0XHRcdFx0XHR0b2dnbGVcclxuXHRcdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgfHwgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3Lm9ubHlJbmNsdWRlU3ViZm9sZGVycyB8fCBmYWxzZSlcclxuXHRcdFx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xyXG5cdFx0XHRcdFx0XHRcdHRoaXMueWFtbC5vbmx5SW5jbHVkZVN1YmZvbGRlcnMgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnVwZGF0ZVlhbWwoKTtcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHR9XHJcblx0b25DbG9zZSgpIHtcclxuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG5cdGFzeW5jIHVwZGF0ZVlhbWwoKSB7XHJcblx0XHRjb25zdCBmaWxlID0gdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aCh0aGlzLmN0eC5zb3VyY2VQYXRoKTtcclxuXHRcdGlmICghKGZpbGUgaW5zdGFuY2VvZiBURmlsZSkpIHJldHVybjtcclxuXHRcdGxldCBzdHJpbmdZYW1sID0gc3RyaW5naWZ5WWFtbCh0aGlzLnlhbWwpO1xyXG5cdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LnByb2Nlc3MoZmlsZSwgKHRleHQpID0+IHtcclxuXHRcdFx0Y29uc3QgaW5mbyA9IHRoaXMuY3R4LmdldFNlY3Rpb25JbmZvKHRoaXMuZWwpO1xyXG5cdFx0XHQvLyBjaGVjayBpZiBzdHJpbmdZYW1sIGVuZHMgd2l0aCBhIG5ld2xpbmVcclxuXHRcdFx0aWYgKHN0cmluZ1lhbWxbc3RyaW5nWWFtbC5sZW5ndGggLSAxXSAhPT0gJ1xcbicpIHtcclxuXHRcdFx0XHRzdHJpbmdZYW1sICs9ICdcXG4nO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChpbmZvKSB7XHJcblx0XHRcdFx0Y29uc3QgeyBsaW5lU3RhcnQgfSA9IGluZm87XHJcblx0XHRcdFx0Y29uc3QgbGluZUVuZCA9IHRoaXMuZ2V0Q29kZUJsb2NrRW5kTGluZSh0ZXh0LCBsaW5lU3RhcnQpO1xyXG5cdFx0XHRcdGlmIChsaW5lRW5kID09PSAtMSB8fCAhbGluZUVuZCkgcmV0dXJuIHRleHQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZUxlbmd0aCA9IGxpbmVFbmQgLSBsaW5lU3RhcnQ7XHJcblx0XHRcdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdFx0XHRsaW5lcy5zcGxpY2UobGluZVN0YXJ0LCBsaW5lTGVuZ3RoICsgMSwgYFxcYFxcYFxcYGZvbGRlci1vdmVydmlld1xcbiR7c3RyaW5nWWFtbH1cXGBcXGBcXGBgKTtcclxuXHRcdFx0XHRyZXR1cm4gbGluZXMuam9pbignXFxuJyk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGBcXGBcXGBcXGBmb2xkZXItb3ZlcnZpZXdcXG4ke3N0cmluZ1lhbWx9XFxgXFxgXFxgYDtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRnZXRDb2RlQmxvY2tFbmRMaW5lKHRleHQ6IHN0cmluZywgc3RhcnRMaW5lOiBudW1iZXIsIGNvdW50ID0gMSkge1xyXG5cdFx0bGV0IGxpbmUgPSBzdGFydExpbmUgKyAxO1xyXG5cdFx0Y29uc3QgbGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcclxuXHRcdHdoaWxlIChsaW5lIDwgbGluZXMubGVuZ3RoKSB7XHJcblx0XHRcdGlmIChjb3VudCA+IDIwKSB7IHJldHVybiAtMTsgfVxyXG5cdFx0XHRpZiAobGluZXNbbGluZV0uc3RhcnRzV2l0aCgnYGBgJykpIHtcclxuXHRcdFx0XHRyZXR1cm4gbGluZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRsaW5lKys7XHJcblx0XHRcdGNvdW50Kys7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbGluZTtcclxuXHR9XHJcbn1cclxuXHJcbiIsICJpbXBvcnQgeyBTZXR0aW5nIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBGb2xkZXJPdmVydmlld1NldHRpbmdzIH0gZnJvbSAnLi4vbW9kYWxzL2ZvbGRlck92ZXJ2aWV3JztcclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGlzdENvbXBvbmVudCB7XHJcblx0Y29udGFpbmVyRWw6IEhUTUxFbGVtZW50O1xyXG5cdGNvbnRyb2xFbDogSFRNTEVsZW1lbnQ7XHJcblx0ZW1wdHlTdGF0ZUVsOiBIVE1MRWxlbWVudDtcclxuXHRsaXN0RWw6IEhUTUxFbGVtZW50O1xyXG5cdHZhbHVlczogc3RyaW5nW107XHJcblx0bW9kYWw6IEZvbGRlck92ZXJ2aWV3U2V0dGluZ3M7XHJcblx0Y29uc3RydWN0b3IoY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KSB7XHJcblx0XHR0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XHJcblx0XHR0aGlzLmNvbnRyb2xFbCA9IGNvbnRhaW5lckVsLnF1ZXJ5U2VsZWN0b3IoJy5zZXR0aW5nLWl0ZW0tY29udHJvbCcpIHx8IGNvbnRhaW5lckVsO1xyXG5cdFx0dGhpcy5saXN0RWwgPSB0aGlzLmNvbnRyb2xFbC5jcmVhdGVEaXYoJ3NldHRpbmctY29tbWFuZC1ob3RrZXlzJyk7XHJcblx0fVxyXG5cdGFkZE1vZGFsKG1vZGFsOiBGb2xkZXJPdmVydmlld1NldHRpbmdzKSB7XHJcblx0XHR0aGlzLm1vZGFsID0gbW9kYWw7XHJcblx0XHR0aGlzLnZhbHVlcyA9IG1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzIHx8IFtdO1xyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG5cdHNldFZhbHVlcyh2YWx1ZXM6IHN0cmluZ1tdKSB7XHJcblx0XHR0aGlzLmxpc3RFbC5lbXB0eSgpO1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB2YWx1ZXM7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdmFsdWVzO1xyXG5cdFx0aWYgKHZhbHVlcy5sZW5ndGggIT09IDApIHtcclxuXHRcdFx0dmFsdWVzLmZvckVhY2goKHZhbHVlKSA9PiB7XHJcblx0XHRcdFx0dGhpcy5hZGRFbGVtZW50KHZhbHVlKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHR0aGlzLm1vZGFsLnVwZGF0ZVlhbWwoKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxuXHRhZGRFbGVtZW50KHZhbHVlOiBzdHJpbmcpIHtcclxuXHRcdHRoaXMubGlzdEVsLmNyZWF0ZVNwYW4oJ3NldHRpbmctaG90a2V5JywgKHNwYW4pID0+IHtcclxuXHRcdFx0c3Bhbi5pbm5lclRleHQgPSB2YWx1ZTtcclxuXHRcdFx0Y29uc3QgcmVtb3ZlU3BhbiA9IHNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlIHNldHRpbmctaG90a2V5LWljb24nIH0pO1xyXG5cdFx0XHQvLyBhZGQgc3ZnIGljb25cclxuXHRcdFx0Y29uc3Qgc3ZnID0gJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBjbGFzcz1cInN2Zy1pY29uIGx1Y2lkZS14XCI+PGxpbmUgeDE9XCIxOFwiIHkxPVwiNlwiIHgyPVwiNlwiIHkyPVwiMThcIj48L2xpbmU+PGxpbmUgeDE9XCI2XCIgeTE9XCI2XCIgeDI9XCIxOFwiIHkyPVwiMThcIj48L2xpbmU+PC9zdmc+JztcclxuXHRcdFx0Y29uc3Qgc3ZnRWxlbWVudCA9IHJlbW92ZVNwYW4uY3JlYXRlRWwoJ3NwYW4nLCB7IGNsczogJ29mbi1saXN0LWl0ZW0tcmVtb3ZlLWljb24nIH0pO1xyXG5cdFx0XHRzdmdFbGVtZW50LmlubmVySFRNTCA9IHN2ZztcclxuXHRcdFx0cmVtb3ZlU3Bhbi5vbkNsaWNrRXZlbnQoKGUpID0+IHtcclxuXHRcdFx0XHR0aGlzLnJlbW92ZVZhbHVlKHZhbHVlKTtcclxuXHRcdFx0XHRzcGFuLnJlbW92ZSgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cdH1cclxuXHRhc3luYyBhZGRWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcblx0XHR0aGlzLnZhbHVlcy5wdXNoKHZhbHVlKTtcclxuXHRcdHRoaXMuYWRkRWxlbWVudCh2YWx1ZSk7XHJcblx0XHR0aGlzLm1vZGFsLnlhbWwuaW5jbHVkZVR5cGVzID0gdGhpcy52YWx1ZXM7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0YWRkUmVzZXRCdXR0b24oKSB7XHJcblx0XHRjb25zdCByZXNldEJ1dHRvbiA9IHRoaXMuY29udHJvbEVsLmNyZWF0ZUVsKCdzcGFuJywgeyBjbHM6ICdjbGlja2FibGUtaWNvbiBzZXR0aW5nLXJlc3RvcmUtaG90a2V5LWJ1dHRvbicgfSk7XHJcblx0XHRjb25zdCBzdmcgPSAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIGNsYXNzPVwic3ZnLWljb24gbHVjaWRlLXJvdGF0ZS1jY3dcIj48cGF0aCBkPVwiTTMgMnY2aDZcIj48L3BhdGg+PHBhdGggZD1cIk0zIDEzYTkgOSAwIDEgMCAzLTcuN0wzIDhcIj48L3BhdGg+PC9zdmc+JztcclxuXHRcdHJlc2V0QnV0dG9uLmlubmVySFRNTCA9IHN2ZztcclxuXHRcdHJlc2V0QnV0dG9uLm9uQ2xpY2tFdmVudCgoZSkgPT4ge1xyXG5cdFx0XHR0aGlzLm1vZGFsLnBsdWdpbi5sb2FkU2V0dGluZ3MoKTtcclxuXHRcdFx0dGhpcy5zZXRWYWx1ZXModGhpcy5tb2RhbC5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdE92ZXJ2aWV3LmluY2x1ZGVUeXBlcyB8fCBbXSk7XHJcblx0XHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdFx0fSk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9XHJcblx0cmVtb3ZlVmFsdWUodmFsdWU6IHN0cmluZykge1xyXG5cdFx0dGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlcy5maWx0ZXIoKHYpID0+IHYgIT09IHZhbHVlKTtcclxuXHRcdHRoaXMuc2V0VmFsdWVzKHRoaXMudmFsdWVzKTtcclxuXHRcdHRoaXMubW9kYWwuZGlzcGxheSgpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGlzdCh0aGlzOiBTZXR0aW5nLCBjYjogKGxpc3Q6IExpc3RDb21wb25lbnQpID0+IExpc3RDb21wb25lbnQpIHtcclxuXHRjb25zdCBsaXN0ID0gbmV3IExpc3RDb21wb25lbnQodGhpcy5zZXR0aW5nRWwpO1xyXG5cdGNiKGxpc3QpO1xyXG5cdHJldHVybiBsaXN0O1xyXG59XHJcblxyXG4vLyBMaXN0Q29tcG9uZW50LnByb3RvdHlwZS5zZXRWYWx1ZXMgPSBzZXRWYWx1ZXM7XHJcbihTZXR0aW5nIGFzIGFueSkucHJvdG90eXBlLmNyZWF0ZUxpc3QgPSBjcmVhdGVMaXN0O1xyXG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFDQSxXQUFPLGVBQWUsU0FBUyxjQUFjLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFBQTtBQUFBOzs7QUNENUQ7QUFBQTtBQUFBO0FBQ0EsV0FBTyxlQUFlLFNBQVMsY0FBYyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQUE7QUFBQTs7O0FDRDVEO0FBQUE7QUFBQTtBQUNBLFdBQU8sZUFBZSxTQUFTLGNBQWMsRUFBRSxPQUFPLEtBQUssQ0FBQztBQUFBO0FBQUE7OztBQ0Q1RDtBQUFBO0FBQUE7QUFDQSxRQUFJLGtCQUFtQixXQUFRLFFBQUssbUJBQXFCLFFBQU8sU0FBVSxTQUFTLEdB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QUFrQixFQUFFLFFBQVEsQ0FBQyxTQUFTO0FBQ3BELFVBQUksQ0FBRSxpQkFBZ0IsNEJBQVU7QUFBRTtBQUFBLE1BQVE7QUFDMUMsWUFBTSxhQUFhLGNBQWMsTUFBTSxLQUFLLElBQUk7QUFDaEQsVUFBSSxDQUFDLFlBQVk7QUFDaEIsYUFBSyxxQkFBcUIsNkJBQU0sTUFBTSxpQkFBaUI7QUFDdkQ7QUFBQSxNQUNEO0FBRUEsWUFBTSxpQkFBaUIsa0JBQWtCLE1BQU0sS0FBSyxJQUFJO0FBR3hELFVBQUksaURBQWdCLG1CQUFtQjtBQUN0QyxhQUFLLHFCQUFxQixXQUFXLE1BQU0sZ0JBQWdCO0FBQzNELGFBQUsscUJBQXFCLEtBQUssTUFBTSxpQkFBaUI7QUFBQSxNQUN2RCxPQUFPO0FBQ04sYUFBSyxxQkFBcUIsV0FBVyxNQUFNLGdCQUFnQjtBQUMzRCxhQUFLLHFCQUFxQixLQUFLLE1BQU0saUJBQWlCO0FBQUEsTUFDdkQ7QUFBQSxJQUNELENBQUM7QUFBQSxFQUNGO0FBQUEsRUFFQSxpQkFBaUI7QUFDaEIsYUFBUyxpQkFBaUIsOEJBQThCLEVBQ3RELFFBQVEsQ0FBQyxZQUF5QjtBQUNsQyxVQUFJLFFBQVE7QUFBUztBQUNyQixjQUFRLFVBQVUsQ0FBQyxVQUFzQixrQkFBa0IsT0FBTyxJQUFJO0FBQUEsSUFDdkUsQ0FBQztBQUFBLEVBQ0g7QUFBQSxFQUVBLFdBQVc7QUFDVixZQUFRLElBQUksK0JBQStCO0FBQzNDLFNBQUssU0FBUyxXQUFXO0FBQ3pCLGFBQVMsS0FBSyxVQUFVLE9BQU8scUJBQXFCO0FBQ3BELGFBQVMsS0FBSyxVQUFVLE9BQU8sdUJBQXVCO0FBQ3RELGFBQVMsS0FBSyxVQUFVLE9BQU8sa0JBQWtCO0FBQ2pELGFBQVMsS0FBSyxVQUFVLE9BQU8sK0JBQStCO0FBQzlELFFBQUksS0FBSyxpQkFBaUI7QUFBRSxXQUFLLGdCQUFnQixZQUFZLFdBQVc7QUFBQSxJQUFHO0FBQzNFLFFBQUksS0FBSyxhQUFhO0FBQ3JCLFdBQUssWUFBWSxZQUFZO0FBQUEsSUFDOUI7QUFBQSxFQUVEO0FBQUEsRUFFQSxNQUFNLGVBQWU7QUFDcEIsU0FBSyxXQUFXLE9BQU8sT0FBTyxDQUFDLEdBQUcsa0JBQWtCLE1BQU0sS0FBSyxTQUFTLENBQUM7QUFBQSxFQUMxRTtBQUFBLEVBRUEsTUFBTSxlQUFlO0FBQ3BCLFVBQU0sS0FBSyxTQUFTLEtBQUssUUFBUTtBQUVqQyxTQUFLLGdCQUFnQixJQUFJO0FBQUEsRUFDMUI7QUFDRDsiLAogICJuYW1lcyI6IFtdCn0K