/******/ ( () => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./content/default/abstracts/grid/grid.js": /*!************************************************!*\ !*** ./content/default/abstracts/grid/grid.js ***! \************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Grid)/* harmony export */ }); let grid; class Grid { init() { grid = this.get_storage(); if (grid) { this.render(); } else { this.get(); } this.init_events(); } } /***/ } ), /***/ "./content/default/blocks/country-picker/country-picker.js": /*!*****************************************************************!*\ !*** ./content/default/blocks/country-picker/country-picker.js ***! \*****************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ CountryPicker)/* harmony export */ }); class CountryPicker { constructor() { this.init() } init() { let countrypickers = document.querySelectorAll(".country-picker") countrypickers.forEach( (element) => { element.addEventListener("click", function() { element.querySelector("svg").classList.toggle("open") element.querySelector("ul").classList.toggle("active") }) } ) } } /***/ } ), /***/ "./content/default/blocks/newsletters/newsletter.js": /*!**********************************************************!*\ !*** ./content/default/blocks/newsletters/newsletter.js ***! \**********************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Newsletter)/* harmony export */ }); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../scripts/utils.js */ "./content/default/scripts/utils.js"); let newsletter; class Newsletter { constructor() { this.init_events(); } init_events() { document.querySelectorAll('.newsletter-form').forEach(form => { form.addEventListener('submit', event => this.handleEvent(form, event)); } ); } handleEvent(form, event) { event.preventDefault(); let email = form.querySelector(".email").value; let country = form.querySelector(".country").value; let interest_id = form.querySelector(".interest_id").value; form.classList.remove("--error"); if (/^\b[A-ZÅÄÖåäö0-9._%+-]+@[A-ZÅÄÖåäö0-9.-]+\.[A-Z]{2,4}\b$/i.test(email)) { this.add_to_newsletter(email, country, interest_id, form); } else { form.classList.add("--error"); } } async add_to_newsletter(email, country, interest_id, form) { const data = new URLSearchParams(); data.append('funk', 'add_to_newsletter'); data.append('email', email); data.append('country', country); data.append('interest_id', interest_id); data.append('profile', "1"); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.status.code == 200) { newsletter = result.data.newsletter; this.pixels = result.data.pixels; this.render(); form.classList.remove("--error"); form.classList.add("--success"); } } async delete_from_newsletter(element) { const data = new URLSearchParams(); data.append('funk', 'delete_from_newsletter'); data.append('email', element.target.value); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.status.code == 200) { newsletter = result.data.newsletter; this.pixels = result.data.pixels; this.render(); } } render() { let page = "/sv/info/nyhetsbrev-tack.html"; if (document.querySelector(".webpage_url")) { page = document.querySelector(".webpage_url").value; } const temporary_element = document.createElement('div'); temporary_element.innerHTML = this.pixels; (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.executeJs)(temporary_element); document.querySelectorAll('.newsletter__input').forEach(element => { element.classList.add('--success'); } ); setTimeout(function() { window.location.href = page; }, 200); } } /***/ } ), /***/ "./content/default/blocks/productlists/recentlyviewed.js": /*!***************************************************************!*\ !*** ./content/default/blocks/productlists/recentlyviewed.js ***! \***************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ RecentlyViewed)/* harmony export */ }); /* harmony import */ var _default_views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../default/views/product/simple_slider */ "./content/default/views/product/simple_slider.js"); const storage_name = 'air_viewed'; const expire_time = 60 * 24 * 365; // In minutes. class RecentlyViewed { constructor() { this.init(); this.init_events(); } init() { const _this = this; window.lazyFunctions.recentlyViewed = function(element) { const data = _this.get(element); } } init_events() { const _this = this; document.addEventListener("product_page_viewed", function() { const id = window.product_id; if (!id) return; let viewed = _this.get_storage(); if (!viewed) { viewed = { items: [] }; } else if (viewed.items.includes(id)) { viewed.items = viewed.items.filter(function(e) { return e !== id }) } viewed.items.unshift(id); viewed.items.length = 100; _this.save_storage(viewed.items); }); } get_storage() { if (typeof (Storage) === 'undefined') return null; let str = window.localStorage.getItem(storage_name); if (str == null) return undefined; let data; try { data = JSON.parse(str); } catch (e) { return undefined; } if (data.expires < Date.now()) { return undefined; } return data; } save_storage(data) { if (typeof (Storage) === 'undefined') return null; let air_viewed = {}; air_viewed.items = data; air_viewed.expires = Date.now() + expire_time * 60000; window.localStorage.setItem(storage_name, JSON.stringify(air_viewed)); } async get(element) { const viewed = this.get_storage(); if (viewed) { if (viewed.items <= 1) { return; } const id = window.product_id; if (id) { viewed.items = viewed.items.filter(function(e) { return e !== id }) } const recently_viewed = JSON.stringify(viewed.items).replace(/\[|\]|\"/g, ""); const response = await fetch('/shop?funk=get_recently_viewed&recently_viewed=' + recently_viewed + '&lazy=1'); const result = await response.json(); if (result.status.code == 200) { element.innerHTML = result.data; document.dispatchEvent(new CustomEvent("product_cell_update")); document.dispatchEvent(new CustomEvent("pdp_latestviewed_loaded")); window.lazyLoadInstance.update(); const slider = document.querySelector('.recently_viewed .snapping--wrapper'); if (slider) { new _default_views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__["default"](slider); } } } } } /***/ } ), /***/ "./content/default/blocks/productlists/styleview.js": /*!**********************************************************!*\ !*** ./content/default/blocks/productlists/styleview.js ***! \**********************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ StyleView)/* harmony export */ }); /* harmony import */ var _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../views/product/simple_slider */ "./content/default/views/product/simple_slider.js"); class StyleView { constructor() { this.init(); } init() { const _this = this; window.lazyFunctions.styleView = function(element) { const data = _this.get(element); } } async get(element) { const id = window.product_id; const response = await fetch("/shop?funk=get_product_page_styleview&product_page_styleview=" + id + "&lazy=1"); const result = await response.json(); if (result.status.code == 200) { element.innerHTML = result.data; document.dispatchEvent(new CustomEvent("product_cell_update")); window.lazyLoadInstance.update(); const slider = document.querySelector('.styleview .snapping--wrapper'); if (slider) { new _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__["default"](slider); } } } } /***/ } ), /***/ "./content/default/blocks/search/search.js": /*!*************************************************!*\ !*** ./content/default/blocks/search/search.js ***! \*************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Search)/* harmony export */ }); let search; const suggestResult = document.getElementById("suggest-result") const suggestInit = document.getElementById("suggest-init") const suggestArea = document.getElementById("suggest-area") class Search { constructor() { this.suggest_highlight = (typeof (window.suggest_highlight) !== "undefined" && window.suggest_highlight === "1") ? true : false; this.full_search_url_fallback = "/shop?funk=gor_sokning&term="; this.search_history_count = (typeof (window.search_history_count) !== "undefined") ? window.search_history_count : 10; this.prev_chars = ""; this.prev_search_chars = ""; this.timeout_suggest; this.timeout_suggest_ms = 100; this.history_reload = false; this.history_url = ""; this.init(); } init() { if (window.shop_settings.other.search_url) { this.full_search_url = window.shop_settings.other.search_url; } else { this.full_search_url = this.full_search_url_fallback; } if (document.getElementById("search-history")) { this.history_init(); } this.init_events(); } init_events() { if (document.getElementById("search")) { document.getElementById("search").addEventListener("keyup", (e) => { this.suggest(e); } ); document.getElementById("search").addEventListener("focus", () => { this.show(); } ); document.getElementById("search-form").addEventListener("submit", (e) => { this.search(e); } ); } if (document.getElementById("search-wrapper")) { document.addEventListener("click", (e) => { var container = document.getElementById('search-wrapper'); if (!container.contains(e.target)) { this.hide(); } } ); } if (document.getElementById("search-history-clear")) { document.getElementById("search-history-clear").addEventListener("click", (e) => { e.preventDefault(); this.history_clear(); } ); } document.addEventListener("search-loaded", (e) => { this.history_save(e.detail.q, e.detail.hits); } ); } search(e) { e.preventDefault(); const chars = document.getElementById("search").value; if (chars.length > 0) { window.location.href = this.full_search_url + chars; } } nomatch() { const noresult = document.querySelector(".noHit") if (suggestResult.contains(noresult)) { suggestArea.classList.add("no-results") } else { suggestArea.classList.remove("no-results") } } suggest() { const chars = document.getElementById("search").value; if ((chars != '') && (chars.length > 1)) { if (chars !== this.prev_chars) { this.prev_chars = chars; this.suggest_request(chars); this.nomatch(); } document.querySelector(".backdrop").classList.add("active") document.querySelector("#header .header__search #suggest-area.active").style.maxHeight = "1000px"; suggestResult.style.display = "block" suggestInit.style.display = "none" } else { if (!chars.length) { if (suggestResult) { suggestResult.style.display = "none" } suggestInit.style.display = "block" document.querySelector("#header .header__search #suggest-area.active").style.maxHeight = "0px" document.body.style.overflow = "" document.querySelector(".backdrop").classList.remove("active") } } } async suggest_request(chars) { const chars_encoded = encodeURIComponent(chars); let response = await fetch("/shop?funk=autosuggest&q=" + chars_encoded); let html = await response.text(); suggestResult.innerHTML = html if (this.suggest_highlight) { this.highlight(chars); } } show() { if (document.getElementById("search").value !== "") { document.querySelector(".backdrop").classList.add("active") suggestArea.classList.add("active") document.querySelector("#header .header__search #suggest-area.active").style.maxHeight = "1000px" suggestInit.style.display = "none" suggestResult.style.display = "block" if (this.prev_chars === "") { this.suggest(); } } else { suggestInit.style.display = "block" } suggestArea.classList.add("active") } hide() { suggestArea.classList.remove("active") } highlight(chars) { chars = chars.trim(); var reg = new RegExp(this._escape_regexp(chars),'gi'); document.querySelectorAll("#suggest-result .term").forEach(function(elem) { var t = elem.innerHTML; t = t.replace(reg, "$&"); elem.innerHTML = t; }); } _escape_regexp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } history_init() { if (typeof (Storage) === "undefined") return null; const history_str = window.localStorage.getItem('search_history'); if (history_str == null || history_str === "") return null; const search_history = JSON.parse(history_str); let history_html = ""; for (let i = 0; i < search_history.length; i++) { const value = search_history[i].value; const url = this.full_search_url + encodeURIComponent(value); const link = '' + value + ''; history_html += '
  • ' + link + '
  • '; } if (history_html) { history_html = "
    " + search_texts['history'] + "" + search_texts['clear'] + "
    "; } document.getElementById("search-history").innerHTML = history_html; } history_save(query, hits) { if (typeof (Storage) === "undefined") return null; if (hits > 0) { var search_history = JSON.parse(window.localStorage.getItem('search_history')); if (search_history == null || search_history === "") { search_history = [{ 'value': query }]; } else { // remove if already exists. for (var i = 0; i < search_history.length; i++) { if (search_history[i].value === query) { search_history.splice(i, 1); i--; } } search_history.unshift({ 'value': query }); if (search_history.length > search_history_count) { search_history.length = search_history_count; } } window.localStorage.setItem('search_history', JSON.stringify(search_history)); } } history_clear() { if (typeof (Storage) === "undefined") return null; window.localStorage.removeItem('search_history'); document.getElementById("search-history").innerHTML = ""; } } /***/ } ), /***/ "./content/default/components/ace/Ace.js": /*!***********************************************!*\ !*** ./content/default/components/ace/Ace.js ***! \***********************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Ace)/* harmony export */ }); class Ace { constructor() { this.init(); } init() { this.selectedCategoriesImg = document.getElementById('img-toggle'); this.init_events(); } init_events() { if (this.selectedCategoriesImg) { const selectedCategories = document.querySelectorAll('.category-list--item'); selectedCategories.forEach(item => { item.addEventListener('mouseenter', (e) => this.set_active_category(e.target)); if (item.classList.contains('open')) { this.selectedCategoriesOpen = item; } } ); } } set_active_category(elem) { if (!elem.classList.contains('open')) { const img_tag = elem.getElementsByTagName('img'); if (img_tag.length) { this.selectedCategoriesImg.src = img_tag[0].src; if (this.selectedCategoriesOpen) { this.selectedCategoriesOpen.classList.remove('open'); } elem.classList.add('open'); this.selectedCategoriesOpen = elem; } } } } /***/ } ), /***/ "./content/default/components/atoms/Navigation/main-navigation.js": /*!************************************************************************!*\ !*** ./content/default/components/atoms/Navigation/main-navigation.js ***! \************************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Nav)/* harmony export */ }); class Nav { constructor() { this.init(); } init() { /* Toggle nav */ let menuBtn = document.querySelectorAll("#main--nav-icon") let menuBtnClose = document.querySelectorAll(".menu__categories--close") this.mainNav = document.querySelectorAll("#main--nav") this.scrollPosition = 0 if (window.matchMedia("screen and (min-width: 65rem)").matches) return; /* Show nav */ for (var i = 0; i < menuBtn.length; ++i) { menuBtn[i].addEventListener("click", () => { this.showMainNav(this) } ) } /* hide nav */ for (var i = 0; i < menuBtnClose.length; ++i) { menuBtnClose[i].addEventListener("click", () => { this.hideMainNav(this) } ) } if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) { document.querySelector("header").addEventListener("click", (event) => { if (!event.target.closest("#nav-wrapper, #main--nav-icon")) { this.hideMainNav(this) } } , false) } /* toggle level 1*/ const navItemsLink = document.querySelectorAll(".menu__categories > li.has__children > a") const navItemsBack = document.querySelectorAll(".menu__categories--back") this.ScrolltoTop = document.querySelector(".menu__categories") navItemsLink.forEach( (listItem) => { listItem.classList.remove('navigate') listItem.addEventListener("click", (e) => { this.setActiveLink(e, this) } ) } ) navItemsBack.forEach( (listItem) => { listItem.addEventListener("click", (e) => { this.setActiveBack(e, this) } ) } ) } showMainNav(_self) { for (let i = 0; i < _self.mainNav.length; ++i) { /* add active classes */ _self.mainNav[i].classList.add("active") document.body.classList.add("modal_active") } /* add scrollpostion */ _self.scrollPosition = window.pageYOffset document.body.style.overflow = "hidden" document.body.style.position = "fixed" document.body.style.top = `-${_self.scrollPosition}px` } hideMainNav(_self) { for (let i = 0; i < _self.mainNav.length; ++i) { /* remove active classes */ _self.mainNav[i].classList.remove("active") document.body.classList.remove("modal_active") } /* remove scrollpostion */ document.body.style.removeProperty("overflow") document.body.style.removeProperty("position") document.body.style.removeProperty("top") document.body.classList.remove("activeNav") document.querySelector(".backdrop").classList.remove('active') // window.scrollTo(0, _self.scrollPosition) } setActiveLink(e, _self) { const parent = e.target.parentNode /* if children prevent link follow - level1 */ e.preventDefault() /* show level - 1 if children */ e.target.parentNode.classList.toggle("open") e.target.parentNode.parentNode.classList.toggle("open") /* scroll menu to top on click */ _self.ScrolltoTop.scrollIntoView() } /* toggle back to level0 */ setActiveBack(e, _self) { const parent = e.target.parentNode e.target.parentNode.parentNode.classList.toggle("open") e.target.parentNode.parentNode.parentNode.classList.toggle("open") /* scroll menu to top on click */ _self.ScrolltoTop.scrollIntoView() } } /***/ } ), /***/ "./content/default/components/molecules/cart/cart.js": /*!***********************************************************!*\ !*** ./content/default/components/molecules/cart/cart.js ***! \***********************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Cart)/* harmony export */ }); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../scripts/utils.js */ "./content/default/scripts/utils.js"); const storage_name = 'air_cart'; const expire_time = 60; // In minutes. class Cart { constructor(wrapper_id='air-cart-wrapper', content_id='air-cart', label_id='air-cart-label') { this.wrapper_id = wrapper_id; this.content_id = content_id; this.label_id = label_id; this.cartErrorHeading = ''; this.cartErrorText = ''; if (window.shop_texts) { this.cartErrorHeading = window.shop_texts.text1 this.cartErrorText = window.shop_texts.text2 } this.currency_prefix = window.shop_settings['currency_prefix'] || ''; this.currency_suffix = window.shop_settings['currency_suffix'] || ''; this.init(); } init() { if (!(0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.getCookie)('SESS')) return; if (!document.getElementById(this.wrapper_id)) return; let getCart = false; if (window.shop_settings) { if (window.shop_settings.request === 'checkout_complete') { getCart = true; localStorage.removeItem(storage_name); } } if (!getCart) { this.cart = this.get_storage(); } if (this.cart) { this.render(); } else { this.get(); } } add_item_event(e) { const elem = e.target; const quantity_field = document.getElementById('cart-quantity'); const product_id = elem.dataset.id; const quantity = quantity_field ? quantity_field.value : 1; this.add_item(product_id, quantity, undefined); } remove_item_event(e) { const elem = e.target; const item_id = elem.parentElement.dataset.itemId; this.remove_item(item_id); } inc_item_event(e) { const elem = e.target; const item_id = elem.parentElement.dataset.itemId; this.inc_item(item_id); } sub_item_event(e) { const elem = e.target; const item_id = elem.parentElement.dataset.itemId; this.sub_item(item_id); } _show() { document.querySelector("body").classList.add("cart-open") document.querySelector(".backdrop").classList.add("active") document.getElementById(this.content_id).classList.add("active"); } _hide() { document.getElementById(this.content_id).classList.remove("active") document.querySelector(".backdrop").classList.remove("active") document.querySelector("body").classList.remove("cart-open") } _toggle() { let elementClasslist = document.getElementById(this.content_id).classList; console.log("hejhej") if (!elementClasslist.contains("active")) { this._show() } else { this._hide() } } async get(action, opt) { // let response = await fetch('/api/cart'); const response = await fetch('/shop?funk=get_cart'); const result = await response.json(); if (result.status.code == 200) { this.cart = result.data; this.save_storage(); this.render(action, opt); } } async add_item(product_id, quantity, extra_data) { const data = new URLSearchParams(); this.get() data.append('funk', 'add_cart_item'); data.append('product_id', product_id); data.append('quantity', quantity); if (extra_data) { // Hantera SET-artiklar. if (extra_data.bundle_fields) { data.append('bundle_fields', JSON.stringify(extra_data.bundle_fields)); } // Hantera presentkort. if (extra_data.giftcard_value_id) { data.append('giftcard_value_id', extra_data.giftcard_value_id); } } const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.status.code == 200) { this.cart = result.data.cart; this.pixels = result.data.pixels; this.save_storage(); this.render('add', { product_id: product_id }); if (product_id) { const data = new URLSearchParams(); data.append('funk', 'google_article_path'); data.append('artnr', product_id); data.append('path', window.shop_settings['product_referrer']); const response = fetch('/cgi-bin/ibutik/API.fcgi', { method: 'POST', body: data }); } } else { this.show_error(result.status); } } inc_item(item_id) { const item = this._get_item_from_cart(item_id); const new_quantity = item.quantity + 1; this._update_item(item, new_quantity); } sub_item(item_id) { const item = this._get_item_from_cart(item_id); const new_quantity = item.quantity - 1; if (new_quantity <= 0) { this.remove_item(item_id); } else { this._update_item(item, new_quantity); } } _get_item_from_cart(item_id) { let matched_item; this.cart.items.forEach( (item, i) => { if (item.id == item_id) { matched_item = item; } } ); return matched_item; } async _update_item(item, new_quantity) { const data = new URLSearchParams(); this.get() data.append('funk', 'update_cart_item'); data.append('id', item.id); data.append('quantity', new_quantity); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); // Update cart model if (result.status.code == 200) { this.cart.total_cost += item.price * (new_quantity - item.quantity); item.row_cost = item.price * new_quantity; item.quantity = new_quantity; this.save_storage(); this.render(); } else { this.show_error(result.status); } } async remove_item(item_id) { const data = new URLSearchParams(); this.get() data.append('funk', 'delete_cart_item'); data.append('id', item_id); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); // Update cart model if (result.status.code == 200) { this.cart.items.forEach( (item, i) => { if (item.id == item_id) { this.cart.total_cost -= item.row_cost; this.cart.items.splice(i, 1); } } ); this.save_storage(); this.render(); } else { this.show_error(result.status); } } save_storage() { if (typeof (Storage) === 'undefined') return null; this.cart.expires = Date.now() + expire_time * 60000; window.localStorage.setItem(storage_name, JSON.stringify(this.cart)); } get_storage() { if (typeof (Storage) === 'undefined') return null; let str = window.localStorage.getItem(storage_name); if (str == null) return undefined; let data; try { data = JSON.parse(str); } catch (e) { return undefined; } if (data.expires < Date.now()) { return undefined; } return data; } show_error(error) { const container = document.getElementById(this.content_id); let html = `

    ${this.cartErrorHeading}

    ${this.cartErrorText}

    ` container.innerHTML = html; document.body.classList.add("cart-open") const backdropBlur = document.querySelector(".backdrop") const airCartModule = document.querySelector("#air-cart-module") document.body.style.overflow = "hidden" document.querySelector("#air-cart").parentElement.classList.add("active") document.querySelector("#air-cart").parentElement.classList.add("error") backdropBlur.classList.add("active") } show(action, opt) { this.get(action, opt); } render(action, opt) { if (this.cart.total_count) { document.getElementById("air-cart-label-text").innerHTML = this.cart.total_count } if (this.cart.total_count > 0) { document.getElementById(this.label_id).classList.add("active") } document.getElementById(this.label_id).addEventListener("click", () => { if (window.checkout_url) { window.location.href = window.checkout_url; } else { window.location.href = "/shop?funk=bestall_steg1" } } ); if (action === 'add') { const container = document.getElementById(this.content_id); const product_id = opt.product_id; const items = this.cart.items; document.querySelector("header").classList.add("header__scrolled") document.querySelector("header").classList.remove("header__notScrolled") document.querySelector("body").classList.add("header__scrolled") document.querySelector("body").classList.remove("header__notScrolled") let item; if (opt.order == 'update_time') { item = items[items.length - 1]; for (let i = items.length - 1; i > 0; i--) { if (items[i - 1].update_time > items[i].update_time) { item = items[i - 1]; } } } else { for (let i = items.length; i > 0; i--) { if (items[i - 1].product_id === product_id) { item = items[i - 1]; break; } } } if (item) { let html = `
    ${item.product.name}
    ${this.currency_prefix}${item.price}${this.currency_suffix}
    ${this.pixels}
    ` container.innerHTML = html; (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.executeJs)(container); document.body.style.overflow = "hidden" document.body.classList.add("cart-open") const backdropBlur = document.querySelector(".backdrop") const airCartModule = document.querySelector("#air-cart-module") document.querySelector("#air-cart").parentElement.classList.add("active") backdropBlur.classList.add("active") } } } } /***/ } ), /***/ "./content/default/components/molecules/login/login.js": /*!*************************************************************!*\ !*** ./content/default/components/molecules/login/login.js ***! \*************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Login)/* harmony export */ }); class Login { constructor(icon_id='login-icon', form_id='login-form', popup_id='#login-wrapper', error_id='login-error', login_success_id='login-wrapper-content-success') { this.icon_id = icon_id; this.form_id = form_id; this.popup_id = popup_id; this.error_id = error_id; this.login_success_id = login_success_id; this.from_checklogin = false; this.isImboxHandling = false; // Flag to prevent loop this.init(); } init() { this.init_events(); this.setupImboxListener(); // Set up the _imbox listener } init_events() { if (!document.getElementById(this.icon_id)) return; if (window.checklogin) { this.init_checklogin(); } document.getElementById(this.icon_id).addEventListener('click', () => { this.show_login(); } ); document.querySelector(this.popup_id + ' .close').addEventListener('click', (e) => { e.stopPropagation(); this.hide_login(); } ); document.getElementById(this.form_id).addEventListener('submit', (e) => { e.preventDefault(); this.login(); } ); document.querySelector('.login-success-button').addEventListener('click', () => { this.handleRedirection(); } ); } init_checklogin() { this.from_checklogin = true; let text = window.checklogin_text || ''; let email = window.checklogin_email || ''; if (text) { let h3 = document.querySelector('#login-wrapper h3'); if (h3) { h3.innerHTML = text; } let ulElements = document.querySelectorAll('#login-wrapper-content ul'); ulElements.forEach(ul => ul.remove()); } if (email) { document.querySelector('#login-wrapper input[name="user"]').value = email; } this.show_login(); } handleRedirection() { if (window.location.href.includes('funk=logout')) { window.location.href = '/'; // Redirect to homepage } else { location.reload(); } } show_login() { const login_form = document.querySelector(this.popup_id); const backdrop = document.querySelector('.backdrop'); // Ensure _imbox is hidden when show_login is called this.hideImbox(); login_form.classList.add('active'); backdrop.classList.add('active'); document.body.classList.add('fullbackdrop'); } hide_login() { const login_form = document.querySelector(this.popup_id); login_form.classList.remove('active'); document.body.classList.remove('fullbackdrop'); } async login() { const form = document.getElementById(this.form_id); if (!form.user.value && !form.pass.value) return; const data = new URLSearchParams(new FormData(form)); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.status.code == 200) { if (typeof (Storage) !== 'undefined') { window.localStorage.removeItem('air_wishlist'); window.localStorage.removeItem('air_cart'); } if (this.from_checklogin) { this.handleRedirection(); } else { document.getElementById(this.form_id).classList.add('hide'); document.getElementById(this.login_success_id).classList.remove('hide'); } } else { document.getElementById(this.error_id).innerHTML = result.status.msg; } } hideImbox() { if (typeof (_imbox) !== "undefined") { this.isImboxHandling = true; // Disable the callback _imbox.push(['hideLauncher']); _imbox.push(['hideWidget']); setTimeout( () => { this.isImboxHandling = false; } , 100); // Re-enable the callback after a delay } } setupImboxListener() { const debounce = (func, wait) => { let timeout; return (...args) => { clearTimeout(timeout); timeout = setTimeout( () => func.apply(this, args), wait); } ; } ; const onToggleCallback = debounce( () => { if (!this.isImboxHandling) { // Only execute if not handling _imbox manually this.hideImbox(); } } , 100); if (typeof (_imbox) !== "undefined") {//_imbox.push(["onToggle", onToggleCallback]); } } } /***/ } ), /***/ "./content/default/components/molecules/toplist/toplist.js": /*!*****************************************************************!*\ !*** ./content/default/components/molecules/toplist/toplist.js ***! \*****************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Toplist)/* harmony export */ }); let toplist; class Toplist { init() { toplist = this.get_storage() if (toplist) { this.render() } else { this.get() } this.init_events(); } init_events() {} } /***/ } ), /***/ "./content/default/components/mystyle.js": /*!***********************************************!*\ !*** ./content/default/components/mystyle.js ***! \***********************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ MyStyle)/* harmony export */ }); class MyStyle { constructor() { this.init_events(); } init_events() { window.liveEvent(".myStyle__switch input", "change", (event, element) => { this.toggleMyStyle(element) } ); document.addEventListener("sort_changed", function(e) { if (e.detail) { if (e.detail.sort !== "most_popular-asc") { document.cookie = "bloomreach_sort_active=" + false + "; max-age=" + 30 * 24 * 60 * 60 + "; path=/"; document.querySelectorAll('.myStyle__switch input').forEach(checkbox => { checkbox.checked = false; } ); } } }); } toggleMyStyle(element) { let checked = element.checked; let type = element.dataset.type; exponea.track('site_click', { 'action': checked, 'type': 'my_style', 'parameter': 'toggle' }); document.querySelectorAll('.myStyle__switch input').forEach(checkbox => { checkbox.checked = checked; } ); document.cookie = "bloomreach_sort_active=" + checked + "; max-age=" + 30 * 24 * 60 * 60 + "; path=/"; if (type == "group") { if (checked) { this.setPopularSort(); } document.dispatchEvent(new Event("refresh_filter")); } else if (type == "widget") { let group_id = element.dataset.group_id; let limit = element.dataset.limit; let sort = element.dataset.sort; this.get(group_id, limit, sort); } } setPopularSort() { document.querySelectorAll('#sort-order-ul li').forEach(sort_li => { if (sort_li.dataset.value == "most_popular-asc") { sort_li.classList.add("--active"); document.querySelectorAll('.active_sort_label').forEach(label => { label.innerHTML = sort_li.innerHTML; } ); } else { sort_li.classList.remove("--active"); } } ); } async get(group_id, limit, sort) { const data = new URLSearchParams(); data.append('funk', 'get_filter'); data.append('json', 1); data.append('id', group_id); data.append('limit', limit); data.append('sort', sort); data.append('type', "product_group"); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.request_data) {} } } /***/ } ), /***/ "./content/default/components/organisms/accordion.js": /*!***********************************************************!*\ !*** ./content/default/components/organisms/accordion.js ***! \***********************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ accordion)/* harmony export */ }); class accordion { constructor() { this.init() } init() { function initAcc(elem, option) { document.addEventListener('click', function(e) { if (!e.target.matches(elem + ' .accordion__item--btn')) return; else { if (!e.target.parentElement.classList.contains('active')) { if (option == true) { var elementList = document.querySelectorAll(elem + ' .accordion__item'); Array.prototype.forEach.call(elementList, function(e) {// e.classList.remove('active'); }); } e.target.parentElement.classList.add('active'); } else { e.target.parentElement.classList.remove('active'); } } }); } initAcc('.accordion', true); } } /***/ } ), /***/ "./content/default/components/organisms/header/header.js": /*!***************************************************************!*\ !*** ./content/default/components/organisms/header/header.js ***! \***************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Header)/* harmony export */ }); class Header { constructor() { this.init() } init() { const ElementLegend = {} function GetElement(selector, refresh) { try { if (refresh) return document.querySelector(selector) if (!(selector in ElementLegend)) { ElementLegend[selector] = document.querySelector(selector) } return ElementLegend[selector] } catch (err) { console.log(err) return null } } var scrollPos = window.scrollY window.addEventListener("scroll", function() { if (!GetElement("header")) return else if (window.scrollY < 130) { scrollPos = window.scrollY GetElement("body").classList.remove("header__scrolled") GetElement("header").classList.remove("header__scrolled") GetElement("header").classList.remove("header__notScrolled") GetElement("header").classList.add("top") } else if (window.scrollY > scrollPos + 100) { scrollPos = window.scrollY GetElement("header").classList.remove("top") GetElement("header").classList.remove("header__scrolled") GetElement("body").classList.remove("header__scrolled") GetElement("body").classList.add("header__notScrolled") GetElement("header").classList.add("header__notScrolled") document.body.style.overflow = "" document.querySelector(".backdrop").classList.remove("active") if (document.querySelector("#header .header__search #suggest-area.active")) { document.querySelector("#header .header__search #suggest-area.active").style.maxHeight = "0px" } if (document.getElementById("suggest-result")) { document.getElementById("suggest-result").style.display = "none" } if (document.getElementById("suggest-init")) { document.getElementById("suggest-init").style.display = "none" } document.querySelector(".backdrop").classList.remove("active") if (document.querySelector("#search")) { document.querySelector("#search").blur() } } else if (window.scrollY < scrollPos - 100) { scrollPos = window.scrollY GetElement("header").classList.remove("header__notScrolled") GetElement("body").classList.remove("header__notScrolled") GetElement("header").classList.add("header__scrolled") GetElement("body").classList.add("header__scrolled") } }) } } /***/ } ), /***/ "./content/default/components/size_and_fit/sizeAndFit.js": /*!***************************************************************!*\ !*** ./content/default/components/size_and_fit/sizeAndFit.js ***! \***************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ SizeAndFit)/* harmony export */ }); class SizeAndFit { constructor() { this.init_events(); window.addEventListener('pdp_ajax_loaded', () => { this.init_events(); } ); } init_events() { const snfPDP = document.querySelector('.buybox .sizeAndFitTrigger'); const sizeAndFit = document.getElementById('sizeandfit2'); if (sizeAndFit) { if (snfPDP) { SizeAndFit.showGeneratedSize(); } this.activeFit(); this.activeStep(); this.snfBtn(); this.bodyTypeHandler(); this.rangeSlider(); const backdropBlur = document.querySelector('.backdrop'); const sizeNFit = document.getElementById('sizeandfit'); const sizeNFitStep = sessionStorage.getItem('snf_step'); // Assuming window.sizeNFitInitialized is not defined anywhere else in your code. if (typeof window.sizeNFitInitialized === 'undefined') { window.sizeNFitInitialized = false; } window.liveEvent('.sizeAndFitTrigger', 'click', () => { if (sizeNFitStep == '1' && !window.sizeNFitInitialized) { trackExponeaStart(); _imbox.push(['hideLauncher']); window.sizeNFitInitialized = true; // Set the flag to true after the first initialization } const productPage = document.querySelector('.single-product'); const sizeAndFit = document.getElementById('sizeandfit'); document.body.classList.add("sizeandfit-open"); document.body.style.overflow = ''; if (productPage) { const images = document.querySelectorAll('.productImg--wrapper img'); const productArtNr = document.querySelector('.product-id-info'); sizeAndFit.classList.add('from-pdp'); const imageSource = images[0].getAttribute('src'); sessionStorage.setItem('snf_image', imageSource); sessionStorage.setItem('snf_artnr', productArtNr.textContent); } backdropBlur.classList.add('active'); sizeNFit.classList.add('active'); this.activeStep(); if (sizeNFitStep > '1') { this.snfBackBtn(); } } ); window.liveEvent('.sizeandfit__header svg', 'click', () => { backdropBlur.classList.remove('active'); document.body.classList.remove("sizeandfit-open"); sizeNFit.classList.remove('active'); window.sizeNFitInitialized = false; } ); window.liveEvent('.sizeandfit__close', 'click', () => { backdropBlur.classList.remove('active'); sizeNFit.classList.remove('active'); document.body.classList.remove("sizeandfit-open"); sessionStorage.setItem('snf_step', '1'); window.sizeNFitInitialized = false; } ); if (!sizeNFitStep) { sessionStorage.setItem('snf_step', '1'); } } } rangeSlider() { const rangeLabels = document.querySelectorAll('.range__label'); const slider = document.getElementById('snf_slider'); rangeLabels.forEach( (label) => { label.addEventListener('click', (event) => { const value = event.target.getAttribute('data-value'); slider.value = value; // Trigger the change event manually to update the slider's value slider.dispatchEvent(new Event('change')); } ); } ); // Listen for changes in the slider's value slider.addEventListener('change', (event) => { const value = event.target.value; // Add or remove 'active' class based on the slider's value rangeLabels.forEach( (label) => { const labelValue = label.getAttribute('data-value'); if (labelValue === value) { label.classList.add('active'); } else { label.classList.remove('active'); } } ); } ); } activeFit() { const sliderLabels = document.querySelectorAll('.range__label'); const slider = document.getElementById('snf_slider'); if (slider) { slider.addEventListener('input', () => { const sliderValue = slider.value; sliderLabels.forEach( (label) => { const labelValue = label.getAttribute('data-value'); if (labelValue === sliderValue) { label.classList.add('active'); } else { label.classList.remove('active'); } } ); } ); } } snfBtn() { const snfContinue = document.querySelector('.sizeandfit__continue'); snfContinue.addEventListener('click', () => { let step = sessionStorage.getItem('snf_step'); const typesActive = document.querySelector('.sizeandfit__types'); const closeBtn = document.querySelector('.sizeandfit__header svg'); const clickEvent = new Event('click'); if (step === '1') { const snfHeight = document.getElementById('snf-height'); const snfWeight = document.getElementById('snf-weight'); const height = snfHeight.value; const weight = snfWeight.value; // Check if both height and weight have values if (height === '' || weight === '') { // Show an error message if either height or weight is missing document.getElementById('step_1_error_message').classList.remove('hide'); return; // Stop the function from proceeding } else { document.getElementById('step_1_error_message').classList.add('hide'); } step = parseInt(step) + 1; step = step.toString(); localStorage.setItem('snf_height', height); localStorage.setItem('snf_weight', weight); sessionStorage.setItem('snf_step', step); sessionStorage.setItem('snf_height', height); sessionStorage.setItem('snf_weight', weight); this.activeStep(); } else if (step === '2' && typesActive) { step = parseInt(step) + 1; step = step.toString(); sessionStorage.setItem('snf_step', step); this.activeStep(); } else if ((step === '3' && typesActive) || (step === '2' && !typesActive)) { const snfFit = document.getElementById('snf_slider'); const fit = snfFit.value; let formValue = ''; if (fit === '1') { formValue = 'tight'; } else if (fit === '2') { formValue = 'normal'; } else if (fit === '3') { formValue = 'spacious'; } step = parseInt(step) + 1; step = step.toString(); sessionStorage.setItem('snf_step', step); sessionStorage.setItem('snf_form', formValue); this.activeStep(); } else if ((step === '4' && typesActive) || (step === '3' && !typesActive)) { closeBtn.dispatchEvent(clickEvent); } this.snfBackBtn(); } ); } activeStep() { const step = sessionStorage.getItem('snf_step'); const continueButton = document.querySelector('.sizeandfit__continue'); const fromPDP = document.querySelector('.sizeandfit.from-pdp'); const snfHeader = document.querySelector('.sizeandfit__header'); const elements = [document.querySelector('.sizeandfit__metrics'), document.querySelector('.sizeandfit__fits'), document.querySelector('.sizeandfit__results-fromPDP'), document.querySelector('.sizeandfit__back'), document.querySelector('.sizeandfit__header h2'), document.querySelector('.sizeandfit__steps p'), document.querySelector('.sizeandfit__continue'), document.querySelector('.sizeandfit__results'), document.querySelector('.sizeandfit__finish'), document.querySelector('.sizeandfit__resultsfail'), document.querySelector('.sizeandfit__close')]; const typesActive = document.querySelector('.sizeandfit__types'); if (typesActive) { elements.splice(1, 0, typesActive); } elements.forEach( (element) => element.classList.add('hide')); if (step === '1' && typesActive) { [elements[0], elements[5], elements[6], elements[7]].forEach( (element) => element.classList.remove('hide')); elements[6].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step1'); } else if (step === '2' && typesActive) { [elements[1], elements[4], elements[6], elements[7]].forEach( (element) => element.classList.remove('hide')); elements[6].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step2'); } else if (step === '3' && typesActive) { [elements[2], elements[4], elements[6], elements[7]].forEach( (element) => element.classList.remove('hide')); elements[6].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step3'); } else if (step === '4' && typesActive && fromPDP) { this.fetchSize([elements[3], elements[4], elements[6]]); elements[6].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step4'); } else if (step === '4' && typesActive && !fromPDP) { this.fetchSize([elements[9], elements[4], elements[6], elements[8], elements[7]]); elements[6].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step4'); // Logic for inactive bodytypes below } else if (step === '1' && !typesActive) { [elements[0], elements[4], elements[5], elements[6]].forEach( (element) => element.classList.remove('hide')); elements[5].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step1'); } else if (step === '2' && !typesActive) { [elements[1], elements[3], elements[5], elements[6]].forEach( (element) => element.classList.remove('hide')); continueButton.classList.remove('hide'); elements[5].textContent = step; snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step2'); } else if (step === '3' && !typesActive && fromPDP) { [elements[5]].forEach( (element) => element.classList.remove('hide')); elements[5].textContent = step; this.fetchSize([elements[2], elements[3]]); snfHeader.className = snfHeader.className.replace(/\bstep\d\b/g, 'step4'); } else if (step === '3' && !typesActive && !fromPDP) { [elements[5]].forEach( (element) => element.classList.remove('hide')); elements[5].textContent = step; this.fetchSize([elements[7], elements[3]]); snfHeader.classList.replace('step2', 'step4'); } } snfBackBtn() { const backBtn = document.querySelector('.sizeandfit__back'); const step = sessionStorage.getItem('snf_step'); const stepBackValue = parseInt(step) - 1; const stepBackString = stepBackValue.toString(); backBtn.addEventListener('click', () => { sessionStorage.setItem('snf_step', stepBackString); this.activeStep(); this.snfBackBtn(); } ); } fetchSize(elementArray) { const sizeResult = document.querySelectorAll('.size-result'); const sizeResultImage = document.querySelector('.sizeandfit__results--img img'); const height = sessionStorage.getItem('snf_height'); const weight = sessionStorage.getItem('snf_weight'); const form = sessionStorage.getItem('snf_form'); const image = sessionStorage.getItem('snf_image'); const loadingWrapper = document.querySelector('.sizeandfit__loading_pageWrapper'); const stepCounter = document.querySelector('.sizeandfit__steps'); const articleNumber = sessionStorage.getItem('snf_artnr'); const resultFailed = document.querySelector('.sizeandfit__resultsfail'); const resultFromPDP = document.querySelector('.sizeandfit__results-fromPDP'); const continueButton = document.querySelector('.sizeandfit__continue'); const finishButton = document.querySelector('.sizeandfit__finish'); const fromPDP = document.querySelector('.sizeandfit.from-pdp'); const closeButton = document.querySelector('.sizeandfit__close'); let type = sessionStorage.getItem('snf_type'); let artnr = ''; if (!type) { type = 'rectangular'; } if (articleNumber) { artnr = `&product_id=${articleNumber}`; } const fetchQuery = `&match_id=1&field_1=${type}&field_2=${form}&field_x=${weight}&field_y=${height}${artnr}`; stepCounter.classList.add('hide'); loadingWrapper.style.display = 'block'; this.loading_start(); fetch(`/cgi-bin/ibutik/API.fcgi?funk=PM${fetchQuery}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }).then( (response) => response.json()).then( (data) => { // Simulating a delay to ensure the loader animation finishes first setTimeout( () => { loadingWrapper.style.display = 'none'; if (elementArray && Array.isArray(elementArray)) { elementArray.forEach( (element) => element.classList.remove('hide')); } stepCounter.classList.remove('hide'); if (data.alt_value && data.alt_value_unavailable !== 1) { sizeResult.forEach( (result) => { result.textContent = data.alt_value; } ); sizeResultImage.setAttribute('src', image); } else if (data.value && !data.alt_value && data.value_unavailable !== 1) { sizeResult.forEach( (result) => { result.textContent = data.value; } ); sizeResultImage.setAttribute('src', image); } else if (data.value_unavailable === 1 || data.alt_value_unavailable === 1) { sizeResult.forEach( (result) => { result.textContent = data.value; } ); finishButton.classList.add('hide'); resultFailed.classList.remove('hide'); resultFromPDP.classList.add('hide'); closeButton.classList.remove('hide'); } if (fromPDP) { if (closeButton.classList.contains('hide')) { finishButton.classList.remove('hide'); } continueButton.classList.add('hide'); SizeAndFit.showGeneratedSize(); } else { continueButton.classList.remove('hide'); finishButton.classList.add('hide'); continueButton.querySelector('.finish').classList.remove('hide'); continueButton.querySelector('.continue').classList.add('hide'); } } , 1500); } ).catch( (error) => { console.error('Error:', error); } ); } bodyTypeHandler() { const types = document.querySelectorAll('.sizeandfit__types-wrapper img'); types.forEach( (type) => { if (type.classList.contains('active')) { // Check if 'snf_type' does not exist in sessionStorage if (!sessionStorage.getItem('snf_type')) { const formValue = type.getAttribute('data-value'); sessionStorage.setItem('snf_type', formValue); } } // Then attach the click event listener to all types regardless type.addEventListener('click', () => { const formValue = type.getAttribute('data-value'); types.forEach( (otherType) => { otherType.classList.remove('active'); } ); type.classList.add('active'); sessionStorage.setItem('snf_type', formValue); } ); } ); } loading_start() { document.getElementsByClassName('progress')[0].style.width = '0%'; document.getElementsByClassName('percentage')[0].innerHTML = '0%'; let count = 0; const progressBar = document.querySelector('.progress'); const percentage = document.querySelector('.percentage'); const interval = setInterval( () => { count = count + 2; progressBar.style.width = count + '%'; percentage.innerHTML = count + '%'; if (count === 100) { clearInterval(interval); this.handleFinishBtn(); } } , 30); } static async showGeneratedSize() { const sizeMatchFailed = document.querySelector('.sizematchfailed'); const generatedsize = document.querySelector('.generatedsize'); const snf_result = document.querySelector('.snf_result'); const generatedsizeValue = document.querySelector('.generatedsize .size'); const sizeMatchFailedValue = document.querySelector('.sizematchfailed .size'); const sizes = document.querySelectorAll('.buybox__variant--item'); const snfTriggerButton = document.querySelectorAll('.snf-trigger__btn'); const sizeHolder = document.getElementById('variation-1'); const trueSizeFields = document.querySelectorAll('.TrueSize'); const articleNumber = sessionStorage.getItem('snf_artnr'); const pdpArtnr = document.querySelector('.product-id-info').textContent; sessionStorage.setItem('snf_step', '1'); try { let artnr = ''; if (articleNumber && 1 == 0) {} else if (pdpArtnr) { artnr = `&product_id=${pdpArtnr}`; } let startTime = performance.now(); const response = await fetch(`/cgi-bin/ibutik/API.fcgi?funk=PM&match_id=1&get_customer=1${artnr}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }); let eventHandledTime = performance.now(); exponea.track('speed', { 'action': 'snf_getSize', 'speed': `${eventHandledTime - startTime}` }); const data = await response.json(); if (data.value && generatedsize) { let sizeFound = false; let data_size = data.value; let data_size_variant = data.value_variant; if (data.alt_value) { data_size = data.alt_value; } if (data.alt_value_variant) { data_size_variant = data.alt_value_variant; } // Matching sizes and checking for disabled class sizes.forEach( (size) => { const sizeValue = size.getAttribute('data-value'); if (data_size === sizeValue || data_size_variant === sizeValue) { sizeFound = true; const snfTriggerButton = document.querySelectorAll('.snf-trigger__btn'); snfTriggerButton[0].classList.add('hide'); if (size.classList.contains('disabled')) { sizes.forEach( (size) => size.classList.remove('active')); generatedsize.classList.add('hide'); sizeMatchFailed.classList.remove('hide'); snf_result.classList.remove('hide'); sizeMatchFailedValue.textContent = data_size; } else { if (data_size_variant) { sizeHolder.dataset.value = data_size_variant; } else { sizeHolder.dataset.value = data_size; } sessionStorage.setItem('snf_size', data_size); if (size.classList.contains('active')) { return; } else { size.click(); } if (data.value_variant) { generatedsizeValue.textContent = data_size_variant; } else { generatedsizeValue.textContent = data_size; } generatedsize.classList.remove('hide'); snf_result.classList.remove('hide') sizeMatchFailed.classList.add('hide'); } } } ); // If the size was not found if (!sizeFound) { generatedsize.classList.add('hide'); sizeMatchFailed.classList.remove('hide'); if (data.value_variant) { sizeMatchFailedValue.textContent = data.value_variant; } else { sizeMatchFailedValue.textContent = data_size; } snf_result.classList.remove('hide') const triggerButton = document.querySelector('button.sizeAndFitTrigger'); sessionStorage.setItem('snf_size', 'not_found'); if (triggerButton) { triggerButton.classList.add('hide'); } trueSizeFields.forEach(function(field) { field.classList.add('hide'); // Add the 'hide' class to each element }); } else { trueSizeFields.forEach(function(field) { field.classList.add('hide'); // Add the 'hide' class to each element }); } } const height = document.getElementById('snf-height'); const weight = document.getElementById('snf-weight'); if (data.field_x && data.field_y) { if (height && weight) { height.value = data.field_y; weight.value = data.field_x; } } else if (localStorage.getItem('snf_height') && localStorage.getItem('snf_weight')) { if (height && weight) { height.value = localStorage.getItem('snf_height'); weight.value = localStorage.getItem('snf_weight'); } } window.dispatchEvent(new CustomEvent("snf_done")); } catch (error) { console.error('Error:', error); } } handleFinishBtn() { const finishButton = document.querySelector('.sizeandfit__finish'); const buyButton = document.getElementById('air-buy'); const sizeAndFit = document.querySelector('.sizeandfit'); finishButton.addEventListener('click', (e) => { e.stopPropagation(); e.preventDefault(); const sizeNFit = document.getElementById('sizeandfit'); const backdropBlur = document.querySelector('.backdrop'); SizeAndFit.showGeneratedSize(); buyButton.click(); sessionStorage.setItem('snf_step', '1'); finishButton.classList.add('hide'); sizeAndFit.classList.remove('from-pdp'); backdropBlur.classList.remove('active'); sizeNFit.classList.remove('active'); } , { once: true }); } } /***/ } ), /***/ "./content/default/components/style_advisor/styleadvisor.js": /*!******************************************************************!*\ !*** ./content/default/components/style_advisor/styleadvisor.js ***! \******************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ StyleAdvisor)/* harmony export */ }); /* harmony import */ var _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../views/product/simple_slider */ "./content/default/views/product/simple_slider.js"); let animating = false; let decisionVal = 80; let pullDeltaX = 0; let startX = 0; let $card; let _this; class StyleAdvisor { constructor() { this.init_events() if (document.getElementById('datepicker')) { this.initCalendar(); } } init_events() { const backdropBlur = document.querySelector(".backdrop") const styleadvisor = document.getElementById("styleadvisor") window.liveEvent(".StyleAdviceTrigger", "click", (event, element) => { if (sessionStorage) { this.uuid = sessionStorage.getItem("style_uuid"); if (!this.uuid) { this.uuid = this.uuidv4(); sessionStorage.setItem("style_uuid", this.uuid); } this.styleCounter = sessionStorage.getItem("style_counter"); if (!this.styleCounter) { this.styleCounter = 1; } this.stored_style_type = sessionStorage.getItem("style_type"); } if (typeof (_imbox) !== "undefined") { _imbox.push(['hideLauncher']); _imbox.push(['hideWidget']); } styleadvisor.classList.add("active") if (styleadvisor.hasAttribute("data-step")) { const step = styleadvisor.dataset.step; if (step === "2" || step === "3") { styleadvisor.classList.add("live"); } } backdropBlur.classList.add("active") document.body.classList.add("styleadvisor") if (!styleadvisor.dataset.step) { if (this.stored_style_type) { this.getContent(4, 1) } else { this.getContent(1) } if (document.querySelectorAll(".styleadvisor .snapping--wrapper").length) { document.querySelectorAll(".styleadvisor .snapping--wrapper").forEach(function(elem) { new _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__["default"](elem) }) } } } ) window.liveEvent(".menu__styleadvicer a", "click", (event, element) => { if (sessionStorage) { this.uuid = sessionStorage.getItem("style_uuid"); if (!this.uuid) { this.uuid = this.uuidv4(); sessionStorage.setItem("style_uuid", this.uuid); } this.styleCounter = sessionStorage.getItem("style_counter"); if (!this.styleCounter) { this.styleCounter = 1; } this.stored_style_type = sessionStorage.getItem("style_type"); } if (typeof (_imbox) !== "undefined") { _imbox.push(['hideLauncher']); _imbox.push(['hideWidget']); } styleadvisor.classList.add("active") if (styleadvisor.hasAttribute("data-step")) { const step = styleadvisor.dataset.step; if (step === "2" || step === "3") { styleadvisor.classList.add("live"); } } backdropBlur.classList.add("active") document.body.classList.add("styleadvisor") if (!styleadvisor.dataset.step) { if (this.stored_style_type) { this.getContent(4, 1) } else { this.getContent(1) } const styleAdvisorSlider = document.querySelector(".styleadvisor .snapping--wrapper") if (styleAdvisorSlider) { new _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__["default"](styleAdvisorSlider) } } } ) window.liveEvent(".continuePop .restart, .StyleAdviceRestart", "click", (event, element) => { this.currentSlide = 1; this.updateCurrentSlide(); document.querySelectorAll(".brands_list_brand.--checked").forEach( (elem) => { elem.classList.remove("--checked"); } ); if (document.querySelectorAll(".brand_continue .styleadvisor__continue").length) { document.querySelectorAll(".brand_continue .styleadvisor__continue")[0].classList.add("--disabled"); } document.querySelectorAll('.styleadvisor__step').forEach( (item) => { if (item.dataset.step === '4') { item.remove(); } } ); this.getContent(1, 0, 1) styleadvisor.classList.remove("live") } ) window.liveEvent(".continuePop .continue", "click", (event, element) => { styleadvisor.classList.remove("live") } ) window.liveEvent(".styleadvisor_back", "click", (event, element) => { const styleadvisor = document.getElementById("styleadvisor") this.getContent(parseInt(styleadvisor.dataset.step) - 1) } ) window.liveEvent(".styleadvisor__header .close, .personlizedContent .cm_article_wrapper a", "click", () => { if (typeof (_imbox) !== "undefined") { _imbox.push(['showLauncher']) } styleadvisor.classList.remove("active") backdropBlur.classList.remove("active") document.body.classList.remove("styleadvisor") if (sessionStorage) { this.test_completed = sessionStorage.getItem("test_completed"); if (this.test_completed && this.test_completed !== '') { location.reload(); sessionStorage.setItem("test_completed", ""); } } } ) window.liveEvent(".styleadvisor__continue", "click", (event, element) => { if (element.classList.contains("--disabled")) return var step = document.querySelector('.styleadvisor__step.--active').dataset.step; if (step === "1") { if (sessionStorage) { this.styleCounter++; sessionStorage.setItem("style_counter", this.styleCounter); } exponea.track('style_event', { 'action': 'start', 'type': 'styleadvisor', 'stylerun': this.uuid + "_" + this.styleCounter }); } if (step === "3") { if (document.getElementsByClassName("styleadvisor__loading_pageWrapper")[0].style.display === 'none') { document.getElementsByClassName("brands_list")[0].style.display = "none"; document.getElementsByClassName("brand_continue")[0].style.display = "none"; document.getElementsByClassName("styleadvisor__loading_pageWrapper")[0].style.display = "block"; this.loading_start(); } } const styleadvisor = document.getElementById("styleadvisor") this.getContent(parseInt(styleadvisor.dataset.step) + 1) } ) /* SWIPE FUNKTIONALITET */ // window.liveEvent(".styleadvisor_swipe", "mousedown", (event, element) => { // if (event.buttons == 1) { // this.swipeHandler(event, element); // } // }); // window.liveEvent(".styleadvisor_swipe", "touchstart", (event, element) => { // this.swipeHandler(event, element); // }); window.liveEvent(".styleadvisor_brand", "click", (event, element) => { if (document.querySelectorAll(".styleadvisor_brand.--checked").length < 800 || element.classList.contains("--checked")) { element.classList.toggle("--checked") } const checkedBrands = document.querySelectorAll(".styleadvisor_brand.--checked").length if (checkedBrands >= 2) { this.toggleContinueButton(0) } else { this.toggleContinueButton(1) } } ) window.liveEvent("#styleadvisor_like", "click", (event, element) => { if (!this.buttonsLocked) { this.buttonsLocked = true; this.triggerSwipe(event, element, "liked"); this.updateCurrentSlide(); } } ) window.liveEvent("#styleadvisor_dislike", "click", (event, element) => { if (!this.buttonsLocked) { this.buttonsLocked = true; this.triggerSwipe(event, element, "disliked"); this.updateCurrentSlide(); } } ) window.liveEvent(".styleadvisor__loginBtn", "click", (event, element) => { const styleadvisor_login_form = document.getElementById("styleadvisor-login-form-wrapper") if (styleadvisor_login_form) { styleadvisor_login_form.classList.toggle("hidden") } } ) window.liveEvent("#styleadvisor-login-form-wrapper .close", "click", (event, element) => { const styleadvisor_login_form = document.getElementById("styleadvisor-login-form-wrapper") styleadvisor_login_form.classList.toggle("hidden") } ) window.liveEvent("#styleadvisor__createprofile .close", "click", (event, element) => { const styleadvisor_login_form = document.getElementById("styleadvisor__createprofile") styleadvisor_login_form.classList.toggle("hidden") } ) window.liveEvent("#styleadvisor-login-form", "submit", (event, element) => { event.preventDefault() this.login(element) } ) window.liveEvent("#styleadvisor-create-form", "submit", (event, element) => { event.preventDefault() this.createProfile(element) } ) window.liveEvent("#styleadvisor__create", "keyup", (event, element) => { if (/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(element.value)) { this.toggleContinueButton(0) } else { this.toggleContinueButton(1) } } ) } async getContent(step, restoring, restart) { const styleadvisor = document.getElementById("styleadvisor") styleadvisor.classList.add("loading") if (step == 1 && !restoring && !restart) { const response = await fetch("shop?funk=get_restoring_style&custom_func=1") const result = await response.json() if (result.restoring_style_type) { step = 4; restoring = 1; } } if (!restoring) { restoring = 0; } if (step == 4 && !restoring) { this.save_styleadvisor(1); } let existing_step = styleadvisor.querySelector('.styleadvisor__step[data-step="' + step + '"]') if (existing_step) { document.querySelectorAll(".styleadvisor__step.--active").forEach( (element) => { element.classList.remove("--active") } ) existing_step.classList.add("--active") styleadvisor.dataset.step = step document.querySelectorAll(".styleadvisor_swipe").forEach( (element) => { element.classList.remove("--liked") element.classList.remove("--disliked") element.classList.remove("--current") element.setAttribute("style", "") } ) styleadvisor.classList.remove("loading") if (step === 3) { // Reset the counter if its visible if (document.getElementsByClassName("styleadvisor__loading_pageWrapper")[0].style.display === 'block') { document.getElementsByClassName("brands_list")[0].style.display = ""; document.getElementsByClassName("brand_continue")[0].style.display = ""; document.getElementsByClassName("styleadvisor__loading_pageWrapper")[0].style.display = "none"; document.getElementsByClassName("progress")[0].style.width = "0%"; document.getElementsByClassName("percentage")[0].innerHTML = "0%"; } } } else { const response = await fetch("shop?funk=get_style_advisor&custom_func=1&step=" + step + "&restoring=" + restoring) const result = await response.json() if (result.html) { var newElement = document.createElement("div") newElement.className = "styleadvisor__step --active" newElement.dataset.step = step newElement.innerHTML = result.html document.querySelectorAll(".styleadvisor__step.--active").forEach( (element) => { element.classList.remove("--active") } ) styleadvisor.appendChild(newElement) styleadvisor.dataset.step = step if (step == 2) { // Set the total number of slides this.totalSlides = document.getElementsByClassName("styleadvisor_swipe").length; this.currentSlide = 1; document.getElementById("sa-totalSlides").innerHTML = this.totalSlides; this.updateCurrentSlide(); } if (step == 4 && !restoring) { var error_display = document.getElementById("style_advisor_error"); if (error_display && window.getComputedStyle(error_display).display === 'block') { // error exponea.track('style_event', { 'action': 'error', 'type': 'styleadvisor', 'parameter': 'no_segment' }); } else { // result_page exponea.track('style_event', { 'action': 'result_page', 'type': 'styleadvisor', 'stylerun': this.uuid + "_" + this.styleCounter, 'parameter': result.style_type }); sessionStorage.setItem("style_type", result.style_type); } } if (step == 6) { grecaptcha.render('captcha_element', { 'sitekey': '6Lcs9cYUAAAAAO6RWrvcXgKPFUCI86ARhIsI7c5t' }); } styleadvisor.classList.remove("loading") } } } loading_start() { var interval; var count = 0; var progressBar = document.querySelector(".progress"); var percentage = document.querySelector(".percentage"); interval = setInterval(function() { count++; progressBar.style.width = count + "%"; percentage.innerHTML = count + "%"; if (count === 100) { clearInterval(interval); } }, 50); } updateCurrentSlide() { if (this.currentSlide <= this.totalSlides) { document.getElementById("sa-count").innerHTML = this.currentSlide; this.currentSlide++; } } releaseSlide() { if (pullDeltaX >= decisionVal) { $card.classList.add("--liked") $card.classList.remove("--current") _this.scaleBackgroundImages(1) const segment_data = _this.get_segment_data_from_element($card) _this.bloomreach_track("liked", "style_segment_image", segment_data) } else if (pullDeltaX <= -decisionVal) { $card.classList.add("--disliked") $card.classList.remove("--current") _this.scaleBackgroundImages(1) const segment_data = _this.get_segment_data_from_element($card) _this.bloomreach_track("disliked", "style_segment_image", segment_data) } else { $card.setAttribute("style", "transform: translateY(0) scale(1);") _this.scaleBackgroundImages(0) } pullDeltaX = 0 animating = false if (!document.querySelectorAll(".styleadvisor_swipe:not(.--liked, .--disliked)").length) { _this.getContent(3) } } swipeHandler(e, element) { if (animating) return $card = element $card.classList.add("--current") startX = e.pageX || e.originalEvent.touches[0].pageX document.addEventListener("mousemove", this.handleMove, true) document.addEventListener("touchmove", this.handleMove, true) _this = this document.addEventListener("mouseup", this.handleRelease, true) document.addEventListener("touchend", this.handleRelease, true) } /* SWIPE FUNKTIONALITET */ // handleMove(e) { // let x = e.pageX || e.originalEvent.touches[0].pageX; // pullDeltaX = (x - startX); // if (!pullDeltaX) return; // let percent = pullDeltaX < 1 ? pullDeltaX / 350 * -1 : pullDeltaX / 350 * 1; // animating = true; // let deg = pullDeltaX / 10; // $card.style.transform = "translateX(" + pullDeltaX + "px) translateY(0px) scale(1) rotate(" + deg + "deg)"; // let opacity = pullDeltaX < 0 ? (pullDeltaX / 100 * -1) : pullDeltaX / 100; // $card.style.opacity = 1 - opacity * 0.3; // $card.classList.add("--current"); // _this.scaleBackgroundImages(percent); // } // handleRelease(e) { // document.removeEventListener("mousemove", _this.handleMove, true); // document.removeEventListener("touchmove", _this.handleMove, true); // document.removeEventListener("mouseup", _this.handleRelease, true); // document.removeEventListener("touchend", _this.handleRelease, true); // _this.releaseSlide(); // } triggerSwipe(e, element, type) { const currentImage = document.querySelectorAll(".styleadvisor_swipe:not(.--liked, .--disliked)")[0] if (!currentImage) { return } currentImage.classList.add("--current") _this = this let counter = 0 let swipeInterval = setInterval(function() { counter++ let pullDeltaX = type == "liked" ? counter * 5 : counter * -5 let deg = pullDeltaX / 10 let opacity = pullDeltaX < 0 ? (pullDeltaX / 100) * -1 : pullDeltaX / 100 currentImage.style.transform = "translateX(" + pullDeltaX + "px) translateY(0px) scale(1) rotate(" + deg + "deg)" currentImage.style.opacity = 1 - opacity * 0.3 if (counter == 100) { clearInterval(swipeInterval) currentImage.classList.add("--" + type) const segment_data = _this.get_segment_data_from_element(currentImage) _this.bloomreach_track(type, "style_segment_image", segment_data) _this.buttonsLocked = false; if (!document.querySelectorAll(".styleadvisor_swipe:not(.--liked, .--disliked)").length) { _this.getContent(3) } } _this.scaleBackgroundImages(counter / 5) }, 0) } scaleBackgroundImages(percent) { const activeImages = document.querySelectorAll(".styleadvisor_swipe:not(.--liked, .--disliked, .--current)") let scale_drag = 0.1 * percent let translate_drag = 2 * percent let opacity_drag = 0.3 * percent let scaleIncrement = scale_drag > 0.1 ? 1 : 0.9 + scale_drag let transform = translate_drag > 2 ? 0 : 2 - translate_drag let opacity = opacity_drag > 0.3 ? 1 : 0.7 + opacity_drag activeImages.forEach( (element) => { element.style.transform = "translateY(" + transform + "px) scale(" + scaleIncrement + ")" element.style.opacity = opacity scaleIncrement = scaleIncrement - 0.1 transform = transform + 2 opacity = opacity > 0.4 ? opacity - 0.4 : 0 } ) } bloomreach_track(like_type, event_type, segment_data, title) { if (!window.exponea) return; window.exponea.track("style_event", { type: "styleadvisor", action: like_type == "liked" ? "like" : "dislike", parameter: event_type, title: segment_data.title, style_segment_1: segment_data.segment_1, style_segment_2: segment_data.segment_2, style_segment_3: segment_data.segment_3, timestamp: Date.now(), stylerun: this.uuid + '_' + this.styleCounter }) } get_segment_data_from_element(element) { return { title: element.dataset.id, segment_1: element.dataset.id, segment_2: element.dataset.id, segment_3: element.dataset.id, } } get_segment_data_from_brand(brand) { return { title: brand.dataset.name, segment_1: brand.dataset.segment_1, segment_2: brand.dataset.segment_2, segment_3: brand.dataset.segment_3, } } async login(form) { if (!form.user.value && !form.pass.value) return const data = new URLSearchParams(new FormData(form)) const response = await fetch("/shop", { method: "POST", body: data, }) const result = await response.json() if (result.status.code == 200) { document.getElementById("styleadvisor__loginwrapper").style.display = "none" document.getElementById("styleadvisor__createwrapper").style.display = "none" this.toggleContinueButton(0) this.setLoginIcon(); } else { document.getElementById("styleadvisor__login-error").innerHTML = "Fel användaruppgifter" } } async createProfile(form) { if (!form.user.value) return const data = new URLSearchParams(new FormData(form)) const response = await fetch("/shop", { method: "POST", body: data, }) const result = await response.json() if (result.status == 1) { this.save_styleadvisor(); document.getElementById("styleadvisor__createprofile").classList.add("hide"); if (document.querySelectorAll("#styleadvisor__loginwrapper").length) { document.getElementById("styleadvisor__loginwrapper").classList.add("hide"); } this.setLoginIcon(); } else if (result.status == 2) { document.getElementById("styleadvisor-create-password").classList.remove("hide"); document.getElementById("create-error").innerHTML = result.message; } } async save_styleadvisor(track) { const brandList = []; const segmentImages = []; document.querySelectorAll(".styleadvisor_brand.--checked").forEach( (element) => { const segment_data = _this.get_segment_data_from_brand(element) if (track) { _this.bloomreach_track("liked", "brand", segment_data) } brandList.push(element.dataset.id); } ); if (track) { // Complete exponea.track('style_event', { 'action': 'complete', 'type': 'styleadvisor', 'stylerun': this.uuid + "_" + this.styleCounter }); sessionStorage.setItem("test_completed", "completed"); } document.querySelectorAll('.styleadvisor_swipe').forEach( (element) => { const imgs = element.getElementsByTagName('img'); let answer; if (element.classList.contains('--disliked')) { answer = '0'; } else if (element.classList.contains('--liked')) { answer = '1'; } if (imgs.length && answer !== '') { segmentImages.push({ segment: element.dataset.id, image: imgs[0].getAttribute('src'), like: answer }); } } ); const data = new URLSearchParams(); data.append('funk', 'save_styleadvisor'); data.append('brands', JSON.stringify(brandList)); data.append('segment_data', JSON.stringify(segmentImages)); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); } toggleContinueButton(locked) { document.querySelectorAll(".styleadvisor__step.--active .styleadvisor__continue").forEach( (element) => { if (locked) { element.classList.add("--disabled") } else { element.classList.remove("--disabled") } } ) } test async initCalendar() { // let link = document.createElement("link"); link.href = '/themes/hypefront/design/css/vanilla-calendar.min.css'; link.type = "text/css"; link.rel = "stylesheet"; document.getElementsByTagName("head")[0].appendChild(link); const d = new Date(); let currDay = d.getDate(); let currMonth = d.getMonth() + 1; let currYear = d.getFullYear(); let monthLength = new Date(currYear,currMonth,0).getDate(); if (currMonth < 10) { currMonth = "0" + currMonth; } if (currDay < 10) { currDay = "0" + currDay; } const qs = new URLSearchParams({ funk: 'Stilradgivning_Populate_Calendar', year: currYear, month: currMonth, day: currDay, monthLength: monthLength }).toString(); const response = await fetch('/shop?' + qs); const result = await response.json(); const enabledDays = []; if (result && result['status'] === '1') { if (result.json) { this.dates = JSON.parse(result.json); const dayExists = []; for (let i = 0; i < this.dates.data.length; i++) { const day = this.dates.data[i].starts_at.split("T")[0]; if (!dayExists[day]) { enabledDays.push(day); dayExists[day] = true; } } } } const obj = this; const calendar = new VanillaCalendar('#datepicker',{ settings: { lang: 'define', range: { enabled: enabledDays } }, locale: { months: ['Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'], weekday: ['Sö', 'Må', 'Ti', 'On', 'To', 'Fr', 'Lö'] }, actions: { clickDay(e, dates) { if (dates.length == 0) return; obj.getTimes(dates[0]) } } }); calendar.init(); document.getElementById('booking-btn').addEventListener('click', function() { obj.bookTimeslot(); }); } getTimes(day) { const d = new Date(day); let currDate = d.getDate(); let currMonth = d.getMonth() + 1; if (currMonth < 10) { currMonth = "0" + currMonth; } if (currDate < 10) { currDate = "0" + currDate; } let timesHtml = ''; const obj = this; for (let i = 0; i < this.dates.data.length; i++) { const dateDay = this.dates.data[i].starts_at.split("T")[0]; if (day !== dateDay) continue; const time = this.dates.data[i].starts_at.split("T")[1].split(":00+")[0]; const timestamp = parseInt(new Date(this.dates.data[i].starts_at).getTime() / 1000); // Tider måste vara minst 6h from nu. const timestampMin = parseInt(new Date().getTime() / 1000) + (6 * 60 * 60); if (timestamp >= timestampMin) { timesHtml += "
    " + time + "
    "; } document.getElementById('timepicker_times').innerHTML = timesHtml; document.querySelectorAll('.timepicker_time').forEach(elem => { elem.addEventListener('click', function() { obj.reserveTimeslot(elem.dataset.start, elem.dataset.end, elem); }); } ); } } async reserveTimeslot(start, end, elem) { if (!this.reserved_times) { this.reserved_times = []; } if (!this.reserved_times[start]) { const qs = new URLSearchParams({ funk: 'Stilradgivning_Reservera_Tid', starts_at: start, ends_at: end }).toString(); const response = await fetch('/shop?' + qs); const result = await response.json(); if (result && result['status'] === '1') { document.querySelectorAll('.timepicker_time').forEach(elem => { elem.classList.remove('reserved'); } ); const json = JSON.parse(result.json); elem.classList.add('reserved'); elem.setAttribute('res_id', json.id); this.reserved_times[start] = json.id; } } } async bookTimeslot() { const timeDiv = document.querySelector('.timepicker_time.reserved'); const phoneInput = document.getElementById('customer_phone'); const phone = phoneInput.value; const thankyou_page_url = document.getElementById('thankyou_page_url').value; if (phone) { phoneInput.classList.remove('error'); } else { phoneInput.classList.add('error'); return false; } if (!timeDiv) return false; const start = timeDiv.dataset.start; const end = timeDiv.dataset.end; const newDate = new Date(start); const newDate_Ends = new Date(end); const timestamp = parseInt(newDate.getTime() / 1000); const timestamp_ends = parseInt(newDate_Ends.getTime() / 1000); const resId = timeDiv.getAttribute('res_id'); const qs = new URLSearchParams({ funk: 'Stilradgivning_Boka_Tid', starts_at: start, starts_unix: timestamp, ends_at: end, ends_unix: timestamp_ends, phone: phone, res_id: resId }).toString(); const response = await fetch('/shop?' + qs); const result = await response.json(); if (result && result['status'] === '1') { window.location.href = thankyou_page_url; var br_phone = phone.replace(/^0/, "0046"); br_phone = br_phone.replace(/\s/g, ''); exponea.track('style_event', { 'action': 'accept', 'type': 'styleadvisor', 'parameter': 'meeting', 'meeting_date': timestamp, 'meeting_phone': br_phone }); } else { alert('bokning kunde inte genomföras'); } } uuidv4() { return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)); } setLoginIcon() { const login_icon = document.querySelector("#login-icon svg"); const login_wrapper = document.getElementById("login-wrapper"); const login_icon_html = login_icon.outerHTML; login_icon.outerHTML = "" + login_icon_html + ""; document.querySelector("#login-icon svg").setAttribute("fill", "black"); login_wrapper.style.visibility = "hidden"; } } /***/ } ), /***/ "./content/default/scripts/utils.js": /*!******************************************!*\ !*** ./content/default/scripts/utils.js ***! \******************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "executeJs": () => (/* binding */ executeJs), /* harmony export */ "formatPriceHtml": () => (/* binding */ formatPriceHtml), /* harmony export */ "getCookie": () => (/* binding */ getCookie), /* harmony export */ "getStorage": () => (/* binding */ getStorage), /* harmony export */ "removeStorage": () => (/* binding */ removeStorage), /* harmony export */ "setStorage": () => (/* binding */ setStorage)/* harmony export */ }); function formatPriceHtml(price, price_regular, campaign, price_prefix="") { const currency_prefix = window.shop_settings['currency_prefix'] || ''; const currency_suffix = window.shop_settings['currency_suffix'] || ''; price = _prettyPrice(price); if (campaign) { price_regular = _prettyPrice(price_regular); return `${currency_prefix}${price_prefix}${price_regular}${currency_suffix} ${currency_prefix}${price_prefix}${price}${currency_suffix}`; } else { return `${currency_prefix}${price_prefix}${price}${currency_suffix}`; } } function _prettyPrice(price) { price = price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' '); return price.replace(/\./g, ','); } function executeJs(container) { const scripts = container.getElementsByTagName('script'); for (let i = 0; i < scripts.length; i++) { let execute = true; if (scripts[i].getAttribute('type') === 'application/ld+json') { execute = false; } if (execute) { const consentType = scripts[i].getAttribute('consent_type'); if (consentType) { execute = check_consent(consentType, ""); } } if (execute) { const s = document.createElement("script"); if (scripts[i].getAttribute('type') !== 'application/ld+json') { s.text = scripts[i].innerHTML; try { document.head.appendChild(s).parentNode.removeChild(s); } catch (err) { console.log(err); } } } } } function getCookie(name) { var cookieArr = document.cookie.split(";"); for (var i = 0; i < cookieArr.length; i++) { var cookiePair = cookieArr[i].split("="); if (name == cookiePair[0].trim()) { return decodeURIComponent(cookiePair[1]); } } return null; } function setStorage(name, value, expires) { if (typeof (Storage) === 'undefined') return null; if (expires) { this.cart.expires = Date.now() + expires * 60000; } window.localStorage.setItem(name, JSON.stringify(value)); } function removeStorage(name) { if (typeof (Storage) === 'undefined') return null; window.localStorage.removeItem(name); } function getStorage(name, expires) { if (typeof (Storage) === 'undefined') return null; let str = window.localStorage.getItem(name); if (str == null) return undefined; let data; try { data = JSON.parse(str); } catch (e) { return undefined; } if (data.expires && data.expires < Date.now()) { return undefined; } return data; } /***/ } ), /***/ "./content/default/views/brand/brandsearch.js": /*!****************************************************!*\ !*** ./content/default/views/brand/brandsearch.js ***! \****************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ BrandSearch)/* harmony export */ }); class BrandSearch { constructor() { this.init_events(); } init_events() { window.liveEvent(".brands_list_filter", "keyup", (event, element) => { this.filter_brands(element.value, element.closest(".brands_list")); } ); window.liveEvent(".brands_list_show_all", "click", (event, element) => { this.filter_brands("", element.closest(".brands_list")) } ); window.liveEvent(".brands_list_letter", "click", (event, element) => { this.filter_brands_letter(element.innerText, element.closest(".brands_list")) } ); } filter_brands(value, parent) { if (!value) { parent.querySelectorAll('.brands_list_brand, .brands_list_wrapper').forEach(element => { element.classList.remove("--hidden"); } ); parent.querySelectorAll('.brands_list_filter').forEach(element => { element.value = ""; } ); } else { parent.querySelectorAll(".brands_list_wrapper").forEach( (element) => { element.classList.remove("--hidden") } ) parent.querySelectorAll('.brands_list_brand').forEach(element => { element.classList.add("--hidden"); } ); parent.querySelectorAll('.brands_list_brand[data-value*="' + value.toLowerCase() + '"]').forEach(element => { element.classList.remove("--hidden"); } ); parent.querySelectorAll('.brands_list_wrapper').forEach(element => { if (element.querySelectorAll('.brands_list_brand').length == element.querySelectorAll('.brands_list_brand.--hidden').length) { element.classList.add("--hidden"); } } ); } } filter_brands_letter(letter, parent) { parent.querySelectorAll('.brands_list_brand').forEach(element => { element.classList.remove("--hidden"); } ); parent.querySelectorAll('.brands_list_wrapper').forEach(element => { element.classList.add("--hidden"); } ); parent.querySelectorAll('.brands_list_wrapper[data-letter*="' + letter.toLowerCase() + '"]').forEach(element => { element.classList.remove("--hidden"); } ); parent.querySelectorAll('.brands_list_filter').forEach(element => { element.value = ""; } ); } } /***/ } ), /***/ "./content/default/views/checkout/checkout.js": /*!****************************************************!*\ !*** ./content/default/views/checkout/checkout.js ***! \****************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Checkout)/* harmony export */ }); class Checkout { } /***/ } ), /***/ "./content/default/views/mypages/reservation.js": /*!******************************************************!*\ !*** ./content/default/views/mypages/reservation.js ***! \******************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Reservation)/* harmony export */ }); class Reservation { constructor(cart) { this.cart = cart; this.init(); } init() { document.querySelectorAll('.Stilradgivning_Artikel .Knapp_Kop a').forEach(element => { element.addEventListener('click', (e) => { e.preventDefault(); let form = element.parentNode.parentNode.parentNode.parentNode.parentNode; let product_id = form.altnr.value; if (product_id) { this.cart.add_item(product_id, 1); } } ); } ); } } /***/ } ), /***/ "./content/default/views/product/ajaxify.js": /*!**************************************************!*\ !*** ./content/default/views/product/ajaxify.js ***! \**************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Ajaxify)/* harmony export */ }); /* harmony import */ var _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../views/product/simple_slider */ "./content/default/views/product/simple_slider.js"); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../scripts/utils.js */ "./content/default/scripts/utils.js"); /* harmony import */ var _components_size_and_fit_sizeAndFit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../components/size_and_fit/sizeAndFit */ "./content/default/components/size_and_fit/sizeAndFit.js"); class Ajaxify { constructor(productPage, nav, filter) { this.productPage = productPage; this.navMenu = nav; this.filter = filter; this.isSetup = false; this.productLoading = false; this.productLoaded = false; this.fromReqestType = ''; this.offset = 0; this.initEvents(); } initEvents() { window.liveEvent('.navigate-product', 'click', (event, element) => { if (document.querySelector('.backdrop').classList.contains('active')) { document.querySelector('.backdrop').classList.remove('active'); document.querySelector('#air-cart-module').classList.remove('active'); document.body.classList.remove('cart-open'); document.body.style.overflow = ''; } if (element.href) { event.preventDefault(); if (this.fromList(element)) { // Pass the element to the getProduct function this.getProduct(element.href, element); } else { this.navigatePage(element.href, 'product'); } } } ); document.querySelectorAll('.Din_Sida_Onskelista_Wrapper .Knapp_Kop a').forEach( (element) => { element.addEventListener('click', (e) => { e.preventDefault(); let form = element.parentNode.parentNode.parentNode.parentNode.parentNode; let product_id = form.altnr.value; if (product_id) { this.cart.add_item(product_id, 1); } } ); } ); document.querySelectorAll('.toggle_content').forEach( (toggleElement) => { toggleElement.addEventListener('click', function() { const targetSelector = toggleElement.getAttribute('data-target'); const targetElement = document.querySelector(targetSelector); if (targetElement) { targetElement.classList.toggle('hide'); } }); } ); const faqContainer = document.querySelector('.faq'); if (faqContainer) { const faqItems = faqContainer.querySelectorAll('ul li.accordion__item'); const faqData = []; faqItems.forEach( (item, index) => { const question = item.querySelector('.accordion__item--btn').textContent.trim(); const answer = item.querySelector('ul').textContent.trim(); faqData.push({ '@type': 'Question', name: question, acceptedAnswer: { '@type': 'Answer', text: answer } }); } ); // Create JSON-LD script element for schema markup const script = document.createElement('script'); script.type = 'application/ld+json'; script.innerHTML = ` { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": ${JSON.stringify(faqData)} } `; // Append the script element to the head of the document document.head.appendChild(script); } window.liveEvent('#air-cart-module .close', 'click', (event, element) => { document.querySelector('.backdrop').classList.remove('active'); document.querySelector('#air-cart-module').classList.remove('active'); if (document.querySelector('#air-cart-module').classList.contains('error')) { document.querySelector('#air-cart-module').classList.remove('error'); } document.body.classList.remove('cart-open'); document.body.style.overflow = ''; } ); window.liveEvent('.backdrop', 'click', (event, element) => { if (document.querySelector('.backdrop').classList.contains('active')) { document.querySelector('.backdrop').classList.remove('active'); document.querySelector('#air-cart-module').classList.remove('active'); var sizeandfitcontainer = document.querySelector('#sizeandfit'); if (sizeandfitcontainer) { sizeandfitcontainer.classList.remove('active'); window.sizeNFitInitialized = false; } document.querySelector('#kundradgivning').classList.remove('active'); document.querySelector('#styleadvisor').classList.remove('active'); document.querySelector('#modal_area').classList.remove('active'); if (document.querySelector('#air-cart-module').classList.contains('error')) { document.querySelector('#air-cart-module').classList.remove('error'); } document.body.classList.remove('cart-open', 'sizeandfit-open', 'styleadvisor', 'kundradgivning'); document.body.style.overflow = ''; } } ); window.liveEvent('.navigate', 'click', async (event, element) => { if (element.href) { this.hash = window.location.hash; this.element = element; let listLoading = false; var listSpinner = document.querySelector('.listspinner'); event.preventDefault(); listLoading = true; if ((listLoading = true)) { // Set a timeout to show the spinner after 100ms var listTimeout = setTimeout(function() { listSpinner.style.display = 'block'; }, 100); } await this.navigatePage(element.href, 'list'); clearTimeout(listTimeout); listSpinner.style.display = 'none'; listLoading = false; if (element.closest('.has__children')) { element.closest('.has__children').classList.add('reload'); } } } ); window.liveEvent('.productpage-back', 'click', (event, element) => { history.back(); } ); window.onpopstate = (event) => { if (this.productLoaded) { this.hideProduct(); if (document.querySelector('.backdrop').classList.contains('active')) { document.querySelector('.backdrop').classList.remove('active'); document.querySelector('#air-cart-module').classList.remove('active'); if (document.querySelector('#air-cart-module').classList.contains('error')) { document.querySelector('#air-cart-module').classList.remove('error'); } document.body.classList.remove('cart-open'); document.body.style.overflow = ''; } } else { if (event.state && event.state.ajax_nav) { window.location = location.href; } } } ; } showTooltip(elementWrapper, tooltip) { elementWrapper.onmousemove = function(e) { var x = e.clientX , y = e.clientY; tooltip.style.top = y + 15 + 'px'; if (tooltip.classList.contains('position-right')) { tooltip.style.left = x - 120 + 'px'; } else { tooltip.style.left = x + 15 + 'px'; } if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) { tooltip.classList.add('active'); setTimeout( () => { tooltip.classList.remove('active'); } , 3000); } else { tooltip.classList.add('active'); } } ; elementWrapper.onmouseout = function(e) { tooltip.classList.remove('active'); } ; } fromList(element) { let requestType = ''; if (this.productLoaded) return true; if (window.shop_settings) { requestType = window.shop_settings['request_type']; } if (requestType === 'product') { return false; } else if (requestType === 'product_group' || requestType === 'brand' || requestType === 'brand_in_group' || requestType === 'search') { return true; } else { // check for sliders if (element.parentNode.parentNode.classList.contains('snapping') || element.parentNode.parentNode.parentNode.classList.contains('product--list')) { return true; } else { return false; } } } setup() { this.mainContainer = document.getElementsByClassName('main')[0]; this.productContainer = document.createElement('main'); this.productContainer.id = 'main-second'; this.mainContainer.after(this.productContainer); this.isSetup = true; } async getProduct(url, element) { // Get the spinner element var spinner = element.querySelector('.spinner'); // Make sure the spinner element exists if (!spinner) { // If the spinner element does not exist, create a new element spinner = document.createElement('div'); spinner.classList.add('spinner'); // Append the spinner element to the clicked element element.appendChild(spinner); } // Set a timeout to show the spinner after 100ms var timeout = setTimeout(function() { spinner.style.display = 'block'; }, 100); if (!this.isSetup) this.setup(); if (this.productLoading) return; if (!this.offset) { this.offset = window.pageYOffset; } this.productLoading = true; let separator = url.includes('?') ? '&' : '?'; let productUrl = url + separator + 'sw=1'; const response = await fetch(productUrl); const html = await response.text(); this.saveMeta(); if (window.shop_settings) { this.fromReqestType = window.shop_settings['request_type']; } this.showProduct(html); this.showProductBack(); if (this.productLoaded) { clearTimeout(timeout); spinner.style.display = 'none'; window.history.replaceState({}, null, url); } else { window.history.pushState({ ajax_nav: true }, null, url); } clearTimeout(timeout); spinner.style.display = 'none'; this.productLoading = false; this.productLoaded = true; window.dispatchEvent(new CustomEvent("pdp_ajax_loaded")) setTimeout( () => { sessionStorage.setItem('snf_artnr', document.querySelector('.product-id-info').textContent); } , 500); const sizeAndFit = document.getElementById('sizeandfit'); if (sizeAndFit) { const backdropBlur = document.querySelector('.backdrop'); const sizeNFit = document.getElementById('sizeandfit'); const sizeNFitStep = sessionStorage.getItem('snf_step'); document.querySelectorAll('.sizeAndFitTrigger').forEach(element => { element.addEventListener('click', () => { const productPage = document.querySelector('.single-product'); const sizeAndFit = document.getElementById('sizeandfit'); document.body.classList.add("sizeandfit-open"); if (productPage) { const images = document.querySelectorAll('.productImg--wrapper img'); const productArtNr = document.querySelector('.product-id-info'); sizeAndFit.classList.add('from-pdp'); const imageSource = images[0].getAttribute('src'); sessionStorage.setItem('snf_image', imageSource); sessionStorage.setItem('snf_artnr', productArtNr.textContent); } backdropBlur.classList.add('active'); sizeNFit.classList.add('active'); this.activeStep(); if (sizeNFitStep > '1') { this.snfBackBtn(); } } ); } ); } } showProductBack() { this.productContainer.querySelectorAll('.productpage-back').forEach(function(elem) { elem.classList.remove('hidden'); }); } async navigatePage(url, type) { if (!url) return; if (!this.isSetup) this.setup(); let separator = url.includes('?') ? '&' : '?'; let pageURL = url + separator + 'sw=1'; const response = await fetch(pageURL); const html = await response.text(); if (this.productLoaded) { this.hideProduct(); } this.navMenu.hideMainNav(this.navMenu); this.mainContainer.innerHTML = html; window.history.pushState({ ajax_nav: true }, null, url); (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_1__.executeJs)(this.mainContainer); if (type === 'product') { this.productPage.reinit(); this.mainContainer.querySelectorAll('.productpage-back').forEach(function(elem) { elem.classList.remove('hidden'); }); window.dispatchEvent(new CustomEvent("pdp_ajax_loaded")); setTimeout( () => { sessionStorage.setItem('snf_artnr', document.querySelector('.product-id-info').textContent); } , 500); } else if (type === 'list') { if (this.element && this.element.classList.contains('page__category--item')) { if (this.hash) { window.location.hash = this.hash; } } window.dispatchEvent(new CustomEvent("plp_ajax_loaded")); initializePage(); this.filter.reinit(); } this.initJs(document); this.ajax_ga_pageview(); this.atm_pixels_after(); document.querySelectorAll('.tooltip-span').forEach( (tooltip) => { const parent = tooltip.parentNode; this.showTooltip(parent, tooltip); } ); //if (type === "list") { // Create and dispatch the custom event // window.dispatchEvent(new CustomEvent("plp_ajax_loaded")) //} setTimeout( () => { window.scrollTo(0, 0); } , 10); } showProduct(html) { this.productContainer.innerHTML = html; this.productContainer.style.display = 'block'; this.mainContainer.style.display = 'none'; window.scrollTo(0, 0); (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_1__.executeJs)(this.productContainer); this.productPage.reinit(); this.initJs(this.productContainer); this.ajax_ga_pageview(); this.atm_pixels_after(); document.querySelector('#header').classList.remove('header__notScrolled'); } hideProduct() { if ('scrollRestoration'in history) { history.scrollRestoration = 'manual'; } this.mainContainer.style.display = 'block'; this.productContainer.style.display = 'none'; this.productContainer.innerHTML = ''; this.productLoaded = false; this.resetMeta(); setTimeout( () => { window.scrollTo(0, this.offset); this.offset = 0; } , 10); } saveMeta() { const titleElem = document.getElementsByTagName('title')[0]; const relElem = document.querySelector("link[rel='canonical']"); if (!titleElem.dataset.reset) { titleElem.dataset.reset = document.title; } if (relElem && !relElem.dataset.reset) { relElem.dataset.reset = relElem.href; } } resetMeta() { const titleElem = document.getElementsByTagName('title')[0]; const relElem = document.querySelector("link[rel='canonical']"); if (window.shop_settings) { window.shop_settings['request_type'] = this.fromReqestType; } if (titleElem.dataset.reset) { document.title = titleElem.dataset.reset; titleElem.dataset.reset = ''; } if (relElem && relElem.dataset.reset) { relElem.href = relElem.dataset.reset; relElem.dataset.reset = ''; } } initJs(container) { container.querySelectorAll('.snapping--wrapper').forEach(function(elem) { new _views_product_simple_slider__WEBPACK_IMPORTED_MODULE_0__["default"](elem); }); window.lazyLoadInstance.update(); /* Produkt grid bredd toggle - mobil */ let tabLink = document.querySelectorAll('.tab-link'); let videoWrapper = document.querySelector('.video'); let videoElem = document.querySelector('video'); // Init videos if needed. container.querySelectorAll('video, .videoInfoWrapper').forEach(function(elem) { elem.addEventListener('click', function() { if (videoElem.paused) { videoElem.play(); } else { videoElem.pause(); } videoWrapper.classList.toggle('playing'); videoWrapper.classList.add('started'); }); }); } ajax_ga_pageview() { if (typeof ga !== 'undefined') { setTimeout( () => { const page = window.location.pathname + window.location.search; ga('set', 'page', page); ga('send', 'pageview'); } , 1); } } atm_pixels_after() { if (typeof atm_pixels_after_function !== 'undefined' && typeof atm_pixels_after_function === 'function') { atm_pixels_after_function(); } } } /***/ } ), /***/ "./content/default/views/product/bundle_product.js": /*!*********************************************************!*\ !*** ./content/default/views/product/bundle_product.js ***! \*********************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ BundleProduct)/* harmony export */ }); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../scripts/utils.js */ "./content/default/scripts/utils.js"); class BundleProduct { constructor(bundleData, buyButton) { this.bundleData = bundleData; this.fields = document.getElementsByClassName('buybox__bundles--items'); this.fieldItems = document.getElementsByClassName('buybox__bundles--item'); this.buyButton = buyButton; this.init(); } init() { this.initEvents(); } initEvents() { // if bundle fields are selects. // for (const f of this.fields) { // f.addEventListener('change', () => this.updateField()); // } for (const f of this.fieldItems) { f.addEventListener('click', (e) => this.updateFieldEvent(e)); } } updateFieldEvent(e) { let button = e.target; const field = button.parentNode; this.buyButton.classList.remove('alert-disabled'); const alert = document.getElementById('alert-popup'); if (alert) { alert.remove(); } for (const c of field.children) { if (c == button) { c.classList.add('active'); field.dataset.value = c.dataset.value; } else { c.classList.remove('active'); } } this.updateField(); } updateField() { this.updateFields(); } updateFields() { let ids = []; for (const field of this.fields) { ids.push(field.dataset.value); } let price = 0; let priceRegular = 0; let campaign = false; for (const [index,field] of this.bundleData.entries()) { ids.sort(); field.items.sort(); for (const item of field.items) { if (ids[index] == item.id) { if (!item.price) { return; } if (item.campaign) { campaign = true; priceRegular += Number(item.price_regular); } else { priceRegular += Number(item.price); } price += Number(item.price); } } } const elems = document.getElementsByClassName('price-info'); for (var elem of elems) { elem.innerHTML = (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.formatPriceHtml)(price, priceRegular, campaign); } } } /***/ } ), /***/ "./content/default/views/product/filter.js": /*!*************************************************!*\ !*** ./content/default/views/product/filter.js ***! \*************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Filter)/* harmony export */ }); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../scripts/utils.js */ "./content/default/scripts/utils.js"); class Filter { constructor() { this.init(); } reinit() { this.init(); document.dispatchEvent(new Event("after_filter")); } init() { if (document.getElementsByClassName('page__filter').length == 0) return; if (window.location.hash) this.setFilterFromHash(); let main = document.querySelector("main") let grid = document.querySelector(".product--group") let gridToggles = document.querySelectorAll(".grid-icon") if (screen.width < 768 && (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.getStorage)('air_view_' + filterSettings.get('id')) == 'single') { main.classList.add("single") grid.classList.add("single") gridToggles.forEach( (element) => { if (element.classList.contains('single')) { element.classList.add("active") } else { element.classList.remove("active") } } ) } gridToggles.forEach( (element) => { element.addEventListener("click", function() { gridToggles.forEach(function(item) { item.classList.remove("active") }) element.classList.add("active") if (element.classList.contains("single")) { main.classList.add("single") grid.classList.add("single"); (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.setStorage)('air_view_' + filterSettings.get('id'), 'single'); } else { main.classList.remove("single") grid.classList.remove("single"); (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeStorage)('air_view_' + filterSettings.get('id')); } }) } ) document.querySelectorAll(".filter_link").forEach( (element) => { element.addEventListener("click", () => { this.clearFilter(); const ids = element.dataset.id.split(','); const values = element.dataset.value.toLowerCase().split(','); ids.forEach( (id) => { document.querySelectorAll(".filter__container").forEach( (w) => { if (w.dataset.id == id) { w.querySelectorAll(".filter__container--items").forEach( (input) => { if (values.includes(input.dataset.filter.toLowerCase())) { input.click(); } } ); } } ); } ); } ); } ); this.moreButton = document.getElementById('filter_more'); this.sortSelect = document.getElementById("sort-order"); document.querySelectorAll('.filter__title').forEach(filter => { filter.addEventListener('click', function(event) { var active_filter = document.querySelector('.filter.--active'); if (active_filter) { if (active_filter != filter.parentNode) { active_filter.classList.remove("--active"); } } filter.parentNode.classList.toggle('--active'); }) } ); document.querySelectorAll('.ul-li-list span').forEach(element => { element.addEventListener('click', event => element.parentNode.classList.toggle('--active')); } ); document.querySelectorAll('.btn--filter, .page--settings--head').forEach(button => { button.addEventListener('click', function(event) { document.querySelectorAll(".page--settings--wrapper, departments--settings--wrapper").forEach( (element) => { element.classList.toggle("--active") document.querySelector(".backdrop").classList.toggle("filter-open") } ) }); } ); document.querySelectorAll('.filter__container--items').forEach(element => { element.addEventListener('click', event => this.handleEvent(element, event)); } ); this.paginationEvents(); document.querySelectorAll('.filter_clear').forEach(element => { element.addEventListener('click', event => { this.clearFilter(); this.get() } ); } ); if (this.moreButton) this.moreButton.addEventListener('click', event => { if (!this.load) { this.load = true; this.get(filterSettings.get('current_offset') ? filterSettings.get('current_offset') : filterSettings.get('page_size'), 1); this.infinit_scroll(); history.scrollRestoration = "manual"; } ; } ); if (this.sortSelect) this.sortSelect.addEventListener('change', event => { this.get(); let[sort,order] = this.sortSelect ? this.sortSelect.value.split('-') : ["", ""]; this.setState({ "sort": sort, "order": order, "page": '', }); } ); document.querySelectorAll('#sort-order-ul li').forEach(element => { element.addEventListener('click', event => { document.querySelectorAll('#sort-order-ul li').forEach(sort_li => { sort_li.classList.remove("--active"); } ); document.querySelectorAll('.active_sort_label').forEach(label => { label.innerHTML = element.innerHTML; } ); element.classList.add("--active"); element.parentNode.parentNode.classList.remove('--active'); this.get(); let[sort,order] = element.dataset.value.split('-'); this.setState({ "sort": sort, "order": order, "page": '' }); document.dispatchEvent(new CustomEvent("sort_changed",{ 'detail': { 'sort': sort, 'order': order } })); } ); } ); document.querySelectorAll('.brand_filter_input').forEach(element => { element.addEventListener('keyup', event => { this.filter_brands(element.value); } ); } ); window.liveEvent("body", "click", (event, element) => { document.querySelectorAll('.filter.--active').forEach(active_filter => { if (!active_filter.contains(event.target)) { active_filter.classList.remove("--active"); } } ); document.querySelectorAll('.filter.--active, .ul-li-list.--active').forEach(active_filter => { if (!active_filter.contains(event.target)) { active_filter.classList.remove("--active"); } } ); } ); document.addEventListener('refresh_filter', () => { this.get(); } ); } handleEvent(element, event) { event.preventDefault(); if (element.classList.contains('--disabled')) return; element.classList.toggle('--active'); this.get(); /* Scroll to filter on filterselect */ const ScrollToFilter = document.getElementById('FilterAnchor'); const headerHeight = document.getElementById('header').offsetHeight window.scrollTo({ top: ScrollToFilter.offsetTop - headerHeight, left: 0, behavior: 'smooth' }); } updateFilterCount() { /* Filter choice counter*/ let filters = document.querySelectorAll(".page__filter .filter") filters.forEach( (filter) => { let activeFilter = filter.querySelectorAll(".filter__container--items.--active") if (activeFilter.length > 0) { filter.querySelector(".active_nbr").innerHTML = "(" + activeFilter.length + ")" } else { filter.querySelector(".active_nbr").innerHTML = '' } } ) } async get(offset, append) { this.updateFilterCount(); const data = new URLSearchParams(); let filterParams = ""; offset = offset ? offset : 0; const selectedFilters = this.getSelectedFilters(); this.setSelectedFilterBoxes(selectedFilters); Object.keys(selectedFilters).forEach(id => { if (filterParams) filterParams += ";"; filterParams += id + ":"; let values = ""; selectedFilters[id].forEach(value => { if (values) values += ","; values += value; } ); filterParams += values; } ); const json_filter = JSON.stringify(selectedFilters); if (window.location.hash || json_filter !== "{}") { window.location.hash = json_filter } let[sort,order] = this.sortSelect ? this.sortSelect.value.split('-') : ["", ""]; let sort_ul = document.querySelectorAll('#sort-order-ul li.--active')[0]; [sort,order] = sort_ul ? sort_ul.dataset.value.split('-') : ["", ""]; data.append('funk', 'get_filter'); filterSettings.get('request_type') === 'search' ? data.append('q', filterSettings.get('q')) : data.append('id', filterSettings.get('id')); data.append('type', filterSettings.get('request_type')); data.append('filter_params', json_filter); data.append('json', 1); data.append('sort', sort); data.append('order', order); data.append('offset', offset ? offset : 0); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.request_data) { let container = document.querySelector(".row.product--group"); if (!container) return; if (result.request_data.filters) this.setInactive(result.request_data.filters); if (append) { container.insertAdjacentHTML("beforeend", result.request_data.html); } else { container.innerHTML = result.request_data.html; } if (this.moreButton) { if (offset + result.request_data.count >= result.request_data.total_count) { console.log() this.moreButton.style.display = 'none'; this.moreButton.classList.remove('infinite'); } else { this.moreButton.style.display = ''; let currentUrl = window.location.pathname if (typeof ga !== 'undefined') { ga("set", "page", currentUrl + "#" + offset + result.request_data.count) ga("send", "pageview") } } } document.querySelectorAll('.filter_count_showing').forEach(element => { element.innerHTML = offset + result.request_data.count; } ); document.querySelectorAll('.filter_count_total').forEach(element => { element.innerHTML = result.request_data.total_count; } ); window.lazyLoadInstance.update(); filterSettings.set('total_count', result.request_data.total_count); filterSettings.set('current_offset', offset + result.request_data.count); if (!offset) { this.setState({ "page": '' }); this.updatePagination(1); } document.dispatchEvent(new Event("after_filter")); if (this.moreButton) this.moreButton.classList.remove('loading'); this.load = false; } } getSelectedFilters() { let selectedFilters = {}; document.querySelectorAll('.filter__container').forEach(filter_type => { filter_type.querySelectorAll('.filter__container--items.--active').forEach(option => { if (!selectedFilters[filter_type.dataset.id]) { selectedFilters[filter_type.dataset.id] = []; } selectedFilters[filter_type.dataset.id].push(option.dataset.value); } ); } ); return selectedFilters; } clearFilter() { document.querySelectorAll('.filter__container .--active').forEach(item => { item.classList.remove('--active'); } ); } setSelectedFilterBoxes(selectedFilters) { let selectedFilterBoxes = ""; const parent = document.getElementById('selected_filters'); if (!parent) return; Object.keys(selectedFilters).forEach(id => { selectedFilters[id].forEach(value => { selectedFilterBoxes += '' + value + ''; } ); } ); parent.innerHTML = selectedFilterBoxes; document.querySelectorAll('.selected_filter').forEach(element => { element.addEventListener('click', event => { this.toggleFilterValue(element.getAttribute('data-id'), element.getAttribute('data-value')); this.get(); } ); } ); document.querySelectorAll('.filter_clear').forEach(element => { selectedFilterBoxes ? element.classList.remove("hide") : element.classList.add("hide"); selectedFilterBoxes ? element.parentNode.classList.remove("hide") : element.parentNode.classList.add("hide") } ); } setInactive(filters) { filters.forEach(filter => { if (filter.type === "Tree") { this.setInactiveTree(filter.id, filter.values); } else if (filter.type === "Slider_Range") { this.setInactiveSlider(filter.id, filter.values); } else { this.setInactiveList(filter); } } ); } setInactiveList(filter) { let id = filter.id; let values = filter.values; let type = filter.type; if (type === 'range') return; let enabled_options = {}; values.forEach(value => { enabled_options[value.value] = 1; } ); document.querySelectorAll('.filter__container[data-id=' + id + '] .filter__container--items').forEach(option => { enabled_options[option.dataset.value] ? option.classList.remove("--disabled") : option.classList.add("--disabled"); } ); } toggleFilterValue(id, value) { const element = document.querySelector('.filter__container[data-id="' + id + '"] .filter__container--items[data-value="' + value + '"]'); if (element) element.classList.toggle('--active') } setFilterFromHash() { const selectedFilters = JSON.parse(decodeURI(window.location.hash.slice(1))); Object.keys(selectedFilters).forEach(id => { selectedFilters[id].forEach(value => { this.toggleFilterValue(id, value); } ); } ); if (Object.keys(selectedFilters).length) this.get(); } setState(inParams) { const params = new URLSearchParams(window.location.search); Object.keys(inParams).forEach(name => { inParams[name] ? params.set(name, inParams[name]) : params.delete(name); } ); let newUrl = window.location.pathname; let search = params.toString(); if (search) { newUrl += "?" + params.toString(); } if (window.location.hash && window.location.hash !== "#{}") { newUrl += window.location.hash } ;window.history.replaceState(null, "", decodeURIComponent(newUrl)); if (typeof ga !== 'undefined') { ga('set', 'page', newUrl) ga('send', 'pageview') } } paginationEvents() { document.querySelectorAll('.pagination-page:not(--dots)').forEach(element => { element.addEventListener('click', event => { this.get((parseInt(element.textContent) - 1) * filterSettings.get('page_size')) this.setState({ "page": element.textContent }); this.updatePagination(parseInt(element.textContent)); window.scrollTo({ top: 0, behavior: "smooth" }); } ); } ); } updatePagination(active_page) { let number_of_pages = Math.ceil(filterSettings.get('total_count') / filterSettings.get('page_size')); if (active_page > number_of_pages) { active_page = number_of_pages; } let pagination = active_page == 1 ? '1' : '1'; if (active_page - 2 > 2) { pagination += '...'; } let number = active_page - 2 > 2 ? active_page - 2 : 2; let page_count = 1; let loops = active_page < 4 ? 4 : 5; while (number > 1 && number < number_of_pages && page_count <= loops) { if (number >= number_of_pages) break; pagination += active_page == number ? '' + number + '' : '' + number + ''; page_count += 1; number += 1; } if (active_page + 3 < number_of_pages) { pagination += '...'; } if (number_of_pages > 1) { pagination += active_page == number_of_pages ? '' + number_of_pages + '' : '' + number_of_pages + ''; } document.querySelectorAll('.page_navigation').forEach(element => { element.innerHTML = pagination; } ); this.paginationEvents(); } filter_brands(value) { if (!value) { document.querySelectorAll('.filter__container[data-id=brand] .filter__item').forEach(element => { element.classList.remove("--hidden"); } ); } else { document.querySelectorAll('.filter__container[data-id=brand] .filter__item').forEach(element => { element.classList.add("--hidden"); } ); document.querySelectorAll('.filter__container[data-id=brand] .filter__item[data-filter*="' + value.toLowerCase() + '"]').forEach(element => { element.classList.remove("--hidden"); } ); } } infinit_scroll() { if (this.moreButton.classList.contains('infinite')) { let count = parseInt(this.moreButton.dataset.count); count == 3 ? this.moreButton.classList.remove("infinite") : this.moreButton.setAttribute("data-count", count + 1); } else { this.moreButton.classList.add('infinite'); this.moreButton.setAttribute('data-count', 1); if (!this.moreButton.classList.contains('infinite_initiated')) { const btn = this.moreButton; window.onscroll = function() { if (btn) { const to_top = btn.offsetTop - window.scrollY; if (to_top <= 2000) { if (!btn.classList.contains('loading') && btn.classList.contains('infinite')) { btn.click(); btn.classList.add('loading'); } } } } ; this.moreButton.classList.add('infinite_initiated'); } } } } /***/ } ), /***/ "./content/default/views/product/product_page.js": /*!*******************************************************!*\ !*** ./content/default/views/product/product_page.js ***! \*******************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ ProductPage)/* harmony export */ }); /* harmony import */ var _variation_variation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./variation/variation */ "./content/default/views/product/variation/variation.js"); /* harmony import */ var _bundle_product__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./bundle_product */ "./content/default/views/product/bundle_product.js"); /* harmony import */ var _zoom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./zoom */ "./content/default/views/product/zoom.js"); /* harmony import */ var _zoom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/ __webpack_require__.n(_zoom__WEBPACK_IMPORTED_MODULE_2__); class ProductPage { constructor(cart, buy_button_id="air-buy", qty_input_id="air-qty") { this.cart = cart this.buy_button_id = buy_button_id this.qty_input_id = qty_input_id this.alert_popup = undefined this.closeAlert = undefined if (window.shop_settings.request_type == "product") { this.init() } } reinit() { if (typeof (lipscore) !== "undefined") { lipscore.initWidgets() } this.init() document.dispatchEvent(new CustomEvent("product_cell_update")) } init(status) { this.buy_button = document.getElementById(this.buy_button_id) this.qty_input = document.getElementById(this.qty_input_id) document.dispatchEvent(new CustomEvent("product_page_viewed")) document.dispatchEvent(new CustomEvent("product_page_styleview")) if (window.variants) { this.variations = new _variation_variation__WEBPACK_IMPORTED_MODULE_0__["default"](window.variants,this.buy_button) } else if (window.bundle_fields) { this.bundle = new _bundle_product__WEBPACK_IMPORTED_MODULE_1__["default"](window.bundle_fields,this.buy_button) } if (this.buy_button) { this.buy_button.addEventListener("click", (e) => { this.add_cart(e, this.buy_button) } ) } // init simple buy buttons. const btns = document.getElementsByClassName("buy-btn") for (const btn of btns) { btn.addEventListener("click", (e) => this.add_cart(e, btn)) } this.initLipscore() this.tabProps = document.getElementById("tab-properties") if (this.tabProps) { this.tabProps.parentNode.addEventListener("click", () => { this.initTabProps() } ) } /* ScrollTo more info about size */ const readMoreSize = document.querySelector(".trueSizeLink") const readMoreScrollTo = document.querySelector(".about--list") if (readMoreSize) { readMoreSize.onclick = function() { scrollToMore() } } function scrollToMore() { window.scrollTo({ top: readMoreScrollTo.offsetTop, left: 0, behavior: "smooth", }) } /* ScrollTo more info about size */ const readMoreReview = document.querySelector(".buybox__rating") const readReviewScrollTo = document.querySelector("#reviewsAccordion") const triggerReview = document.querySelector("#reviewsAccordion > span") if (readMoreReview) { readMoreReview.onclick = function() { scrollToReview() } } function scrollToReview() { window.scrollTo({ top: readReviewScrollTo.offsetTop, left: 0, behavior: "smooth", }) if (readReviewScrollTo.classList.contains("active")) {} else { triggerReview.click() } } if (!this.zoomInit) { this.initZoom() } this.initTooltip() // Handle add to cart for old gift card page. this.handleGiftcards() } add_cart(e, elem) { e.stopPropagation() if (elem.classList.contains("alertable")) { this.show_alert_popup() return } const product_id = elem.dataset.id const qty = this.qty_input.value || 1 let extra_data = {} if (elem.dataset.type === "bundle") { const fields = this.bundle.fields let fields_data = [] for (const f of fields) { fields_data.push({ field_id: f.dataset.id, bundle_id: f.dataset.value }) } extra_data["bundle_fields"] = fields_data } elem.dispatchEvent(new CustomEvent("addToCart")) if (!product_id) { return } this.cart.add_item(product_id, qty, extra_data) } async show_alert_popup() { if (this.buy_button.classList.contains("disabled") || this.buy_button.classList.contains("alert-disabled")) { return } /* hide bevaka */ const product_id = this.buy_button.dataset.id const stock_id = this.buy_button.dataset.stock_id const response = await fetch("/shop?funk=get_alert_popup&product_id=" + product_id + "&stock_id=" + stock_id) const result = await response.json() if (result.status == 200) { const data = result.data let newsletter_html = "" if (data.newsletter) { newsletter_html = `
    ${data.newsletter_phrase}
    ` } let html = `
    ${data.heading}
    ${data.phrase}
    ${newsletter_html}
    ` if (!this.alert_popup) { this.alert_popup = document.createElement("div") this.buy_button.after(this.alert_popup) } this.alert_popup.innerHTML = html const closeAlert = document.getElementById("close-alert") const alerPopup = document.getElementById("alert-popup") if (closeAlert) { closeAlert.addEventListener("click", function() { alerPopup.parentNode.removeChild(alerPopup) }) } document.getElementById("alert-save").addEventListener("click", (e) => { this.save_alert() } ) } } async save_alert() { this.buy_button.classList.add("alert-disabled") const product_id = this.buy_button.dataset.id const email = document.getElementById("alert-email").value const newsletter = document.getElementById("alert-newsletter").checked if (product_id && email) { const data = new URLSearchParams() data.append("funk", "save_alert") data.append("product_id", product_id) data.append("email", email) data.append("newsletter", newsletter) const response = await fetch("/shop", { method: "POST", body: data, }) const result = await response.json() if (result.status == 200) { this.alert_popup.remove() if (result.data.phrase) { const btnLabel = this.buy_button.getElementsByClassName("air-buy-label")[0] btnLabel.innerHTML = result.data.phrase } } } } initLipscore() { setTimeout(function() { const lipscoreWrapper = document.getElementById("lipscore-review-list") if (lipscoreWrapper && lipscoreWrapper.dataset["lsProductVotes"] == 0) { document.getElementById("lipscore-review-list").parentNode.parentNode.remove() } }, 400) } async initTabProps() { if (this.tabPropsLoaded) return this.tabPropsLoaded = true const response = await fetch("/cgi-bin/ibutik/API.fcgi?funk=get_tab_properties&artnr=" + window.product_id) const html = await response.text() this.tabProps.innerHTML = html } handleGiftcards() { const digital = document.getElementById("AIR_ibutik_laggtill_d") const irlGiftcard = document.getElementById("AIR_ibutik_laggtill_f") if (digital) { const digitalBtn = digital.querySelector("a") digitalBtn.addEventListener("click", (e) => { this.addToCartGiftcard(e, digital) } ) } if (irlGiftcard) { const irlGiftcardBtn = irlGiftcard.querySelector("a") irlGiftcardBtn.addEventListener("click", (e) => { this.addToCartGiftcard(e, irlGiftcard) } ) } } async addToCartGiftcard(e, form) { e.preventDefault() const response = await fetch("/shop", { method: "POST", body: new FormData(form), }) this.cart.show("add", { order: "update_time" }) } initZoom() { this.zoomInit = true this.zoomActive = false this.changeEvent = (e) => { let tooltipSpan = document.querySelector(".snapping--wrapper .tooltip-span") if (this.zoomActive) { tooltipSpan.classList.remove("notActive") this.removeZoom(e, this) } else { this.showZoom(e, this) tooltipSpan.classList.add("notActive") } } this.removeEvent = (e) => { this.removeZoom(e, this) } this.hoverEvent = (e) => { this.showZoomHover(e, this) } this.hoverRemoveEvent = (e) => { this.hideZoomHover(e, this) } this.imgWrapper = document.querySelector(".single--product__img") this.imgWrapper.addEventListener("mouseover", this.hoverEvent) this.imgWrapper.addEventListener("mouseout", this.hoverRemoveEvent) document.addEventListener("slider_clicked", this.changeEvent) document.addEventListener("slider_changed", this.removeEvent) } showZoomHover(e, _self) { // Preload superzoom on hover. if (!e.target.parentNode.classList.contains("superzoom-loaded")) { e.target.parentNode.classList.add("superzoom-loaded") if (e.target.parentNode.dataset.superzoom) { let img = document.createElement("img") img.src = e.target.parentNode.dataset.superzoom } } } initTooltip() { // let tooltipSpan = document.getElementById("tooltip-span") // let tooltipColor = document.getElementsByClassName("tooltip-color") // const imageWrapper = // document.querySelector(".snapping--wrapper") // const colorWrapper = document.querySelector(".row.variusColors") // let imageWrapper = document.querySelector('.single--product__img').parentNode; // this.showTooltip(imageWrapper, tooltipSpan) document.querySelectorAll(".tooltip-span").forEach( (tooltip) => { const parent = tooltip.parentNode this.showTooltip(parent, tooltip) } ) } hideZoomHover(e, _self) {} showZoom(e, _self) { // if (e.pointerType !== 'mouse') return; _self.zoomActive = true _self.zooms = [] _self.imgWrapper.removeEventListener("mouseover", _self.hoverEvent) let zoomWrapper = document.getElementById("zoomWrapper") let productDesc = document.querySelector(".productDesc") const width = productDesc.offsetWidth - 10 document.querySelectorAll(".productImg--wrapper img").forEach( (img) => { const element = img.parentNode let image = img.src if (element.dataset.superzoom) { image = element.dataset.superzoom } _self.zooms.push(new (_zoom__WEBPACK_IMPORTED_MODULE_2___default())(element,{ zoomContainer: zoomWrapper, zoomWidth: width, zoomImage: image, })) } ) if (e.detail) { const evt = e.detail.evt if (evt) { setTimeout(function() { let wrapper = evt.target.parentNode wrapper.dispatchEvent(new MouseEvent("mousemove",{ clientX: evt.clientX, clientY: evt.clientY, })) }, 10) } } } removeZoom(e, _self) { if (!_self.zoomActive) return _self.zoomActive = false let element = _self.imgWrapper _self.zooms.forEach( (zoom) => { zoom.kill() } ) element.removeEventListener("click", _self.removeEvent) element.addEventListener("click", _self.showEvent) _self.imgWrapper.addEventListener("mouseover", _self.hoverEvent) } showTooltip(elementWrapper, tooltip) { elementWrapper.onmousemove = function(e) { var x = e.clientX , y = e.clientY tooltip.style.top = y + 15 + "px" tooltip.style.left = x + 15 + "px" tooltip.classList.add("active") } elementWrapper.onmouseout = function(e) { tooltip.classList.remove("active") } } } /***/ } ), /***/ "./content/default/views/product/simple_slider.js": /*!********************************************************!*\ !*** ./content/default/views/product/simple_slider.js ***! \********************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ SimpleSlider)/* harmony export */ }); class SimpleSlider { constructor(slider) { this.slider = slider; this.slidesWrapper = slider.querySelector('.snapping'); this.slides = this.slidesWrapper.children; const parent = this.slider.parentElement; this.prev = slider.querySelector('.nav-prev'); this.next = slider.querySelector('.nav-next'); if (!this.prev) { if (parent.querySelector('.nav-prev')) { this.prev = parent.querySelector('.nav-prev'); } } if (!this.next) { if (parent.querySelector('.nav-next')) { this.next = parent.querySelector('.nav-next'); } } this.slidesLength = this.slides.length; if (!this.slidesLength) return; this.slideSize = this.slides[0].offsetWidth; this.index = 1; this.posX1 = 0; this.posX2 = 0; this.posInitial = 0; this.touchEndPosition = 0; this.touchEventTimer; this.hasAutoslide = false; this.initPagination(); if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) {} else { this.initAutoslide(); } this.initEvents(); this.slider.classList.add('loaded'); } initEvents() { this.mouseUpEvent = (e) => { this.dragEnd(e, this); } ; this.mouseMoveEvent = (e) => { this.dragAction(e, this); } ; this.disablePagination = false; if (this.slidesWrapper.scrollWidth <= this.slidesWrapper.clientWidth) { this.disablePagination = true; } if (this.prev) { if (this.disablePagination) { this.prev.style.display = 'none'; } else { this.prev.addEventListener('click', () => { this.shiftSlide(this, -1) } ); } } if (this.next) { if (this.disablePagination) { this.next.style.display = 'none'; } else { this.next.addEventListener('click', () => { this.shiftSlide(this, 1) } ); } } this.slidesWrapper.addEventListener('mousedown', (e) => { if (e.buttons == 1 && !e.target.closest(".product__wishlist")) { this.dragStart(e, this); } } ); this.slidesWrapper.addEventListener('touchend', (e) => { this.touchEvent(this) } ); this.slidesWrapper.addEventListener('mousewheel', (e) => { this.touchEvent(this) } ); } initAutoslide() { if (this.slidesWrapper.classList.contains('autoslide')) { this.hasAutoslide = true; } if (this.hasAutoslide) { this.maxScroll = this.slidesWrapper.scrollWidth - this.slidesWrapper.clientWidth; this.autoslideTimer = setInterval(this.autoslideHandler, 50, this); this.slidesWrapper.addEventListener('mouseover', () => { this.slidesWrapper.classList.add('pause'); } ); this.slidesWrapper.addEventListener('mouseout', () => { this.slidesWrapper.classList.remove('pause'); } ); this.slidesWrapper.addEventListener('touchstart', () => { this.slidesWrapper.classList.add('pause'); } ); this.slidesWrapper.addEventListener('touchend', () => { this.slidesWrapper.classList.remove('pause'); } ); } } autoslideHandler(_self) { if (_self.slidesWrapper.classList.contains("sliding")) return; if (_self.slidesWrapper.classList.contains("pause")) return; _self.slidesWrapper.scrollLeft += 1; if (_self.slidesWrapper.scrollLeft >= _self.maxScroll) { clearInterval(_self.autoslideTimer); } } initPagination() { this.paginationWrapper = this.slider.getElementsByClassName('slider__pagination'); this.hasPagination = this.paginationWrapper.length ? true : false; if (this.hasPagination) { this.paginationWrapper = this.slider.getElementsByClassName('slider__pagination')[0]; this.paginationWrapper.firstElementChild.classList.add('active'); const pagination_dots = this.paginationWrapper.getElementsByClassName('slider__pagination--dot'); for (const dot of pagination_dots) { dot.addEventListener('click', (e) => this.paginationClick(e, this)); } } } paginationClick(e, _self) { const element = e.target; const parent = element.parentElement; _self.index = Array.from(parent.children).indexOf(element) + 1; _self.slidesWrapper.scrollLeft = _self.slideSize * (_self.index - 1); _self.updatePagination(); } touchEvent(_self) { _self.touchEndPosition = _self.slidesWrapper.scrollLeft; _self.touchEventTimer = setInterval(_self.touchEventHandler, 50, _self); } touchEventHandler(obj) { if (obj.touchEndPosition == obj.slidesWrapper.scrollLeft) { clearInterval(obj.touchEventTimer); obj.index = Math.round(obj.touchEndPosition / obj.slideSize) + 1; obj.updatePagination(); } else { obj.touchEndPosition = obj.slidesWrapper.scrollLeft; } } dragStart(e, _self) { _self.posInitial = _self.slidesWrapper.scrollLeft; _self.initialX = e.clientX; _self.posX1 = e.clientX; document.addEventListener('mouseup', _self.mouseUpEvent); document.addEventListener('mousemove', _self.mouseMoveEvent); } dragAction(e, _self) { _self.slidesWrapper.classList.add("sliding"); _self.posX2 = _self.posX1 - e.clientX; _self.posX1 = e.clientX; _self.slidesWrapper.scrollLeft = _self.slidesWrapper.scrollLeft + _self.posX2; } dragEnd(e, _self) { _self.index = Math.round(_self.slidesWrapper.scrollLeft / _self.slideSize) + 1; document.removeEventListener('mouseup', _self.mouseUpEvent); document.removeEventListener('mousemove', _self.mouseMoveEvent); _self.slidesWrapper.classList.remove("sliding"); if (_self.initialX == e.clientX) { document.dispatchEvent(new CustomEvent("slider_clicked",{ detail: { evt: e } })); } else { document.dispatchEvent(new CustomEvent("slider_changed",{ detail: { evt: e } })); } _self.updatePagination(); } shiftSlide(_self, dir) { _self.posInitial = _self.slidesWrapper.scrollLeft; if (dir == 1) { if (_self.index > _self.slidesLength || (_self.slidesWrapper.scrollWidth >= (_self.slidesWrapper.scrollLeft + _self.slidesWrapper.clientWidth - 1) && _self.slidesWrapper.scrollWidth <= (_self.slidesWrapper.scrollLeft + _self.slidesWrapper.clientWidth + 1))) { _self.slidesWrapper.scrollLeft = 0; _self.index = 1; } else { _self.slidesWrapper.scrollLeft = _self.posInitial + _self.slideSize; _self.index++; } } else if (dir == -1 && _self.index > 1) { _self.slidesWrapper.scrollLeft = _self.posInitial - _self.slideSize; _self.index--; } document.dispatchEvent(new CustomEvent("slider_changed")); this.updatePagination(); } updatePagination() { if (!this.hasPagination) { return; } ; this.paginationWrapper.querySelectorAll('.active').forEach(e => e.classList.remove("active")); this.paginationWrapper.querySelectorAll('.slider__pagination--dot:nth-child(' + this.index + ')')[0].classList.add('active'); } } /***/ } ), /***/ "./content/default/views/product/variation/variation.js": /*!**************************************************************!*\ !*** ./content/default/views/product/variation/variation.js ***! \**************************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Variation)/* harmony export */ }); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../scripts/utils.js */ "./content/default/scripts/utils.js"); class Variation { constructor(variantsData, buyButton) { this.product_id = variantsData.product_id; this.variantsData = variantsData.variants; this.fields = document.getElementById('variation-1'); this.poi_sizes = document.querySelectorAll('.poi.buybox__variant--item'); this.variants = document.getElementsByClassName('buybox__variant--item'); this.buyButton = buyButton; this.autoAdd = false; this.isInitialized = false; // Added to control re-initialization this.init(this.variants); } init(variants) { this.initEvents(); this.initPOI_toggle(); } initEvents() { const container = document.querySelector('.buybox__variant--items'); if (!container) return; container.addEventListener('click', (event) => { // Check if the clicked element is a .buybox__variant--item var target = event.target.closest('.buybox__variant--item'); if (!target) return; // Hide all overlay texts var overlays = container.querySelectorAll('.overlay-text'); overlays.forEach( (overlay) => { overlay.classList.add('hide'); } ); // Show the overlay text for the clicked item var overlayText = target.querySelector('.overlay-text'); if (overlayText && target.classList && !target.classList.contains('disabled')) { overlayText.classList.remove('hide'); } // Also handle the field update event this.updateFieldEvent(event); } ); this.buyButton.addEventListener('addToCart', e => { this.showCartError(e); } ); const labels = document.getElementsByClassName('buybox__variant--title'); for (const label of labels) { label.addEventListener('click', e => { this.toggleVariantWrapper(label); } ); } } toggleVariantWrapper(label) { const wrapper = label.parentNode; if (wrapper.classList.contains('open')) { wrapper.classList.remove('open'); } else { wrapper.classList.add('open'); label.classList.add('hide'); } } updateFieldEvent(e) { let button = e.target.closest('.buybox__variant--item'); if (!button || !button.dataset.id) return; const variantId = button.dataset.id; //document.querySelector('.product-id-info').innerHTML = variantId; // Hide all dd.ean_placeholder elements const placeholders = document.querySelectorAll('dd.ean_placeholder.property--listItem'); placeholders.forEach(placeholder => { placeholder.classList.add('hide'); }); const product_id_holders = document.querySelectorAll('.product-id-info'); // Update product ID holders and remove 'hide' class for matching elements product_id_holders.forEach(product_id_holder => { product_id_holder.innerHTML = variantId; // Find the matching
    element where data-id matches variantId const matchingElement = document.querySelector(`dd.ean_placeholder.property--listItem.hide[data-id="${variantId}"]`); if (matchingElement) { matchingElement.classList.remove('hide'); } }); const field = this.fields; //button.parentNode; Array.from(this.poi_sizes).forEach(elem => elem.classList.remove('active')); Array.from(field.children).forEach(child => child.classList.remove('active')); button.classList.toggle('active'); this.buyButton.classList.toggle("disabled", !button.classList.contains('active')); field.dataset.value = button.classList.contains('active') ? variantId : ''; this.updateLabel(field, button.classList.contains('active') ? variantId : ''); this.updateFields(); } updateLabel(field, variantId) { const labels = field.parentNode.querySelectorAll('.label'); // Assuming multiple labels labels.forEach(label => { const dataFor = label.getAttribute('data-for'); if (dataFor === variantId) { const variant = this.variantsData.find(v => v.id === variantId); if (variant) { label.textContent = variant.label || ''; } } } ); } updateFields() { let values = []; let allFieldsSelected = true; if (this.fields.dataset.value) { values.push(this.fields.dataset.value); } else { allFieldsSelected = false; } allFieldsSelected ? this.setVariant(values) : this.clearVariant(); } async setVariant(values) { for (const value of values) { const variant = this.variantsData.find(v => v.id === value); if (variant) { const response = await fetch(`/shop?funk=get_variant&product_id=${this.product_id}&variant_id=${variant.id}`); const result = await response.json(); if (result.status.code === 200) { const data = result.data; this.updateVariantInfo(variant, data); // Correctly call updateVariantInfo here } else { console.error('Failed to fetch variant data:', result.status.message); } } else { console.error('Variant not found for ID:', value); } } } initPOI_toggle() { const toggleTrigger = document.querySelector(".poi_toggle"); const variantContainers = document.querySelectorAll(".buybox__variant--items"); if (toggleTrigger) { toggleTrigger.addEventListener("click", () => { this.unselectVariants(); variantContainers.forEach(container => { Array.from(container.children).forEach(child => { if (!child.classList.contains("poi_toggle")) { child.classList.toggle("hide"); // Toggle visibility for each non-toggle child } } ); } ); // Determine the toggle text based on the visibility of the first item across all containers const someVisible = Array.from(variantContainers).some(container => container.querySelector('.poi.buybox__variant--item') && !container.querySelector('.poi.buybox__variant--item').classList.contains("hide")); toggleTrigger.textContent = someVisible ? "Visa endast nya" : "Visa endast Pre-owned"; } ); } } unselectVariants() { Array.from(this.variants).forEach(item => { item.classList.remove('active'); Array.from(item.getElementsByTagName('span')).forEach(span => { span.classList.add('hide'); } ); } ); const airBuyElement = this.buyButton; if (airBuyElement) { airBuyElement.classList.add('disabled'); airBuyElement.classList.remove('error'); airBuyElement.dataset.id = ''; } this.clearVariant(); this.clearFields(); this.buyButton.addEventListener('addToCart', e => { this.showCartError(e); } ); } updateVariantInfo(variant, data) { // Update buy button label and classes based on variant properties const btnLabel = this.buyButton.getElementsByClassName('air-buy-label')[0]; if (variant.buyable) { btnLabel.textContent = btnLabel.dataset.buyable; this.buyButton.classList.add('buyable'); this.buyButton.classList.remove('alertable'); } else if (variant.watchable) { btnLabel.textContent = btnLabel.dataset.alertable; this.buyButton.classList.add('alertable'); this.buyButton.classList.remove('buyable'); } // Set buy button data attributes for variant tracking this.buyButton.dataset.id = variant.id; this.buyButton.dataset.stock_id = variant.availability_id; this.buyButton.classList.remove('error'); // Update various elements across the page with variant-specific data this.updateVariantElements(variant.id, data); if (this.autoAdd) { document.querySelector("#air-buy").click(); this.autoAdd = false; } } updateVariantElements(variantId, data) { // Assume data contains the pricing and other variant-specific information const priceElement = document.querySelector('.price-info '); if (!priceElement) { return; } // Assuming formatPriceHtml is a function defined elsewhere that formats the price HTML priceElement.innerHTML = (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.formatPriceHtml)(data.price, data.price_regular, data.campaign, data.price_prefix); } clearVariant() { this.buyButton.dataset.id = ''; } clearFields() { // Iterate over each field and reset its dataset value if (this.fields.dataset.value) { this.fields.dataset.value = ''; // Reset the dataset value } } showCartError() { let hasActiveVariant = false; // First, check if any variant has the 'active' class for (const field of this.variants) { if (field.classList.contains('active')) { hasActiveVariant = true; break; } } // If no variant has the 'active' class, apply the 'error' class if (!hasActiveVariant) { for (const field of this.variants) { field.classList.add('error'); field.parentElement.classList.add('error'); } document.querySelector("#air-buy").classList.add("error"); this.errorEvent = () => this.hideErrorEvent(); document.addEventListener('click', this.errorEvent); } else { // If a variant is active, remove any existing error classes for (const field of this.variants) { field.classList.remove('error'); field.parentElement.classList.remove('error'); } document.querySelector("#air-buy").classList.remove("error"); } } hideErrorEvent() { for (const field of this.fields) { field.classList.remove('error'); field.parentElement.classList.remove('error'); } document.removeEventListener('click', this.errorEvent); } } /***/ } ), /***/ "./content/default/views/product/wishlist.js": /*!***************************************************!*\ !*** ./content/default/views/product/wishlist.js ***! \***************************************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (/* binding */ Wishlist)/* harmony export */ }); /* harmony import */ var _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../scripts/utils.js */ "./content/default/scripts/utils.js"); const storage_name = 'air_wishlist'; const expire_time = 60; // In minutes. let wishlist; class Wishlist { constructor(cart) { this.cart = cart; this.init(); this.init_events(); } init() { if (!(0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.getCookie)('SESS')) return; if (!document.getElementsByClassName("header__wishlist").length) return; document.querySelectorAll('.Din_Sida_Onskelista_Wrapper .Knapp_Kop a').forEach(element => { element.addEventListener('click', (e) => { e.preventDefault(); let form = element.parentNode.parentNode.parentNode.parentNode.parentNode; let product_id = form.altnr.value; if (product_id) { this.cart.add_item(product_id, 1); } } ); } ); wishlist = this.get_storage(); if (wishlist) { this.render(); } else { this.get(); } } init_events() { window.liveEvent(".product__wishlist", "click", (event, element) => { this.handle_event(element, event); } ); window.liveEvent(".remove_single", "click", (event, element) => { this.handle_event(element, event); } ); document.addEventListener('after_filter', () => { this.init(); } ); document.addEventListener('product_cell_update', () => { this.init(); } ); } async get() { const response = await fetch('/shop?funk=get_wishlist'); const result = await response.json(); if (result.status.code == 200) { wishlist = result.data; this.save_storage(); this.render(); } } get_storage() { if (typeof (Storage) === 'undefined') return null; let str = window.localStorage.getItem(storage_name); if (str == null) return undefined; let data; try { data = JSON.parse(str); } catch (e) { return undefined; } if (data.expires < Date.now()) { return undefined; } return data; } save_storage() { if (typeof (Storage) === 'undefined') return null; wishlist.expires = Date.now() + expire_time * 60000; window.localStorage.setItem(storage_name, JSON.stringify(wishlist)); } handle_event(element, event) { event.preventDefault(); if (element.classList.contains('--filled') || element.classList.contains('remove_single')) { element.classList.remove("--filled"); this.remove_item(element.dataset.id); } else { element.classList.add("--filled"); this.add_item(element.dataset.id); } } async add_item(id, no_render=false) { const data = new URLSearchParams(); data.append('funk', 'add_wishlist_item'); data.append('id', id); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.status.code == 200) { wishlist = result.data.wishlist; this.save_storage(); if (!no_render) { this.save_storage(); this.render(); } } if (!no_render) { await this.remove_item(id, true); //get pixel for wishlist const data_2 = new URLSearchParams(); data_2.append('funk', 'Onskelista_Lagg_Till_Artikel_JSON'); data_2.append('Artnr', id); const response_2 = await fetch('/shop', { method: 'POST', body: data_2 }); const result_2 = await response_2.json(); if (result_2.status == 'OK') { const temporary_element = document.createElement('div'); temporary_element.innerHTML = result_2.pixels; (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.executeJs)(temporary_element); } } } async remove_item(id, no_render=false) { const data = new URLSearchParams(); data.append('funk', 'remove_wishlist_item'); data.append('id', id); const response = await fetch('/shop', { method: 'POST', body: data }); const result = await response.json(); if (result.status.code == 200) { wishlist = result.data.wishlist; if (!no_render) { this.save_storage(); this.render(); } } if (!no_render) { await this.add_item(id, true); //get pixel for wishlist const data_2 = new URLSearchParams(); data_2.append('funk', 'Onskelista_Radera_Artikel_JSON'); data_2.append('Artnr', id); const response_2 = await fetch('/shop', { method: 'POST', body: data_2 }); const result_2 = await response_2.json(); if (result_2.status == 'OK') { const temporary_element = document.createElement('div'); temporary_element.innerHTML = result_2.pixels; (0, _scripts_utils_js__WEBPACK_IMPORTED_MODULE_0__.executeJs)(temporary_element); } } } render() { document.querySelectorAll('.product__wishlist.--filled').forEach(element => { element.classList.remove("--filled"); } ); // Lights up stars for products in wishlist let i = 0; while (i < wishlist.length) { const elements = document.querySelectorAll('[data-id="' + wishlist[i].id + '"]'); elements.forEach(function(element) { element.classList.add('--filled'); }); i++; } // Lights up star in header var header_element = document.getElementsByClassName("header__wishlist"); if (!header_element) return; if (wishlist.length) { header_element[0].classList.add('--filled'); } else { header_element[0].classList.remove("--filled"); } } } /***/ } ), /***/ "./content/default/views/product/zoom.js": /*!***********************************************!*\ !*** ./content/default/views/product/zoom.js ***! \***********************************************/ /***/ (function(module) { (function(root, factory) { if (true && module.exports) { module.exports = factory(); } else { root.ImageZoom = factory(); } }(this, function() { /** * @param {Object} container DOM element, which contains an image to be zoomed (required) * @param {Object} options js-image-zoom options (required) * **width** (number) - width of the source image (optional) * **height** (number) - height of the source image (optional). * **zoomWidth** (number) - width of the zoomed image. Zoomed image height equals source image height (optional) * **img** (string) - url of the source image. Provided if container does not contain img element as a tag (optional) * **scale** (number) - zoom scale. if not provided, scale is calculated as natural image size / image size, provided in params (optional if zoomWidth param is provided) * **offset** (object) - {vertical: number, horizontal: number}. Zoomed image offset (optional) * **zoomContainer** (node) - DOM node reference where zoomedImage will be appended to (default to the container element of image) * **zoomStyle** (string) - custom style applied to the zoomed image (i.e. 'opacity: 0.1;background-color: white;') * **zoomPosition** (string) - position of zoomed image. It can be: `top`, `left`, `bottom`, `original` or the default `right`. * **zoomLensStyle** (string) custom style applied to to zoom lents (i.e. 'opacity: 0.1;background-color: white;') */ return function ImageZoom(container, opts) { "use strict"; var options = opts; if (!container) { return; } var data = { sourceImg: { element: null, width: 0, height: 0, naturalWidth: 0, naturalHeight: 0 }, img: { element: null, width: 0, height: 0, naturalWidth: 0, naturalHeight: 0 }, zoomedImgOffset: { vertical: 0, horizontal: 0 }, zoomedImg: { element: null, width: 0, height: 0 }, zoomLens: { element: null, width: 0, height: 0 } }; var div = document.createElement('div'); var lensDiv = document.createElement('div'); var scaleX; var scaleY; var offset; var zoomScaleX; var zoomScaleY; var zoomOffset; data.zoomedImgOffset = { vertical: options.offset && options.offset.vertical ? options.offset.vertical : 0, horizontal: options.offset && options.offset.horizontal ? options.offset.horizontal : 0 }; data.zoomPosition = options.zoomPosition || 'right'; data.zoomContainer = (options.zoomContainer) ? options.zoomContainer : container; function getOffset(el) { if (el) { var elRect = el.getBoundingClientRect(); return { left: elRect.left, top: elRect.top }; } return { left: 0, top: 0 }; } function leftLimit(min) { return options.width - min; } function topLimit(min) { return options.height - min; } function getValue(val, min, max) { if (val < min) { return min; } if (val > max) { return max; } return val; } function getPosition(v, min, max) { var value = getValue(v, min, max); return value - min; } function zoomLensLeft(left) { var leftMin = data.zoomLens.width / 2; return getPosition(left, leftMin, leftLimit(leftMin)); } function zoomLensTop(top) { var topMin = data.zoomLens.height / 2; return getPosition(top, topMin, topLimit(topMin)); } function setZoomedImgSize(options, data) { if (options.scale) { data.zoomedImg.element.style.width = options.width * options.scale + 'px'; data.zoomedImg.element.style.height = options.height * options.scale + 'px'; } else if (options.zoomWidth) { data.zoomedImg.element.style.width = options.zoomWidth + 'px'; data.zoomedImg.element.style.height = data.sourceImg.element.style.height; } else { data.zoomedImg.element.style.width = '100%'; data.zoomedImg.element.style.height = '100%'; } } function onSourceImgLoad() { // use height determined by browser if height is not set in options options.height = options.height || data.sourceImg.element.height; // data.sourceImg.element.style.height = options.height + 'px'; data.sourceImg.element.style.height = '100%'; // use width determined by browser if width is not set in options options.width = options.width || data.sourceImg.element.width; data.sourceImg.element.style.width = options.width + 'px'; setZoomedImgSize(options, data); data.sourceImg.naturalWidth = data.sourceImg.element.naturalWidth; data.sourceImg.naturalHeight = data.sourceImg.element.naturalHeight; data.zoomedImg.element.style.backgroundSize = data.img.element.naturalWidth + 'px ' + data.img.element.naturalHeight + 'px'; if (options.zoomStyle) { data.zoomedImg.element.style.cssText += options.zoomStyle; } if (options.zoomLensStyle) { data.zoomLens.element.style.cssText += options.zoomLensStyle; } else { data.zoomLens.element.style.background = 'white'; data.zoomLens.element.style.opacity = '0.4'; } zoomScaleX = data.img.element.naturalWidth / options.width; zoomScaleY = data.img.element.naturalHeight / options.height; zoomOffset = getOffset(data.img.element); scaleX = data.sourceImg.naturalWidth / options.width; scaleY = data.sourceImg.naturalHeight / options.height; offset = getOffset(data.sourceImg.element); // set zoomLens dimensions // if custom scale is set if (options.scale) { data.zoomLens.width = options.width / (data.sourceImg.naturalWidth / (options.width * options.scale)); data.zoomLens.height = options.height / (data.sourceImg.naturalHeight / (options.height * options.scale)); } // else if zoomWidth is set else if (options.zoomWidth) { data.zoomLens.width = options.zoomWidth / zoomScaleX; data.zoomLens.height = options.height / zoomScaleY; } // else read from the zoomedImg else { data.zoomedImg.element.style.display = 'block'; data.zoomLens.width = data.zoomedImg.element.clientWidth / scaleX; data.zoomLens.height = data.zoomedImg.element.clientHeight / scaleY; data.zoomedImg.element.style.display = 'none'; } data.zoomLens.element.style.position = 'absolute'; data.zoomLens.element.style.width = data.zoomLens.width + 'px'; data.zoomLens.element.style.height = data.zoomLens.height + 'px'; data.zoomLens.element.pointerEvents = 'none'; } function setup() { // create sourceImg element if (options.img) { var img = document.createElement('img'); img.src = options.img; data.sourceImg.element = container.appendChild(img); } else { data.sourceImg.element = container.children[0]; // if sourceImg is not an img (might be a picture element), try to find one if (data.sourceImg.element.nodeName !== "IMG") { data.sourceImg.element = data.sourceImg.element.querySelector('img'); } } // if (options.zoomImage) { let img = document.createElement('img'); img.src = options.zoomImage; data.img.element = img; } else { data.img.element = data.sourceImg.element; } options = options || {}; container.style.position = 'relative'; // data.sourceImg.element.style.width = options.width ? options.width + 'px' : 'auto'; // data.sourceImg.element.style.height = options.height ? options.height + 'px' : 'auto'; data.zoomLens.element = container.appendChild(lensDiv); data.zoomLens.element.style.display = 'none'; data.zoomLens.element.classList.add('js-image-zoom__zoomed-area'); data.zoomedImg.element = data.zoomContainer.appendChild(div); data.zoomedImg.element.classList.add('js-image-zoom__zoomed-image'); data.zoomedImg.element.style.backgroundImage = "url('" + data.img.element.src + "')"; // data.zoomedImg.element.style.backgroundImage = "url('" + data.sourceImg.element.src + "')"; data.zoomedImg.element.style.backgroundRepeat = 'no-repeat'; data.zoomedImg.element.style.display = 'none'; data.zoomedImg.element.style.zIndex = '2'; data.zoomedImg.element.style.position = 'absolute'; data.zoomedImg.element.style.top = data.zoomedImgOffset.vertical + 'px'; data.zoomedImg.element.style.right = data.zoomedImgOffset.horizontal - (data.zoomedImgOffset.horizontal * 2) + 'px'; data.zoomedImg.element.style.transform = 'translateX(100%)'; // setup event listeners container.addEventListener('mousemove', events, false); container.addEventListener('mouseenter', events, false); container.addEventListener('mouseleave', events, false); data.zoomLens.element.addEventListener('mouseenter', events, false); data.zoomLens.element.addEventListener('mouseleave', events, false); window.addEventListener('scroll', events, false); return data; } function kill() { // remove event listeners container.removeEventListener('mousemove', events, false); container.removeEventListener('mouseenter', events, false); container.removeEventListener('mouseleave', events, false); data.zoomLens.element.removeEventListener('mouseenter', events, false); data.zoomLens.element.removeEventListener('mouseleave', events, false); window.removeEventListener('scroll', events, false); // remove dom nodes if (data.zoomLens && data.zoomedImg) { container.removeChild(data.zoomLens.element); data.zoomContainer.removeChild(data.zoomedImg.element); } if (options.img) { container.removeChild(data.sourceImg.element); } else { data.sourceImg.element.style.width = ''; data.sourceImg.element.style.height = ''; } return data; } var events = { handleEvent: function(event) { switch (event.type) { case 'mousemove': return this.handleMouseMove(event); case 'mouseenter': return this.handleMouseEnter(event); case 'mouseleave': return this.handleMouseLeave(event); case 'scroll': return this.handleScroll(event); } }, handleMouseMove: function(event) { var offsetX; var offsetY; var backgroundTop; var backgroundRight; var backgroundPosition; if (offset) { offsetX = zoomLensLeft(event.clientX - offset.left); offsetY = zoomLensTop(event.clientY - offset.top); backgroundTop = offsetX * zoomScaleX; backgroundRight = offsetY * zoomScaleY; backgroundPosition = '-' + backgroundTop + 'px ' + '-' + backgroundRight + 'px'; data.zoomedImg.element.style.backgroundPosition = backgroundPosition; data.zoomLens.element.style.cssText += 'top:' + offsetY + 'px;' + 'left:' + offsetX + 'px;display: block;'; } }, handleMouseEnter: function() { data.zoomedImg.element.style.display = 'block'; data.zoomLens.element.style.display = 'block'; }, handleMouseLeave: function() { data.zoomedImg.element.style.display = 'none'; data.zoomLens.element.style.display = 'none'; }, handleScroll: function() { offset = getOffset(data.sourceImg.element); } }; // Setup/Initialize library setup(); // if (data.sourceImg.element.complete) { if (data.img.element.complete) { onSourceImgLoad(); } else { data.img.element.onload = onSourceImgLoad; // data.sourceImg.element.onload = onSourceImgLoad; } return { setup: function() { setup(); }, kill: function() { kill(); }, _getInstanceInfo: function() { return { setup: setup, kill: kill, onSourceImgLoad: onSourceImgLoad, data: data, options: options } } } } })); /***/ } ), /***/ "./content/default/app.scss": /*!**********************************!*\ !*** ./content/default/app.scss ***! \**********************************/ /***/ ( (__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); // extracted by mini-css-extract-plugin /***/ } ), /***/ "./node_modules/vanilla-lazyload/dist/lazyload.min.js": /*!************************************************************!*\ !*** ./node_modules/vanilla-lazyload/dist/lazyload.min.js ***! \************************************************************/ /***/ (function(module) { !function(n, t) { true ? module.exports = t() : 0 }(this, (function() { "use strict"; function n() { return n = Object.assign || function(n) { for (var t = 1; t < arguments.length; t++) { var e = arguments[t]; for (var i in e) Object.prototype.hasOwnProperty.call(e, i) && (n[i] = e[i]) } return n } , n.apply(this, arguments) } var t = "undefined" != typeof window , e = t && !("onscroll"in window) || "undefined" != typeof navigator && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent) , i = t && "IntersectionObserver"in window , o = t && "classList"in document.createElement("p") , a = t && window.devicePixelRatio > 1 , r = { elements_selector: ".lazy", container: e || t ? document : null, threshold: 300, thresholds: null, data_src: "src", data_srcset: "srcset", data_sizes: "sizes", data_bg: "bg", data_bg_hidpi: "bg-hidpi", data_bg_multi: "bg-multi", data_bg_multi_hidpi: "bg-multi-hidpi", data_bg_set: "bg-set", data_poster: "poster", class_applied: "applied", class_loading: "loading", class_loaded: "loaded", class_error: "error", class_entered: "entered", class_exited: "exited", unobserve_completed: !0, unobserve_entered: !1, cancel_on_exit: !0, callback_enter: null, callback_exit: null, callback_applied: null, callback_loading: null, callback_loaded: null, callback_error: null, callback_finish: null, callback_cancel: null, use_native: !1, restore_on_error: !1 } , c = function(t) { return n({}, r, t) } , l = function(n, t) { var e, i = "LazyLoad::Initialized", o = new n(t); try { e = new CustomEvent(i,{ detail: { instance: o } }) } catch (n) { (e = document.createEvent("CustomEvent")).initCustomEvent(i, !1, !1, { instance: o }) } window.dispatchEvent(e) } , u = "src" , s = "srcset" , d = "sizes" , f = "poster" , _ = "llOriginalAttrs" , g = "data" , v = "loading" , b = "loaded" , m = "applied" , p = "error" , h = "native" , E = "data-" , I = "ll-status" , y = function(n, t) { return n.getAttribute(E + t) } , k = function(n) { return y(n, I) } , w = function(n, t) { return function(n, t, e) { var i = "data-ll-status"; null !== e ? n.setAttribute(i, e) : n.removeAttribute(i) }(n, 0, t) } , A = function(n) { return w(n, null) } , L = function(n) { return null === k(n) } , O = function(n) { return k(n) === h } , x = [v, b, m, p] , C = function(n, t, e, i) { n && (void 0 === i ? void 0 === e ? n(t) : n(t, e) : n(t, e, i)) } , N = function(n, t) { o ? n.classList.add(t) : n.className += (n.className ? " " : "") + t } , M = function(n, t) { o ? n.classList.remove(t) : n.className = n.className.replace(new RegExp("(^|\\s+)" + t + "(\\s+|$)"), " ").replace(/^\s+/, "").replace(/\s+$/, "") } , z = function(n) { return n.llTempImage } , T = function(n, t) { if (t) { var e = t._observer; e && e.unobserve(n) } } , R = function(n, t) { n && (n.loadingCount += t) } , G = function(n, t) { n && (n.toLoadCount = t) } , j = function(n) { for (var t, e = [], i = 0; t = n.children[i]; i += 1) "SOURCE" === t.tagName && e.push(t); return e } , D = function(n, t) { var e = n.parentNode; e && "PICTURE" === e.tagName && j(e).forEach(t) } , H = function(n, t) { j(n).forEach(t) } , V = [u] , F = [u, f] , B = [u, s, d] , J = [g] , P = function(n) { return !!n[_] } , S = function(n) { return n[_] } , U = function(n) { return delete n[_] } , $ = function(n, t) { if (!P(n)) { var e = {}; t.forEach((function(t) { e[t] = n.getAttribute(t) } )), n[_] = e } } , q = function(n, t) { if (P(n)) { var e = S(n); t.forEach((function(t) { !function(n, t, e) { e ? n.setAttribute(t, e) : n.removeAttribute(t) }(n, t, e[t]) } )) } } , K = function(n, t, e) { N(n, t.class_applied), w(n, m), e && (t.unobserve_completed && T(n, t), C(t.callback_applied, n, e)) } , Q = function(n, t, e) { N(n, t.class_loading), w(n, v), e && (R(e, 1), C(t.callback_loading, n, e)) } , W = function(n, t, e) { e && n.setAttribute(t, e) } , X = function(n, t) { W(n, d, y(n, t.data_sizes)), W(n, s, y(n, t.data_srcset)), W(n, u, y(n, t.data_src)) } , Y = { IMG: function(n, t) { D(n, (function(n) { $(n, B), X(n, t) } )), $(n, B), X(n, t) }, IFRAME: function(n, t) { $(n, V), W(n, u, y(n, t.data_src)) }, VIDEO: function(n, t) { H(n, (function(n) { $(n, V), W(n, u, y(n, t.data_src)) } )), $(n, F), W(n, f, y(n, t.data_poster)), W(n, u, y(n, t.data_src)), n.load() }, OBJECT: function(n, t) { $(n, J), W(n, g, y(n, t.data_src)) } } , Z = ["IMG", "IFRAME", "VIDEO", "OBJECT"] , nn = function(n, t) { !t || function(n) { return n.loadingCount > 0 }(t) || function(n) { return n.toLoadCount > 0 }(t) || C(n.callback_finish, t) } , tn = function(n, t, e) { n.addEventListener(t, e), n.llEvLisnrs[t] = e } , en = function(n, t, e) { n.removeEventListener(t, e) } , on = function(n) { return !!n.llEvLisnrs } , an = function(n) { if (on(n)) { var t = n.llEvLisnrs; for (var e in t) { var i = t[e]; en(n, e, i) } delete n.llEvLisnrs } } , rn = function(n, t, e) { !function(n) { delete n.llTempImage }(n), R(e, -1), function(n) { n && (n.toLoadCount -= 1) }(e), M(n, t.class_loading), t.unobserve_completed && T(n, e) } , cn = function(n, t, e) { var i = z(n) || n; on(i) || function(n, t, e) { on(n) || (n.llEvLisnrs = {}); var i = "VIDEO" === n.tagName ? "loadeddata" : "load"; tn(n, i, t), tn(n, "error", e) }(i, (function(o) { !function(n, t, e, i) { var o = O(t); rn(t, e, i), N(t, e.class_loaded), w(t, b), C(e.callback_loaded, t, i), o || nn(e, i) }(0, n, t, e), an(i) } ), (function(o) { !function(n, t, e, i) { var o = O(t); rn(t, e, i), N(t, e.class_error), w(t, p), C(e.callback_error, t, i), e.restore_on_error && q(t, B), o || nn(e, i) }(0, n, t, e), an(i) } )) } , ln = function(n, t, e) { !function(n) { return Z.indexOf(n.tagName) > -1 }(n) ? function(n, t, e) { !function(n) { n.llTempImage = document.createElement("IMG") }(n), cn(n, t, e), function(n) { P(n) || (n[_] = { backgroundImage: n.style.backgroundImage }) }(n), function(n, t, e) { var i = y(n, t.data_bg) , o = y(n, t.data_bg_hidpi) , r = a && o ? o : i; r && (n.style.backgroundImage = 'url("'.concat(r, '")'), z(n).setAttribute(u, r), Q(n, t, e)) }(n, t, e), function(n, t, e) { var i = y(n, t.data_bg_multi) , o = y(n, t.data_bg_multi_hidpi) , r = a && o ? o : i; r && (n.style.backgroundImage = r, K(n, t, e)) }(n, t, e), function(n, t, e) { var i = y(n, t.data_bg_set); if (i) { var o = i.split("|") , a = o.map((function(n) { return "image-set(".concat(n, ")") } )); n.style.backgroundImage = a.join(), "" === n.style.backgroundImage && (a = o.map((function(n) { return "-webkit-image-set(".concat(n, ")") } )), n.style.backgroundImage = a.join()), K(n, t, e) } }(n, t, e) }(n, t, e) : function(n, t, e) { cn(n, t, e), function(n, t, e) { var i = Y[n.tagName]; i && (i(n, t), Q(n, t, e)) }(n, t, e) }(n, t, e) } , un = function(n) { n.removeAttribute(u), n.removeAttribute(s), n.removeAttribute(d) } , sn = function(n) { D(n, (function(n) { q(n, B) } )), q(n, B) } , dn = { IMG: sn, IFRAME: function(n) { q(n, V) }, VIDEO: function(n) { H(n, (function(n) { q(n, V) } )), q(n, F), n.load() }, OBJECT: function(n) { q(n, J) } } , fn = function(n, t) { (function(n) { var t = dn[n.tagName]; t ? t(n) : function(n) { if (P(n)) { var t = S(n); n.style.backgroundImage = t.backgroundImage } }(n) } )(n), function(n, t) { L(n) || O(n) || (M(n, t.class_entered), M(n, t.class_exited), M(n, t.class_applied), M(n, t.class_loading), M(n, t.class_loaded), M(n, t.class_error)) }(n, t), A(n), U(n) } , _n = ["IMG", "IFRAME", "VIDEO"] , gn = function(n) { return n.use_native && "loading"in HTMLImageElement.prototype } , vn = function(n, t, e) { n.forEach((function(n) { return function(n) { return n.isIntersecting || n.intersectionRatio > 0 }(n) ? function(n, t, e, i) { var o = function(n) { return x.indexOf(k(n)) >= 0 }(n); w(n, "entered"), N(n, e.class_entered), M(n, e.class_exited), function(n, t, e) { t.unobserve_entered && T(n, e) }(n, e, i), C(e.callback_enter, n, t, i), o || ln(n, e, i) }(n.target, n, t, e) : function(n, t, e, i) { L(n) || (N(n, e.class_exited), function(n, t, e, i) { e.cancel_on_exit && function(n) { return k(n) === v }(n) && "IMG" === n.tagName && (an(n), function(n) { D(n, (function(n) { un(n) } )), un(n) }(n), sn(n), M(n, e.class_loading), R(i, -1), A(n), C(e.callback_cancel, n, t, i)) }(n, t, e, i), C(e.callback_exit, n, t, i)) }(n.target, n, t, e) } )) } , bn = function(n) { return Array.prototype.slice.call(n) } , mn = function(n) { return n.container.querySelectorAll(n.elements_selector) } , pn = function(n) { return function(n) { return k(n) === p }(n) } , hn = function(n, t) { return function(n) { return bn(n).filter(L) }(n || mn(t)) } , En = function(n, e) { var o = c(n); this._settings = o, this.loadingCount = 0, function(n, t) { i && !gn(n) && (t._observer = new IntersectionObserver((function(e) { vn(e, n, t) } ),function(n) { return { root: n.container === document ? null : n.container, rootMargin: n.thresholds || n.threshold + "px" } }(n))) }(o, this), function(n, e) { t && (e._onlineHandler = function() { !function(n, t) { var e; (e = mn(n), bn(e).filter(pn)).forEach((function(t) { M(t, n.class_error), A(t) } )), t.update() }(n, e) } , window.addEventListener("online", e._onlineHandler)) }(o, this), this.update(e) }; return En.prototype = { update: function(n) { var t, o, a = this._settings, r = hn(n, a); G(this, r.length), !e && i ? gn(a) ? function(n, t, e) { n.forEach((function(n) { -1 !== _n.indexOf(n.tagName) && function(n, t, e) { n.setAttribute("loading", "lazy"), cn(n, t, e), function(n, t) { var e = Y[n.tagName]; e && e(n, t) }(n, t), w(n, h) }(n, t, e) } )), G(e, 0) }(r, a, this) : (o = r, function(n) { n.disconnect() }(t = this._observer), function(n, t) { t.forEach((function(t) { n.observe(t) } )) }(t, o)) : this.loadAll(r) }, destroy: function() { this._observer && this._observer.disconnect(), t && window.removeEventListener("online", this._onlineHandler), mn(this._settings).forEach((function(n) { U(n) } )), delete this._observer, delete this._settings, delete this._onlineHandler, delete this.loadingCount, delete this.toLoadCount }, loadAll: function(n) { var t = this , e = this._settings; hn(n, e).forEach((function(n) { T(n, t), ln(n, e, t) } )) }, restoreAll: function() { var n = this._settings; mn(n).forEach((function(t) { fn(t, n) } )) } }, En.load = function(n, t) { var e = c(t); ln(n, e) } , En.resetStatus = function(n) { A(n) } , t && function(n, t) { if (t) if (t.length) for (var e, i = 0; e = t[i]; i += 1) l(n, e); else l(n, t) }(En, window.lazyLoadOptions), En } )); /***/ } ) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {}/******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ ( () => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ } ; /******/ } )(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ ( () => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for (var key in definition) { /******/ if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ } ; /******/ } )(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ ( () => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ } )(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ ( () => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ } ; /******/ } )(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be in strict mode. ( () => { "use strict"; /*!************************!*\ !*** ./content/app.js ***! \************************/ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _default_views_product_ajaxify__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./default/views/product/ajaxify */ "./content/default/views/product/ajaxify.js"); /* harmony import */ var _default_components_organisms_accordion__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./default/components/organisms/accordion */ "./content/default/components/organisms/accordion.js"); /* harmony import */ var _default_components_organisms_header_header__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./default/components/organisms/header/header */ "./content/default/components/organisms/header/header.js"); /* harmony import */ var _default_components_molecules_cart_cart__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./default/components/molecules/cart/cart */ "./content/default/components/molecules/cart/cart.js"); /* harmony import */ var _default_abstracts_grid_grid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./default/abstracts/grid/grid */ "./content/default/abstracts/grid/grid.js"); /* harmony import */ var _default_components_molecules_login_login__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./default/components/molecules/login/login */ "./content/default/components/molecules/login/login.js"); /* harmony import */ var _default_components_atoms_Navigation_main_navigation__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./default/components/atoms/Navigation/main-navigation */ "./content/default/components/atoms/Navigation/main-navigation.js"); /* harmony import */ var _default_blocks_search_search__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./default/blocks/search/search */ "./content/default/blocks/search/search.js"); /* harmony import */ var _default_blocks_country_picker_country_picker__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./default/blocks/country-picker/country-picker */ "./content/default/blocks/country-picker/country-picker.js"); /* harmony import */ var _default_components_molecules_toplist_toplist__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./default/components/molecules/toplist/toplist */ "./content/default/components/molecules/toplist/toplist.js"); /* harmony import */ var _default_components_ace_Ace__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./default/components/ace/Ace */ "./content/default/components/ace/Ace.js"); /* harmony import */ var _default_views_product_product_page__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./default/views/product/product_page */ "./content/default/views/product/product_page.js"); /* harmony import */ var _default_blocks_newsletters_newsletter__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./default/blocks/newsletters/newsletter */ "./content/default/blocks/newsletters/newsletter.js"); /* harmony import */ var _default_views_product_filter__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./default/views/product/filter */ "./content/default/views/product/filter.js"); /* harmony import */ var _default_components_style_advisor_styleadvisor__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./default/components/style_advisor/styleadvisor */ "./content/default/components/style_advisor/styleadvisor.js"); /* harmony import */ var _default_views_brand_brandsearch__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./default/views/brand/brandsearch */ "./content/default/views/brand/brandsearch.js"); /* harmony import */ var _default_views_product_wishlist__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./default/views/product/wishlist */ "./content/default/views/product/wishlist.js"); /* harmony import */ var _default_views_mypages_reservation__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./default/views/mypages/reservation */ "./content/default/views/mypages/reservation.js"); /* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! vanilla-lazyload */ "./node_modules/vanilla-lazyload/dist/lazyload.min.js"); /* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_18___default = /*#__PURE__*/ __webpack_require__.n(vanilla_lazyload__WEBPACK_IMPORTED_MODULE_18__); /* harmony import */ var _default_components_mystyle__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./default/components/mystyle */ "./content/default/components/mystyle.js"); /* harmony import */ var _default_views_product_simple_slider__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./default/views/product/simple_slider */ "./content/default/views/product/simple_slider.js"); /* harmony import */ var _default_blocks_productlists_recentlyviewed_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./default/blocks/productlists/recentlyviewed.js */ "./content/default/blocks/productlists/recentlyviewed.js"); /* harmony import */ var _default_blocks_productlists_styleview_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./default/blocks/productlists/styleview.js */ "./content/default/blocks/productlists/styleview.js"); /* harmony import */ var _default_views_checkout_checkout__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./default/views/checkout/checkout */ "./content/default/views/checkout/checkout.js"); /* harmony import */ var _default_components_size_and_fit_sizeAndFit__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./default/components/size_and_fit/sizeAndFit */ "./content/default/components/size_and_fit/sizeAndFit.js"); /* harmony import */ var _default_app_scss__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./default/app.scss */ "./content/default/app.scss"); // handle scss class App { constructor() { this.liveEvent(); this.init(); this.header = new _default_components_organisms_header_header__WEBPACK_IMPORTED_MODULE_2__["default"](); this.checkout = new _default_views_checkout_checkout__WEBPACK_IMPORTED_MODULE_23__["default"](); this.accordion = new _default_components_organisms_accordion__WEBPACK_IMPORTED_MODULE_1__["default"](); this.cart = new _default_components_molecules_cart_cart__WEBPACK_IMPORTED_MODULE_3__["default"](); this.login = new _default_components_molecules_login_login__WEBPACK_IMPORTED_MODULE_5__["default"](); this.grid = new _default_abstracts_grid_grid__WEBPACK_IMPORTED_MODULE_4__["default"](); this.nav = new _default_components_atoms_Navigation_main_navigation__WEBPACK_IMPORTED_MODULE_6__["default"](); this.search = new _default_blocks_search_search__WEBPACK_IMPORTED_MODULE_7__["default"](); this.toplist = new _default_components_molecules_toplist_toplist__WEBPACK_IMPORTED_MODULE_9__["default"](); this.countryPicker = new _default_blocks_country_picker_country_picker__WEBPACK_IMPORTED_MODULE_8__["default"](); this.recently_viewed = new _default_blocks_productlists_recentlyviewed_js__WEBPACK_IMPORTED_MODULE_21__["default"](); this.styleview = new _default_blocks_productlists_styleview_js__WEBPACK_IMPORTED_MODULE_22__["default"](); this.product_page = new _default_views_product_product_page__WEBPACK_IMPORTED_MODULE_11__["default"](this.cart); this.wishlist = new _default_views_product_wishlist__WEBPACK_IMPORTED_MODULE_16__["default"](this.cart); this.reservation = new _default_views_mypages_reservation__WEBPACK_IMPORTED_MODULE_17__["default"](this.cart); this.filter = new _default_views_product_filter__WEBPACK_IMPORTED_MODULE_13__["default"](); this.ajaxify = new _default_views_product_ajaxify__WEBPACK_IMPORTED_MODULE_0__["default"](this.product_page,this.nav,this.filter); this.style_advisor = new _default_components_style_advisor_styleadvisor__WEBPACK_IMPORTED_MODULE_14__["default"](); this.brand_search = new _default_views_brand_brandsearch__WEBPACK_IMPORTED_MODULE_15__["default"](); this.ace = new _default_components_ace_Ace__WEBPACK_IMPORTED_MODULE_10__["default"](); this.mystyle = new _default_components_mystyle__WEBPACK_IMPORTED_MODULE_19__["default"](); this.newsletter = new _default_blocks_newsletters_newsletter__WEBPACK_IMPORTED_MODULE_12__["default"](); this.size_and_fit = new _default_components_size_and_fit_sizeAndFit__WEBPACK_IMPORTED_MODULE_24__["default"](); const smoothScrollToAnchor = (anchor) => { const {top} = document.querySelector(anchor).getBoundingClientRect(); const startPosition = window.pageYOffset; const distance = top - startPosition; const duration = 1000; let start = null; const step = (timestamp) => { if (!start) start = timestamp; const progress = timestamp - start; window.scrollTo(0, easeInOutCubic(progress, startPosition, distance, duration)); if (progress < duration) window.requestAnimationFrame(step); } ; window.requestAnimationFrame(step); } ; const easeInOutCubic = (t, b, c, d) => { t /= d / 2; return t < 1 ? (c / 2) * t * t * t + b : (c / 2) * ((t -= 2) * t * t + 2) + b; } ; window.liveEvent('.smoothAnchor', 'click', (event, element) => { event.preventDefault(); const target = element.dataset.scrolltarget; smoothScrollToAnchor(target); } ); function showTooltip(elementWrapper, tooltip) { elementWrapper.onmousemove = function(e) { var x = e.clientX , y = e.clientY; tooltip.style.top = y + 15 + 'px'; if (tooltip.classList.contains('position-right')) { tooltip.style.left = x - 120 + 'px'; } else { tooltip.style.left = x + 15 + 'px'; } if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) { tooltip.classList.add('active'); setTimeout( () => { tooltip.classList.remove('active'); } , 3000); } else { tooltip.classList.add('active'); } } ; elementWrapper.onmouseout = function(e) { tooltip.classList.remove('active'); } ; } document.querySelectorAll('.tooltip-span').forEach( (tooltip) => { const parent = tooltip.parentNode; showTooltip(parent, tooltip); } ); const backdrop = document.querySelector('.backdrop'); // Preowned info toggle let preownedInfo = document.querySelector('#testJJ'); let preownedInfoBtn = document.querySelector('.modal a'); if (preownedInfoBtn) { preownedInfoBtn.addEventListener('click', function() { preownedInfo.classList.add('active'); backdrop.classList.add('active'); }); } let video = document.querySelector('video'); let videoElements = document.querySelectorAll('video, .videoInfoWrapper'); let videoWrapper = document.querySelector('.video'); if (videoElements) { videoElements.forEach( (element) => { element.addEventListener('click', function() { if (video.paused) { video.play(); } else { video.pause(); } videoWrapper.classList.toggle('playing'); videoWrapper.classList.add('started'); }); } ); } /* Fredrik special för egenskaper */ var products = document.querySelectorAll('.product--group .big img:not(.product__img--hover)'); products.forEach(myFunction); function myFunction(item, index, arr) { item.src = item.src.replace('.jpg', '_2.jpg').replace('artiklar/', 'artiklar/zoom/'); } const target = document.querySelector('.menu__categories'); const close = document.querySelectorAll('.close'); if (target) { target.addEventListener('mouseover', mOver, false); target.addEventListener('mouseout', mOut, false); } function mOver(event) { if (event.target.closest('.has__children, .brandsLink')) { document.body.classList.add('activeNav'); backdrop.classList.add('active'); } } function mOut() { const clicked = document.querySelector('.reload'); if (clicked) { clicked.classList.remove('reload'); } backdrop.classList.remove('active'); document.body.classList.remove('activeNav'); } const kundradgivning = document.querySelector('.kundradgivning'); if (kundradgivning) { window.liveEvent('.header__customerservice', 'click', (event, element) => { kundradgivning.classList.add('active'); backdrop.classList.add('active'); document.body.classList.add('fullbackdrop'); } ); const kundradgivningClose = document.querySelector('.kundradgivning .close'); if (kundradgivningClose) { kundradgivningClose.addEventListener('click', () => { kundradgivning.classList.remove('active'); backdrop.classList.remove('active'); document.body.classList.remove('fullbackdrop'); } ); } } const modalSlideOut = document.querySelector('#modal_area'); if (modalSlideOut) { window.liveEvent('.modalTrigger', 'click', (event, element) => { // Get the data-header and data-content attributes from the clicked element const headerText = element.getAttribute('data-header'); const contentText = element.getAttribute('data-content'); // Find the modal header and content elements const modalHeader = modalSlideOut.querySelector('.modal__header h2'); const modalContent = modalSlideOut.querySelector('.modal__content'); // Update the modal header and content with the new text if (modalHeader) { modalHeader.textContent = headerText; } if (modalContent) { modalContent.innerHTML = contentText; } if (contentText && contentText.includes('lipscore')) { lipscore.initWidgets(); } // Add the active class to the modal and backdrop modalSlideOut.classList.add('active'); if (backdrop) { backdrop.classList.add('active'); document.body.classList.add('fullbackdrop'); } } ); const modalSlideOutClose = document.querySelector('#modal_area .close'); if (modalSlideOutClose) { modalSlideOutClose.addEventListener('click', () => { modalSlideOut.classList.remove('active'); backdrop.classList.remove('active'); document.body.classList.remove('fullbackdrop'); } ); } } const sizeNFit = document.getElementById('sizeandfit'); const styleadvisor = document.getElementById('styleadvisor'); const login_form = document.getElementById('login-wrapper'); const cart = document.querySelector('#air-cart'); backdrop.addEventListener('click', function() { document.body.style.overflow = ''; cart.classList.remove('active'); document.body.classList.remove('cart-open'); document.body.classList.remove('fullbackdrop'); backdrop.classList.remove('active'); if (document.querySelector('.page--settings--wrapper')) { document.querySelector('.page--settings--wrapper').classList.remove('--active'); } backdrop.classList.remove('filter-open'); if (document.querySelector('#header .header__search #suggest-area.active')) { document.querySelector('#header .header__search #suggest-area.active').style.maxHeight = '0px'; } if (styleadvisor.classList.contains('active') && typeof _imbox !== 'undefined') { _imbox.push(['showLauncher']); } if (sizeNFit && sizeNFit.classList.contains('active')) { sessionStorage.clear(); sessionStorage.setItem('snf_step', '1'); sizeNFit.classList.remove('from-pdp'); sizeNFit.classList.remove('active'); document.body.classList.remove('sizeandfit-open'); } login_form.classList.remove('active'); kundradgivning.classList.remove('active'); styleadvisor.classList.remove('active'); document.body.classList.remove('styleadvisor'); document.getElementById('suggest-result').style.display = 'none'; document.getElementById('suggest-init').style.display = 'none'; if (sessionStorage) { this.test_completed = sessionStorage.getItem('test_completed'); if (this.test_completed && this.test_completed !== '') { location.reload(); sessionStorage.setItem('test_completed', ''); } } }); close.forEach( (element) => { element.addEventListener('click', function() { document.body.style.overflow = ''; backdrop.classList.remove('active'); if (cart) { cart.classList.remove('active'); } document.body.classList.remove('cart-open'); styleadvisor.classList.remove('active'); document.body.classList.remove('styleadvisor'); document.getElementById('suggest-result').style.display = 'none'; document.getElementById('suggest-init').style.display = 'none'; }); } ); } init() { this.lazyload(); // init sliders document.querySelectorAll('.snapping--wrapper').forEach(function(elem) { new _default_views_product_simple_slider__WEBPACK_IMPORTED_MODULE_20__["default"](elem); }); } lazyload() { window.lazyLoadInstance = new (vanilla_lazyload__WEBPACK_IMPORTED_MODULE_18___default())({ unobserve_entered: true, // <- Avoid executing the function multiple times callback_enter: this.executeLazyFunction // Assigning the function defined above }); window.lazyFunctions = {}; } executeLazyFunction(element) { var lazyFunctionName = element.getAttribute('data-lazy-function'); var lazyFunction = window.lazyFunctions[lazyFunctionName]; if (!lazyFunction) return; lazyFunction(element); } liveEvent() { window.liveEvent = (selector, event, handler) => { document.body.addEventListener(event, function(e) { var target = e.target; while (target != null) { var isMatch = target.matches(selector); if (isMatch) { handler(e, target); return; } target = target.parentElement; } }, true); } ; } } const app = new App(); } )(); /******/ } )(); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhlbWVzL2h5cGVmcm9udC9hc3NldHMvYXBwLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUNBOztBQUVlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTs7QUFFQTtBQUNBOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7QUNqQmU7QUFDZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDZmlEOztBQUVqRDs7QUFFZTs7QUFFZjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHdEQUF3RCxJQUFJO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEVBQUUsNERBQVM7O0FBRVg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FDbkd3RTs7QUFFeEU7QUFDQSwrQkFBK0I7O0FBRWhCOztBQUVmO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EscURB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O0FBQ1Y7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztB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TjtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUcsRUFBRTs7QUFFTDtBQUNBO0FBQ0EsR0FBRzs7QUFFSCw2REFBNkQsNkJBQTZCOztBQUUxRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7QUN4RmU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7Ozs7O0FDNUJlO0FBQ2Y7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxRQUFRO0FBQ1I7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7Ozs7Ozs7Ozs7Ozs7OztBQ3JFZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7O0FBRTNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOzs7O0FBSUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNO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Q0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXOztBQUVYO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxtRUFBbUU7QUFDN0c7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMsK0hBQStIO0FBQ3pLO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTixxRUFBcUU7QUFDckU7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtB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O0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUgsRUFBRSw0REFBUzs7QUFFWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsNERBQVM7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNB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O0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRiw0QkFBNEIsZUFBZTs7QUFFN0g7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtB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QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixHQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTyw2RUFBWTtBQUNuQixHQUFHO0FBQ0g7O0FBRUE7QUFDQSxnQ0FBZ0MsMERBQVE7QUFDeEM7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L2Fic3RyYWN0cy9ncmlkL2dyaWQuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC9ibG9ja3MvY291bnRyeS1waWNrZXIvY291bnRyeS1waWNrZXIuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC9ibG9ja3MvbmV3c2xldHRlcnMvbmV3c2xldHRlci5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L2Jsb2Nrcy9wcm9kdWN0bGlzdHMvcmVjZW50bHl2aWV3ZWQuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC9ibG9ja3MvcHJvZHVjdGxpc3RzL3N0eWxldmlldy5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L2Jsb2Nrcy9zZWFyY2gvc2VhcmNoLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvY29tcG9uZW50cy9hY2UvQWNlLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvY29tcG9uZW50cy9hdG9tcy9OYXZpZ2F0aW9uL21haW4tbmF2aWdhdGlvbi5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L2NvbXBvbmVudHMvbW9sZWN1bGVzL2NhcnQvY2FydC5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L2NvbXBvbmVudHMvbW9sZWN1bGVzL2xvZ2luL2xvZ2luLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvY29tcG9uZW50cy9tb2xlY3VsZXMvdG9wbGlzdC90b3BsaXN0LmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvY29tcG9uZW50cy9teXN0eWxlLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvY29tcG9uZW50cy9vcmdhbmlzbXMvYWNjb3JkaW9uLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvY29tcG9uZW50cy9vcmdhbmlzbXMvaGVhZGVyL2hlYWRlci5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L2NvbXBvbmVudHMvc2l6ZV9hbmRfZml0L3NpemVBbmRGaXQuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC9jb21wb25lbnRzL3N0eWxlX2Fkdmlzb3Ivc3R5bGVhZHZpc29yLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvc2NyaXB0cy91dGlscy5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L3ZpZXdzL2JyYW5kL2JyYW5kc2VhcmNoLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvdmlld3MvY2hlY2tvdXQvY2hlY2tvdXQuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC92aWV3cy9teXBhZ2VzL3Jlc2VydmF0aW9uLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvdmlld3MvcHJvZHVjdC9hamF4aWZ5LmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvdmlld3MvcHJvZHVjdC9idW5kbGVfcHJvZHVjdC5qcyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vY29udGVudC9kZWZhdWx0L3ZpZXdzL3Byb2R1Y3QvZmlsdGVyLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvdmlld3MvcHJvZHVjdC9wcm9kdWN0X3BhZ2UuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC92aWV3cy9wcm9kdWN0L3NpbXBsZV9zbGlkZXIuanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC92aWV3cy9wcm9kdWN0L3ZhcmlhdGlvbi92YXJpYXRpb24uanMiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvZGVmYXVsdC92aWV3cy9wcm9kdWN0L3dpc2hsaXN0LmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvdmlld3MvcHJvZHVjdC96b29tLmpzIiwid2VicGFjazovL2NvbnRlbnQvLi9jb250ZW50L2RlZmF1bHQvYXBwLnNjc3M/ZjI2YyIsIndlYnBhY2s6Ly9jb250ZW50Ly4vbm9kZV9tb2R1bGVzL3ZhbmlsbGEtbGF6eWxvYWQvZGlzdC9sYXp5bG9hZC5taW4uanMiLCJ3ZWJwYWNrOi8vY29udGVudC93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9jb250ZW50L3dlYnBhY2svcnVudGltZS9jb21wYXQgZ2V0IGRlZmF1bHQgZXhwb3J0Iiwid2VicGFjazovL2NvbnRlbnQvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL2NvbnRlbnQvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9jb250ZW50L3dlYnBhY2svcnVudGltZS9tYWtlIG5hbWVzcGFjZSBvYmplY3QiLCJ3ZWJwYWNrOi8vY29udGVudC8uL2NvbnRlbnQvYXBwLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIlxubGV0IGdyaWQ7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEdyaWQge1xuICAgIFxuICAgIGluaXQoKSB7XG4gICAgICAgIGdyaWQgPSB0aGlzLmdldF9zdG9yYWdlKCk7XG5cbiAgICAgICAgaWYgKGdyaWQpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbml0X2V2ZW50cygpO1xuICAgIH1cblxufSIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIENvdW50cnlQaWNrZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmluaXQoKVxuICB9XG5cbiAgaW5pdCgpIHtcbiAgICBsZXQgY291bnRyeXBpY2tlcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNvdW50cnktcGlja2VyXCIpXG4gICAgY291bnRyeXBpY2tlcnMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJzdmdcIikuY2xhc3NMaXN0LnRvZ2dsZShcIm9wZW5cIilcbiAgICAgICAgZWxlbWVudC5xdWVyeVNlbGVjdG9yKFwidWxcIikuY2xhc3NMaXN0LnRvZ2dsZShcImFjdGl2ZVwiKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG4gIFxufVxuIiwiaW1wb3J0IHtleGVjdXRlSnN9IGZyb20gXCIuLi8uLi9zY3JpcHRzL3V0aWxzLmpzXCI7XG5cbmxldCBuZXdzbGV0dGVyO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOZXdzbGV0dGVyIHtcblxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLmluaXRfZXZlbnRzKCk7XG5cdH1cblxuXHRpbml0X2V2ZW50cygpIHtcblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcubmV3c2xldHRlci1mb3JtJykuZm9yRWFjaChmb3JtID0+IHtcblx0XHRcdGZvcm0uYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0JywgZXZlbnQgPT4gdGhpcy5oYW5kbGVFdmVudChmb3JtLCBldmVudCkpO1xuXHRcdH0pO1xuXG5cdH1cblxuXHRoYW5kbGVFdmVudChmb3JtLCBldmVudCkge1xuXHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHRsZXQgZW1haWwgPSBmb3JtLnF1ZXJ5U2VsZWN0b3IoXCIuZW1haWxcIikudmFsdWU7XG5cdFx0bGV0IGNvdW50cnkgPSBmb3JtLnF1ZXJ5U2VsZWN0b3IoXCIuY291bnRyeVwiKS52YWx1ZTtcblx0XHRsZXQgaW50ZXJlc3RfaWQgPSBmb3JtLnF1ZXJ5U2VsZWN0b3IoXCIuaW50ZXJlc3RfaWRcIikudmFsdWU7XG5cdFx0Zm9ybS5jbGFzc0xpc3QucmVtb3ZlKFwiLS1lcnJvclwiKTtcblxuXHRcdGlmICgvXlxcYltBLVrDhcOEw5bDpcOkw7YwLTkuXyUrLV0rQFtBLVrDhcOEw5bDpcOkw7YwLTkuLV0rXFwuW0EtWl17Miw0fVxcYiQvaS50ZXN0KGVtYWlsKSkge1xuXHRcdFx0dGhpcy5hZGRfdG9fbmV3c2xldHRlcihlbWFpbCwgY291bnRyeSwgaW50ZXJlc3RfaWQsIGZvcm0pO1xuXHRcdH1cblx0XHRlbHNlXG5cdFx0e1xuXHRcdFx0Zm9ybS5jbGFzc0xpc3QuYWRkKFwiLS1lcnJvclwiKTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBhZGRfdG9fbmV3c2xldHRlcihlbWFpbCwgY291bnRyeSwgaW50ZXJlc3RfaWQsIGZvcm0pIHtcblx0XHRjb25zdCBkYXRhID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuXG5cdFx0ZGF0YS5hcHBlbmQoJ2Z1bmsnLCAnYWRkX3RvX25ld3NsZXR0ZXInKTtcblx0XHRkYXRhLmFwcGVuZCgnZW1haWwnLCBlbWFpbCk7XG5cdFx0ZGF0YS5hcHBlbmQoJ2NvdW50cnknLCBjb3VudHJ5KTtcblx0XHRkYXRhLmFwcGVuZCgnaW50ZXJlc3RfaWQnLCBpbnRlcmVzdF9pZCk7XG5cdFx0ZGF0YS5hcHBlbmQoJ3Byb2ZpbGUnLCBcIjFcIik7XG5cblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcCcsIHtcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0Ym9keTogZGF0YVxuXHRcdH0pO1xuXG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXHRcdGlmIChyZXN1bHQuc3RhdHVzLmNvZGUgPT0gMjAwKSB7XG5cdFx0XHRuZXdzbGV0dGVyID0gcmVzdWx0LmRhdGEubmV3c2xldHRlcjtcblx0XHRcdHRoaXMucGl4ZWxzID0gcmVzdWx0LmRhdGEucGl4ZWxzO1xuXG5cdFx0XHR0aGlzLnJlbmRlcigpO1xuXHRcdFx0Zm9ybS5jbGFzc0xpc3QucmVtb3ZlKFwiLS1lcnJvclwiKTtcblx0XHRcdGZvcm0uY2xhc3NMaXN0LmFkZChcIi0tc3VjY2Vzc1wiKTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBkZWxldGVfZnJvbV9uZXdzbGV0dGVyKGVsZW1lbnQpIHtcblx0XHRjb25zdCBkYXRhID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuXG5cdFx0ZGF0YS5hcHBlbmQoJ2Z1bmsnLCAnZGVsZXRlX2Zyb21fbmV3c2xldHRlcicpO1xuXHRcdGRhdGEuYXBwZW5kKCdlbWFpbCcsIGVsZW1lbnQudGFyZ2V0LnZhbHVlKTtcblxuXHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9zaG9wJywge1xuXHRcdFx0bWV0aG9kOiAnUE9TVCcsXG5cdFx0XHRib2R5OiBkYXRhXG5cdFx0fSk7XG5cblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cdFx0aWYgKHJlc3VsdC5zdGF0dXMuY29kZSA9PSAyMDApIHtcblx0XHRcdG5ld3NsZXR0ZXIgPSByZXN1bHQuZGF0YS5uZXdzbGV0dGVyO1xuXHRcdFx0dGhpcy5waXhlbHMgPSByZXN1bHQuZGF0YS5waXhlbHM7XG5cblx0XHRcdHRoaXMucmVuZGVyKCk7XG5cdFx0fVxuXHR9XG5cblx0cmVuZGVyKCkge1xuXHRcdGxldCBwYWdlID0gXCIvc3YvaW5mby9ueWhldHNicmV2LXRhY2suaHRtbFwiO1xuXHRcdFxuXHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLndlYnBhZ2VfdXJsXCIpKSB7XG5cdFx0XHRwYWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi53ZWJwYWdlX3VybFwiKS52YWx1ZTtcblx0XHR9XG5cblx0XHRjb25zdCB0ZW1wb3JhcnlfZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXHRcdHRlbXBvcmFyeV9lbGVtZW50LmlubmVySFRNTCA9IHRoaXMucGl4ZWxzO1xuXG5cdFx0ZXhlY3V0ZUpzKHRlbXBvcmFyeV9lbGVtZW50KTtcblxuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5uZXdzbGV0dGVyX19pbnB1dCcpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoJy0tc3VjY2VzcycpO1xuXHRcdH0pO1xuXG5cdFx0c2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHR3aW5kb3cubG9jYXRpb24uaHJlZiA9IHBhZ2U7XG5cdFx0fSwgMjAwKTtcblx0fVxufSIsImltcG9ydCBTaW1wbGVTbGlkZXIgZnJvbSBcIi4uLy4uLy4uL2RlZmF1bHQvdmlld3MvcHJvZHVjdC9zaW1wbGVfc2xpZGVyXCI7XG5cbmNvbnN0IHN0b3JhZ2VfbmFtZSA9ICdhaXJfdmlld2VkJztcbmNvbnN0IGV4cGlyZV90aW1lID0gNjAqMjQqMzY1OyAvLyBJbiBtaW51dGVzLlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWNlbnRseVZpZXdlZCB7XG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5pbml0KCk7XG5cdFx0dGhpcy5pbml0X2V2ZW50cygpO1xuXHR9XG5cblx0aW5pdCgpIHtcblx0XHRjb25zdCBfdGhpcyA9IHRoaXM7XG5cdFx0d2luZG93LmxhenlGdW5jdGlvbnMucmVjZW50bHlWaWV3ZWQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cdFx0XHRjb25zdCBkYXRhID0gX3RoaXMuZ2V0KGVsZW1lbnQpO1xuXHRcdH1cblx0fVxuXG5cdGluaXRfZXZlbnRzKCkge1xuXHRcdGNvbnN0IF90aGlzID0gdGhpcztcblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwicHJvZHVjdF9wYWdlX3ZpZXdlZFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zdCBpZCA9IHdpbmRvdy5wcm9kdWN0X2lkO1xuXHRcdFx0aWYgKCFpZCkgcmV0dXJuO1xuXG5cdFx0XHRsZXQgdmlld2VkID0gX3RoaXMuZ2V0X3N0b3JhZ2UoKTtcblx0XHRcdGlmICghdmlld2VkKVxuXHRcdFx0e1xuXHRcdFx0XHR2aWV3ZWQgPSB7aXRlbXM6IFtdfTtcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKHZpZXdlZC5pdGVtcy5pbmNsdWRlcyhpZCkpIHtcblx0XHRcdFx0dmlld2VkLml0ZW1zID0gdmlld2VkLml0ZW1zLmZpbHRlcihmdW5jdGlvbihlKSB7IHJldHVybiBlICE9PSBpZCB9KVxuXHRcdFx0fVxuXHRcdFx0dmlld2VkLml0ZW1zLnVuc2hpZnQoaWQpO1xuXHRcdFx0XG5cdFx0XHR2aWV3ZWQuaXRlbXMubGVuZ3RoID0gMTAwO1xuXHRcdFx0X3RoaXMuc2F2ZV9zdG9yYWdlKHZpZXdlZC5pdGVtcyk7XG5cdFx0fSk7XG5cdH1cblxuXHRnZXRfc3RvcmFnZSgpIHtcblx0XHRpZiAodHlwZW9mIChTdG9yYWdlKSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBudWxsO1xuXG5cdFx0bGV0IHN0ciA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShzdG9yYWdlX25hbWUpO1xuXG5cdFx0aWYgKHN0ciA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuXG5cdFx0bGV0IGRhdGE7XG5cblx0XHR0cnkge1xuXHRcdFx0ZGF0YSA9IEpTT04ucGFyc2Uoc3RyKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoZGF0YS5leHBpcmVzIDwgRGF0ZS5ub3coKSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YTtcblx0fVxuXG5cdHNhdmVfc3RvcmFnZShkYXRhKSB7XG5cdFx0aWYgKHR5cGVvZiAoU3RvcmFnZSkgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcblx0XHRcblx0XHRsZXQgYWlyX3ZpZXdlZCA9IHt9O1xuXHRcdGFpcl92aWV3ZWQuaXRlbXMgPSBkYXRhO1xuXHRcdGFpcl92aWV3ZWQuZXhwaXJlcyA9IERhdGUubm93KCkgKyBleHBpcmVfdGltZSAqIDYwMDAwO1xuXHRcdCBcblx0XHR3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oc3RvcmFnZV9uYW1lLCBKU09OLnN0cmluZ2lmeShhaXJfdmlld2VkKSk7XG5cdH1cblxuXHRhc3luYyBnZXQoZWxlbWVudCkge1xuXHRcdGNvbnN0IHZpZXdlZCA9IHRoaXMuZ2V0X3N0b3JhZ2UoKTtcblx0XHRpZiAodmlld2VkKSB7XG5cdFx0XHRpZiAodmlld2VkLml0ZW1zIDw9IDEpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjb25zdCBpZCA9IHdpbmRvdy5wcm9kdWN0X2lkO1xuXHRcdFx0aWYgKGlkKSB7XG5cdFx0XHRcdHZpZXdlZC5pdGVtcyA9IHZpZXdlZC5pdGVtcy5maWx0ZXIoZnVuY3Rpb24oZSkgeyByZXR1cm4gZSAhPT0gaWQgfSlcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgcmVjZW50bHlfdmlld2VkID0gSlNPTi5zdHJpbmdpZnkodmlld2VkLml0ZW1zKS5yZXBsYWNlKC9cXFt8XFxdfFxcXCIvZywgXCJcIik7XG5cdFx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcD9mdW5rPWdldF9yZWNlbnRseV92aWV3ZWQmcmVjZW50bHlfdmlld2VkPScgKyByZWNlbnRseV92aWV3ZWQgKyAnJmxhenk9MScpO1xuXHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXHRcdFx0aWYgKHJlc3VsdC5zdGF0dXMuY29kZSA9PSAyMDApIHtcblx0XHRcdFx0ZWxlbWVudC5pbm5lckhUTUwgPSByZXN1bHQuZGF0YTtcblx0XHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJwcm9kdWN0X2NlbGxfdXBkYXRlXCIpKTtcblx0XHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJwZHBfbGF0ZXN0dmlld2VkX2xvYWRlZFwiKSk7XG5cdFx0XHRcdHdpbmRvdy5sYXp5TG9hZEluc3RhbmNlLnVwZGF0ZSgpO1xuXG5cdFx0XHRcdGNvbnN0IHNsaWRlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5yZWNlbnRseV92aWV3ZWQgLnNuYXBwaW5nLS13cmFwcGVyJyk7XG5cblx0XHRcdFx0aWYgKHNsaWRlcikge1xuXHRcdFx0XHRcdG5ldyBTaW1wbGVTbGlkZXIoc2xpZGVyKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSIsImltcG9ydCBTaW1wbGVTbGlkZXIgZnJvbSBcIi4uLy4uL3ZpZXdzL3Byb2R1Y3Qvc2ltcGxlX3NsaWRlclwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdHlsZVZpZXcge1xuXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMuaW5pdCgpO1xuXHR9XG5cblx0aW5pdCgpIHtcblx0XHRjb25zdCBfdGhpcyA9IHRoaXM7XG5cdFx0d2luZG93LmxhenlGdW5jdGlvbnMuc3R5bGVWaWV3ID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdFx0Y29uc3QgZGF0YSA9IF90aGlzLmdldChlbGVtZW50KTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBnZXQoZWxlbWVudCkge1xuXHRcdGNvbnN0IGlkID0gd2luZG93LnByb2R1Y3RfaWQ7XG5cdFx0Y29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcIi9zaG9wP2Z1bms9Z2V0X3Byb2R1Y3RfcGFnZV9zdHlsZXZpZXcmcHJvZHVjdF9wYWdlX3N0eWxldmlldz1cIiArIGlkICsgXCImbGF6eT0xXCIpO1xuXHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblx0XHRpZiAocmVzdWx0LnN0YXR1cy5jb2RlID09IDIwMCkge1xuXHRcdFx0ZWxlbWVudC5pbm5lckhUTUwgPSByZXN1bHQuZGF0YTtcblx0XHRcdGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwicHJvZHVjdF9jZWxsX3VwZGF0ZVwiKSk7XG5cdFx0XHR3aW5kb3cubGF6eUxvYWRJbnN0YW5jZS51cGRhdGUoKTtcblxuXHRcdFx0Y29uc3Qgc2xpZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnN0eWxldmlldyAuc25hcHBpbmctLXdyYXBwZXInKTtcblxuXHRcdFx0aWYgKHNsaWRlcikge1xuXHRcdFx0XHRuZXcgU2ltcGxlU2xpZGVyKHNsaWRlcik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59IiwiXG5sZXQgc2VhcmNoO1xuY29uc3Qgc3VnZ2VzdFJlc3VsdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3VnZ2VzdC1yZXN1bHRcIilcbmNvbnN0IHN1Z2dlc3RJbml0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdWdnZXN0LWluaXRcIilcbmNvbnN0IHN1Z2dlc3RBcmVhID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdWdnZXN0LWFyZWFcIilcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2VhcmNoIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5zdWdnZXN0X2hpZ2hsaWdodCA9ICh0eXBlb2YgKHdpbmRvdy5zdWdnZXN0X2hpZ2hsaWdodCkgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93LnN1Z2dlc3RfaGlnaGxpZ2h0ID09PSBcIjFcIikgPyB0cnVlIDogZmFsc2U7XG4gICAgdGhpcy5mdWxsX3NlYXJjaF91cmxfZmFsbGJhY2sgPSBcIi9zaG9wP2Z1bms9Z29yX3Nva25pbmcmdGVybT1cIjtcbiAgICB0aGlzLnNlYXJjaF9oaXN0b3J5X2NvdW50ID0gKHR5cGVvZiAod2luZG93LnNlYXJjaF9oaXN0b3J5X2NvdW50KSAhPT0gXCJ1bmRlZmluZWRcIikgPyB3aW5kb3cuc2VhcmNoX2hpc3RvcnlfY291bnQgOiAxMDtcblxuICAgIHRoaXMucHJldl9jaGFycyA9IFwiXCI7XG4gICAgdGhpcy5wcmV2X3NlYXJjaF9jaGFycyA9IFwiXCI7XG4gICAgdGhpcy50aW1lb3V0X3N1Z2dlc3Q7XG4gICAgdGhpcy50aW1lb3V0X3N1Z2dlc3RfbXMgPSAxMDA7XG4gICAgdGhpcy5oaXN0b3J5X3JlbG9hZCA9IGZhbHNlO1xuICAgIHRoaXMuaGlzdG9yeV91cmwgPSBcIlwiO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gIH1cblxuICBpbml0KCkge1xuICAgIGlmICh3aW5kb3cuc2hvcF9zZXR0aW5ncy5vdGhlci5zZWFyY2hfdXJsKVxuICAgIHtcbiAgICAgIHRoaXMuZnVsbF9zZWFyY2hfdXJsID0gd2luZG93LnNob3Bfc2V0dGluZ3Mub3RoZXIuc2VhcmNoX3VybDtcbiAgICB9XG4gICAgZWxzZVxuICAgIHtcbiAgICAgIHRoaXMuZnVsbF9zZWFyY2hfdXJsID0gdGhpcy5mdWxsX3NlYXJjaF91cmxfZmFsbGJhY2s7XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoLWhpc3RvcnlcIikpIHtcbiAgICAgIHRoaXMuaGlzdG9yeV9pbml0KCk7XG4gICAgfVxuXG4gICAgdGhpcy5pbml0X2V2ZW50cygpO1xuICB9XG5cbiAgaW5pdF9ldmVudHMoKSB7XG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoXCIpKSB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlYXJjaFwiKS5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIiwgKGUpID0+IHsgdGhpcy5zdWdnZXN0KGUpOyB9KTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c1wiLCAoKSA9PiB7IHRoaXMuc2hvdygpOyB9KTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoLWZvcm1cIikuYWRkRXZlbnRMaXN0ZW5lcihcInN1Ym1pdFwiLCAoZSkgPT4geyB0aGlzLnNlYXJjaChlKTsgfSk7XG4gICAgfVxuXG4gICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoLXdyYXBwZXJcIikpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICB2YXIgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlYXJjaC13cmFwcGVyJyk7XG4gICAgICAgIGlmICghY29udGFpbmVyLmNvbnRhaW5zKGUudGFyZ2V0KSkge1xuICAgICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFyY2gtaGlzdG9yeS1jbGVhclwiKSkge1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFyY2gtaGlzdG9yeS1jbGVhclwiKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB0aGlzLmhpc3RvcnlfY2xlYXIoKTsgfSk7XG4gICAgfVxuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNlYXJjaC1sb2FkZWRcIiwgKGUpID0+IHtcbiAgICAgIHRoaXMuaGlzdG9yeV9zYXZlKGUuZGV0YWlsLnEsIGUuZGV0YWlsLmhpdHMpO1xuICAgIH0pO1xuICB9XG5cbiAgc2VhcmNoKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBjb25zdCBjaGFycyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoXCIpLnZhbHVlO1xuXG4gICAgaWYgKGNoYXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdGhpcy5mdWxsX3NlYXJjaF91cmwgKyBjaGFycztcbiAgICB9XG4gIH1cblxuICBub21hdGNoKCkge1xuICAgIGNvbnN0IG5vcmVzdWx0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5ub0hpdFwiKVxuXG4gICAgaWYgKHN1Z2dlc3RSZXN1bHQuY29udGFpbnMobm9yZXN1bHQpKSB7XG4gICAgICBzdWdnZXN0QXJlYS5jbGFzc0xpc3QuYWRkKFwibm8tcmVzdWx0c1wiKVxuICAgIH1cbiAgICBlbHNle1xuICAgICAgc3VnZ2VzdEFyZWEuY2xhc3NMaXN0LnJlbW92ZShcIm5vLXJlc3VsdHNcIilcbiAgICB9XG4gIH1cblxuICBzdWdnZXN0KCkge1xuICAgIGNvbnN0IGNoYXJzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFyY2hcIikudmFsdWU7XG5cbiAgICBpZiAoKGNoYXJzICE9ICcnKSAmJiAoY2hhcnMubGVuZ3RoID4gMSkpIHtcbiAgICAgIGlmIChjaGFycyAhPT0gdGhpcy5wcmV2X2NoYXJzKSB7XG4gICAgICAgIHRoaXMucHJldl9jaGFycyA9IGNoYXJzO1xuICAgICAgICB0aGlzLnN1Z2dlc3RfcmVxdWVzdChjaGFycyk7XG4gICAgICAgIHRoaXMubm9tYXRjaCgpO1xuICAgICAgfVxuICAgICAgXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhY2tkcm9wXCIpLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjaGVhZGVyIC5oZWFkZXJfX3NlYXJjaCAjc3VnZ2VzdC1hcmVhLmFjdGl2ZVwiKS5zdHlsZS5tYXhIZWlnaHQgPSBcIjEwMDBweFwiO1xuICAgICAgc3VnZ2VzdFJlc3VsdC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiXG4gICAgICBzdWdnZXN0SW5pdC5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCJcblxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWNoYXJzLmxlbmd0aCkge1xuICAgICAgICBpZiAoc3VnZ2VzdFJlc3VsdCkge1xuICAgICAgICAgIHN1Z2dlc3RSZXN1bHQuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiXG4gICAgICAgIH1cbiAgICAgICAgc3VnZ2VzdEluaXQuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIlxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgIFwiI2hlYWRlciAuaGVhZGVyX19zZWFyY2ggI3N1Z2dlc3QtYXJlYS5hY3RpdmVcIlxuICAgICAgICApLnN0eWxlLm1heEhlaWdodCA9IFwiMHB4XCJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5zdHlsZS5vdmVyZmxvdyA9IFwiXCJcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYWNrZHJvcFwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpXG4gICAgICAgIFxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHN1Z2dlc3RfcmVxdWVzdChjaGFycykge1xuICAgIGNvbnN0IGNoYXJzX2VuY29kZWQgPSBlbmNvZGVVUklDb21wb25lbnQoY2hhcnMpO1xuXG4gICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXCIvc2hvcD9mdW5rPWF1dG9zdWdnZXN0JnE9XCIgKyBjaGFyc19lbmNvZGVkKTtcbiAgICBsZXQgaHRtbCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICBzdWdnZXN0UmVzdWx0LmlubmVySFRNTCA9IGh0bWxcblxuICAgIGlmICh0aGlzLnN1Z2dlc3RfaGlnaGxpZ2h0KSB7XG4gICAgICB0aGlzLmhpZ2hsaWdodChjaGFycyk7XG4gICAgfVxuICB9XG5cbiAgc2hvdygpIHtcbiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzZWFyY2hcIikudmFsdWUgIT09IFwiXCIpIHtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFja2Ryb3BcIikuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKVxuICAgICAgc3VnZ2VzdEFyZWEuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKVxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgXCIjaGVhZGVyIC5oZWFkZXJfX3NlYXJjaCAjc3VnZ2VzdC1hcmVhLmFjdGl2ZVwiXG4gICAgICApLnN0eWxlLm1heEhlaWdodCA9IFwiMTAwMHB4XCJcbiAgICAgIHN1Z2dlc3RJbml0LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgICAgc3VnZ2VzdFJlc3VsdC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiXG5cbiAgICAgIGlmICh0aGlzLnByZXZfY2hhcnMgPT09IFwiXCIpIHtcbiAgICAgICAgdGhpcy5zdWdnZXN0KCk7XG4gICAgICB9XG4gICAgICBcbiAgICB9IGVsc2Uge1xuICAgICAgc3VnZ2VzdEluaXQuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIlxuICAgIH1cblxuICAgIHN1Z2dlc3RBcmVhLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgc3VnZ2VzdEFyZWEuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKVxuICB9XG5cbiAgaGlnaGxpZ2h0KGNoYXJzKSB7XG4gICAgY2hhcnMgPSBjaGFycy50cmltKCk7XG4gICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAodGhpcy5fZXNjYXBlX3JlZ2V4cChjaGFycyksICdnaScpO1xuXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIiNzdWdnZXN0LXJlc3VsdCAudGVybVwiKS5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICB2YXIgdCA9IGVsZW0uaW5uZXJIVE1MO1xuICAgICAgdCA9IHQucmVwbGFjZShyZWcsIFwiPHNwYW4gY2xhc3M9J3N1Z2dlc3QtaGwnPiQmPC9zcGFuPlwiKTtcbiAgICAgIGVsZW0uaW5uZXJIVE1MID0gdDtcbiAgICB9KTtcbiAgfVxuXG4gIF9lc2NhcGVfcmVnZXhwKHN0cmluZykge1xuICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKTtcbiAgfVxuXG4gIGhpc3RvcnlfaW5pdCgpIHtcbiAgICBpZiAodHlwZW9mIChTdG9yYWdlKSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgaGlzdG9yeV9zdHIgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3NlYXJjaF9oaXN0b3J5Jyk7XG4gICAgaWYgKGhpc3Rvcnlfc3RyID09IG51bGwgfHwgaGlzdG9yeV9zdHIgPT09IFwiXCIpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3Qgc2VhcmNoX2hpc3RvcnkgPSBKU09OLnBhcnNlKGhpc3Rvcnlfc3RyKTtcbiAgICBsZXQgaGlzdG9yeV9odG1sID0gXCJcIjtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VhcmNoX2hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc2VhcmNoX2hpc3RvcnlbaV0udmFsdWU7XG4gICAgICBjb25zdCB1cmwgPSB0aGlzLmZ1bGxfc2VhcmNoX3VybCArIGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gICAgICBjb25zdCBsaW5rID0gJzxhIGNsYXNzPVwic2VhcmNoLWxpbmtcIiBkYXRhLXRlcm09XCInICsgdmFsdWUgKyAnXCIgaHJlZj1cIicgKyB1cmwgKyAnXCI+JyArIHZhbHVlICsgJzwvYT4nO1xuICAgICAgaGlzdG9yeV9odG1sICs9ICc8bGkgY2xhc3M9XCJzZWFyY2gtaGlzdG9yeS1saVwiPicgKyBsaW5rICsgJzwvbGk+JztcbiAgICB9XG5cbiAgICBpZiAoaGlzdG9yeV9odG1sKSB7XG4gICAgICBoaXN0b3J5X2h0bWwgPSBcIjxkaXYgY2xhc3M9J3NlYXJjaC1oaXN0b3J5LWhlYWRlcic+PHNwYW4gY2xhc3M9J3NlYXJjaC1oaXN0b3J5LXRpdGxlJz5cIiArIHNlYXJjaF90ZXh0c1snaGlzdG9yeSddICsgXCI8L3NwYW4+PGEgaHJlZj0nIycgaWQ9J3NlYXJjaC1oaXN0b3J5LWNsZWFyJz5cIiArIHNlYXJjaF90ZXh0c1snY2xlYXInXSArIFwiPC9hPjwvZGl2Pjx1bD5cIiArIGhpc3RvcnlfaHRtbCArIFwiPC91bD5cIjtcbiAgICB9XG5cbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNlYXJjaC1oaXN0b3J5XCIpLmlubmVySFRNTCA9IGhpc3RvcnlfaHRtbDtcbiAgfVxuXG4gIGhpc3Rvcnlfc2F2ZShxdWVyeSwgaGl0cykge1xuICAgIGlmICh0eXBlb2YgKFN0b3JhZ2UpID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gbnVsbDtcblxuICAgIGlmIChoaXRzID4gMCkge1xuICAgICAgdmFyIHNlYXJjaF9oaXN0b3J5ID0gSlNPTi5wYXJzZSh3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oJ3NlYXJjaF9oaXN0b3J5JykpO1xuXG4gICAgICBpZiAoc2VhcmNoX2hpc3RvcnkgPT0gbnVsbCB8fCBzZWFyY2hfaGlzdG9yeSA9PT0gXCJcIikge1xuICAgICAgICBzZWFyY2hfaGlzdG9yeSA9IFt7ICd2YWx1ZSc6IHF1ZXJ5IH1dO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gcmVtb3ZlIGlmIGFscmVhZHkgZXhpc3RzLlxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlYXJjaF9oaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKHNlYXJjaF9oaXN0b3J5W2ldLnZhbHVlID09PSBxdWVyeSkge1xuICAgICAgICAgICAgc2VhcmNoX2hpc3Rvcnkuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaS0tO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzZWFyY2hfaGlzdG9yeS51bnNoaWZ0KHsgJ3ZhbHVlJzogcXVlcnkgfSk7XG5cbiAgICAgICAgaWYgKHNlYXJjaF9oaXN0b3J5Lmxlbmd0aCA+IHNlYXJjaF9oaXN0b3J5X2NvdW50KSB7XG4gICAgICAgICAgc2VhcmNoX2hpc3RvcnkubGVuZ3RoID0gc2VhcmNoX2hpc3RvcnlfY291bnQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKCdzZWFyY2hfaGlzdG9yeScsIEpTT04uc3RyaW5naWZ5KHNlYXJjaF9oaXN0b3J5KSk7XG4gICAgfVxuICB9XG5cbiAgaGlzdG9yeV9jbGVhcigpIHtcbiAgICBpZiAodHlwZW9mIChTdG9yYWdlKSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuIG51bGw7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdzZWFyY2hfaGlzdG9yeScpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic2VhcmNoLWhpc3RvcnlcIikuaW5uZXJIVE1MID0gXCJcIjtcbiAgfVxufVxuIiwiXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBY2Uge1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yaWVzSW1nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ltZy10b2dnbGUnKTtcbiAgICAgICAgdGhpcy5pbml0X2V2ZW50cygpO1xuICAgIH1cblxuICAgIGluaXRfZXZlbnRzKCkge1xuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZENhdGVnb3JpZXNJbWcpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkQ2F0ZWdvcmllcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5jYXRlZ29yeS1saXN0LS1pdGVtJyk7XG5cbiAgICAgICAgICAgIHNlbGVjdGVkQ2F0ZWdvcmllcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIChlKSA9PiB0aGlzLnNldF9hY3RpdmVfY2F0ZWdvcnkoZS50YXJnZXQpKTtcblxuICAgICAgICAgICAgICAgIGlmIChpdGVtLmNsYXNzTGlzdC5jb250YWlucygnb3BlbicpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yaWVzT3BlbiA9IGl0ZW07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRfYWN0aXZlX2NhdGVnb3J5KGVsZW0pIHtcbiAgICAgICAgaWYgKCFlbGVtLmNsYXNzTGlzdC5jb250YWlucygnb3BlbicpKSB7XG4gICAgICAgICAgICBjb25zdCBpbWdfdGFnID0gZWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW1nJyk7XG5cbiAgICAgICAgICAgIGlmIChpbWdfdGFnLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yaWVzSW1nLnNyYyA9IGltZ190YWdbMF0uc3JjO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRDYXRlZ29yaWVzT3Blbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcmllc09wZW4uY2xhc3NMaXN0LnJlbW92ZSgnb3BlbicpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGVsZW0uY2xhc3NMaXN0LmFkZCgnb3BlbicpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yaWVzT3BlbiA9IGVsZW07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJleHBvcnQgZGVmYXVsdCBjbGFzcyBOYXYge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgaW5pdCgpIHtcblxuICAgIC8qIFRvZ2dsZSBuYXYgKi9cbiAgICBsZXQgbWVudUJ0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIjbWFpbi0tbmF2LWljb25cIilcbiAgICBsZXQgbWVudUJ0bkNsb3NlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIFwiLm1lbnVfX2NhdGVnb3JpZXMtLWNsb3NlXCJcbiAgICApXG4gICAgdGhpcy5tYWluTmF2ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIiNtYWluLS1uYXZcIilcbiAgICB0aGlzLnNjcm9sbFBvc2l0aW9uID0gMFxuXG4gICAgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKFwic2NyZWVuIGFuZCAobWluLXdpZHRoOiA2NXJlbSlcIikubWF0Y2hlcykgcmV0dXJuO1xuXG4gICAgLyogU2hvdyBuYXYgKi9cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lbnVCdG4ubGVuZ3RoOyArK2kpIHtcbiAgICAgIG1lbnVCdG5baV0uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHsgdGhpcy5zaG93TWFpbk5hdih0aGlzKSB9KVxuICAgIH1cblxuICAgIC8qIGhpZGUgbmF2ICovXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZW51QnRuQ2xvc2UubGVuZ3RoOyArK2kpIHtcbiAgICAgIG1lbnVCdG5DbG9zZVtpXS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4geyB0aGlzLmhpZGVNYWluTmF2KHRoaXMpIH0pXG4gICAgfVxuXG4gICAgaWYgKC9BbmRyb2lkfHdlYk9TfGlQaG9uZXxpUGFkfGlQb2R8QmxhY2tCZXJyeS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJoZWFkZXJcIikuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgXCJjbGlja1wiLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICBpZiAoIWV2ZW50LnRhcmdldC5jbG9zZXN0KFwiI25hdi13cmFwcGVyLCAjbWFpbi0tbmF2LWljb25cIikpIHtcbiAgICAgICAgICAgIHRoaXMuaGlkZU1haW5OYXYodGhpcylcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZhbHNlKVxuICAgIH1cblxuICAgIC8qIHRvZ2dsZSBsZXZlbCAxKi9cbiAgICBjb25zdCBuYXZJdGVtc0xpbmsgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgXCIubWVudV9fY2F0ZWdvcmllcyA+IGxpLmhhc19fY2hpbGRyZW4gPiBhXCJcbiAgICApXG4gICAgY29uc3QgbmF2SXRlbXNCYWNrID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgIFwiLm1lbnVfX2NhdGVnb3JpZXMtLWJhY2tcIlxuICAgIClcblxuICAgIHRoaXMuU2Nyb2xsdG9Ub3AgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLm1lbnVfX2NhdGVnb3JpZXNcIilcblxuICAgIG5hdkl0ZW1zTGluay5mb3JFYWNoKChsaXN0SXRlbSkgPT4ge1xuICAgICAgbGlzdEl0ZW0uY2xhc3NMaXN0LnJlbW92ZSgnbmF2aWdhdGUnKVxuICAgICAgbGlzdEl0ZW0uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7IHRoaXMuc2V0QWN0aXZlTGluayhlLCB0aGlzKSB9KVxuICAgIH0pXG5cbiAgICBuYXZJdGVtc0JhY2suZm9yRWFjaCgobGlzdEl0ZW0pID0+IHtcbiAgICAgIGxpc3RJdGVtLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4geyB0aGlzLnNldEFjdGl2ZUJhY2soZSwgdGhpcykgfSlcbiAgICB9KVxuICB9XG5cbiAgc2hvd01haW5OYXYoX3NlbGYpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IF9zZWxmLm1haW5OYXYubGVuZ3RoOyArK2kpIHtcbiAgICAgIC8qIGFkZCBhY3RpdmUgY2xhc3NlcyAqL1xuICAgICAgX3NlbGYubWFpbk5hdltpXS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpXG4gICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoXCJtb2RhbF9hY3RpdmVcIilcbiAgICB9XG4gICAgLyogYWRkIHNjcm9sbHBvc3Rpb24gKi9cbiAgICBfc2VsZi5zY3JvbGxQb3NpdGlvbiA9IHdpbmRvdy5wYWdlWU9mZnNldFxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5wb3NpdGlvbiA9IFwiZml4ZWRcIlxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUudG9wID0gYC0ke19zZWxmLnNjcm9sbFBvc2l0aW9ufXB4YFxuICB9XG5cbiAgaGlkZU1haW5OYXYoX3NlbGYpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IF9zZWxmLm1haW5OYXYubGVuZ3RoOyArK2kpIHtcbiAgICAgIC8qIHJlbW92ZSBhY3RpdmUgY2xhc3NlcyAqL1xuXG4gICAgICBfc2VsZi5tYWluTmF2W2ldLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIilcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcIm1vZGFsX2FjdGl2ZVwiKVxuICAgIH1cbiAgICAvKiByZW1vdmUgc2Nyb2xscG9zdGlvbiAqL1xuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJvdmVyZmxvd1wiKVxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJwb3NpdGlvblwiKVxuICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucmVtb3ZlUHJvcGVydHkoXCJ0b3BcIilcbiAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVOYXZcIilcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhY2tkcm9wXCIpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpXG4gICAgLy8gd2luZG93LnNjcm9sbFRvKDAsIF9zZWxmLnNjcm9sbFBvc2l0aW9uKVxuICB9XG5cbiAgc2V0QWN0aXZlTGluayhlLCBfc2VsZikge1xuICAgIGNvbnN0IHBhcmVudCA9IGUudGFyZ2V0LnBhcmVudE5vZGVcbiAgICAvKiBpZiBjaGlsZHJlbiBwcmV2ZW50IGxpbmsgZm9sbG93IC0gbGV2ZWwxICovXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgLyogc2hvdyBsZXZlbCAtIDEgaWYgY2hpbGRyZW4gKi9cblxuICAgIGUudGFyZ2V0LnBhcmVudE5vZGUuY2xhc3NMaXN0LnRvZ2dsZShcIm9wZW5cIilcbiAgICBlLnRhcmdldC5wYXJlbnROb2RlLnBhcmVudE5vZGUuY2xhc3NMaXN0LnRvZ2dsZShcIm9wZW5cIilcbiAgICAvKiBzY3JvbGwgbWVudSB0byB0b3Agb24gY2xpY2sgKi9cbiAgICBfc2VsZi5TY3JvbGx0b1RvcC5zY3JvbGxJbnRvVmlldygpXG4gIH1cblxuICAvKiB0b2dnbGUgYmFjayB0byBsZXZlbDAgKi9cbiAgc2V0QWN0aXZlQmFjayhlLCBfc2VsZikge1xuICAgIGNvbnN0IHBhcmVudCA9IGUudGFyZ2V0LnBhcmVudE5vZGVcbiAgICBlLnRhcmdldC5wYXJlbnROb2RlLnBhcmVudE5vZGUuY2xhc3NMaXN0LnRvZ2dsZShcIm9wZW5cIilcbiAgICBlLnRhcmdldC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc0xpc3QudG9nZ2xlKFwib3BlblwiKVxuICAgIC8qIHNjcm9sbCBtZW51IHRvIHRvcCBvbiBjbGljayAqL1xuICAgIF9zZWxmLlNjcm9sbHRvVG9wLnNjcm9sbEludG9WaWV3KClcbiAgfVxufSIsImltcG9ydCB7ZXhlY3V0ZUpzLCBnZXRDb29raWV9IGZyb20gXCIuLi8uLi8uLi9zY3JpcHRzL3V0aWxzLmpzXCI7XG5cbmNvbnN0IHN0b3JhZ2VfbmFtZSA9ICdhaXJfY2FydCc7XG5jb25zdCBleHBpcmVfdGltZSA9IDYwOyAvLyBJbiBtaW51dGVzLlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDYXJ0IHtcblxuICAgIGNvbnN0cnVjdG9yKHdyYXBwZXJfaWQgPSAnYWlyLWNhcnQtd3JhcHBlcicsIGNvbnRlbnRfaWQgPSAnYWlyLWNhcnQnLCBsYWJlbF9pZCA9ICdhaXItY2FydC1sYWJlbCcpIHtcbiAgICAgICAgdGhpcy53cmFwcGVyX2lkID0gd3JhcHBlcl9pZDtcbiAgICAgICAgdGhpcy5jb250ZW50X2lkID0gY29udGVudF9pZDtcbiAgICAgICAgdGhpcy5sYWJlbF9pZCA9IGxhYmVsX2lkO1xuICAgICAgICB0aGlzLmNhcnRFcnJvckhlYWRpbmcgPSAnJztcbiAgICAgICAgdGhpcy5jYXJ0RXJyb3JUZXh0ID0gJyc7XG5cbiAgICAgICAgaWYgKHdpbmRvdy5zaG9wX3RleHRzKSB7XG4gICAgICAgICAgICB0aGlzLmNhcnRFcnJvckhlYWRpbmcgPSB3aW5kb3cuc2hvcF90ZXh0cy50ZXh0MVxuICAgICAgICAgICAgdGhpcy5jYXJ0RXJyb3JUZXh0ID0gd2luZG93LnNob3BfdGV4dHMudGV4dDJcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3VycmVuY3lfcHJlZml4ID0gd2luZG93LnNob3Bfc2V0dGluZ3NbJ2N1cnJlbmN5X3ByZWZpeCddIHx8ICcnO1xuICAgICAgICB0aGlzLmN1cnJlbmN5X3N1ZmZpeCA9IHdpbmRvdy5zaG9wX3NldHRpbmdzWydjdXJyZW5jeV9zdWZmaXgnXSB8fCAnJztcbiAgICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuXG4gICAgaW5pdCgpIHtcbiAgICAgICAgaWYgKCFnZXRDb29raWUoJ1NFU1MnKSkgcmV0dXJuO1xuICAgICAgICBpZiAoIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMud3JhcHBlcl9pZCkpIHJldHVybjtcblxuICAgICAgICBsZXQgZ2V0Q2FydCA9IGZhbHNlO1xuXG4gICAgICAgIGlmICh3aW5kb3cuc2hvcF9zZXR0aW5ncykge1xuICAgICAgICAgICAgaWYgKHdpbmRvdy5zaG9wX3NldHRpbmdzLnJlcXVlc3QgPT09ICdjaGVja291dF9jb21wbGV0ZScpIHtcbiAgICAgICAgICAgICAgICBnZXRDYXJ0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShzdG9yYWdlX25hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFnZXRDYXJ0KSB7XG4gICAgICAgICAgICB0aGlzLmNhcnQgPSB0aGlzLmdldF9zdG9yYWdlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jYXJ0KSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIFxuXG4gICAgYWRkX2l0ZW1fZXZlbnQoZSkge1xuICAgICAgICBjb25zdCBlbGVtID0gZS50YXJnZXQ7XG4gICAgICAgIGNvbnN0IHF1YW50aXR5X2ZpZWxkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NhcnQtcXVhbnRpdHknKTtcbiAgICAgICAgY29uc3QgcHJvZHVjdF9pZCA9IGVsZW0uZGF0YXNldC5pZDtcbiAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBxdWFudGl0eV9maWVsZCA/IHF1YW50aXR5X2ZpZWxkLnZhbHVlIDogMTtcblxuICAgICAgICB0aGlzLmFkZF9pdGVtKHByb2R1Y3RfaWQsIHF1YW50aXR5LCB1bmRlZmluZWQpO1xuICAgIH1cblxuICAgIHJlbW92ZV9pdGVtX2V2ZW50KGUpIHtcbiAgICAgICAgY29uc3QgZWxlbSA9IGUudGFyZ2V0O1xuICAgICAgICBjb25zdCBpdGVtX2lkID0gZWxlbS5wYXJlbnRFbGVtZW50LmRhdGFzZXQuaXRlbUlkO1xuICAgICAgICB0aGlzLnJlbW92ZV9pdGVtKGl0ZW1faWQpO1xuICAgIH1cblxuICAgIGluY19pdGVtX2V2ZW50KGUpIHtcbiAgICAgICAgY29uc3QgZWxlbSA9IGUudGFyZ2V0O1xuICAgICAgICBjb25zdCBpdGVtX2lkID0gZWxlbS5wYXJlbnRFbGVtZW50LmRhdGFzZXQuaXRlbUlkO1xuICAgICAgICB0aGlzLmluY19pdGVtKGl0ZW1faWQpO1xuICAgIH1cblxuICAgIHN1Yl9pdGVtX2V2ZW50KGUpIHtcbiAgICAgICAgY29uc3QgZWxlbSA9IGUudGFyZ2V0O1xuICAgICAgICBjb25zdCBpdGVtX2lkID0gZWxlbS5wYXJlbnRFbGVtZW50LmRhdGFzZXQuaXRlbUlkO1xuICAgICAgICB0aGlzLnN1Yl9pdGVtKGl0ZW1faWQpO1xuICAgIH1cblxuICAgIF9zaG93KCkge1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKS5jbGFzc0xpc3QuYWRkKFwiY2FydC1vcGVuXCIpXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFja2Ryb3BcIikuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKVxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNvbnRlbnRfaWQpLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIik7XG4gICAgfVxuXG4gICAgX2hpZGUoKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuY29udGVudF9pZCkuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKVxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhY2tkcm9wXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIilcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJvZHlcIikuY2xhc3NMaXN0LnJlbW92ZShcImNhcnQtb3BlblwiKVxuICAgIH1cblxuICAgIF90b2dnbGUoKSB7XG4gICAgICAgIGxldCBlbGVtZW50Q2xhc3NsaXN0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5jb250ZW50X2lkKS5jbGFzc0xpc3Q7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiaGVqaGVqXCIpXG5cbiAgICAgICAgaWYgKCFlbGVtZW50Q2xhc3NsaXN0LmNvbnRhaW5zKFwiYWN0aXZlXCIpKSB7XG4gICAgICAgICAgdGhpcy5fc2hvdygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5faGlkZSgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBnZXQoYWN0aW9uLCBvcHQpIHtcbiAgICAgICAgLy8gbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9hcGkvY2FydCcpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcD9mdW5rPWdldF9jYXJ0Jyk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICBpZiAocmVzdWx0LnN0YXR1cy5jb2RlID09IDIwMCkge1xuICAgICAgICAgICAgdGhpcy5jYXJ0ID0gcmVzdWx0LmRhdGE7XG5cbiAgICAgICAgICAgIHRoaXMuc2F2ZV9zdG9yYWdlKCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcihhY3Rpb24sIG9wdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBhZGRfaXRlbShwcm9kdWN0X2lkLCBxdWFudGl0eSwgZXh0cmFfZGF0YSkge1xuICAgICAgICBjb25zdCBkYXRhID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgICAgICB0aGlzLmdldCgpXG4gICAgICAgIGRhdGEuYXBwZW5kKCdmdW5rJywgJ2FkZF9jYXJ0X2l0ZW0nKTtcbiAgICAgICAgZGF0YS5hcHBlbmQoJ3Byb2R1Y3RfaWQnLCBwcm9kdWN0X2lkKTtcbiAgICAgICAgZGF0YS5hcHBlbmQoJ3F1YW50aXR5JywgcXVhbnRpdHkpO1xuXG4gICAgICAgIGlmIChleHRyYV9kYXRhKSB7XG4gICAgICAgICAgICAvLyBIYW50ZXJhIFNFVC1hcnRpa2xhci5cbiAgICAgICAgICAgIGlmIChleHRyYV9kYXRhLmJ1bmRsZV9maWVsZHMpIHtcbiAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgnYnVuZGxlX2ZpZWxkcycsIEpTT04uc3RyaW5naWZ5KGV4dHJhX2RhdGEuYnVuZGxlX2ZpZWxkcykpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIYW50ZXJhIHByZXNlbnRrb3J0LlxuICAgICAgICAgICAgaWYgKGV4dHJhX2RhdGEuZ2lmdGNhcmRfdmFsdWVfaWQpIHtcbiAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgnZ2lmdGNhcmRfdmFsdWVfaWQnLCBleHRyYV9kYXRhLmdpZnRjYXJkX3ZhbHVlX2lkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9zaG9wJywge1xuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBib2R5OiBkYXRhXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICBpZiAocmVzdWx0LnN0YXR1cy5jb2RlID09IDIwMCkge1xuICAgICAgICAgICAgdGhpcy5jYXJ0ID0gcmVzdWx0LmRhdGEuY2FydDtcbiAgICAgICAgICAgIHRoaXMucGl4ZWxzID0gcmVzdWx0LmRhdGEucGl4ZWxzO1xuXG4gICAgICAgICAgICB0aGlzLnNhdmVfc3RvcmFnZSgpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoJ2FkZCcsIHtwcm9kdWN0X2lkOiBwcm9kdWN0X2lkfSk7XG4gICAgICAgICAgICBpZiAocHJvZHVjdF9pZCkgeyAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcblxuICAgICAgICAgICAgICAgIGRhdGEuYXBwZW5kKCdmdW5rJywgJ2dvb2dsZV9hcnRpY2xlX3BhdGgnKTtcbiAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgnYXJ0bnInLCBwcm9kdWN0X2lkKTtcbiAgICAgICAgICAgICAgICBkYXRhLmFwcGVuZCgncGF0aCcsIHdpbmRvdy5zaG9wX3NldHRpbmdzWydwcm9kdWN0X3JlZmVycmVyJ10pO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBmZXRjaCgnL2NnaS1iaW4vaWJ1dGlrL0FQSS5mY2dpJywge1xuICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogZGF0YVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zaG93X2Vycm9yKHJlc3VsdC5zdGF0dXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaW5jX2l0ZW0oaXRlbV9pZCkge1xuICAgICAgICBjb25zdCBpdGVtID0gdGhpcy5fZ2V0X2l0ZW1fZnJvbV9jYXJ0KGl0ZW1faWQpO1xuXG4gICAgICAgIGNvbnN0IG5ld19xdWFudGl0eSA9IGl0ZW0ucXVhbnRpdHkgKyAxO1xuICAgICAgICB0aGlzLl91cGRhdGVfaXRlbShpdGVtLCBuZXdfcXVhbnRpdHkpO1xuICAgIH1cblxuICAgIHN1Yl9pdGVtKGl0ZW1faWQpIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMuX2dldF9pdGVtX2Zyb21fY2FydChpdGVtX2lkKTtcblxuICAgICAgICBjb25zdCBuZXdfcXVhbnRpdHkgPSBpdGVtLnF1YW50aXR5IC0gMTtcblxuICAgICAgICBpZiAobmV3X3F1YW50aXR5IDw9IDApIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlX2l0ZW0oaXRlbV9pZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVfaXRlbShpdGVtLCBuZXdfcXVhbnRpdHkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgX2dldF9pdGVtX2Zyb21fY2FydChpdGVtX2lkKSB7XG4gICAgICAgIGxldCBtYXRjaGVkX2l0ZW07XG5cbiAgICAgICAgdGhpcy5jYXJ0Lml0ZW1zLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgICAgIGlmIChpdGVtLmlkID09IGl0ZW1faWQpIHtcbiAgICAgICAgICAgICAgICBtYXRjaGVkX2l0ZW0gPSBpdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbWF0Y2hlZF9pdGVtO1xuICAgIH1cblxuICAgIGFzeW5jIF91cGRhdGVfaXRlbShpdGVtLCBuZXdfcXVhbnRpdHkpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICAgICAgdGhpcy5nZXQoKVxuICAgICAgICBkYXRhLmFwcGVuZCgnZnVuaycsICd1cGRhdGVfY2FydF9pdGVtJyk7XG4gICAgICAgIGRhdGEuYXBwZW5kKCdpZCcsIGl0ZW0uaWQpO1xuICAgICAgICBkYXRhLmFwcGVuZCgncXVhbnRpdHknLCBuZXdfcXVhbnRpdHkpO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9zaG9wJywge1xuICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICBib2R5OiBkYXRhXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICAvLyBVcGRhdGUgY2FydCBtb2RlbFxuICAgICAgICBpZiAocmVzdWx0LnN0YXR1cy5jb2RlID09IDIwMCkge1xuICAgICAgICAgICAgdGhpcy5jYXJ0LnRvdGFsX2Nvc3QgKz0gaXRlbS5wcmljZSAqIChuZXdfcXVhbnRpdHkgLSBpdGVtLnF1YW50aXR5KTtcbiAgICAgICAgICAgIGl0ZW0ucm93X2Nvc3QgPSBpdGVtLnByaWNlICogbmV3X3F1YW50aXR5O1xuICAgICAgICAgICAgaXRlbS5xdWFudGl0eSA9IG5ld19xdWFudGl0eTtcblxuICAgICAgICAgICAgdGhpcy5zYXZlX3N0b3JhZ2UoKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNob3dfZXJyb3IocmVzdWx0LnN0YXR1cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyByZW1vdmVfaXRlbShpdGVtX2lkKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgICAgIHRoaXMuZ2V0KClcbiAgICAgICAgZGF0YS5hcHBlbmQoJ2Z1bmsnLCAnZGVsZXRlX2NhcnRfaXRlbScpO1xuICAgICAgICBkYXRhLmFwcGVuZCgnaWQnLCBpdGVtX2lkKTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcCcsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgYm9keTogZGF0YVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgICAgLy8gVXBkYXRlIGNhcnQgbW9kZWxcbiAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMuY29kZSA9PSAyMDApIHtcbiAgICAgICAgICAgIHRoaXMuY2FydC5pdGVtcy5mb3JFYWNoKChpdGVtLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0uaWQgPT0gaXRlbV9pZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhcnQudG90YWxfY29zdCAtPSBpdGVtLnJvd19jb3N0O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhcnQuaXRlbXMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnNhdmVfc3RvcmFnZSgpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2hvd19lcnJvcihyZXN1bHQuc3RhdHVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNhdmVfc3RvcmFnZSgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiAoU3RvcmFnZSkgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcblxuICAgICAgICB0aGlzLmNhcnQuZXhwaXJlcyA9IERhdGUubm93KCkgKyBleHBpcmVfdGltZSAqIDYwMDAwO1xuICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oc3RvcmFnZV9uYW1lLCBKU09OLnN0cmluZ2lmeSh0aGlzLmNhcnQpKTtcbiAgICB9XG5cbiAgICBnZXRfc3RvcmFnZSgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiAoU3RvcmFnZSkgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcblxuICAgICAgICBsZXQgc3RyID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHN0b3JhZ2VfbmFtZSk7XG5cbiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIGxldCBkYXRhO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShzdHIpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRhdGEuZXhwaXJlcyA8IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBzaG93X2Vycm9yKGVycm9yKSB7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNvbnRlbnRfaWQpO1xuICAgIFxuICAgICAgICBsZXQgaHRtbCA9IGBcbiAgICAgICAgPGRpdiBjbGFzcz1cImFpci1jYXJ0LXJvdyByb3cgcHQtMTZcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8aDMgaWQ9XCJhaXItY2FydC1tc2dcIiBjbGFzcz1cIm1iLTE2IG10LTI0XCI+JHt0aGlzLmNhcnRFcnJvckhlYWRpbmd9PC9oMz5cbiAgICAgICAgICAgICAgICA8cD4ke3RoaXMuY2FydEVycm9yVGV4dH08L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIGBcbiAgICAgICAgY29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcImNhcnQtb3BlblwiKVxuICAgICAgICBjb25zdCBiYWNrZHJvcEJsdXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhY2tkcm9wXCIpXG4gICAgICAgIGNvbnN0IGFpckNhcnRNb2R1bGUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2Fpci1jYXJ0LW1vZHVsZVwiKVxuICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIlxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2Fpci1jYXJ0XCIpLnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKVxuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2Fpci1jYXJ0XCIpLnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImVycm9yXCIpXG4gICAgICAgIGJhY2tkcm9wQmx1ci5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpXG4gICAgfVxuXG4gICAgc2hvdyhhY3Rpb24sIG9wdCkge1xuICAgICAgICB0aGlzLmdldChhY3Rpb24sIG9wdCk7XG4gICAgfVxuXG4gICAgcmVuZGVyKGFjdGlvbiwgb3B0KSB7XG4gICAgICAgIGlmICh0aGlzLmNhcnQudG90YWxfY291bnQpIHtcbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYWlyLWNhcnQtbGFiZWwtdGV4dFwiKS5pbm5lckhUTUwgPVxuICAgICAgICAgICAgdGhpcy5jYXJ0LnRvdGFsX2NvdW50XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jYXJ0LnRvdGFsX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5sYWJlbF9pZCkuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5sYWJlbF9pZCkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAgICAgICAgICAgIGlmICh3aW5kb3cuY2hlY2tvdXRfdXJsKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gd2luZG93LmNoZWNrb3V0X3VybDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IFwiL3Nob3A/ZnVuaz1iZXN0YWxsX3N0ZWcxXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoYWN0aW9uID09PSAnYWRkJykge1xuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5jb250ZW50X2lkKTtcbiAgICAgICAgICAgIGNvbnN0IHByb2R1Y3RfaWQgPSBvcHQucHJvZHVjdF9pZDtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5jYXJ0Lml0ZW1zO1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImhlYWRlclwiKS5jbGFzc0xpc3QuYWRkKFwiaGVhZGVyX19zY3JvbGxlZFwiKVxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImhlYWRlclwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiaGVhZGVyX19ub3RTY3JvbGxlZFwiKVxuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJvZHlcIikuY2xhc3NMaXN0LmFkZChcImhlYWRlcl9fc2Nyb2xsZWRcIilcbiAgICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5XCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJoZWFkZXJfX25vdFNjcm9sbGVkXCIpXG5cbiAgICAgICAgICAgIGxldCBpdGVtO1xuXG4gICAgICAgICAgICBpZiAob3B0Lm9yZGVyID09ICd1cGRhdGVfdGltZScpIHtcbiAgICAgICAgICAgICAgICBpdGVtID0gaXRlbXNbaXRlbXMubGVuZ3RoLTFdO1xuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGl0ZW1zLmxlbmd0aCAtIDE7IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1zW2ktMV0udXBkYXRlX3RpbWUgPiBpdGVtc1tpXS51cGRhdGVfdGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbSA9IGl0ZW1zW2ktMV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBpdGVtcy5sZW5ndGg7IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1zW2ktMV0ucHJvZHVjdF9pZCA9PT0gcHJvZHVjdF9pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbSA9IGl0ZW1zW2ktMV07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBsZXQgaHRtbCA9IGBcbiAgICAgICAgICAgICAgICA8YSBocmVmPVwiJHtpdGVtLnByb2R1Y3QudXJsfVwiIGNsYXNzPVwiYWlyLWNhcnQtcm93IHJvdyBwdC0xNlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGNhcnRQcm9kdWN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXhzLTQgcGwtMCBwYi0xNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiJHtpdGVtLnByb2R1Y3QuaW1hZ2V9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wteHMtOFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweS00XCI+JHtpdGVtLnByb2R1Y3QubmFtZX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHktNFwiPiR7dGhpcy5jdXJyZW5jeV9wcmVmaXh9JHtpdGVtLnByaWNlfSR7dGhpcy5jdXJyZW5jeV9zdWZmaXh9PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdG0tcGl4ZWxzXCI+JHt0aGlzLnBpeGVsc308L2Rpdj5cbiAgICAgICAgICAgICAgICBgXG5cbiAgICAgICAgICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgICAgICAgICBleGVjdXRlSnMoY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIlxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcImNhcnQtb3BlblwiKVxuICAgICAgICAgICAgICAgIGNvbnN0IGJhY2tkcm9wQmx1ciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFja2Ryb3BcIilcbiAgICAgICAgICAgICAgICBjb25zdCBhaXJDYXJ0TW9kdWxlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhaXItY2FydC1tb2R1bGVcIilcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2Fpci1jYXJ0XCIpLnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKVxuICAgICAgICAgICAgICAgIGJhY2tkcm9wQmx1ci5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbn1cbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIExvZ2luIHtcbiAgICBjb25zdHJ1Y3RvcihpY29uX2lkID0gJ2xvZ2luLWljb24nLCBmb3JtX2lkID0gJ2xvZ2luLWZvcm0nLCBwb3B1cF9pZCA9ICcjbG9naW4td3JhcHBlcicsIGVycm9yX2lkID0gJ2xvZ2luLWVycm9yJywgbG9naW5fc3VjY2Vzc19pZCA9ICdsb2dpbi13cmFwcGVyLWNvbnRlbnQtc3VjY2VzcycpIHtcbiAgICAgICAgdGhpcy5pY29uX2lkID0gaWNvbl9pZDtcbiAgICAgICAgdGhpcy5mb3JtX2lkID0gZm9ybV9pZDtcbiAgICAgICAgdGhpcy5wb3B1cF9pZCA9IHBvcHVwX2lkO1xuICAgICAgICB0aGlzLmVycm9yX2lkID0gZXJyb3JfaWQ7XG4gICAgICAgIHRoaXMubG9naW5fc3VjY2Vzc19pZCA9IGxvZ2luX3N1Y2Nlc3NfaWQ7XG4gICAgICAgIHRoaXMuZnJvbV9jaGVja2xvZ2luID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNJbWJveEhhbmRsaW5nID0gZmFsc2U7IC8vIEZsYWcgdG8gcHJldmVudCBsb29wXG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG4gICAgICAgIHRoaXMuaW5pdF9ldmVudHMoKTtcbiAgICAgICAgdGhpcy5zZXR1cEltYm94TGlzdGVuZXIoKTsgLy8gU2V0IHVwIHRoZSBfaW1ib3ggbGlzdGVuZXJcbiAgICB9XG5cbiAgICBpbml0X2V2ZW50cygpIHtcbiAgICAgICAgaWYgKCFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmljb25faWQpKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHdpbmRvdy5jaGVja2xvZ2luKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRfY2hlY2tsb2dpbigpO1xuICAgICAgICB9IFxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmljb25faWQpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4geyB0aGlzLnNob3dfbG9naW4oKTsgfSk7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5wb3B1cF9pZCArICcgLmNsb3NlJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4geyBlLnN0b3BQcm9wYWdhdGlvbigpOyB0aGlzLmhpZGVfbG9naW4oKTsgfSk7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuZm9ybV9pZCkuYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0JywgKGUpID0+IHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB0aGlzLmxvZ2luKCk7IH0pO1xuICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubG9naW4tc3VjY2Vzcy1idXR0b24nKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUmVkaXJlY3Rpb24oKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdF9jaGVja2xvZ2luKCkgeyAgXG4gICAgICAgIHRoaXMuZnJvbV9jaGVja2xvZ2luID0gdHJ1ZTtcblxuICAgICAgICBsZXQgdGV4dCA9IHdpbmRvdy5jaGVja2xvZ2luX3RleHQgfHwgJyc7XG4gICAgICAgIGxldCBlbWFpbCA9IHdpbmRvdy5jaGVja2xvZ2luX2VtYWlsIHx8ICcnO1xuXG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgICBsZXQgaDMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbG9naW4td3JhcHBlciBoMycpO1xuICAgICAgICAgICAgaWYgKGgzKSB7XG4gICAgICAgICAgICAgICAgaDMuaW5uZXJIVE1MID0gdGV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB1bEVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI2xvZ2luLXdyYXBwZXItY29udGVudCB1bCcpO1xuICAgICAgICAgICAgdWxFbGVtZW50cy5mb3JFYWNoKHVsID0+IHVsLnJlbW92ZSgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbWFpbCkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2xvZ2luLXdyYXBwZXIgaW5wdXRbbmFtZT1cInVzZXJcIl0nKS52YWx1ZSA9IGVtYWlsO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zaG93X2xvZ2luKCk7XG4gICAgfVxuXG4gICAgaGFuZGxlUmVkaXJlY3Rpb24oKSB7XG4gICAgICAgIGlmICh3aW5kb3cubG9jYXRpb24uaHJlZi5pbmNsdWRlcygnZnVuaz1sb2dvdXQnKSkge1xuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnLyc7IC8vIFJlZGlyZWN0IHRvIGhvbWVwYWdlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNob3dfbG9naW4oKSB7XG4gICAgICAgIGNvbnN0IGxvZ2luX2Zvcm0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMucG9wdXBfaWQpO1xuICAgICAgICBjb25zdCBiYWNrZHJvcCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5iYWNrZHJvcCcpO1xuICAgICAgICAvLyBFbnN1cmUgX2ltYm94IGlzIGhpZGRlbiB3aGVuIHNob3dfbG9naW4gaXMgY2FsbGVkXG4gICAgICAgIHRoaXMuaGlkZUltYm94KCk7XG4gICAgICAgIGxvZ2luX2Zvcm0uY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgIGJhY2tkcm9wLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2Z1bGxiYWNrZHJvcCcpO1xuICAgIH1cblxuICAgIGhpZGVfbG9naW4oKSB7XG4gICAgICAgIGNvbnN0IGxvZ2luX2Zvcm0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMucG9wdXBfaWQpO1xuICAgICAgICBcbiAgICAgICAgbG9naW5fZm9ybS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdmdWxsYmFja2Ryb3AnKTtcbiAgICB9XG5cbiAgICBhc3luYyBsb2dpbigpIHtcbiAgICAgICAgY29uc3QgZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuZm9ybV9pZCk7XG5cbiAgICAgICAgaWYgKCFmb3JtLnVzZXIudmFsdWUgJiYgIWZvcm0ucGFzcy52YWx1ZSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IGRhdGEgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKG5ldyBGb3JtRGF0YShmb3JtKSk7XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL3Nob3AnLCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGJvZHk6IGRhdGFcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICAgIGlmIChyZXN1bHQuc3RhdHVzLmNvZGUgPT0gMjAwKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIChTdG9yYWdlKSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oJ2Fpcl93aXNobGlzdCcpO1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSgnYWlyX2NhcnQnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuZnJvbV9jaGVja2xvZ2luKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVSZWRpcmVjdGlvbigpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmZvcm1faWQpLmNsYXNzTGlzdC5hZGQoJ2hpZGUnKTtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmxvZ2luX3N1Y2Nlc3NfaWQpLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuZXJyb3JfaWQpLmlubmVySFRNTCA9IHJlc3VsdC5zdGF0dXMubXNnO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGlkZUltYm94KCkge1xuICAgICAgICBpZiAodHlwZW9mKF9pbWJveCkgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuaXNJbWJveEhhbmRsaW5nID0gdHJ1ZTsgLy8gRGlzYWJsZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIF9pbWJveC5wdXNoKFsnaGlkZUxhdW5jaGVyJ10pO1xuICAgICAgICAgICAgX2ltYm94LnB1c2goWydoaWRlV2lkZ2V0J10pO1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuaXNJbWJveEhhbmRsaW5nID0gZmFsc2U7IH0sIDEwMCk7IC8vIFJlLWVuYWJsZSB0aGUgY2FsbGJhY2sgYWZ0ZXIgYSBkZWxheVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0dXBJbWJveExpc3RlbmVyKCkge1xuICAgICAgICBjb25zdCBkZWJvdW5jZSA9IChmdW5jLCB3YWl0KSA9PiB7XG4gICAgICAgICAgICBsZXQgdGltZW91dDtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpLCB3YWl0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qgb25Ub2dnbGVDYWxsYmFjayA9IGRlYm91bmNlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0ltYm94SGFuZGxpbmcpIHsgLy8gT25seSBleGVjdXRlIGlmIG5vdCBoYW5kbGluZyBfaW1ib3ggbWFudWFsbHlcbiAgICAgICAgICAgICAgICB0aGlzLmhpZGVJbWJveCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAxMDApO1xuXG4gICAgICAgIGlmICh0eXBlb2YoX2ltYm94KSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgX2ltYm94LnB1c2goW1wib25Ub2dnbGVcIiwgb25Ub2dnbGVDYWxsYmFja10pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4iLCJcbmxldCB0b3BsaXN0O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUb3BsaXN0IHtcbiAgaW5pdCgpIHtcbiAgICB0b3BsaXN0ID0gdGhpcy5nZXRfc3RvcmFnZSgpXG5cbiAgICBpZiAodG9wbGlzdCkge1xuICAgICAgdGhpcy5yZW5kZXIoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmdldCgpXG4gICAgfVxuXG4gICAgdGhpcy5pbml0X2V2ZW50cygpO1xuICB9XG5cbiAgaW5pdF9ldmVudHMoKSB7XG4gIH1cbn1cbiIsIlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXlTdHlsZSB7XG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5pbml0X2V2ZW50cygpO1xuXHR9XG5cblx0aW5pdF9ldmVudHMoKSB7XG5cdFx0XG5cdFx0d2luZG93LmxpdmVFdmVudChcIi5teVN0eWxlX19zd2l0Y2ggaW5wdXRcIiwgXCJjaGFuZ2VcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7IFxuXHRcdFx0dGhpcy50b2dnbGVNeVN0eWxlKGVsZW1lbnQpXG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic29ydF9jaGFuZ2VkXCIsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRpZiAoZS5kZXRhaWwpIHtcblx0XHRcdFx0aWYgKGUuZGV0YWlsLnNvcnQgIT09IFwibW9zdF9wb3B1bGFyLWFzY1wiKSB7XG5cdFx0XHRcdFx0ZG9jdW1lbnQuY29va2llID0gXCJibG9vbXJlYWNoX3NvcnRfYWN0aXZlPVwiICsgZmFsc2UgKyBcIjsgbWF4LWFnZT1cIiArIDMwKjI0KjYwKjYwICsgXCI7IHBhdGg9L1wiO1xuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5teVN0eWxlX19zd2l0Y2ggaW5wdXQnKS5mb3JFYWNoKGNoZWNrYm94ID0+IHtcblx0XHRcdFx0XHRcdGNoZWNrYm94LmNoZWNrZWQgPSBmYWxzZTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0dG9nZ2xlTXlTdHlsZShlbGVtZW50KSB7XG5cblx0XHRsZXQgY2hlY2tlZCA9IGVsZW1lbnQuY2hlY2tlZDtcblx0XHRsZXQgdHlwZSA9IGVsZW1lbnQuZGF0YXNldC50eXBlO1xuXHRcdGV4cG9uZWEudHJhY2soJ3NpdGVfY2xpY2snLCB7XG5cdFx0XHQnYWN0aW9uJzogY2hlY2tlZCxcblx0XHRcdCd0eXBlJzogJ215X3N0eWxlJyxcblx0XHRcdCdwYXJhbWV0ZXInOiAndG9nZ2xlJ1xuXHRcdH0pO+KAg1xuXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLm15U3R5bGVfX3N3aXRjaCBpbnB1dCcpLmZvckVhY2goY2hlY2tib3ggPT4ge1xuXHRcdFx0Y2hlY2tib3guY2hlY2tlZCA9IGNoZWNrZWQ7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5jb29raWUgPSBcImJsb29tcmVhY2hfc29ydF9hY3RpdmU9XCIgKyBjaGVja2VkICsgXCI7IG1heC1hZ2U9XCIgKyAzMCoyNCo2MCo2MCArIFwiOyBwYXRoPS9cIjtcblxuXHRcdGlmICh0eXBlID09IFwiZ3JvdXBcIikge1xuXHRcdFx0aWYgKGNoZWNrZWQpIHtcblx0XHRcdFx0dGhpcy5zZXRQb3B1bGFyU29ydCgpO1xuXHRcdFx0fVxuXHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJyZWZyZXNoX2ZpbHRlclwiKSk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKHR5cGUgPT0gXCJ3aWRnZXRcIilcblx0XHR7XG5cdFx0XHRsZXQgZ3JvdXBfaWQgPSBlbGVtZW50LmRhdGFzZXQuZ3JvdXBfaWQ7XG5cdFx0XHRsZXQgbGltaXQgPSBlbGVtZW50LmRhdGFzZXQubGltaXQ7XG5cdFx0XHRsZXQgc29ydCA9IGVsZW1lbnQuZGF0YXNldC5zb3J0O1xuXHRcdFx0dGhpcy5nZXQoZ3JvdXBfaWQsIGxpbWl0LCBzb3J0KTtcblx0XHR9XG5cdH1cblxuXHRzZXRQb3B1bGFyU29ydCgpIHtcblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcjc29ydC1vcmRlci11bCBsaScpLmZvckVhY2goc29ydF9saSA9PiB7XG5cdFx0XHRpZiAoc29ydF9saS5kYXRhc2V0LnZhbHVlID09IFwibW9zdF9wb3B1bGFyLWFzY1wiKSB7XG5cdFx0XHRcdHNvcnRfbGkuY2xhc3NMaXN0LmFkZChcIi0tYWN0aXZlXCIpO1xuXHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYWN0aXZlX3NvcnRfbGFiZWwnKS5mb3JFYWNoKGxhYmVsID0+IHtcblx0XHRcdFx0XHRsYWJlbC5pbm5lckhUTUwgPSBzb3J0X2xpLmlubmVySFRNTDtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0c29ydF9saS5jbGFzc0xpc3QucmVtb3ZlKFwiLS1hY3RpdmVcIik7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRhc3luYyBnZXQoZ3JvdXBfaWQsIGxpbWl0LCBzb3J0KSB7XG5cdFx0Y29uc3QgZGF0YSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcblx0XHRkYXRhLmFwcGVuZCgnZnVuaycsICdnZXRfZmlsdGVyJyk7XHRcblx0XHRkYXRhLmFwcGVuZCgnanNvbicsIDEpO1xuXHRcdGRhdGEuYXBwZW5kKCdpZCcsIGdyb3VwX2lkKTtcblx0XHRkYXRhLmFwcGVuZCgnbGltaXQnLCBsaW1pdCk7XG5cdFx0ZGF0YS5hcHBlbmQoJ3NvcnQnLCBzb3J0KTtcblx0XHRkYXRhLmFwcGVuZCgndHlwZScsIFwicHJvZHVjdF9ncm91cFwiKTtcblx0XG5cdFx0Y29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL3Nob3AnLCB7XG5cdFx0XHRtZXRob2Q6ICdQT1NUJyxcblx0XHRcdGJvZHk6IGRhdGFcblx0XHR9KTtcblxuXHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblx0XHRpZiAocmVzdWx0LnJlcXVlc3RfZGF0YSkge31cblx0fVxufSIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIGFjY29yZGlvbiB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICB0aGlzLmluaXQoKVxuICAgIH1cbiAgICBpbml0KCkge1xuICAgICAgICBmdW5jdGlvbiBpbml0QWNjKGVsZW0sIG9wdGlvbil7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWUudGFyZ2V0Lm1hdGNoZXMoZWxlbSsnIC5hY2NvcmRpb25fX2l0ZW0tLWJ0bicpKSByZXR1cm47XG4gICAgICAgICAgICAgICAgZWxzZXtcbiAgICAgICAgICAgICAgICAgICAgaWYoIWUudGFyZ2V0LnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdhY3RpdmUnKSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZihvcHRpb249PXRydWUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50TGlzdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbSArJyAuYWNjb3JkaW9uX19pdGVtJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChlbGVtZW50TGlzdCwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIGUudGFyZ2V0LnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgICAgICAgICAgZS50YXJnZXQucGFyZW50RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5pdEFjYygnLmFjY29yZGlvbicsIHRydWUpO1xuXG4gICAgfVxufSIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIEhlYWRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaW5pdCgpXG4gIH1cblxuICBpbml0KCkge1xuXG4gICAgY29uc3QgRWxlbWVudExlZ2VuZCA9IHt9XG5cbiAgICBmdW5jdGlvbiBHZXRFbGVtZW50KHNlbGVjdG9yLCByZWZyZXNoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAocmVmcmVzaCkgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpXG5cbiAgICAgICAgaWYgKCEoc2VsZWN0b3IgaW4gRWxlbWVudExlZ2VuZCkpIHtcbiAgICAgICAgICBFbGVtZW50TGVnZW5kW3NlbGVjdG9yXSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gRWxlbWVudExlZ2VuZFtzZWxlY3Rvcl1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmxvZyhlcnIpXG5cbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc2Nyb2xsUG9zID0gd2luZG93LnNjcm9sbFlcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIUdldEVsZW1lbnQoXCJoZWFkZXJcIikpIHJldHVyblxuICAgICAgZWxzZSBpZiAod2luZG93LnNjcm9sbFkgPCAxMzApIHtcbiAgICAgICAgc2Nyb2xsUG9zID0gd2luZG93LnNjcm9sbFlcbiAgICAgICAgR2V0RWxlbWVudChcImJvZHlcIikuY2xhc3NMaXN0LnJlbW92ZShcImhlYWRlcl9fc2Nyb2xsZWRcIilcbiAgICAgICAgR2V0RWxlbWVudChcImhlYWRlclwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiaGVhZGVyX19zY3JvbGxlZFwiKVxuICAgICAgICBHZXRFbGVtZW50KFwiaGVhZGVyXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJoZWFkZXJfX25vdFNjcm9sbGVkXCIpXG4gICAgICAgIEdldEVsZW1lbnQoXCJoZWFkZXJcIikuY2xhc3NMaXN0LmFkZChcInRvcFwiKVxuICAgICAgfSBlbHNlIGlmICh3aW5kb3cuc2Nyb2xsWSA+IHNjcm9sbFBvcyArIDEwMCkge1xuICAgICAgICBzY3JvbGxQb3MgPSB3aW5kb3cuc2Nyb2xsWVxuICAgICAgICBHZXRFbGVtZW50KFwiaGVhZGVyXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJ0b3BcIilcbiAgICAgICAgR2V0RWxlbWVudChcImhlYWRlclwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiaGVhZGVyX19zY3JvbGxlZFwiKVxuICAgICAgICBHZXRFbGVtZW50KFwiYm9keVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiaGVhZGVyX19zY3JvbGxlZFwiKVxuICAgICAgICBHZXRFbGVtZW50KFwiYm9keVwiKS5jbGFzc0xpc3QuYWRkKFwiaGVhZGVyX19ub3RTY3JvbGxlZFwiKVxuICAgICAgICBHZXRFbGVtZW50KFwiaGVhZGVyXCIpLmNsYXNzTGlzdC5hZGQoXCJoZWFkZXJfX25vdFNjcm9sbGVkXCIpXG4gICAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSBcIlwiXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuYmFja2Ryb3BcIikuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKVxuICAgICAgICBpZiAoXG4gICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNoZWFkZXIgLmhlYWRlcl9fc2VhcmNoICNzdWdnZXN0LWFyZWEuYWN0aXZlXCIpXG4gICAgICAgICkge1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgICBcIiNoZWFkZXIgLmhlYWRlcl9fc2VhcmNoICNzdWdnZXN0LWFyZWEuYWN0aXZlXCJcbiAgICAgICAgICApLnN0eWxlLm1heEhlaWdodCA9IFwiMHB4XCJcbiAgICAgICAgfVxuICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdWdnZXN0LXJlc3VsdFwiKSkge1xuICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3VnZ2VzdC1yZXN1bHRcIikuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3VnZ2VzdC1pbml0XCIpKSB7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdWdnZXN0LWluaXRcIikuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiXG4gICAgICAgIH1cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYWNrZHJvcFwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpXG4gICAgICAgIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI3NlYXJjaFwiKSkge1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjc2VhcmNoXCIpLmJsdXIoKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHdpbmRvdy5zY3JvbGxZIDwgc2Nyb2xsUG9zIC0gMTAwKSB7XG4gICAgICAgIHNjcm9sbFBvcyA9IHdpbmRvdy5zY3JvbGxZXG4gICAgICAgIEdldEVsZW1lbnQoXCJoZWFkZXJcIikuY2xhc3NMaXN0LnJlbW92ZShcImhlYWRlcl9fbm90U2Nyb2xsZWRcIilcbiAgICAgICAgR2V0RWxlbWVudChcImJvZHlcIikuY2xhc3NMaXN0LnJlbW92ZShcImhlYWRlcl9fbm90U2Nyb2xsZWRcIilcbiAgICAgICAgR2V0RWxlbWVudChcImhlYWRlclwiKS5jbGFzc0xpc3QuYWRkKFwiaGVhZGVyX19zY3JvbGxlZFwiKVxuICAgICAgICBHZXRFbGVtZW50KFwiYm9keVwiKS5jbGFzc0xpc3QuYWRkKFwiaGVhZGVyX19zY3JvbGxlZFwiKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIFNpemVBbmRGaXQge1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLmluaXRfZXZlbnRzKCk7XG5cdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BkcF9hamF4X2xvYWRlZCcsICgpID0+IHtcblx0XHRcdHRoaXMuaW5pdF9ldmVudHMoKTsgXG5cdFx0fSk7XG5cdH1cblx0XG5cdGluaXRfZXZlbnRzKCkge1xuXHRcdGNvbnN0IHNuZlBEUCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5idXlib3ggLnNpemVBbmRGaXRUcmlnZ2VyJyk7XG5cdFx0Y29uc3Qgc2l6ZUFuZEZpdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaXplYW5kZml0MicpO1xuXG5cdFx0aWYgKHNpemVBbmRGaXQpIHtcblx0XHRcdGlmIChzbmZQRFApIHtcblxuXHRcdFx0XHRTaXplQW5kRml0LnNob3dHZW5lcmF0ZWRTaXplKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmFjdGl2ZUZpdCgpO1xuXHRcdFx0dGhpcy5hY3RpdmVTdGVwKCk7XG5cdFx0XHR0aGlzLnNuZkJ0bigpO1xuXHRcdFx0dGhpcy5ib2R5VHlwZUhhbmRsZXIoKTtcblx0XHRcdHRoaXMucmFuZ2VTbGlkZXIoKTtcblxuXHRcdFx0Y29uc3QgYmFja2Ryb3BCbHVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmJhY2tkcm9wJyk7XG5cdFx0XHRjb25zdCBzaXplTkZpdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaXplYW5kZml0Jyk7XG5cdFx0XHRjb25zdCBzaXplTkZpdFN0ZXAgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdzbmZfc3RlcCcpO1xuXG4vLyBBc3N1bWluZyB3aW5kb3cuc2l6ZU5GaXRJbml0aWFsaXplZCBpcyBub3QgZGVmaW5lZCBhbnl3aGVyZSBlbHNlIGluIHlvdXIgY29kZS5cbmlmICh0eXBlb2Ygd2luZG93LnNpemVORml0SW5pdGlhbGl6ZWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgd2luZG93LnNpemVORml0SW5pdGlhbGl6ZWQgPSBmYWxzZTtcbn1cblxuXHRcdFx0d2luZG93LmxpdmVFdmVudCgnLnNpemVBbmRGaXRUcmlnZ2VyJywgJ2NsaWNrJywgKCkgPT4ge1xuXHRcdFx0XHRpZiAoc2l6ZU5GaXRTdGVwID09ICcxJyAmJiAhd2luZG93LnNpemVORml0SW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgdHJhY2tFeHBvbmVhU3RhcnQoKTtcbiAgICAgICAgX2ltYm94LnB1c2goWydoaWRlTGF1bmNoZXInXSk7XG4gICAgICAgIHdpbmRvdy5zaXplTkZpdEluaXRpYWxpemVkID0gdHJ1ZTsgLy8gU2V0IHRoZSBmbGFnIHRvIHRydWUgYWZ0ZXIgdGhlIGZpcnN0IGluaXRpYWxpemF0aW9uXG5cbiAgICB9XG5cdFx0XHRcdFxuXHRcdFx0XHRjb25zdCBwcm9kdWN0UGFnZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaW5nbGUtcHJvZHVjdCcpO1xuXHRcdFx0XHRjb25zdCBzaXplQW5kRml0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NpemVhbmRmaXQnKTtcblx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwic2l6ZWFuZGZpdC1vcGVuXCIpO1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7XG5cdFx0XHRcdGlmIChwcm9kdWN0UGFnZSkge1xuXHRcdFx0XHRcdGNvbnN0IGltYWdlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wcm9kdWN0SW1nLS13cmFwcGVyIGltZycpO1xuXHRcdFx0XHRcdGNvbnN0IHByb2R1Y3RBcnROciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wcm9kdWN0LWlkLWluZm8nKTtcblx0XHRcdFx0XHRzaXplQW5kRml0LmNsYXNzTGlzdC5hZGQoJ2Zyb20tcGRwJyk7XG5cblx0XHRcdFx0XHRjb25zdCBpbWFnZVNvdXJjZSA9IGltYWdlc1swXS5nZXRBdHRyaWJ1dGUoJ3NyYycpO1xuXHRcdFx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ3NuZl9pbWFnZScsIGltYWdlU291cmNlKTtcblx0XHRcdFx0XHRzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdzbmZfYXJ0bnInLCBwcm9kdWN0QXJ0TnIudGV4dENvbnRlbnQpO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRiYWNrZHJvcEJsdXIuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdHNpemVORml0LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuXHRcdFx0XHR0aGlzLmFjdGl2ZVN0ZXAoKTtcblxuXHRcdFx0XHRpZiAoc2l6ZU5GaXRTdGVwID4gJzEnKSB7XG5cdFx0XHRcdFx0dGhpcy5zbmZCYWNrQnRuKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHR3aW5kb3cubGl2ZUV2ZW50KCcuc2l6ZWFuZGZpdF9faGVhZGVyIHN2ZycsICdjbGljaycsICgpID0+IHtcblx0XHRcdFx0YmFja2Ryb3BCbHVyLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoXCJzaXplYW5kZml0LW9wZW5cIik7XG5cdFx0XHRcdHNpemVORml0LmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xud2luZG93LnNpemVORml0SW5pdGlhbGl6ZWQgPSBmYWxzZTtcblx0XHRcdH0pO1xuXG5cdFx0XHR3aW5kb3cubGl2ZUV2ZW50KCcuc2l6ZWFuZGZpdF9fY2xvc2UnLCAnY2xpY2snLCAoKSA9PiB7XG5cdFx0XHRcdGJhY2tkcm9wQmx1ci5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0c2l6ZU5GaXQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcInNpemVhbmRmaXQtb3BlblwiKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCAnMScpO1xud2luZG93LnNpemVORml0SW5pdGlhbGl6ZWQgPSBmYWxzZTtcblx0XHRcdH0pO1xuXG5cblxuXHRcdFx0aWYgKCFzaXplTkZpdFN0ZXApIHtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCAnMScpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJhbmdlU2xpZGVyKCkge1xuXHRcdGNvbnN0IHJhbmdlTGFiZWxzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnJhbmdlX19sYWJlbCcpO1xuXHRcdGNvbnN0IHNsaWRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmZfc2xpZGVyJyk7XG5cblx0XHRyYW5nZUxhYmVscy5mb3JFYWNoKChsYWJlbCkgPT4ge1xuXHRcdFx0bGFiZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHtcblx0XHRcdFx0Y29uc3QgdmFsdWUgPSBldmVudC50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG5cdFx0XHRcdHNsaWRlci52YWx1ZSA9IHZhbHVlO1xuXHRcdFx0XHQvLyBUcmlnZ2VyIHRoZSBjaGFuZ2UgZXZlbnQgbWFudWFsbHkgdG8gdXBkYXRlIHRoZSBzbGlkZXIncyB2YWx1ZVxuXHRcdFx0XHRzbGlkZXIuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2NoYW5nZScpKTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0Ly8gTGlzdGVuIGZvciBjaGFuZ2VzIGluIHRoZSBzbGlkZXIncyB2YWx1ZVxuXHRcdHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZXZlbnQpID0+IHtcblx0XHRcdGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuXHRcdFx0Ly8gQWRkIG9yIHJlbW92ZSAnYWN0aXZlJyBjbGFzcyBiYXNlZCBvbiB0aGUgc2xpZGVyJ3MgdmFsdWVcblx0XHRcdHJhbmdlTGFiZWxzLmZvckVhY2goKGxhYmVsKSA9PiB7XG5cdFx0XHRcdGNvbnN0IGxhYmVsVmFsdWUgPSBsYWJlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKTtcblx0XHRcdFx0aWYgKGxhYmVsVmFsdWUgPT09IHZhbHVlKSB7XG5cdFx0XHRcdFx0bGFiZWwuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bGFiZWwuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0YWN0aXZlRml0KCkge1xuXHRcdGNvbnN0IHNsaWRlckxhYmVscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5yYW5nZV9fbGFiZWwnKTtcblx0XHRjb25zdCBzbGlkZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25mX3NsaWRlcicpO1xuXHRcdGlmIChzbGlkZXIpIHtcblx0XHRcdHNsaWRlci5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsICgpID0+IHtcblx0XHRcdFx0Y29uc3Qgc2xpZGVyVmFsdWUgPSBzbGlkZXIudmFsdWU7XG5cblx0XHRcdFx0c2xpZGVyTGFiZWxzLmZvckVhY2goKGxhYmVsKSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgbGFiZWxWYWx1ZSA9IGxhYmVsLmdldEF0dHJpYnV0ZSgnZGF0YS12YWx1ZScpO1xuXG5cdFx0XHRcdFx0aWYgKGxhYmVsVmFsdWUgPT09IHNsaWRlclZhbHVlKSB7XG5cdFx0XHRcdFx0XHRsYWJlbC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0bGFiZWwuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdHNuZkJ0bigpIHtcblx0XHRjb25zdCBzbmZDb250aW51ZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X19jb250aW51ZScpO1xuXG5cdFx0c25mQ29udGludWUuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG5cdFx0XHRsZXQgc3RlcCA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ3NuZl9zdGVwJyk7XG5cdFx0XHRjb25zdCB0eXBlc0FjdGl2ZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X190eXBlcycpO1xuXHRcdFx0Y29uc3QgY2xvc2VCdG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9faGVhZGVyIHN2ZycpO1xuXHRcdFx0Y29uc3QgY2xpY2tFdmVudCA9IG5ldyBFdmVudCgnY2xpY2snKTtcblxuXHRcdFx0aWYgKHN0ZXAgPT09ICcxJykge1xuXHRcdFx0XHRjb25zdCBzbmZIZWlnaHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25mLWhlaWdodCcpO1xuXHRcdFx0XHRjb25zdCBzbmZXZWlnaHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25mLXdlaWdodCcpO1xuXHRcdFx0XHRjb25zdCBoZWlnaHQgPSBzbmZIZWlnaHQudmFsdWU7XG5cdFx0XHRcdGNvbnN0IHdlaWdodCA9IHNuZldlaWdodC52YWx1ZTtcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgYm90aCBoZWlnaHQgYW5kIHdlaWdodCBoYXZlIHZhbHVlc1xuXHRcdFx0XHRpZiAoaGVpZ2h0ID09PSAnJyB8fCB3ZWlnaHQgPT09ICcnKSB7XG5cdFx0XHRcdFx0Ly8gU2hvdyBhbiBlcnJvciBtZXNzYWdlIGlmIGVpdGhlciBoZWlnaHQgb3Igd2VpZ2h0IGlzIG1pc3Npbmdcblx0XHRcdFx0XHRkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RlcF8xX2Vycm9yX21lc3NhZ2UnKS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJyk7XG5cdFx0XHRcdFx0cmV0dXJuOyAvLyBTdG9wIHRoZSBmdW5jdGlvbiBmcm9tIHByb2NlZWRpbmdcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNle1xuXHRcdFx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdGVwXzFfZXJyb3JfbWVzc2FnZScpLmNsYXNzTGlzdC5hZGQoJ2hpZGUnKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzdGVwID0gcGFyc2VJbnQoc3RlcCkgKyAxO1xuXHRcdFx0XHRzdGVwID0gc3RlcC50b1N0cmluZygpO1xuXHRcdFx0XHRsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnc25mX2hlaWdodCcsIGhlaWdodCk7XG5cdFx0XHRcdGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdzbmZfd2VpZ2h0Jywgd2VpZ2h0KTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCBzdGVwKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX2hlaWdodCcsIGhlaWdodCk7XG5cdFx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ3NuZl93ZWlnaHQnLCB3ZWlnaHQpO1xuXG5cdFx0XHRcdHRoaXMuYWN0aXZlU3RlcCgpO1xuXHRcdFx0fSBlbHNlIGlmIChzdGVwID09PSAnMicgJiYgdHlwZXNBY3RpdmUpIHtcblx0XHRcdFx0c3RlcCA9IHBhcnNlSW50KHN0ZXApICsgMTtcblx0XHRcdFx0c3RlcCA9IHN0ZXAudG9TdHJpbmcoKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCBzdGVwKTtcblx0XHRcdFx0dGhpcy5hY3RpdmVTdGVwKCk7XG5cdFx0XHR9IGVsc2UgaWYgKChzdGVwID09PSAnMycgJiYgdHlwZXNBY3RpdmUpIHx8IChzdGVwID09PSAnMicgJiYgIXR5cGVzQWN0aXZlKSkge1xuXHRcdFx0XHRjb25zdCBzbmZGaXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc25mX3NsaWRlcicpO1xuXHRcdFx0XHRjb25zdCBmaXQgPSBzbmZGaXQudmFsdWU7XG5cdFx0XHRcdGxldCBmb3JtVmFsdWUgPSAnJztcblxuXHRcdFx0XHRpZiAoZml0ID09PSAnMScpIHtcblx0XHRcdFx0XHRmb3JtVmFsdWUgPSAndGlnaHQnO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGZpdCA9PT0gJzInKSB7XG5cdFx0XHRcdFx0Zm9ybVZhbHVlID0gJ25vcm1hbCc7XG5cdFx0XHRcdH0gZWxzZSBpZiAoZml0ID09PSAnMycpIHtcblx0XHRcdFx0XHRmb3JtVmFsdWUgPSAnc3BhY2lvdXMnO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c3RlcCA9IHBhcnNlSW50KHN0ZXApICsgMTtcblx0XHRcdFx0c3RlcCA9IHN0ZXAudG9TdHJpbmcoKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCBzdGVwKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX2Zvcm0nLCBmb3JtVmFsdWUpO1xuXG5cdFx0XHRcdHRoaXMuYWN0aXZlU3RlcCgpO1xuXHRcdFx0fSBlbHNlIGlmICgoc3RlcCA9PT0gJzQnICYmIHR5cGVzQWN0aXZlKSB8fCAoc3RlcCA9PT0gJzMnICYmICF0eXBlc0FjdGl2ZSkpIHtcblx0XHRcdFx0Y2xvc2VCdG4uZGlzcGF0Y2hFdmVudChjbGlja0V2ZW50KTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5zbmZCYWNrQnRuKCk7XG5cdFx0fSk7XG5cdH1cblxuXHRhY3RpdmVTdGVwKCkge1xuXHRcdGNvbnN0IHN0ZXAgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdzbmZfc3RlcCcpO1xuXHRcdGNvbnN0IGNvbnRpbnVlQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX2NvbnRpbnVlJyk7XG5cdFx0Y29uc3QgZnJvbVBEUCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0LmZyb20tcGRwJyk7XG5cdFx0Y29uc3Qgc25mSGVhZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX2hlYWRlcicpO1xuXG5cdFx0Y29uc3QgZWxlbWVudHMgPSBbXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fbWV0cmljcycpLFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX2ZpdHMnKSxcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X19yZXN1bHRzLWZyb21QRFAnKSxcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X19iYWNrJyksXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9faGVhZGVyIGgyJyksXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fc3RlcHMgcCcpLFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX2NvbnRpbnVlJyksXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fcmVzdWx0cycpLFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX2ZpbmlzaCcpLFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX3Jlc3VsdHNmYWlsJyksXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fY2xvc2UnKVxuXHRcdF07XG5cblx0XHRjb25zdCB0eXBlc0FjdGl2ZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X190eXBlcycpO1xuXG5cdFx0aWYgKHR5cGVzQWN0aXZlKSB7XG5cdFx0XHRlbGVtZW50cy5zcGxpY2UoMSwgMCwgdHlwZXNBY3RpdmUpO1xuXHRcdH1cblxuXHRcdGVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnaGlkZScpKTtcblxuXHRcdGlmIChzdGVwID09PSAnMScgJiYgdHlwZXNBY3RpdmUpIHtcblx0XHRcdFtlbGVtZW50c1swXSwgZWxlbWVudHNbNV0sIGVsZW1lbnRzWzZdLCBlbGVtZW50c1s3XV0uZm9yRWFjaCgoZWxlbWVudCkgPT4gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJykpO1xuXHRcdFx0ZWxlbWVudHNbNl0udGV4dENvbnRlbnQgPSBzdGVwO1xuXHRcdFx0c25mSGVhZGVyLmNsYXNzTmFtZSA9IHNuZkhlYWRlci5jbGFzc05hbWUucmVwbGFjZSgvXFxic3RlcFxcZFxcYi9nLCAnc3RlcDEnKTtcblx0XHR9IGVsc2UgaWYgKHN0ZXAgPT09ICcyJyAmJiB0eXBlc0FjdGl2ZSkge1xuXHRcdFx0W2VsZW1lbnRzWzFdLCBlbGVtZW50c1s0XSwgZWxlbWVudHNbNl0sIGVsZW1lbnRzWzddXS5mb3JFYWNoKChlbGVtZW50KSA9PiBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKSk7XG5cdFx0XHRlbGVtZW50c1s2XS50ZXh0Q29udGVudCA9IHN0ZXA7XG5cdFx0XHRzbmZIZWFkZXIuY2xhc3NOYW1lID0gc25mSGVhZGVyLmNsYXNzTmFtZS5yZXBsYWNlKC9cXGJzdGVwXFxkXFxiL2csICdzdGVwMicpO1xuXHRcdH0gZWxzZSBpZiAoc3RlcCA9PT0gJzMnICYmIHR5cGVzQWN0aXZlKSB7XG5cdFx0XHRbZWxlbWVudHNbMl0sIGVsZW1lbnRzWzRdLCBlbGVtZW50c1s2XSwgZWxlbWVudHNbN11dLmZvckVhY2goKGVsZW1lbnQpID0+IGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnaGlkZScpKTtcblx0XHRcdGVsZW1lbnRzWzZdLnRleHRDb250ZW50ID0gc3RlcDtcblx0XHRcdHNuZkhlYWRlci5jbGFzc05hbWUgPSBzbmZIZWFkZXIuY2xhc3NOYW1lLnJlcGxhY2UoL1xcYnN0ZXBcXGRcXGIvZywgJ3N0ZXAzJyk7XG5cdFx0fSBlbHNlIGlmIChzdGVwID09PSAnNCcgJiYgdHlwZXNBY3RpdmUgJiYgZnJvbVBEUCkge1xuXHRcdFx0dGhpcy5mZXRjaFNpemUoW2VsZW1lbnRzWzNdLCBlbGVtZW50c1s0XSwgZWxlbWVudHNbNl1dKTtcblx0XHRcdGVsZW1lbnRzWzZdLnRleHRDb250ZW50ID0gc3RlcDtcblx0XHRcdHNuZkhlYWRlci5jbGFzc05hbWUgPSBzbmZIZWFkZXIuY2xhc3NOYW1lLnJlcGxhY2UoL1xcYnN0ZXBcXGRcXGIvZywgJ3N0ZXA0Jyk7XG5cdFx0fSBlbHNlIGlmIChzdGVwID09PSAnNCcgJiYgdHlwZXNBY3RpdmUgJiYgIWZyb21QRFApIHtcblx0XHRcdHRoaXMuZmV0Y2hTaXplKFtlbGVtZW50c1s5XSwgZWxlbWVudHNbNF0sIGVsZW1lbnRzWzZdLCBlbGVtZW50c1s4XSwgZWxlbWVudHNbN11dKTtcblx0XHRcdGVsZW1lbnRzWzZdLnRleHRDb250ZW50ID0gc3RlcDtcblx0XHRcdHNuZkhlYWRlci5jbGFzc05hbWUgPSBzbmZIZWFkZXIuY2xhc3NOYW1lLnJlcGxhY2UoL1xcYnN0ZXBcXGRcXGIvZywgJ3N0ZXA0Jyk7XG5cblx0XHRcdC8vIExvZ2ljIGZvciBpbmFjdGl2ZSBib2R5dHlwZXMgYmVsb3dcblx0XHR9IGVsc2UgaWYgKHN0ZXAgPT09ICcxJyAmJiAhdHlwZXNBY3RpdmUpIHtcblx0XHRcdFtlbGVtZW50c1swXSwgZWxlbWVudHNbNF0sIGVsZW1lbnRzWzVdLCBlbGVtZW50c1s2XV0uZm9yRWFjaCgoZWxlbWVudCkgPT4gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJykpO1xuXHRcdFx0ZWxlbWVudHNbNV0udGV4dENvbnRlbnQgPSBzdGVwO1xuXHRcdFx0c25mSGVhZGVyLmNsYXNzTmFtZSA9IHNuZkhlYWRlci5jbGFzc05hbWUucmVwbGFjZSgvXFxic3RlcFxcZFxcYi9nLCAnc3RlcDEnKTtcblx0XHR9IGVsc2UgaWYgKHN0ZXAgPT09ICcyJyAmJiAhdHlwZXNBY3RpdmUpIHtcblx0XHRcdFtlbGVtZW50c1sxXSwgZWxlbWVudHNbM10sIGVsZW1lbnRzWzVdLCBlbGVtZW50c1s2XV0uZm9yRWFjaCgoZWxlbWVudCkgPT4gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJykpO1xuXHRcdFx0Y29udGludWVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnaGlkZScpO1xuXHRcdFx0ZWxlbWVudHNbNV0udGV4dENvbnRlbnQgPSBzdGVwO1xuXHRcdFx0c25mSGVhZGVyLmNsYXNzTmFtZSA9IHNuZkhlYWRlci5jbGFzc05hbWUucmVwbGFjZSgvXFxic3RlcFxcZFxcYi9nLCAnc3RlcDInKTtcblx0XHR9IGVsc2UgaWYgKHN0ZXAgPT09ICczJyAmJiAhdHlwZXNBY3RpdmUgJiYgZnJvbVBEUCkge1xuXHRcdFx0W2VsZW1lbnRzWzVdXS5mb3JFYWNoKChlbGVtZW50KSA9PiBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKSk7XG5cdFx0XHRlbGVtZW50c1s1XS50ZXh0Q29udGVudCA9IHN0ZXA7XG5cdFx0XHR0aGlzLmZldGNoU2l6ZShbZWxlbWVudHNbMl0sIGVsZW1lbnRzWzNdXSk7XG5cdFx0XHRzbmZIZWFkZXIuY2xhc3NOYW1lID0gc25mSGVhZGVyLmNsYXNzTmFtZS5yZXBsYWNlKC9cXGJzdGVwXFxkXFxiL2csICdzdGVwNCcpO1xuXHRcdH0gZWxzZSBpZiAoc3RlcCA9PT0gJzMnICYmICF0eXBlc0FjdGl2ZSAmJiAhZnJvbVBEUCkge1xuXHRcdFx0W2VsZW1lbnRzWzVdXS5mb3JFYWNoKChlbGVtZW50KSA9PiBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKSk7XG5cdFx0XHRlbGVtZW50c1s1XS50ZXh0Q29udGVudCA9IHN0ZXA7XG5cdFx0XHR0aGlzLmZldGNoU2l6ZShbZWxlbWVudHNbN10sIGVsZW1lbnRzWzNdXSk7XG5cdFx0XHRzbmZIZWFkZXIuY2xhc3NMaXN0LnJlcGxhY2UoJ3N0ZXAyJywgJ3N0ZXA0Jyk7XG5cdFx0fVxuXHR9XG5cblx0c25mQmFja0J0bigpIHtcblx0XHRjb25zdCBiYWNrQnRuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX2JhY2snKTtcblx0XHRjb25zdCBzdGVwID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgnc25mX3N0ZXAnKTtcblx0XHRjb25zdCBzdGVwQmFja1ZhbHVlID0gcGFyc2VJbnQoc3RlcCkgLSAxO1xuXHRcdGNvbnN0IHN0ZXBCYWNrU3RyaW5nID0gc3RlcEJhY2tWYWx1ZS50b1N0cmluZygpO1xuXG5cdFx0YmFja0J0bi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcblx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ3NuZl9zdGVwJywgc3RlcEJhY2tTdHJpbmcpO1xuXHRcdFx0dGhpcy5hY3RpdmVTdGVwKCk7XG5cdFx0XHR0aGlzLnNuZkJhY2tCdG4oKTtcblx0XHR9KTtcblx0fVxuXG5cdGZldGNoU2l6ZShlbGVtZW50QXJyYXkpIHtcblx0XHRjb25zdCBzaXplUmVzdWx0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnNpemUtcmVzdWx0Jyk7XG5cdFx0Y29uc3Qgc2l6ZVJlc3VsdEltYWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX3Jlc3VsdHMtLWltZyBpbWcnKTtcblx0XHRjb25zdCBoZWlnaHQgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdzbmZfaGVpZ2h0Jyk7XG5cdFx0Y29uc3Qgd2VpZ2h0ID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgnc25mX3dlaWdodCcpO1xuXHRcdGNvbnN0IGZvcm0gPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdzbmZfZm9ybScpO1xuXHRcdGNvbnN0IGltYWdlID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgnc25mX2ltYWdlJyk7XG5cdFx0Y29uc3QgbG9hZGluZ1dyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fbG9hZGluZ19wYWdlV3JhcHBlcicpO1xuXHRcdGNvbnN0IHN0ZXBDb3VudGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNpemVhbmRmaXRfX3N0ZXBzJyk7XG5cdFx0Y29uc3QgYXJ0aWNsZU51bWJlciA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ3NuZl9hcnRucicpO1xuXHRcdGNvbnN0IHJlc3VsdEZhaWxlZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X19yZXN1bHRzZmFpbCcpO1xuXHRcdGNvbnN0IHJlc3VsdEZyb21QRFAgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fcmVzdWx0cy1mcm9tUERQJyk7XG5cdFx0Y29uc3QgY29udGludWVCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fY29udGludWUnKTtcblx0XHRjb25zdCBmaW5pc2hCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fZmluaXNoJyk7XG5cdFx0Y29uc3QgZnJvbVBEUCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0LmZyb20tcGRwJyk7XG5cdFx0Y29uc3QgY2xvc2VCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdF9fY2xvc2UnKTtcblxuXHRcdGxldCB0eXBlID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgnc25mX3R5cGUnKTtcblx0XHRsZXQgYXJ0bnIgPSAnJztcblxuXHRcdGlmICghdHlwZSkge1xuXHRcdFx0dHlwZSA9ICdyZWN0YW5ndWxhcic7XG5cdFx0fVxuXG5cdFx0aWYgKGFydGljbGVOdW1iZXIpIHtcblx0XHRcdGFydG5yID0gYCZwcm9kdWN0X2lkPSR7YXJ0aWNsZU51bWJlcn1gO1xuXHRcdH1cblxuXHRcdGNvbnN0IGZldGNoUXVlcnkgPSBgJm1hdGNoX2lkPTEmZmllbGRfMT0ke3R5cGV9JmZpZWxkXzI9JHtmb3JtfSZmaWVsZF94PSR7d2VpZ2h0fSZmaWVsZF95PSR7aGVpZ2h0fSR7YXJ0bnJ9YDtcblxuXHRcdHN0ZXBDb3VudGVyLmNsYXNzTGlzdC5hZGQoJ2hpZGUnKTtcblx0XHRsb2FkaW5nV3JhcHBlci5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblx0XHR0aGlzLmxvYWRpbmdfc3RhcnQoKTtcblxuXG5cblx0XHRmZXRjaChgL2NnaS1iaW4vaWJ1dGlrL0FQSS5mY2dpP2Z1bms9UE0ke2ZldGNoUXVlcnl9YCwge1xuXHRcdFx0bWV0aG9kOiAnR0VUJyxcblx0XHRcdGhlYWRlcnM6IHtcblx0XHRcdFx0J0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuXHRcdFx0fVxuXHRcdH0pXG5cdFx0LnRoZW4oKHJlc3BvbnNlKSA9PiByZXNwb25zZS5qc29uKCkpXG5cdFx0LnRoZW4oKGRhdGEpID0+IHtcblx0XHRcdC8vIFNpbXVsYXRpbmcgYSBkZWxheSB0byBlbnN1cmUgdGhlIGxvYWRlciBhbmltYXRpb24gZmluaXNoZXMgZmlyc3Rcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRsb2FkaW5nV3JhcHBlci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG5cdFx0XHRcdGlmIChlbGVtZW50QXJyYXkgJiYgQXJyYXkuaXNBcnJheShlbGVtZW50QXJyYXkpKSB7XG5cdFx0XHRcdFx0ZWxlbWVudEFycmF5LmZvckVhY2goKGVsZW1lbnQpID0+IGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnaGlkZScpKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHN0ZXBDb3VudGVyLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKTtcblxuXHRcdFx0XHRpZiAoZGF0YS5hbHRfdmFsdWUgJiYgZGF0YS5hbHRfdmFsdWVfdW5hdmFpbGFibGUgIT09IDEpIHtcblx0XHRcdFx0XHRzaXplUmVzdWx0LmZvckVhY2goKHJlc3VsdCkgPT4ge1xuXHRcdFx0XHRcdFx0cmVzdWx0LnRleHRDb250ZW50ID0gZGF0YS5hbHRfdmFsdWU7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0c2l6ZVJlc3VsdEltYWdlLnNldEF0dHJpYnV0ZSgnc3JjJywgaW1hZ2UpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGRhdGEudmFsdWUgJiYgIWRhdGEuYWx0X3ZhbHVlICYmIGRhdGEudmFsdWVfdW5hdmFpbGFibGUgIT09IDEpIHtcblx0XHRcdFx0XHRzaXplUmVzdWx0LmZvckVhY2goKHJlc3VsdCkgPT4ge1xuXHRcdFx0XHRcdFx0cmVzdWx0LnRleHRDb250ZW50ID0gZGF0YS52YWx1ZTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRzaXplUmVzdWx0SW1hZ2Uuc2V0QXR0cmlidXRlKCdzcmMnLCBpbWFnZSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoZGF0YS52YWx1ZV91bmF2YWlsYWJsZSA9PT0gMSB8fCBkYXRhLmFsdF92YWx1ZV91bmF2YWlsYWJsZSA9PT0gMSkge1xuXHRcdFx0XHRcdHNpemVSZXN1bHQuZm9yRWFjaCgocmVzdWx0KSA9PiB7XG5cdFx0XHRcdFx0XHRyZXN1bHQudGV4dENvbnRlbnQgPSBkYXRhLnZhbHVlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGZpbmlzaEJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7XG5cdFx0XHRcdFx0cmVzdWx0RmFpbGVkLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKTtcblx0XHRcdFx0XHRyZXN1bHRGcm9tUERQLmNsYXNzTGlzdC5hZGQoJ2hpZGUnKTtcblx0XHRcdFx0XHRjbG9zZUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoZnJvbVBEUCkge1xuXHRcdFx0XHRcdGlmIChjbG9zZUJ1dHRvbi5jbGFzc0xpc3QuY29udGFpbnMoJ2hpZGUnKSkge1xuXHRcdFx0XHRcdFx0ZmluaXNoQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29udGludWVCdXR0b24uY2xhc3NMaXN0LmFkZCgnaGlkZScpO1xuXG5cdFx0XHRcdFx0U2l6ZUFuZEZpdC5zaG93R2VuZXJhdGVkU2l6ZSgpO1xuXHQgIFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGludWVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnaGlkZScpO1xuXHRcdFx0XHRcdGZpbmlzaEJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7XG5cdFx0XHRcdFx0Y29udGludWVCdXR0b24ucXVlcnlTZWxlY3RvcignLmZpbmlzaCcpLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKTtcblx0XHRcdFx0XHRjb250aW51ZUJ1dHRvbi5xdWVyeVNlbGVjdG9yKCcuY29udGludWUnKS5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7XG5cdFx0XHRcdH1cblx0XHRcdH0sIDE1MDApO1xuXHRcdH0pXG5cdFx0LmNhdGNoKChlcnJvcikgPT4ge1xuXHRcdFx0Y29uc29sZS5lcnJvcignRXJyb3I6JywgZXJyb3IpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ym9keVR5cGVIYW5kbGVyKCkge1xuXHRcdGNvbnN0IHR5cGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnNpemVhbmRmaXRfX3R5cGVzLXdyYXBwZXIgaW1nJyk7XG5cblx0XHR0eXBlcy5mb3JFYWNoKCh0eXBlKSA9PiB7XG5cdFx0XHRpZiAodHlwZS5jbGFzc0xpc3QuY29udGFpbnMoJ2FjdGl2ZScpKSB7XG5cdFx0XHRcdC8vIENoZWNrIGlmICdzbmZfdHlwZScgZG9lcyBub3QgZXhpc3QgaW4gc2Vzc2lvblN0b3JhZ2Vcblx0XHRcdFx0aWYgKCFzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdzbmZfdHlwZScpKSB7XG5cdFx0XHRcdFx0Y29uc3QgZm9ybVZhbHVlID0gdHlwZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKTtcblx0XHRcdFx0XHRzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdzbmZfdHlwZScsIGZvcm1WYWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcblx0XHRcdC8vIFRoZW4gYXR0YWNoIHRoZSBjbGljayBldmVudCBsaXN0ZW5lciB0byBhbGwgdHlwZXMgcmVnYXJkbGVzc1xuXHRcdFx0dHlwZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcblx0XHRcdFx0Y29uc3QgZm9ybVZhbHVlID0gdHlwZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKTtcblx0XHRcblx0XHRcdFx0dHlwZXMuZm9yRWFjaCgob3RoZXJUeXBlKSA9PiB7XG5cdFx0XHRcdFx0b3RoZXJUeXBlLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHR9KTtcblx0XHRcblx0XHRcdFx0dHlwZS5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3R5cGUnLCBmb3JtVmFsdWUpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRsb2FkaW5nX3N0YXJ0KCkge1xuXHRcdGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3Byb2dyZXNzJylbMF0uc3R5bGUud2lkdGggPSAnMCUnO1xuXHRcdGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3BlcmNlbnRhZ2UnKVswXS5pbm5lckhUTUwgPSAnMCUnO1xuXG5cdFx0bGV0IGNvdW50ID0gMDtcblx0XHRjb25zdCBwcm9ncmVzc0JhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wcm9ncmVzcycpO1xuXHRcdGNvbnN0IHBlcmNlbnRhZ2UgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGVyY2VudGFnZScpO1xuXHRcdGNvbnN0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuXHRcdFx0Y291bnQgPSBjb3VudCArIDI7XG5cdFx0XHRwcm9ncmVzc0Jhci5zdHlsZS53aWR0aCA9IGNvdW50ICsgJyUnO1xuXHRcdFx0cGVyY2VudGFnZS5pbm5lckhUTUwgPSBjb3VudCArICclJztcblx0XHRcdGlmIChjb3VudCA9PT0gMTAwKSB7XG5cdFx0XHRcdGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuXG5cdFx0XHRcdHRoaXMuaGFuZGxlRmluaXNoQnRuKCk7XG5cdFx0XHR9XG5cdFx0fSwgMzApO1xuXHR9XG5cblx0c3RhdGljIGFzeW5jIHNob3dHZW5lcmF0ZWRTaXplKCkge1xuXHRcdGNvbnN0IHNpemVNYXRjaEZhaWxlZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplbWF0Y2hmYWlsZWQnKTtcblx0XHRjb25zdCBnZW5lcmF0ZWRzaXplID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmdlbmVyYXRlZHNpemUnKTtcblx0XHRjb25zdCBzbmZfcmVzdWx0PSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc25mX3Jlc3VsdCcpO1xuXHRcdGNvbnN0IGdlbmVyYXRlZHNpemVWYWx1ZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5nZW5lcmF0ZWRzaXplIC5zaXplJyk7XG5cdFx0Y29uc3Qgc2l6ZU1hdGNoRmFpbGVkVmFsdWUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZW1hdGNoZmFpbGVkIC5zaXplJyk7XG5cdFx0Y29uc3Qgc2l6ZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYnV5Ym94X192YXJpYW50LS1pdGVtJyk7XG5cdFx0Y29uc3Qgc25mVHJpZ2dlckJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zbmYtdHJpZ2dlcl9fYnRuJyk7XG5cdFx0Y29uc3Qgc2l6ZUhvbGRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2YXJpYXRpb24tMScpO1xuXHRcdGNvbnN0IHRydWVTaXplRmllbGRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLlRydWVTaXplJyk7XG5cdFx0Y29uc3QgYXJ0aWNsZU51bWJlciA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ3NuZl9hcnRucicpO1xuXHRcdGNvbnN0IHBkcEFydG5yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QtaWQtaW5mbycpLnRleHRDb250ZW50O1xuXG5cdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCAnMScpO1xuXG5cdFx0dHJ5IHtcblx0XHRcdGxldCBhcnRuciA9ICcnO1xuXG5cdFx0XHRpZiAoYXJ0aWNsZU51bWJlciAmJiAxPT0wKSB7XG5cdFx0XHRcdGFydG5yID0gYCZwcm9kdWN0X2lkPSR7YXJ0aWNsZU51bWJlcn1gO1xuXHRcdFx0fSBlbHNlIGlmIChwZHBBcnRucikge1xuXHRcdFx0XHRhcnRuciA9IGAmcHJvZHVjdF9pZD0ke3BkcEFydG5yfWA7XG5cdFx0XHR9XG5cdCAgXHRcdGxldCBzdGFydFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcblx0XHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYC9jZ2ktYmluL2lidXRpay9BUEkuZmNnaT9mdW5rPVBNJm1hdGNoX2lkPTEmZ2V0X2N1c3RvbWVyPTEke2FydG5yfWAsIHtcblx0XHRcdFx0bWV0aG9kOiAnR0VUJyxcblx0XHRcdFx0aGVhZGVyczoge1xuXHRcdFx0XHRcdCdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblxuXHRcdFx0bGV0IGV2ZW50SGFuZGxlZFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcblx0XHRcdGV4cG9uZWEudHJhY2soJ3NwZWVkJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FjdGlvbic6ICdzbmZfZ2V0U2l6ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAnc3BlZWQnOiBgJHtldmVudEhhbmRsZWRUaW1lIC0gc3RhcnRUaW1lfWBcbiAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgfSk7XG4gICAgXG5cblx0XHRcdGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cdFx0XHRpZiAoZGF0YS52YWx1ZSAmJiBnZW5lcmF0ZWRzaXplKSB7XG5cdFx0XHRcdGxldCBzaXplRm91bmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YV9zaXplID0gZGF0YS52YWx1ZTtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YV9zaXplX3ZhcmlhbnQgPSBkYXRhLnZhbHVlX3ZhcmlhbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuYWx0X3ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFfc2l6ZSA9IGRhdGEuYWx0X3ZhbHVlO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuYWx0X3ZhbHVlX3ZhcmlhbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YV9zaXplX3ZhcmlhbnQgPSBkYXRhLmFsdF92YWx1ZV92YXJpYW50O1xuICAgICAgICAgICAgICAgIH0gXG5cdFx0XHRcdC8vIE1hdGNoaW5nIHNpemVzIGFuZCBjaGVja2luZyBmb3IgZGlzYWJsZWQgY2xhc3Ncblx0XHRcdFx0c2l6ZXMuZm9yRWFjaCgoc2l6ZSkgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IHNpemVWYWx1ZSA9IHNpemUuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG5cdFx0XHRcdFx0XG5cdFx0XHRcdFx0aWYgKGRhdGFfc2l6ZSA9PT0gc2l6ZVZhbHVlIHx8IGRhdGFfc2l6ZV92YXJpYW50ICA9PT0gc2l6ZVZhbHVlKSB7XG5cdFx0XHRcdFx0XHRzaXplRm91bmQgPSB0cnVlO1xuXG5cdFx0XHRcdFx0XHRjb25zdCBzbmZUcmlnZ2VyQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnNuZi10cmlnZ2VyX19idG4nKTtcblx0XHRcdFx0XHRcdHNuZlRyaWdnZXJCdXR0b25bMF0uY2xhc3NMaXN0LmFkZCgnaGlkZScpO1xuXHRcdFx0XHRcdFx0aWYgKHNpemUuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG5cdFx0XHRcdFx0XHRcdHNpemVzLmZvckVhY2goKHNpemUpID0+IHNpemUuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpO1xuXHRcdFx0XHRcdFx0XHRnZW5lcmF0ZWRzaXplLmNsYXNzTGlzdC5hZGQoJ2hpZGUnKTtcblx0XHRcdFx0XHRcdFx0c2l6ZU1hdGNoRmFpbGVkLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKTtcblx0XHRcdFx0XHRcdFx0c25mX3Jlc3VsdC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJyk7XG5cdFx0XHRcdFx0XHRcdHNpemVNYXRjaEZhaWxlZFZhbHVlLnRleHRDb250ZW50ID0gZGF0YV9zaXplO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0aWYoZGF0YV9zaXplX3ZhcmlhbnQpe1xuXHRcdFx0XHRcdFx0XHRcdHNpemVIb2xkZXIuZGF0YXNldC52YWx1ZSA9IGRhdGFfc2l6ZV92YXJpYW50O1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHNpemVIb2xkZXIuZGF0YXNldC52YWx1ZSA9IGRhdGFfc2l6ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdzbmZfc2l6ZScsIGRhdGFfc2l6ZSk7XG5cdFx0XHRcdFx0XHRcdGlmIChzaXplLmNsYXNzTGlzdC5jb250YWlucygnYWN0aXZlJykpIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0c2l6ZS5jbGljaygpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGlmKGRhdGEudmFsdWVfdmFyaWFudCl7XG5cdFx0XHRcdFx0XHRcdFx0Z2VuZXJhdGVkc2l6ZVZhbHVlLnRleHRDb250ZW50ID0gZGF0YV9zaXplX3ZhcmlhbnQ7XG5cdFx0XHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Z2VuZXJhdGVkc2l6ZVZhbHVlLnRleHRDb250ZW50ID0gZGF0YV9zaXplO1xuXHRcdFx0XHRcdFx0XHRcdFxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGdlbmVyYXRlZHNpemUuY2xhc3NMaXN0LnJlbW92ZSgnaGlkZScpO1xuXHRcdFx0XHRcdFx0XHRzbmZfcmVzdWx0LmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGUnKVxuXHRcdFx0XHRcdFx0XHRzaXplTWF0Y2hGYWlsZWQuY2xhc3NMaXN0LmFkZCgnaGlkZScpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0Ly8gSWYgdGhlIHNpemUgd2FzIG5vdCBmb3VuZFxuXHRcdFx0XHRpZiAoIXNpemVGb3VuZCkge1xuXHRcdFx0XHRcdGdlbmVyYXRlZHNpemUuY2xhc3NMaXN0LmFkZCgnaGlkZScpO1xuXHRcdFx0XHRcdHNpemVNYXRjaEZhaWxlZC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJyk7XG5cdFx0XHRcdFx0aWYoZGF0YS52YWx1ZV92YXJpYW50KXtcblx0XHRcdFx0XHRcdFx0c2l6ZU1hdGNoRmFpbGVkVmFsdWUudGV4dENvbnRlbnQgPSBkYXRhLnZhbHVlX3ZhcmlhbnQ7XG5cdFx0XHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRzaXplTWF0Y2hGYWlsZWRWYWx1ZS50ZXh0Q29udGVudCA9IGRhdGFfc2l6ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c25mX3Jlc3VsdC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJylcblx0XHRcdFx0XHRjb25zdCB0cmlnZ2VyQnV0dG9uID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYnV0dG9uLnNpemVBbmRGaXRUcmlnZ2VyJyk7XG5cdFx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3NpemUnLCAnbm90X2ZvdW5kJyk7XG5cdFx0XHRcdFx0aWYgKHRyaWdnZXJCdXR0b24pIHtcblx0XHRcdFx0XHRcdHRyaWdnZXJCdXR0b24uY2xhc3NMaXN0LmFkZCgnaGlkZScpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcblx0XHRcdFx0XHR0cnVlU2l6ZUZpZWxkcy5mb3JFYWNoKGZ1bmN0aW9uKGZpZWxkKSB7XG5cdFx0XHRcdFx0XHRmaWVsZC5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7IC8vIEFkZCB0aGUgJ2hpZGUnIGNsYXNzIHRvIGVhY2ggZWxlbWVudFxuXHRcdFx0XHRcdH0pO31cblx0XHRcdFx0ZWxzZXtcblx0XHRcdFx0XHR0cnVlU2l6ZUZpZWxkcy5mb3JFYWNoKGZ1bmN0aW9uKGZpZWxkKSB7XG5cdFx0XHRcdFx0XHRmaWVsZC5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7IC8vIEFkZCB0aGUgJ2hpZGUnIGNsYXNzIHRvIGVhY2ggZWxlbWVudFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRcblxuXHRcdFx0Y29uc3QgaGVpZ2h0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NuZi1oZWlnaHQnKTtcblx0XHRcdGNvbnN0IHdlaWdodCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzbmYtd2VpZ2h0Jyk7XG5cblx0XHRcdGlmIChkYXRhLmZpZWxkX3ggJiYgZGF0YS5maWVsZF95KSB7XG5cdFx0XHRcdGlmIChoZWlnaHQgJiYgd2VpZ2h0KSB7XG5cdFx0XHRcdFx0aGVpZ2h0LnZhbHVlID0gZGF0YS5maWVsZF95O1xuXHRcdFx0XHRcdHdlaWdodC52YWx1ZSA9IGRhdGEuZmllbGRfeDtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmIChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc25mX2hlaWdodCcpICYmIGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdzbmZfd2VpZ2h0JykpIHtcblx0XHRcdFx0aWYgKGhlaWdodCAmJiB3ZWlnaHQpIHtcblx0XHRcdFx0XHRoZWlnaHQudmFsdWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc25mX2hlaWdodCcpO1xuXHRcdFx0XHRcdHdlaWdodC52YWx1ZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdzbmZfd2VpZ2h0Jyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0d2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwic25mX2RvbmVcIikpO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKCdFcnJvcjonLCBlcnJvcik7XG5cdFx0fVxuXHR9XG5cblx0aGFuZGxlRmluaXNoQnRuKCkge1xuXHRcdGNvbnN0IGZpbmlzaEJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaXplYW5kZml0X19maW5pc2gnKTtcblx0XHRjb25zdCBidXlCdXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYWlyLWJ1eScpO1xuXHRcdGNvbnN0IHNpemVBbmRGaXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2l6ZWFuZGZpdCcpO1xuXG5cdFx0ZmluaXNoQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoXG5cdFx0XHQnY2xpY2snLFxuXHRcdFx0KGUpID0+IHtcblx0XHRcdFx0ZS5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRjb25zdCBzaXplTkZpdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaXplYW5kZml0Jyk7XG5cdFx0XHRcdGNvbnN0IGJhY2tkcm9wQmx1ciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5iYWNrZHJvcCcpO1xuXG5cdFx0XHRcdFNpemVBbmRGaXQuc2hvd0dlbmVyYXRlZFNpemUoKTtcblxuXHRcdFx0XHRidXlCdXR0b24uY2xpY2soKTtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX3N0ZXAnLCAnMScpO1xuXHRcdFx0XHRmaW5pc2hCdXR0b24uY2xhc3NMaXN0LmFkZCgnaGlkZScpO1xuXHRcdFx0XHRzaXplQW5kRml0LmNsYXNzTGlzdC5yZW1vdmUoJ2Zyb20tcGRwJyk7XG5cblx0XHRcdFx0YmFja2Ryb3BCbHVyLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRzaXplTkZpdC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdH0sXG5cdFx0XHR7IG9uY2U6IHRydWUgfVxuXHRcdCk7XG5cdH1cbn1cbiIsImltcG9ydCBTaW1wbGVTbGlkZXIgZnJvbSBcIi4uLy4uL3ZpZXdzL3Byb2R1Y3Qvc2ltcGxlX3NsaWRlclwiO1xuXG5sZXQgYW5pbWF0aW5nID0gZmFsc2U7XG5sZXQgZGVjaXNpb25WYWwgPSA4MDtcbmxldCBwdWxsRGVsdGFYID0gMDtcbmxldCBzdGFydFggPSAwO1xubGV0ICRjYXJkO1xubGV0IF90aGlzO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3R5bGVBZHZpc29yIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5pbml0X2V2ZW50cygpXG5cbiAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RhdGVwaWNrZXInKSkge1xuICAgICAgdGhpcy5pbml0Q2FsZW5kYXIoKTtcbiAgICB9XG4gIH1cblxuICBpbml0X2V2ZW50cygpIHtcbiAgICBjb25zdCBiYWNrZHJvcEJsdXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJhY2tkcm9wXCIpXG4gICAgY29uc3Qgc3R5bGVhZHZpc29yID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdHlsZWFkdmlzb3JcIilcbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiLlN0eWxlQWR2aWNlVHJpZ2dlclwiLCBcImNsaWNrXCIsIChldmVudCwgZWxlbWVudCkgPT4ge1xuXG4gICAgICBpZiAoc2Vzc2lvblN0b3JhZ2UpIHtcbiAgICAgICAgdGhpcy51dWlkID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShcInN0eWxlX3V1aWRcIik7XG4gICAgICAgIGlmICghdGhpcy51dWlkKSB7XG4gICAgICAgICAgdGhpcy51dWlkID0gdGhpcy51dWlkdjQoKTtcbiAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFwic3R5bGVfdXVpZFwiLCB0aGlzLnV1aWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHlsZUNvdW50ZXIgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFwic3R5bGVfY291bnRlclwiKTtcblxuICAgICAgICBpZiAoIXRoaXMuc3R5bGVDb3VudGVyKSB7XG4gICAgICAgICAgdGhpcy5zdHlsZUNvdW50ZXIgPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9yZWRfc3R5bGVfdHlwZSA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oXCJzdHlsZV90eXBlXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mKF9pbWJveCkgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgX2ltYm94LnB1c2goWydoaWRlTGF1bmNoZXInXSk7XG4gICAgICAgIF9pbWJveC5wdXNoKFsnaGlkZVdpZGdldCddKTtcbiAgICAgIH1cblxuICAgICAgc3R5bGVhZHZpc29yLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcbiAgICAgIGlmIChzdHlsZWFkdmlzb3IuaGFzQXR0cmlidXRlKFwiZGF0YS1zdGVwXCIpKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPSBzdHlsZWFkdmlzb3IuZGF0YXNldC5zdGVwO1xuICAgICAgICBpZiAoc3RlcCA9PT0gXCIyXCIgfHwgc3RlcCA9PT0gXCIzXCIpIHtcbiAgICAgICAgICBzdHlsZWFkdmlzb3IuY2xhc3NMaXN0LmFkZChcImxpdmVcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJhY2tkcm9wQmx1ci5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpXG4gICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoXCJzdHlsZWFkdmlzb3JcIilcbiAgICAgIGlmICghc3R5bGVhZHZpc29yLmRhdGFzZXQuc3RlcCkge1xuICAgICAgICBpZiAodGhpcy5zdG9yZWRfc3R5bGVfdHlwZSkge1xuICAgICAgICAgIHRoaXMuZ2V0Q29udGVudCg0LCAxKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMuZ2V0Q29udGVudCgxKVxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5zdHlsZWFkdmlzb3IgLnNuYXBwaW5nLS13cmFwcGVyXCIpLmxlbmd0aCkge1xuICAgICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuc3R5bGVhZHZpc29yIC5zbmFwcGluZy0td3JhcHBlclwiKS5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgICAgICBuZXcgU2ltcGxlU2xpZGVyKGVsZW0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiLm1lbnVfX3N0eWxlYWR2aWNlciBhXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoc2Vzc2lvblN0b3JhZ2UpIHtcbiAgICAgICAgdGhpcy51dWlkID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShcInN0eWxlX3V1aWRcIik7XG4gICAgICAgIGlmICghdGhpcy51dWlkKSB7XG4gICAgICAgICAgdGhpcy51dWlkID0gdGhpcy51dWlkdjQoKTtcbiAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFwic3R5bGVfdXVpZFwiLCB0aGlzLnV1aWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdHlsZUNvdW50ZXIgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFwic3R5bGVfY291bnRlclwiKTtcblxuICAgICAgICBpZiAoIXRoaXMuc3R5bGVDb3VudGVyKSB7XG4gICAgICAgICAgdGhpcy5zdHlsZUNvdW50ZXIgPSAxO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdG9yZWRfc3R5bGVfdHlwZSA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oXCJzdHlsZV90eXBlXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mKF9pbWJveCkgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgX2ltYm94LnB1c2goWydoaWRlTGF1bmNoZXInXSk7XG4gICAgICAgIF9pbWJveC5wdXNoKFsnaGlkZVdpZGdldCddKTtcbiAgICAgIH1cblxuICAgICAgc3R5bGVhZHZpc29yLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcbiAgICAgIFxuICAgICAgaWYgKHN0eWxlYWR2aXNvci5oYXNBdHRyaWJ1dGUoXCJkYXRhLXN0ZXBcIikpIHtcbiAgICAgICAgY29uc3Qgc3RlcCA9IHN0eWxlYWR2aXNvci5kYXRhc2V0LnN0ZXA7XG4gICAgICAgIGlmIChzdGVwID09PSBcIjJcIiB8fCBzdGVwID09PSBcIjNcIikge1xuICAgICAgICAgIHN0eWxlYWR2aXNvci5jbGFzc0xpc3QuYWRkKFwibGl2ZVwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYmFja2Ryb3BCbHVyLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcInN0eWxlYWR2aXNvclwiKVxuICAgICAgaWYgKCFzdHlsZWFkdmlzb3IuZGF0YXNldC5zdGVwKSB7XG4gICAgICAgIGlmICh0aGlzLnN0b3JlZF9zdHlsZV90eXBlKSB7XG4gICAgICAgICAgdGhpcy5nZXRDb250ZW50KDQsIDEpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5nZXRDb250ZW50KDEpXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3R5bGVBZHZpc29yU2xpZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICBcIi5zdHlsZWFkdmlzb3IgLnNuYXBwaW5nLS13cmFwcGVyXCJcbiAgICAgICAgKVxuXG4gICAgICAgIGlmIChzdHlsZUFkdmlzb3JTbGlkZXIpIHtcbiAgICAgICAgICBuZXcgU2ltcGxlU2xpZGVyKHN0eWxlQWR2aXNvclNsaWRlcilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiLmNvbnRpbnVlUG9wIC5yZXN0YXJ0LCAuU3R5bGVBZHZpY2VSZXN0YXJ0XCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICB0aGlzLmN1cnJlbnRTbGlkZSA9IDE7XG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRTbGlkZSgpO1xuXG4gICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmJyYW5kc19saXN0X2JyYW5kLi0tY2hlY2tlZFwiKS5mb3JFYWNoKChlbGVtKSA9PiB7XG4gICAgICAgIGVsZW0uY2xhc3NMaXN0LnJlbW92ZShcIi0tY2hlY2tlZFwiKTtcbiAgICAgIH0pO1xuICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuYnJhbmRfY29udGludWUgLnN0eWxlYWR2aXNvcl9fY29udGludWVcIikubGVuZ3RoKSB7XG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuYnJhbmRfY29udGludWUgLnN0eWxlYWR2aXNvcl9fY29udGludWVcIilbMF0uY2xhc3NMaXN0LmFkZChcIi0tZGlzYWJsZWRcIik7XG4gICAgICB9XG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdHlsZWFkdmlzb3JfX3N0ZXAnKS5mb3JFYWNoKChpdGVtKT0+e1xuICAgICAgICBpZihpdGVtLmRhdGFzZXQuc3RlcCA9PT0gJzQnKXtcbiAgICAgICAgICBpdGVtLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5nZXRDb250ZW50KDEsIDAsIDEpXG4gICAgICBzdHlsZWFkdmlzb3IuY2xhc3NMaXN0LnJlbW92ZShcImxpdmVcIilcbiAgICB9KVxuXG4gICAgd2luZG93LmxpdmVFdmVudChcIi5jb250aW51ZVBvcCAuY29udGludWVcIiwgXCJjbGlja1wiLCAoZXZlbnQsIGVsZW1lbnQpID0+IHtcbiAgICAgIHN0eWxlYWR2aXNvci5jbGFzc0xpc3QucmVtb3ZlKFwibGl2ZVwiKVxuICAgIH0pXG5cbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiLnN0eWxlYWR2aXNvcl9iYWNrXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBzdHlsZWFkdmlzb3IgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInN0eWxlYWR2aXNvclwiKVxuICAgICAgdGhpcy5nZXRDb250ZW50KHBhcnNlSW50KHN0eWxlYWR2aXNvci5kYXRhc2V0LnN0ZXApIC0gMSlcbiAgICB9KVxuXG4gICAgd2luZG93LmxpdmVFdmVudChcIi5zdHlsZWFkdmlzb3JfX2hlYWRlciAuY2xvc2UsIC5wZXJzb25saXplZENvbnRlbnQgLmNtX2FydGljbGVfd3JhcHBlciBhXCIsIFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZihfaW1ib3gpICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIF9pbWJveC5wdXNoKFsnc2hvd0xhdW5jaGVyJ10pXG4gICAgICB9XG4gICAgICBzdHlsZWFkdmlzb3IuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKVxuICAgICAgYmFja2Ryb3BCbHVyLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIilcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcInN0eWxlYWR2aXNvclwiKVxuICAgICAgaWYgKHNlc3Npb25TdG9yYWdlKSB7XG4gICAgICAgIHRoaXMudGVzdF9jb21wbGV0ZWQgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFwidGVzdF9jb21wbGV0ZWRcIik7XG4gICAgICAgIGlmICh0aGlzLnRlc3RfY29tcGxldGVkICYmIHRoaXMudGVzdF9jb21wbGV0ZWQgIT09ICcnKSB7XG4gICAgICAgICAgbG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcInRlc3RfY29tcGxldGVkXCIsIFwiXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcblxuICAgIHdpbmRvdy5saXZlRXZlbnQoXCIuc3R5bGVhZHZpc29yX19jb250aW51ZVwiLCBcImNsaWNrXCIsIChldmVudCwgZWxlbWVudCkgPT4ge1xuICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKFwiLS1kaXNhYmxlZFwiKSkgcmV0dXJuXG4gICAgICB2YXIgc3RlcD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc3R5bGVhZHZpc29yX19zdGVwLi0tYWN0aXZlJykuZGF0YXNldC5zdGVwO1xuICAgICAgaWYoc3RlcCA9PT0gXCIxXCIpIHtcbiAgICAgICAgaWYgKHNlc3Npb25TdG9yYWdlKSB7XG4gICAgICAgICAgdGhpcy5zdHlsZUNvdW50ZXIrKztcbiAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFwic3R5bGVfY291bnRlclwiLCB0aGlzLnN0eWxlQ291bnRlcik7XG4gICAgICAgIH1cbiAgICAgICAgZXhwb25lYS50cmFjaygnc3R5bGVfZXZlbnQnLCB7J2FjdGlvbic6ICdzdGFydCcsJ3R5cGUnOiAnc3R5bGVhZHZpc29yJywnc3R5bGVydW4nOiB0aGlzLnV1aWQgKyBcIl9cIiArIHRoaXMuc3R5bGVDb3VudGVyfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGVwID09PSBcIjNcIilcbiAgICAgIHtcbiAgICAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwic3R5bGVhZHZpc29yX19sb2FkaW5nX3BhZ2VXcmFwcGVyXCIpWzBdLnN0eWxlLmRpc3BsYXkgPT09ICdub25lJylcbiAgICAgICAgIHtcbiAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImJyYW5kc19saXN0XCIpWzBdLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImJyYW5kX2NvbnRpbnVlXCIpWzBdLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInN0eWxlYWR2aXNvcl9fbG9hZGluZ19wYWdlV3JhcHBlclwiKVswXS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICAgICB0aGlzLmxvYWRpbmdfc3RhcnQoKTtcbiAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3R5bGVhZHZpc29yID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJzdHlsZWFkdmlzb3JcIilcbiAgICAgIHRoaXMuZ2V0Q29udGVudChwYXJzZUludChzdHlsZWFkdmlzb3IuZGF0YXNldC5zdGVwKSArIDEpXG4gICAgfSlcblxuICAgIC8qIFNXSVBFIEZVTktUSU9OQUxJVEVUICovXG4gICAgLy8gd2luZG93LmxpdmVFdmVudChcIi5zdHlsZWFkdmlzb3Jfc3dpcGVcIiwgXCJtb3VzZWRvd25cIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgLy8gIGlmIChldmVudC5idXR0b25zID09IDEpIHtcbiAgICAvLyAgICB0aGlzLnN3aXBlSGFuZGxlcihldmVudCwgZWxlbWVudCk7XG4gICAgLy8gIH1cbiAgICAvLyB9KTtcbiAgICAvLyB3aW5kb3cubGl2ZUV2ZW50KFwiLnN0eWxlYWR2aXNvcl9zd2lwZVwiLCBcInRvdWNoc3RhcnRcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgLy8gIHRoaXMuc3dpcGVIYW5kbGVyKGV2ZW50LCBlbGVtZW50KTtcbiAgICAvLyB9KTtcblxuICAgIHdpbmRvdy5saXZlRXZlbnQoXCIuc3R5bGVhZHZpc29yX2JyYW5kXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuc3R5bGVhZHZpc29yX2JyYW5kLi0tY2hlY2tlZFwiKS5sZW5ndGggPCA4MDAgfHxcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoXCItLWNoZWNrZWRcIilcbiAgICAgICkge1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoXCItLWNoZWNrZWRcIilcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hlY2tlZEJyYW5kcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIFwiLnN0eWxlYWR2aXNvcl9icmFuZC4tLWNoZWNrZWRcIlxuICAgICAgKS5sZW5ndGhcbiAgICAgIGlmIChjaGVja2VkQnJhbmRzID49IDIpIHtcbiAgICAgICAgdGhpcy50b2dnbGVDb250aW51ZUJ1dHRvbigwKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50b2dnbGVDb250aW51ZUJ1dHRvbigxKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiI3N0eWxlYWR2aXNvcl9saWtlXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBpZiAoIXRoaXMuYnV0dG9uc0xvY2tlZCkge1xuICAgICAgICB0aGlzLmJ1dHRvbnNMb2NrZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnRyaWdnZXJTd2lwZShldmVudCwgZWxlbWVudCwgXCJsaWtlZFwiKTtcbiAgICAgICAgdGhpcy51cGRhdGVDdXJyZW50U2xpZGUoKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIHdpbmRvdy5saXZlRXZlbnQoXCIjc3R5bGVhZHZpc29yX2Rpc2xpa2VcIiwgXCJjbGlja1wiLCAoZXZlbnQsIGVsZW1lbnQpID0+IHtcbiAgICAgIGlmICghdGhpcy5idXR0b25zTG9ja2VkKSB7XG4gICAgICAgIHRoaXMuYnV0dG9uc0xvY2tlZCA9IHRydWU7XG4gICAgICAgIHRoaXMudHJpZ2dlclN3aXBlKGV2ZW50LCBlbGVtZW50LCBcImRpc2xpa2VkXCIpO1xuICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRTbGlkZSgpO1xuICAgICAgfVxuICAgIH0pXG5cbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiLnN0eWxlYWR2aXNvcl9fbG9naW5CdG5cIiwgXCJjbGlja1wiLCAoZXZlbnQsIGVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHN0eWxlYWR2aXNvcl9sb2dpbl9mb3JtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXG4gICAgICAgIFwic3R5bGVhZHZpc29yLWxvZ2luLWZvcm0td3JhcHBlclwiXG4gICAgICApXG4gICAgICBpZiAoc3R5bGVhZHZpc29yX2xvZ2luX2Zvcm0pIHtcbiAgICAgICAgc3R5bGVhZHZpc29yX2xvZ2luX2Zvcm0uY2xhc3NMaXN0LnRvZ2dsZShcImhpZGRlblwiKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICB3aW5kb3cubGl2ZUV2ZW50KFwiI3N0eWxlYWR2aXNvci1sb2dpbi1mb3JtLXdyYXBwZXIgLmNsb3NlXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBzdHlsZWFkdmlzb3JfbG9naW5fZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxuICAgICAgICBcInN0eWxlYWR2aXNvci1sb2dpbi1mb3JtLXdyYXBwZXJcIlxuICAgICAgKVxuICAgICAgc3R5bGVhZHZpc29yX2xvZ2luX2Zvcm0uY2xhc3NMaXN0LnRvZ2dsZShcImhpZGRlblwiKVxuICAgIH0pXG4gICAgd2luZG93LmxpdmVFdmVudChcIiNzdHlsZWFkdmlzb3JfX2NyZWF0ZXByb2ZpbGUgLmNsb3NlXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBzdHlsZWFkdmlzb3JfbG9naW5fZm9ybSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFxuICAgICAgICBcInN0eWxlYWR2aXNvcl9fY3JlYXRlcHJvZmlsZVwiXG4gICAgICApXG4gICAgICBzdHlsZWFkdmlzb3JfbG9naW5fZm9ybS5jbGFzc0xpc3QudG9nZ2xlKFwiaGlkZGVuXCIpXG4gICAgfSlcblxuICAgIHdpbmRvdy5saXZlRXZlbnQoXCIjc3R5bGVhZHZpc29yLWxvZ2luLWZvcm1cIiwgXCJzdWJtaXRcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICB0aGlzLmxvZ2luKGVsZW1lbnQpXG4gICAgfSlcblxuICAgIHdpbmRvdy5saXZlRXZlbnQoXCIjc3R5bGVhZHZpc29yLWNyZWF0ZS1mb3JtXCIsIFwic3VibWl0XCIsIChldmVudCwgZWxlbWVudCkgPT4ge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgdGhpcy5jcmVhdGVQcm9maWxlKGVsZW1lbnQpXG4gICAgfSlcblxuICAgIHdpbmRvdy5saXZlRXZlbnQoXCIjc3R5bGVhZHZpc29yX19jcmVhdGVcIiwgXCJrZXl1cFwiLCAoZXZlbnQsIGVsZW1lbnQpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgL14oW2EtekEtWjAtOV9cXC5cXC1dKStcXEAoKFthLXpBLVowLTlcXC1dKStcXC4pKyhbYS16QS1aMC05XXsyLDR9KSskLy50ZXN0KFxuICAgICAgICAgIGVsZW1lbnQudmFsdWVcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlQ29udGludWVCdXR0b24oMClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudG9nZ2xlQ29udGludWVCdXR0b24oMSlcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgYXN5bmMgZ2V0Q29udGVudChzdGVwLCByZXN0b3JpbmcsIHJlc3RhcnQpIHtcbiAgICBjb25zdCBzdHlsZWFkdmlzb3IgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInN0eWxlYWR2aXNvclwiKVxuICAgIHN0eWxlYWR2aXNvci5jbGFzc0xpc3QuYWRkKFwibG9hZGluZ1wiKVxuXG4gICAgaWYgKHN0ZXAgPT0gMSAmJiAhcmVzdG9yaW5nICYmICFyZXN0YXJ0KVxuICAgIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcbiAgICAgICAgICBcInNob3A/ZnVuaz1nZXRfcmVzdG9yaW5nX3N0eWxlJmN1c3RvbV9mdW5jPTFcIlxuICAgICAgICApXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuICAgICAgICBpZiAocmVzdWx0LnJlc3RvcmluZ19zdHlsZV90eXBlKSB7XG4gICAgICAgICAgc3RlcCA9IDQ7XG4gICAgICAgICAgcmVzdG9yaW5nID0gMTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcmVzdG9yaW5nKVxuICAgIHtcbiAgICAgIHJlc3RvcmluZyA9IDA7XG4gICAgfVxuXG4gICAgaWYgKHN0ZXAgPT0gNCAmJiAhcmVzdG9yaW5nKSB7XG4gICAgICB0aGlzLnNhdmVfc3R5bGVhZHZpc29yKDEpO1xuICAgIH1cblxuICAgIGxldCBleGlzdGluZ19zdGVwID0gc3R5bGVhZHZpc29yLnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAnLnN0eWxlYWR2aXNvcl9fc3RlcFtkYXRhLXN0ZXA9XCInICsgc3RlcCArICdcIl0nXG4gICAgKVxuICAgIGlmIChleGlzdGluZ19zdGVwKSB7XG4gICAgICBkb2N1bWVudFxuICAgICAgICAucXVlcnlTZWxlY3RvckFsbChcIi5zdHlsZWFkdmlzb3JfX3N0ZXAuLS1hY3RpdmVcIilcbiAgICAgICAgLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWFjdGl2ZVwiKVxuICAgICAgICB9KVxuICAgICAgZXhpc3Rpbmdfc3RlcC5jbGFzc0xpc3QuYWRkKFwiLS1hY3RpdmVcIilcbiAgICAgIHN0eWxlYWR2aXNvci5kYXRhc2V0LnN0ZXAgPSBzdGVwXG5cbiAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuc3R5bGVhZHZpc29yX3N3aXBlXCIpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiLS1saWtlZFwiKVxuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWRpc2xpa2VkXCIpXG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcIi0tY3VycmVudFwiKVxuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShcInN0eWxlXCIsIFwiXCIpXG4gICAgICB9KVxuICAgICAgc3R5bGVhZHZpc29yLmNsYXNzTGlzdC5yZW1vdmUoXCJsb2FkaW5nXCIpXG4gICAgICBpZiAoc3RlcCA9PT0gMylcbiAgICAgIHtcbiAgICAgICAgIC8vIFJlc2V0IHRoZSBjb3VudGVyIGlmIGl0cyB2aXNpYmxlXG4gICAgICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInN0eWxlYWR2aXNvcl9fbG9hZGluZ19wYWdlV3JhcHBlclwiKVswXS5zdHlsZS5kaXNwbGF5ID09PSAnYmxvY2snKVxuICAgICAgICAge1xuICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiYnJhbmRzX2xpc3RcIilbMF0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJicmFuZF9jb250aW51ZVwiKVswXS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcbiAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInN0eWxlYWR2aXNvcl9fbG9hZGluZ19wYWdlV3JhcHBlclwiKVswXS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJwcm9ncmVzc1wiKVswXS5zdHlsZS53aWR0aCA9IFwiMCVcIjtcbiAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInBlcmNlbnRhZ2VcIilbMF0uaW5uZXJIVE1MID0gXCIwJVwiO1xuICAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFxuICAgICAgICBcInNob3A/ZnVuaz1nZXRfc3R5bGVfYWR2aXNvciZjdXN0b21fZnVuYz0xJnN0ZXA9XCIgKyBzdGVwICsgXCImcmVzdG9yaW5nPVwiICsgcmVzdG9yaW5nXG4gICAgICApXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKClcblxuICAgICAgaWYgKHJlc3VsdC5odG1sKSB7XG4gICAgICAgIHZhciBuZXdFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKVxuICAgICAgICBuZXdFbGVtZW50LmNsYXNzTmFtZSA9IFwic3R5bGVhZHZpc29yX19zdGVwIC0tYWN0aXZlXCJcbiAgICAgICAgbmV3RWxlbWVudC5kYXRhc2V0LnN0ZXAgPSBzdGVwXG4gICAgICAgIG5ld0VsZW1lbnQuaW5uZXJIVE1MID0gcmVzdWx0Lmh0bWxcblxuICAgICAgICBkb2N1bWVudFxuICAgICAgICAgIC5xdWVyeVNlbGVjdG9yQWxsKFwiLnN0eWxlYWR2aXNvcl9fc3RlcC4tLWFjdGl2ZVwiKVxuICAgICAgICAgIC5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWFjdGl2ZVwiKVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgc3R5bGVhZHZpc29yLmFwcGVuZENoaWxkKG5ld0VsZW1lbnQpXG4gICAgICAgIHN0eWxlYWR2aXNvci5kYXRhc2V0LnN0ZXAgPSBzdGVwXG5cbiAgICAgICAgaWYgKHN0ZXAgPT0gMikge1xuICAgICAgICAgICAgLy8gU2V0IHRoZSB0b3RhbCBudW1iZXIgb2Ygc2xpZGVzXG4gICAgICAgICAgICB0aGlzLnRvdGFsU2xpZGVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInN0eWxlYWR2aXNvcl9zd2lwZVwiKS5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTbGlkZSA9IDE7XG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNhLXRvdGFsU2xpZGVzXCIpLmlubmVySFRNTCA9IHRoaXMudG90YWxTbGlkZXM7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRTbGlkZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHN0ZXAgPT0gNCAmJiAhcmVzdG9yaW5nKSB7XG4gICAgICAgICAgdmFyIGVycm9yX2Rpc3BsYXkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInN0eWxlX2Fkdmlzb3JfZXJyb3JcIik7XG4gICAgICAgICAgaWYgKGVycm9yX2Rpc3BsYXkgJiYgd2luZG93LmdldENvbXB1dGVkU3R5bGUoZXJyb3JfZGlzcGxheSkuZGlzcGxheSA9PT0gJ2Jsb2NrJylcbiAgICAgICAgICB7XG4gICAgICAgICAgICAvLyBlcnJvclxuICAgICAgICAgICAgZXhwb25lYS50cmFjaygnc3R5bGVfZXZlbnQnLCB7J2FjdGlvbic6ICdlcnJvcicsJ3R5cGUnOiAnc3R5bGVhZHZpc29yJywncGFyYW1ldGVyJzogJ25vX3NlZ21lbnQnfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICB7XG4gICAgICAgICAgICAvLyByZXN1bHRfcGFnZVxuICAgICAgICAgICAgZXhwb25lYS50cmFjaygnc3R5bGVfZXZlbnQnLCB7J2FjdGlvbic6ICdyZXN1bHRfcGFnZScsJ3R5cGUnOiAnc3R5bGVhZHZpc29yJywnc3R5bGVydW4nOiB0aGlzLnV1aWQgKyBcIl9cIiArIHRoaXMuc3R5bGVDb3VudGVyLCAncGFyYW1ldGVyJzogcmVzdWx0LnN0eWxlX3R5cGV9KTtcbiAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oXCJzdHlsZV90eXBlXCIsIHJlc3VsdC5zdHlsZV90eXBlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RlcCA9PSA2KVxuICAgICAgICB7XG4gICAgICAgICAgICBncmVjYXB0Y2hhLnJlbmRlcignY2FwdGNoYV9lbGVtZW50Jywge1xuICAgICAgICAgICAgICAnc2l0ZWtleScgOiAnNkxjczljWVVBQUFBQU82UldydmNYZ0tQRlVDSTg2QVJoSXNJN2M1dCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgc3R5bGVhZHZpc29yLmNsYXNzTGlzdC5yZW1vdmUoXCJsb2FkaW5nXCIpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbG9hZGluZ19zdGFydCgpIHtcbiAgICB2YXIgaW50ZXJ2YWw7XG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB2YXIgcHJvZ3Jlc3NCYXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnByb2dyZXNzXCIpO1xuICAgIHZhciBwZXJjZW50YWdlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5wZXJjZW50YWdlXCIpO1xuICAgIGludGVydmFsID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XG4gICAgICBjb3VudCsrO1xuICAgICAgcHJvZ3Jlc3NCYXIuc3R5bGUud2lkdGggPSBjb3VudCArIFwiJVwiO1xuICAgICAgcGVyY2VudGFnZS5pbm5lckhUTUwgPSBjb3VudCArIFwiJVwiO1xuICAgICAgaWYgKGNvdW50ID09PSAxMDApIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICB9XG4gICAgfSwgNTApO1xuICB9XG5cbiAgdXBkYXRlQ3VycmVudFNsaWRlKCkge1xuICAgIGlmICh0aGlzLmN1cnJlbnRTbGlkZSA8PSB0aGlzLnRvdGFsU2xpZGVzKSB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNhLWNvdW50XCIpLmlubmVySFRNTCA9IHRoaXMuY3VycmVudFNsaWRlO1xuICAgICAgdGhpcy5jdXJyZW50U2xpZGUrKztcbiAgICB9XG4gIH1cblxuICByZWxlYXNlU2xpZGUoKSB7XG4gICAgaWYgKHB1bGxEZWx0YVggPj0gZGVjaXNpb25WYWwpIHtcbiAgICAgICRjYXJkLmNsYXNzTGlzdC5hZGQoXCItLWxpa2VkXCIpXG4gICAgICAkY2FyZC5jbGFzc0xpc3QucmVtb3ZlKFwiLS1jdXJyZW50XCIpXG4gICAgICBfdGhpcy5zY2FsZUJhY2tncm91bmRJbWFnZXMoMSlcblxuICAgICAgY29uc3Qgc2VnbWVudF9kYXRhID0gX3RoaXMuZ2V0X3NlZ21lbnRfZGF0YV9mcm9tX2VsZW1lbnQoJGNhcmQpXG4gICAgICBfdGhpcy5ibG9vbXJlYWNoX3RyYWNrKFwibGlrZWRcIiwgXCJzdHlsZV9zZWdtZW50X2ltYWdlXCIsIHNlZ21lbnRfZGF0YSlcbiAgICB9IGVsc2UgaWYgKHB1bGxEZWx0YVggPD0gLWRlY2lzaW9uVmFsKSB7XG4gICAgICAkY2FyZC5jbGFzc0xpc3QuYWRkKFwiLS1kaXNsaWtlZFwiKVxuICAgICAgJGNhcmQuY2xhc3NMaXN0LnJlbW92ZShcIi0tY3VycmVudFwiKVxuICAgICAgX3RoaXMuc2NhbGVCYWNrZ3JvdW5kSW1hZ2VzKDEpXG5cbiAgICAgIGNvbnN0IHNlZ21lbnRfZGF0YSA9IF90aGlzLmdldF9zZWdtZW50X2RhdGFfZnJvbV9lbGVtZW50KCRjYXJkKVxuICAgICAgX3RoaXMuYmxvb21yZWFjaF90cmFjayhcImRpc2xpa2VkXCIsIFwic3R5bGVfc2VnbWVudF9pbWFnZVwiLCBzZWdtZW50X2RhdGEpXG4gICAgfSBlbHNlIHtcbiAgICAgICRjYXJkLnNldEF0dHJpYnV0ZShcInN0eWxlXCIsIFwidHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApIHNjYWxlKDEpO1wiKVxuICAgICAgX3RoaXMuc2NhbGVCYWNrZ3JvdW5kSW1hZ2VzKDApXG4gICAgfVxuICAgIHB1bGxEZWx0YVggPSAwXG5cbiAgICBhbmltYXRpbmcgPSBmYWxzZVxuXG4gICAgaWYgKFxuICAgICAgIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgIFwiLnN0eWxlYWR2aXNvcl9zd2lwZTpub3QoLi0tbGlrZWQsIC4tLWRpc2xpa2VkKVwiXG4gICAgICApLmxlbmd0aFxuICAgICkge1xuICAgICAgX3RoaXMuZ2V0Q29udGVudCgzKVxuICAgIH1cbiAgfVxuXG4gIHN3aXBlSGFuZGxlcihlLCBlbGVtZW50KSB7XG4gICAgaWYgKGFuaW1hdGluZykgcmV0dXJuXG5cbiAgICAkY2FyZCA9IGVsZW1lbnRcbiAgICAkY2FyZC5jbGFzc0xpc3QuYWRkKFwiLS1jdXJyZW50XCIpXG4gICAgc3RhcnRYID0gZS5wYWdlWCB8fCBlLm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXS5wYWdlWFxuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLmhhbmRsZU1vdmUsIHRydWUpXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCB0aGlzLmhhbmRsZU1vdmUsIHRydWUpXG5cbiAgICBfdGhpcyA9IHRoaXNcblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuaGFuZGxlUmVsZWFzZSwgdHJ1ZSlcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5oYW5kbGVSZWxlYXNlLCB0cnVlKVxuICB9XG4gIC8qIFNXSVBFIEZVTktUSU9OQUxJVEVUICovXG4gIC8vIGhhbmRsZU1vdmUoZSkge1xuICAvLyAgbGV0IHggPSBlLnBhZ2VYIHx8IGUub3JpZ2luYWxFdmVudC50b3VjaGVzWzBdLnBhZ2VYO1xuICAvLyAgcHVsbERlbHRhWCA9ICh4IC0gc3RhcnRYKTtcbiAgLy8gIGlmICghcHVsbERlbHRhWCkgcmV0dXJuO1xuXG4gIC8vICBsZXQgcGVyY2VudCA9IHB1bGxEZWx0YVggPCAxID8gcHVsbERlbHRhWCAvIDM1MCAqIC0xIDogcHVsbERlbHRhWCAvIDM1MCAqIDE7XG5cbiAgLy8gIGFuaW1hdGluZyA9IHRydWU7XG4gIC8vICBsZXQgZGVnID0gcHVsbERlbHRhWCAvIDEwO1xuICAvLyAgJGNhcmQuc3R5bGUudHJhbnNmb3JtID0gXCJ0cmFuc2xhdGVYKFwiICsgcHVsbERlbHRhWCArIFwicHgpIHRyYW5zbGF0ZVkoMHB4KSBzY2FsZSgxKSByb3RhdGUoXCIgKyBkZWcgKyBcImRlZylcIjtcblxuICAvLyAgbGV0IG9wYWNpdHkgPSBwdWxsRGVsdGFYIDwgMCA/IChwdWxsRGVsdGFYIC8gMTAwICogLTEpIDogcHVsbERlbHRhWCAvIDEwMDtcbiAgLy8gICRjYXJkLnN0eWxlLm9wYWNpdHkgPSAxIC0gb3BhY2l0eSAqIDAuMztcbiAgLy8gICRjYXJkLmNsYXNzTGlzdC5hZGQoXCItLWN1cnJlbnRcIik7XG5cbiAgLy8gIF90aGlzLnNjYWxlQmFja2dyb3VuZEltYWdlcyhwZXJjZW50KTtcbiAgLy8gfVxuXG4gIC8vIGhhbmRsZVJlbGVhc2UoZSkge1xuICAvLyAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCBfdGhpcy5oYW5kbGVNb3ZlLCB0cnVlKTtcbiAgLy8gIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgX3RoaXMuaGFuZGxlTW92ZSwgdHJ1ZSk7XG4gIC8vICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBfdGhpcy5oYW5kbGVSZWxlYXNlLCB0cnVlKTtcbiAgLy8gIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBfdGhpcy5oYW5kbGVSZWxlYXNlLCB0cnVlKTtcblxuICAvLyAgX3RoaXMucmVsZWFzZVNsaWRlKCk7XG4gIC8vIH1cblxuICB0cmlnZ2VyU3dpcGUoZSwgZWxlbWVudCwgdHlwZSkge1xuICAgIGNvbnN0IGN1cnJlbnRJbWFnZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBcIi5zdHlsZWFkdmlzb3Jfc3dpcGU6bm90KC4tLWxpa2VkLCAuLS1kaXNsaWtlZClcIlxuICAgIClbMF1cbiAgICBpZiAoIWN1cnJlbnRJbWFnZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY3VycmVudEltYWdlLmNsYXNzTGlzdC5hZGQoXCItLWN1cnJlbnRcIilcblxuICAgIF90aGlzID0gdGhpc1xuICAgIGxldCBjb3VudGVyID0gMFxuICAgIGxldCBzd2lwZUludGVydmFsID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuICAgICAgY291bnRlcisrXG5cbiAgICAgIGxldCBwdWxsRGVsdGFYID0gdHlwZSA9PSBcImxpa2VkXCIgPyBjb3VudGVyICogNSA6IGNvdW50ZXIgKiAtNVxuXG4gICAgICBsZXQgZGVnID0gcHVsbERlbHRhWCAvIDEwXG4gICAgICBsZXQgb3BhY2l0eSA9IHB1bGxEZWx0YVggPCAwID8gKHB1bGxEZWx0YVggLyAxMDApICogLTEgOiBwdWxsRGVsdGFYIC8gMTAwXG5cbiAgICAgIGN1cnJlbnRJbWFnZS5zdHlsZS50cmFuc2Zvcm0gPVxuICAgICAgICBcInRyYW5zbGF0ZVgoXCIgK1xuICAgICAgICBwdWxsRGVsdGFYICtcbiAgICAgICAgXCJweCkgdHJhbnNsYXRlWSgwcHgpIHNjYWxlKDEpIHJvdGF0ZShcIiArXG4gICAgICAgIGRlZyArXG4gICAgICAgIFwiZGVnKVwiXG4gICAgICBjdXJyZW50SW1hZ2Uuc3R5bGUub3BhY2l0eSA9IDEgLSBvcGFjaXR5ICogMC4zXG5cbiAgICAgIGlmIChjb3VudGVyID09IDEwMCkge1xuICAgICAgICBjbGVhckludGVydmFsKHN3aXBlSW50ZXJ2YWwpXG4gICAgICAgIGN1cnJlbnRJbWFnZS5jbGFzc0xpc3QuYWRkKFwiLS1cIiArIHR5cGUpXG4gICAgICAgIGNvbnN0IHNlZ21lbnRfZGF0YSA9IF90aGlzLmdldF9zZWdtZW50X2RhdGFfZnJvbV9lbGVtZW50KGN1cnJlbnRJbWFnZSlcbiAgICAgICAgX3RoaXMuYmxvb21yZWFjaF90cmFjayh0eXBlLCBcInN0eWxlX3NlZ21lbnRfaW1hZ2VcIiwgc2VnbWVudF9kYXRhKVxuXG4gICAgICAgIF90aGlzLmJ1dHRvbnNMb2NrZWQgPSBmYWxzZTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICAgICAgICBcIi5zdHlsZWFkdmlzb3Jfc3dpcGU6bm90KC4tLWxpa2VkLCAuLS1kaXNsaWtlZClcIlxuICAgICAgICAgICkubGVuZ3RoXG4gICAgICAgICkge1xuICAgICAgICAgIF90aGlzLmdldENvbnRlbnQoMylcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgX3RoaXMuc2NhbGVCYWNrZ3JvdW5kSW1hZ2VzKGNvdW50ZXIgLyA1KVxuICAgIH0sIDApXG4gIH1cblxuICBzY2FsZUJhY2tncm91bmRJbWFnZXMocGVyY2VudCkge1xuICAgIGNvbnN0IGFjdGl2ZUltYWdlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXG4gICAgICBcIi5zdHlsZWFkdmlzb3Jfc3dpcGU6bm90KC4tLWxpa2VkLCAuLS1kaXNsaWtlZCwgLi0tY3VycmVudClcIlxuICAgIClcblxuICAgIGxldCBzY2FsZV9kcmFnID0gMC4xICogcGVyY2VudFxuICAgIGxldCB0cmFuc2xhdGVfZHJhZyA9IDIgKiBwZXJjZW50XG4gICAgbGV0IG9wYWNpdHlfZHJhZyA9IDAuMyAqIHBlcmNlbnRcblxuICAgIGxldCBzY2FsZUluY3JlbWVudCA9IHNjYWxlX2RyYWcgPiAwLjEgPyAxIDogMC45ICsgc2NhbGVfZHJhZ1xuICAgIGxldCB0cmFuc2Zvcm0gPSB0cmFuc2xhdGVfZHJhZyA+IDIgPyAwIDogMiAtIHRyYW5zbGF0ZV9kcmFnXG4gICAgbGV0IG9wYWNpdHkgPSBvcGFjaXR5X2RyYWcgPiAwLjMgPyAxIDogMC43ICsgb3BhY2l0eV9kcmFnXG5cbiAgICBhY3RpdmVJbWFnZXMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPVxuICAgICAgICBcInRyYW5zbGF0ZVkoXCIgKyB0cmFuc2Zvcm0gKyBcInB4KSBzY2FsZShcIiArIHNjYWxlSW5jcmVtZW50ICsgXCIpXCJcbiAgICAgIGVsZW1lbnQuc3R5bGUub3BhY2l0eSA9IG9wYWNpdHlcblxuICAgICAgc2NhbGVJbmNyZW1lbnQgPSBzY2FsZUluY3JlbWVudCAtIDAuMVxuICAgICAgdHJhbnNmb3JtID0gdHJhbnNmb3JtICsgMlxuICAgICAgb3BhY2l0eSA9IG9wYWNpdHkgPiAwLjQgPyBvcGFjaXR5IC0gMC40IDogMFxuICAgIH0pXG4gIH1cblxuICBibG9vbXJlYWNoX3RyYWNrKGxpa2VfdHlwZSwgZXZlbnRfdHlwZSwgc2VnbWVudF9kYXRhLCB0aXRsZSkge1xuICAgIGlmICghd2luZG93LmV4cG9uZWEpIHJldHVybjtcblxuICAgIHdpbmRvdy5leHBvbmVhLnRyYWNrKFwic3R5bGVfZXZlbnRcIiwge1xuICAgICAgdHlwZTogXCJzdHlsZWFkdmlzb3JcIixcbiAgICAgIGFjdGlvbjogbGlrZV90eXBlID09IFwibGlrZWRcIiA/IFwibGlrZVwiIDogXCJkaXNsaWtlXCIsXG4gICAgICBwYXJhbWV0ZXI6IGV2ZW50X3R5cGUsXG4gICAgICB0aXRsZTogc2VnbWVudF9kYXRhLnRpdGxlLFxuICAgICAgc3R5bGVfc2VnbWVudF8xOiBzZWdtZW50X2RhdGEuc2VnbWVudF8xLFxuICAgICAgc3R5bGVfc2VnbWVudF8yOiBzZWdtZW50X2RhdGEuc2VnbWVudF8yLFxuICAgICAgc3R5bGVfc2VnbWVudF8zOiBzZWdtZW50X2RhdGEuc2VnbWVudF8zLFxuICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgc3R5bGVydW46IHRoaXMudXVpZCArICdfJyArIHRoaXMuc3R5bGVDb3VudGVyXG4gICAgfSlcbiAgfVxuXG4gIGdldF9zZWdtZW50X2RhdGFfZnJvbV9lbGVtZW50KGVsZW1lbnQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6IGVsZW1lbnQuZGF0YXNldC5pZCxcbiAgICAgIHNlZ21lbnRfMTogZWxlbWVudC5kYXRhc2V0LmlkLFxuICAgICAgc2VnbWVudF8yOiBlbGVtZW50LmRhdGFzZXQuaWQsXG4gICAgICBzZWdtZW50XzM6IGVsZW1lbnQuZGF0YXNldC5pZCxcbiAgICB9XG4gIH1cblxuICBnZXRfc2VnbWVudF9kYXRhX2Zyb21fYnJhbmQoYnJhbmQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGl0bGU6IGJyYW5kLmRhdGFzZXQubmFtZSxcbiAgICAgIHNlZ21lbnRfMTogYnJhbmQuZGF0YXNldC5zZWdtZW50XzEsXG4gICAgICBzZWdtZW50XzI6IGJyYW5kLmRhdGFzZXQuc2VnbWVudF8yLFxuICAgICAgc2VnbWVudF8zOiBicmFuZC5kYXRhc2V0LnNlZ21lbnRfMyxcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2dpbihmb3JtKSB7XG4gICAgaWYgKCFmb3JtLnVzZXIudmFsdWUgJiYgIWZvcm0ucGFzcy52YWx1ZSkgcmV0dXJuXG5cbiAgICBjb25zdCBkYXRhID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhuZXcgRm9ybURhdGEoZm9ybSkpXG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFwiL3Nob3BcIiwge1xuICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIGJvZHk6IGRhdGEsXG4gICAgfSlcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuXG4gICAgaWYgKHJlc3VsdC5zdGF0dXMuY29kZSA9PSAyMDApIHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3R5bGVhZHZpc29yX19sb2dpbndyYXBwZXJcIikuc3R5bGUuZGlzcGxheSA9XG4gICAgICAgIFwibm9uZVwiXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInN0eWxlYWR2aXNvcl9fY3JlYXRld3JhcHBlclwiKS5zdHlsZS5kaXNwbGF5ID1cbiAgICAgICAgXCJub25lXCJcbiAgICAgIHRoaXMudG9nZ2xlQ29udGludWVCdXR0b24oMClcbiAgICAgIHRoaXMuc2V0TG9naW5JY29uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3R5bGVhZHZpc29yX19sb2dpbi1lcnJvclwiKS5pbm5lckhUTUwgPVxuICAgICAgICBcIkZlbCBhbnbDpG5kYXJ1cHBnaWZ0ZXJcIlxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVByb2ZpbGUoZm9ybSkge1xuICAgIGlmICghZm9ybS51c2VyLnZhbHVlKSByZXR1cm5cblxuICAgIGNvbnN0IGRhdGEgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKG5ldyBGb3JtRGF0YShmb3JtKSlcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXCIvc2hvcFwiLCB7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgYm9keTogZGF0YSxcbiAgICB9KVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpXG5cbiAgICBpZiAocmVzdWx0LnN0YXR1cyA9PSAxKSB7XG4gICAgICB0aGlzLnNhdmVfc3R5bGVhZHZpc29yKCk7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInN0eWxlYWR2aXNvcl9fY3JlYXRlcHJvZmlsZVwiKS5jbGFzc0xpc3QuYWRkKFwiaGlkZVwiKTtcblxuICAgICAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIjc3R5bGVhZHZpc29yX19sb2dpbndyYXBwZXJcIikubGVuZ3RoKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3R5bGVhZHZpc29yX19sb2dpbndyYXBwZXJcIikuY2xhc3NMaXN0LmFkZChcImhpZGVcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnNldExvZ2luSWNvbigpO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZXN1bHQuc3RhdHVzID09IDIpIHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwic3R5bGVhZHZpc29yLWNyZWF0ZS1wYXNzd29yZFwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKTtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiY3JlYXRlLWVycm9yXCIpLmlubmVySFRNTCA9IHJlc3VsdC5tZXNzYWdlO1xuICAgIH1cbiAgfVxuXG5hc3luYyBzYXZlX3N0eWxlYWR2aXNvcih0cmFjaykge1xuICBjb25zdCBicmFuZExpc3QgPSBbXTtcbiAgY29uc3Qgc2VnbWVudEltYWdlcyA9IFtdO1xuXG4gIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuc3R5bGVhZHZpc29yX2JyYW5kLi0tY2hlY2tlZFwiKS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgY29uc3Qgc2VnbWVudF9kYXRhID0gX3RoaXMuZ2V0X3NlZ21lbnRfZGF0YV9mcm9tX2JyYW5kKGVsZW1lbnQpXG4gICAgaWYgKHRyYWNrKVxuICAgIHtcbiAgICAgIF90aGlzLmJsb29tcmVhY2hfdHJhY2soXCJsaWtlZFwiLCBcImJyYW5kXCIsIHNlZ21lbnRfZGF0YSlcbiAgICB9XG4gICAgYnJhbmRMaXN0LnB1c2goZWxlbWVudC5kYXRhc2V0LmlkKTtcbiAgfSk7XG5cbiAgaWYgKHRyYWNrKVxuICB7XG4gICAgLy8gQ29tcGxldGVcbiAgICBleHBvbmVhLnRyYWNrKCdzdHlsZV9ldmVudCcsIHsnYWN0aW9uJzogJ2NvbXBsZXRlJywndHlwZSc6ICdzdHlsZWFkdmlzb3InLCdzdHlsZXJ1bic6IHRoaXMudXVpZCArIFwiX1wiICsgdGhpcy5zdHlsZUNvdW50ZXJ9KTtcbiAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFwidGVzdF9jb21wbGV0ZWRcIiwgXCJjb21wbGV0ZWRcIik7XG4gIH1cbiAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnN0eWxlYWR2aXNvcl9zd2lwZScpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICBjb25zdCBpbWdzID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW1nJyk7XG5cbiAgICBsZXQgYW5zd2VyO1xuXG4gICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCctLWRpc2xpa2VkJykpIHtcbiAgICAgIGFuc3dlciA9ICcwJztcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCctLWxpa2VkJykpIHtcbiAgICAgIGFuc3dlciA9ICcxJztcbiAgICB9XG5cbiAgICBpZiAoaW1ncy5sZW5ndGggJiYgYW5zd2VyICE9PSAnJykge1xuICAgICAgc2VnbWVudEltYWdlcy5wdXNoKHsgc2VnbWVudDogZWxlbWVudC5kYXRhc2V0LmlkLCBpbWFnZTogaW1nc1swXS5nZXRBdHRyaWJ1dGUoJ3NyYycpLCBsaWtlOiBhbnN3ZXIgfSk7XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBkYXRhID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuXG4gIGRhdGEuYXBwZW5kKCdmdW5rJywgJ3NhdmVfc3R5bGVhZHZpc29yJyk7XG4gIGRhdGEuYXBwZW5kKCdicmFuZHMnLCBKU09OLnN0cmluZ2lmeShicmFuZExpc3QpKTtcbiAgZGF0YS5hcHBlbmQoJ3NlZ21lbnRfZGF0YScsIEpTT04uc3RyaW5naWZ5KHNlZ21lbnRJbWFnZXMpKTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcCcsIHtcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBib2R5OiBkYXRhXG4gIH0pO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbn1cblxuICB0b2dnbGVDb250aW51ZUJ1dHRvbihsb2NrZWQpIHtcbiAgICBkb2N1bWVudFxuICAgICAgLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuc3R5bGVhZHZpc29yX19zdGVwLi0tYWN0aXZlIC5zdHlsZWFkdmlzb3JfX2NvbnRpbnVlXCIpXG4gICAgICAuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAobG9ja2VkKSB7XG4gICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiLS1kaXNhYmxlZFwiKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcIi0tZGlzYWJsZWRcIilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgfVxuICB0ZXN0XG5cbiAgYXN5bmMgaW5pdENhbGVuZGFyKCkge1xuICAgIC8vIDxzY3JpcHQgdHlwZT1cInRleHQvamF2YXNjcmlwdFwiIHNyYz1cIi90aGVtZXMvaHlwZWZyb250L2Rlc2lnbi9zY3JpcHQvdmFuaWxsYS1jYWxlbmRhci5taW4uanNcIj48L3NjcmlwdD5cbiAgICBsZXQgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaW5rXCIpO1xuICAgIGxpbmsuaHJlZiA9ICcvdGhlbWVzL2h5cGVmcm9udC9kZXNpZ24vY3NzL3ZhbmlsbGEtY2FsZW5kYXIubWluLmNzcyc7XG4gICAgbGluay50eXBlID0gXCJ0ZXh0L2Nzc1wiO1xuICAgIGxpbmsucmVsID0gXCJzdHlsZXNoZWV0XCI7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdLmFwcGVuZENoaWxkKGxpbmspO1xuXG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IGN1cnJEYXkgPSBkLmdldERhdGUoKTtcbiAgICBsZXQgY3Vyck1vbnRoID0gZC5nZXRNb250aCgpICsgMTtcbiAgICBsZXQgY3VyclllYXIgPSBkLmdldEZ1bGxZZWFyKCk7XG5cbiAgICBsZXQgbW9udGhMZW5ndGggPSBuZXcgRGF0ZShjdXJyWWVhciwgY3Vyck1vbnRoLCAwKS5nZXREYXRlKCk7XG5cbiAgICBpZiAoY3Vyck1vbnRoIDwgMTApIHtcbiAgICAgIGN1cnJNb250aCA9IFwiMFwiICsgY3Vyck1vbnRoO1xuICAgIH1cbiAgICBpZiAoY3VyckRheSA8IDEwKSB7XG4gICAgICBjdXJyRGF5ID0gXCIwXCIgKyBjdXJyRGF5O1xuICAgIH1cblxuICAgIGNvbnN0IHFzID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICBmdW5rOiAnU3RpbHJhZGdpdm5pbmdfUG9wdWxhdGVfQ2FsZW5kYXInLFxuICAgICAgeWVhcjogY3VyclllYXIsXG4gICAgICBtb250aDogY3Vyck1vbnRoLFxuICAgICAgZGF5OiBjdXJyRGF5LFxuICAgICAgbW9udGhMZW5ndGg6IG1vbnRoTGVuZ3RoXG4gICAgfSkudG9TdHJpbmcoKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9zaG9wPycgKyBxcyk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIGNvbnN0IGVuYWJsZWREYXlzID0gW107XG5cbiAgICBpZiAocmVzdWx0ICYmIHJlc3VsdFsnc3RhdHVzJ10gPT09ICcxJykge1xuICAgICAgaWYgKHJlc3VsdC5qc29uKSB7XG4gICAgICAgIHRoaXMuZGF0ZXMgPSBKU09OLnBhcnNlKHJlc3VsdC5qc29uKTtcblxuICAgICAgICBjb25zdCBkYXlFeGlzdHMgPSBbXTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGF0ZXMuZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGRheSA9IHRoaXMuZGF0ZXMuZGF0YVtpXS5zdGFydHNfYXQuc3BsaXQoXCJUXCIpWzBdO1xuXG4gICAgICAgICAgaWYgKCFkYXlFeGlzdHNbZGF5XSkge1xuICAgICAgICAgICAgZW5hYmxlZERheXMucHVzaChkYXkpO1xuICAgICAgICAgICAgZGF5RXhpc3RzW2RheV0gPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgfVxuXG4gICAgY29uc3Qgb2JqID0gdGhpcztcblxuICAgIGNvbnN0IGNhbGVuZGFyID0gbmV3IFZhbmlsbGFDYWxlbmRhcignI2RhdGVwaWNrZXInLCB7XG4gICAgICBzZXR0aW5nczoge1xuICAgICAgICBsYW5nOiAnZGVmaW5lJyxcbiAgICAgICAgcmFuZ2U6IHtcbiAgICAgICAgICBlbmFibGVkOiBlbmFibGVkRGF5c1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgbG9jYWxlOiB7XG4gICAgICAgIG1vbnRoczogWydKYW51YXJpJywgJ0ZlYnJ1YXJpJywgJ01hcnMnLCAnQXByaWwnLCAnTWFqJywgJ0p1bmknLCAnSnVsaScsICdBdWd1c3RpJywgJ1NlcHRlbWJlcicsICdPa3RvYmVyJywgJ05vdmVtYmVyJywgJ0RlY2VtYmVyJ10sXG4gICAgICAgIHdlZWtkYXk6IFsnU8O2JywgJ03DpScsICdUaScsICdPbicsICdUbycsICdGcicsICdMw7YnXVxuICAgICAgfSxcbiAgICAgIGFjdGlvbnM6IHtcbiAgICAgICAgY2xpY2tEYXkoZSwgZGF0ZXMpIHtcbiAgICAgICAgICBpZiAoZGF0ZXMubGVuZ3RoID09IDApIHJldHVybjtcbiAgICAgICAgICBvYmouZ2V0VGltZXMoZGF0ZXNbMF0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjYWxlbmRhci5pbml0KCk7XG5cbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYm9va2luZy1idG4nKS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIG9iai5ib29rVGltZXNsb3QoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldFRpbWVzKGRheSkge1xuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShkYXkpO1xuICAgIGxldCBjdXJyRGF0ZSA9IGQuZ2V0RGF0ZSgpO1xuICAgIGxldCBjdXJyTW9udGggPSBkLmdldE1vbnRoKCkgKyAxO1xuXG4gICAgaWYgKGN1cnJNb250aCA8IDEwKSB7XG4gICAgICBjdXJyTW9udGggPSBcIjBcIiArIGN1cnJNb250aDtcbiAgICB9XG4gICAgaWYgKGN1cnJEYXRlIDwgMTApIHtcbiAgICAgIGN1cnJEYXRlID0gXCIwXCIgKyBjdXJyRGF0ZTtcbiAgICB9XG5cbiAgICBsZXQgdGltZXNIdG1sID0gJyc7XG4gICAgY29uc3Qgb2JqID0gdGhpcztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kYXRlcy5kYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBkYXRlRGF5ID0gdGhpcy5kYXRlcy5kYXRhW2ldLnN0YXJ0c19hdC5zcGxpdChcIlRcIilbMF07XG5cbiAgICAgIGlmIChkYXkgIT09IGRhdGVEYXkpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCB0aW1lID0gdGhpcy5kYXRlcy5kYXRhW2ldLnN0YXJ0c19hdC5zcGxpdChcIlRcIilbMV0uc3BsaXQoXCI6MDArXCIpWzBdO1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gcGFyc2VJbnQobmV3IERhdGUodGhpcy5kYXRlcy5kYXRhW2ldLnN0YXJ0c19hdCkuZ2V0VGltZSgpIC8gMTAwMCk7XG5cbiAgICAgIC8vIFRpZGVyIG3DpXN0ZSB2YXJhIG1pbnN0IDZoIGZyb20gbnUuXG4gICAgICBjb25zdCB0aW1lc3RhbXBNaW4gPSBwYXJzZUludChuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApICsgKDYgKiA2MCAqIDYwKTtcblxuICAgICAgaWYgKHRpbWVzdGFtcCA+PSB0aW1lc3RhbXBNaW4pIHtcbiAgICAgICAgdGltZXNIdG1sICs9IFwiPGRpdiBjbGFzcz0ndGltZXBpY2tlcl90aW1lJyBkYXRhLXN0YXJ0PSdcIiArIHRoaXMuZGF0ZXMuZGF0YVtpXS5zdGFydHNfYXQgKyBcIicgZGF0YS1lbmQ9J1wiICsgdGhpcy5kYXRlcy5kYXRhW2ldLmVuZHNfYXQgKyBcIic+XCIgKyB0aW1lICsgXCI8L2Rpdj5cIjtcblxuICAgICAgfVxuXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGltZXBpY2tlcl90aW1lcycpLmlubmVySFRNTCA9IHRpbWVzSHRtbDtcblxuICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRpbWVwaWNrZXJfdGltZScpLmZvckVhY2goZWxlbSA9PiB7XG4gICAgICAgIGVsZW0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgb2JqLnJlc2VydmVUaW1lc2xvdChlbGVtLmRhdGFzZXQuc3RhcnQsIGVsZW0uZGF0YXNldC5lbmQsIGVsZW0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcmVzZXJ2ZVRpbWVzbG90KHN0YXJ0LCBlbmQsIGVsZW0pIHtcbiAgICBpZiAoIXRoaXMucmVzZXJ2ZWRfdGltZXMpIHtcbiAgICAgIHRoaXMucmVzZXJ2ZWRfdGltZXMgPSBbXTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMucmVzZXJ2ZWRfdGltZXNbc3RhcnRdKSB7XG5cbiAgICAgIGNvbnN0IHFzID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAgIGZ1bms6ICdTdGlscmFkZ2l2bmluZ19SZXNlcnZlcmFfVGlkJyxcbiAgICAgICAgc3RhcnRzX2F0OiBzdGFydCxcbiAgICAgICAgZW5kc19hdDogZW5kXG4gICAgICB9KS50b1N0cmluZygpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcD8nICsgcXMpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdFsnc3RhdHVzJ10gPT09ICcxJykge1xuXG4gICAgICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy50aW1lcGlja2VyX3RpbWUnKS5mb3JFYWNoKGVsZW0gPT4ge1xuICAgICAgICAgIGVsZW0uY2xhc3NMaXN0LnJlbW92ZSgncmVzZXJ2ZWQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QganNvbiA9IEpTT04ucGFyc2UocmVzdWx0Lmpzb24pO1xuICAgICAgICBlbGVtLmNsYXNzTGlzdC5hZGQoJ3Jlc2VydmVkJyk7XG4gICAgICAgIGVsZW0uc2V0QXR0cmlidXRlKCdyZXNfaWQnLCBqc29uLmlkKTtcbiAgICAgICAgdGhpcy5yZXNlcnZlZF90aW1lc1tzdGFydF0gPSBqc29uLmlkO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGJvb2tUaW1lc2xvdCgpIHtcblxuICAgIGNvbnN0IHRpbWVEaXYgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGltZXBpY2tlcl90aW1lLnJlc2VydmVkJyk7XG4gICAgY29uc3QgcGhvbmVJbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjdXN0b21lcl9waG9uZScpO1xuICAgIGNvbnN0IHBob25lID0gcGhvbmVJbnB1dC52YWx1ZTtcbiAgICBjb25zdCB0aGFua3lvdV9wYWdlX3VybCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGFua3lvdV9wYWdlX3VybCcpLnZhbHVlO1xuICBcbiAgICBpZiAocGhvbmUpIHtcbiAgICAgIHBob25lSW5wdXQuY2xhc3NMaXN0LnJlbW92ZSgnZXJyb3InKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGhvbmVJbnB1dC5jbGFzc0xpc3QuYWRkKCdlcnJvcicpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghdGltZURpdikgcmV0dXJuIGZhbHNlO1xuXG4gICAgY29uc3Qgc3RhcnQgPSB0aW1lRGl2LmRhdGFzZXQuc3RhcnQ7XG4gICAgY29uc3QgZW5kID0gdGltZURpdi5kYXRhc2V0LmVuZDtcbiAgICBjb25zdCBuZXdEYXRlID0gbmV3IERhdGUoc3RhcnQpO1xuICAgIGNvbnN0IG5ld0RhdGVfRW5kcyA9IG5ldyBEYXRlKGVuZCk7XG5cbiAgICBjb25zdCB0aW1lc3RhbXAgPSBwYXJzZUludChuZXdEYXRlLmdldFRpbWUoKSAvIDEwMDApO1xuICAgIGNvbnN0IHRpbWVzdGFtcF9lbmRzID0gcGFyc2VJbnQobmV3RGF0ZV9FbmRzLmdldFRpbWUoKSAvIDEwMDApO1xuICAgIGNvbnN0IHJlc0lkID0gdGltZURpdi5nZXRBdHRyaWJ1dGUoJ3Jlc19pZCcpO1xuXG4gICAgY29uc3QgcXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgIGZ1bms6ICdTdGlscmFkZ2l2bmluZ19Cb2thX1RpZCcsXG4gICAgICBzdGFydHNfYXQ6IHN0YXJ0LFxuICAgICAgc3RhcnRzX3VuaXg6IHRpbWVzdGFtcCxcbiAgICAgIGVuZHNfYXQ6IGVuZCxcbiAgICAgIGVuZHNfdW5peDogdGltZXN0YW1wX2VuZHMsXG4gICAgICBwaG9uZTogcGhvbmUsXG4gICAgICByZXNfaWQ6IHJlc0lkXG4gICAgfSkudG9TdHJpbmcoKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJy9zaG9wPycgKyBxcyk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXG4gICAgaWYgKHJlc3VsdCAmJiByZXN1bHRbJ3N0YXR1cyddID09PSAnMScpIHtcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdGhhbmt5b3VfcGFnZV91cmw7XG4gICAgICB2YXIgYnJfcGhvbmUgPSBwaG9uZS5yZXBsYWNlKC9eMC8sIFwiMDA0NlwiKTtcbiAgICAgIGJyX3Bob25lID0gYnJfcGhvbmUucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICAgIGV4cG9uZWEudHJhY2soJ3N0eWxlX2V2ZW50JywgeydhY3Rpb24nOiAnYWNjZXB0JywndHlwZSc6ICdzdHlsZWFkdmlzb3InLCdwYXJhbWV0ZXInOidtZWV0aW5nJywnbWVldGluZ19kYXRlJzogdGltZXN0YW1wLCdtZWV0aW5nX3Bob25lJzogYnJfcGhvbmV9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxlcnQoJ2Jva25pbmcga3VuZGUgaW50ZSBnZW5vbWbDtnJhcycpO1xuICAgIH1cbiAgfVxuIFxuICB1dWlkdjQoKSB7XG4gICAgcmV0dXJuIChbMWU3XSstMWUzKy00ZTMrLThlMystMWUxMSkucmVwbGFjZSgvWzAxOF0vZywgYyA9PlxuICAgICAgKGMgXiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KDEpKVswXSAmIDE1ID4+IGMgLyA0KS50b1N0cmluZygxNilcbiAgICApO1xuICB9XG5cbiAgc2V0TG9naW5JY29uKCkge1xuICAgIGNvbnN0IGxvZ2luX2ljb24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2xvZ2luLWljb24gc3ZnXCIpO1xuICAgIGNvbnN0IGxvZ2luX3dyYXBwZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImxvZ2luLXdyYXBwZXJcIik7XG4gICAgY29uc3QgbG9naW5faWNvbl9odG1sID0gbG9naW5faWNvbi5vdXRlckhUTUw7XG5cbiAgICBsb2dpbl9pY29uLm91dGVySFRNTCA9IFwiPGEgaHJlZj0nL3Nob3A/ZnVuaz1kaW5zaWRhJz5cIiArIGxvZ2luX2ljb25faHRtbCArIFwiPC9hPlwiO1xuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjbG9naW4taWNvbiBzdmdcIikuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcImJsYWNrXCIpO1xuICAgIGxvZ2luX3dyYXBwZXIuc3R5bGUudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG4gIH1cblxufSIsImV4cG9ydCBmdW5jdGlvbiBmb3JtYXRQcmljZUh0bWwocHJpY2UsIHByaWNlX3JlZ3VsYXIsIGNhbXBhaWduLCBwcmljZV9wcmVmaXggPSBcIlwiKSB7XG4gICAgY29uc3QgY3VycmVuY3lfcHJlZml4ID0gd2luZG93LnNob3Bfc2V0dGluZ3NbJ2N1cnJlbmN5X3ByZWZpeCddIHx8ICcnO1xuICAgIGNvbnN0IGN1cnJlbmN5X3N1ZmZpeCA9IHdpbmRvdy5zaG9wX3NldHRpbmdzWydjdXJyZW5jeV9zdWZmaXgnXSB8fCAnJztcblxuICAgIHByaWNlID0gX3ByZXR0eVByaWNlKHByaWNlKTtcblxuICAgIGlmIChjYW1wYWlnbikge1xuICAgICAgICBwcmljZV9yZWd1bGFyID0gX3ByZXR0eVByaWNlKHByaWNlX3JlZ3VsYXIpO1xuICAgICAgICByZXR1cm4gYDxzcGFuIGNsYXNzPVwiYnV5Ym94X19wcmljZS0tcmVndWxhci0tc2FsZSBkYXJrLWJsYWNrLXRleHRcIj4ke2N1cnJlbmN5X3ByZWZpeH0ke3ByaWNlX3ByZWZpeH0ke3ByaWNlX3JlZ3VsYXJ9JHtjdXJyZW5jeV9zdWZmaXh9PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImJ1eWJveF9fcHJpY2UtLWNhbXBhaWduIGxpZ2h0LXJlZC10ZXh0IGRhcmstYmxhY2stdGV4dFwiPiR7Y3VycmVuY3lfcHJlZml4fSR7cHJpY2VfcHJlZml4fSR7cHJpY2V9JHtjdXJyZW5jeV9zdWZmaXh9PC9zcGFuPmA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGA8c3BhbiBjbGFzcz1cImJ1eWJveF9fcHJpY2UtLXJlZ3VsYXIgZGFyay1ibGFjay10ZXh0XCI+JHtjdXJyZW5jeV9wcmVmaXh9JHtwcmljZV9wcmVmaXh9JHtwcmljZX0ke2N1cnJlbmN5X3N1ZmZpeH08L3NwYW4+YDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIF9wcmV0dHlQcmljZShwcmljZSkge1xuICAgIHByaWNlID0gcHJpY2UudG9TdHJpbmcoKS5yZXBsYWNlKC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLCAnICcpO1xuICAgIHJldHVybiBwcmljZS5yZXBsYWNlKC9cXC4vZywgJywnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4ZWN1dGVKcyhjb250YWluZXIpIHtcbiAgICBjb25zdCBzY3JpcHRzID0gY29udGFpbmVyLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzY3JpcHQnKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjcmlwdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGV4ZWN1dGUgPSB0cnVlO1xuXG4gICAgICAgIGlmIChzY3JpcHRzW2ldLmdldEF0dHJpYnV0ZSgndHlwZScpID09PSAnYXBwbGljYXRpb24vbGQranNvbicpIHtcbiAgICAgICAgICAgIGV4ZWN1dGUgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChleGVjdXRlKSB7XG4gICAgICAgICAgICBjb25zdCBjb25zZW50VHlwZSA9IHNjcmlwdHNbaV0uZ2V0QXR0cmlidXRlKCdjb25zZW50X3R5cGUnKTtcblxuICAgICAgICAgICAgaWYgKGNvbnNlbnRUeXBlKSB7XG4gICAgICAgICAgICAgICAgZXhlY3V0ZSA9IGNoZWNrX2NvbnNlbnQoY29uc2VudFR5cGUsIFwiXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV4ZWN1dGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuXG4gICAgICAgICAgICBpZiAoc2NyaXB0c1tpXS5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSAhPT0gJ2FwcGxpY2F0aW9uL2xkK2pzb24nKSB7XG4gICAgICAgICAgICAgICAgcy50ZXh0ID0gc2NyaXB0c1tpXS5pbm5lckhUTUw7XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHMpLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvb2tpZShuYW1lKSB7XG4gICAgdmFyIGNvb2tpZUFyciA9IGRvY3VtZW50LmNvb2tpZS5zcGxpdChcIjtcIik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvb2tpZUFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY29va2llUGFpciA9IGNvb2tpZUFycltpXS5zcGxpdChcIj1cIik7XG5cbiAgICAgICAgaWYgKG5hbWUgPT0gY29va2llUGFpclswXS50cmltKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoY29va2llUGFpclsxXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFN0b3JhZ2UobmFtZSwgdmFsdWUsIGV4cGlyZXMpIHtcbiAgICBpZiAodHlwZW9mIChTdG9yYWdlKSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBudWxsO1xuXG4gICAgaWYgKGV4cGlyZXMpIHtcbiAgICAgICAgdGhpcy5jYXJ0LmV4cGlyZXMgPSBEYXRlLm5vdygpICsgZXhwaXJlcyAqIDYwMDAwO1xuICAgIH1cbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0obmFtZSwgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVN0b3JhZ2UobmFtZSkge1xuICAgIGlmICh0eXBlb2YgKFN0b3JhZ2UpID09PSAndW5kZWZpbmVkJykgcmV0dXJuIG51bGw7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKG5hbWUpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RvcmFnZShuYW1lICwgZXhwaXJlcykge1xuICAgIGlmICh0eXBlb2YgKFN0b3JhZ2UpID09PSAndW5kZWZpbmVkJykgcmV0dXJuIG51bGw7XG5cbiAgICBsZXQgc3RyID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKG5hbWUpO1xuXG4gICAgaWYgKHN0ciA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgbGV0IGRhdGE7XG5cbiAgICB0cnkge1xuICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShzdHIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5leHBpcmVzICYmIGRhdGEuZXhwaXJlcyA8IERhdGUubm93KCkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YTtcbn1cbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIEJyYW5kU2VhcmNoIHtcblxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLmluaXRfZXZlbnRzKCk7XG5cdH1cblxuXHRpbml0X2V2ZW50cygpIHtcblx0XHR3aW5kb3cubGl2ZUV2ZW50KFwiLmJyYW5kc19saXN0X2ZpbHRlclwiLCBcImtleXVwXCIsIChldmVudCwgZWxlbWVudCkgPT4ge3RoaXMuZmlsdGVyX2JyYW5kcyhlbGVtZW50LnZhbHVlLCBlbGVtZW50LmNsb3Nlc3QoXCIuYnJhbmRzX2xpc3RcIikpO30pO1xuXHRcdHdpbmRvdy5saXZlRXZlbnQoXCIuYnJhbmRzX2xpc3Rfc2hvd19hbGxcIiwgXCJjbGlja1wiLCAoZXZlbnQsIGVsZW1lbnQpID0+IHt0aGlzLmZpbHRlcl9icmFuZHMoXCJcIiwgZWxlbWVudC5jbG9zZXN0KFwiLmJyYW5kc19saXN0XCIpKX0pO1xuXHRcdHdpbmRvdy5saXZlRXZlbnQoXCIuYnJhbmRzX2xpc3RfbGV0dGVyXCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG5cdFx0XHR0aGlzLmZpbHRlcl9icmFuZHNfbGV0dGVyKGVsZW1lbnQuaW5uZXJUZXh0LCBlbGVtZW50LmNsb3Nlc3QoXCIuYnJhbmRzX2xpc3RcIikpXG5cdFx0fSk7XG5cdH1cblxuXHRmaWx0ZXJfYnJhbmRzKHZhbHVlLCBwYXJlbnQpIHtcblx0XHRpZiAoIXZhbHVlKVxuXHRcdHtcblx0XHRcdHBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYnJhbmRzX2xpc3RfYnJhbmQsIC5icmFuZHNfbGlzdF93cmFwcGVyJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiLS1oaWRkZW5cIik7XG5cdFx0XHR9KTtcblxuXHRcdFx0cGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5icmFuZHNfbGlzdF9maWx0ZXInKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXHRcdFx0XHRlbGVtZW50LnZhbHVlID0gXCJcIjtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRlbHNlXG5cdFx0e1xuXHRcdFx0cGFyZW50XG4gICAgICAgIC5xdWVyeVNlbGVjdG9yQWxsKFwiLmJyYW5kc19saXN0X3dyYXBwZXJcIilcbiAgICAgICAgLmZvckVhY2goKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWhpZGRlblwiKVxuICAgICAgICB9KVxuXG5cdFx0XHRwYXJlbnQucXVlcnlTZWxlY3RvckFsbCgnLmJyYW5kc19saXN0X2JyYW5kJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiLS1oaWRkZW5cIik7XG5cdFx0XHR9KTtcblx0XHRcdHBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYnJhbmRzX2xpc3RfYnJhbmRbZGF0YS12YWx1ZSo9XCInICsgdmFsdWUudG9Mb3dlckNhc2UoKSArICdcIl0nKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWhpZGRlblwiKTtcblx0XHRcdH0pO1xuXHRcdFx0cGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5icmFuZHNfbGlzdF93cmFwcGVyJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0aWYgKGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmJyYW5kc19saXN0X2JyYW5kJykubGVuZ3RoID09IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmJyYW5kc19saXN0X2JyYW5kLi0taGlkZGVuJykubGVuZ3RoKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiLS1oaWRkZW5cIik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdGZpbHRlcl9icmFuZHNfbGV0dGVyKGxldHRlciwgcGFyZW50KSB7XG5cdFx0cGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5icmFuZHNfbGlzdF9icmFuZCcpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWhpZGRlblwiKTtcblx0XHR9KTtcblxuXHRcdHBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYnJhbmRzX2xpc3Rfd3JhcHBlcicpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoXCItLWhpZGRlblwiKTtcblx0XHR9KTtcblxuXHRcdHBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYnJhbmRzX2xpc3Rfd3JhcHBlcltkYXRhLWxldHRlcio9XCInICsgbGV0dGVyLnRvTG93ZXJDYXNlKCkgKyAnXCJdJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcIi0taGlkZGVuXCIpO1xuXHRcdH0pO1xuXG5cdFx0cGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5icmFuZHNfbGlzdF9maWx0ZXInKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXHRcdFx0ZWxlbWVudC52YWx1ZSA9IFwiXCI7XG5cdFx0fSk7XG5cdH1cblxuXHRcbn1cblxuICBcbiAgIiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2hlY2tvdXQge1xuXHRcbn0iLCJleHBvcnQgZGVmYXVsdCBjbGFzcyBSZXNlcnZhdGlvbiB7XG5cblx0Y29uc3RydWN0b3IoY2FydCkge1xuXHRcdHRoaXMuY2FydCA9IGNhcnQ7XG5cdFx0dGhpcy5pbml0KCk7XG5cdH1cblxuXHRpbml0KCkge1xuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5TdGlscmFkZ2l2bmluZ19BcnRpa2VsIC5LbmFwcF9Lb3AgYScpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKGUpID0+IHtcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRsZXQgZm9ybSA9IGVsZW1lbnQucGFyZW50Tm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5wYXJlbnROb2RlO1xuXHRcdFx0XHRsZXQgcHJvZHVjdF9pZCA9IGZvcm0uYWx0bnIudmFsdWU7XG5cblx0XHRcdFx0aWYgKHByb2R1Y3RfaWQpIHtcblx0XHRcdFx0XHR0aGlzLmNhcnQuYWRkX2l0ZW0ocHJvZHVjdF9pZCwgMSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG59XG4iLCJpbXBvcnQgU2ltcGxlU2xpZGVyIGZyb20gJy4uLy4uL3ZpZXdzL3Byb2R1Y3Qvc2ltcGxlX3NsaWRlcic7XG5pbXBvcnQgeyBleGVjdXRlSnMgfSBmcm9tICcuLi8uLi9zY3JpcHRzL3V0aWxzLmpzJztcbmltcG9ydCBTaXplQW5kRml0IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvc2l6ZV9hbmRfZml0L3NpemVBbmRGaXQnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBamF4aWZ5IHtcblx0Y29uc3RydWN0b3IocHJvZHVjdFBhZ2UsIG5hdiwgZmlsdGVyKSB7XG5cdFx0dGhpcy5wcm9kdWN0UGFnZSA9IHByb2R1Y3RQYWdlO1xuXHRcdHRoaXMubmF2TWVudSA9IG5hdjtcblx0XHR0aGlzLmZpbHRlciA9IGZpbHRlcjtcblx0XHR0aGlzLmlzU2V0dXAgPSBmYWxzZTtcblx0XHR0aGlzLnByb2R1Y3RMb2FkaW5nID0gZmFsc2U7XG5cdFx0dGhpcy5wcm9kdWN0TG9hZGVkID0gZmFsc2U7XG5cdFx0dGhpcy5mcm9tUmVxZXN0VHlwZSA9ICcnO1xuXHRcdHRoaXMub2Zmc2V0ID0gMDtcblx0XHR0aGlzLmluaXRFdmVudHMoKTtcblx0fVxuXG5cdGluaXRFdmVudHMoKSB7XG5cdFx0d2luZG93LmxpdmVFdmVudCgnLm5hdmlnYXRlLXByb2R1Y3QnLCAnY2xpY2snLCAoZXZlbnQsIGVsZW1lbnQpID0+IHtcblx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYmFja2Ryb3AnKS5jbGFzc0xpc3QuY29udGFpbnMoJ2FjdGl2ZScpKSB7XG5cdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5iYWNrZHJvcCcpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWlyLWNhcnQtbW9kdWxlJykuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnY2FydC1vcGVuJyk7XG5cdFx0XHRcdGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnJztcblx0XHRcdH1cblx0XHRcdGlmIChlbGVtZW50LmhyZWYpIHtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0aWYgKHRoaXMuZnJvbUxpc3QoZWxlbWVudCkpIHtcblx0XHRcdFx0XHQvLyBQYXNzIHRoZSBlbGVtZW50IHRvIHRoZSBnZXRQcm9kdWN0IGZ1bmN0aW9uXG5cdFx0XHRcdFx0dGhpcy5nZXRQcm9kdWN0KGVsZW1lbnQuaHJlZiwgZWxlbWVudCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5uYXZpZ2F0ZVBhZ2UoZWxlbWVudC5ocmVmLCAncHJvZHVjdCcpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuRGluX1NpZGFfT25za2VsaXN0YV9XcmFwcGVyIC5LbmFwcF9Lb3AgYScpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcblxuXHRcdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB7XG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblxuXG5cdFx0XHRcdGxldCBmb3JtID0gZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGU7XG5cdFx0XHRcdGxldCBwcm9kdWN0X2lkID0gZm9ybS5hbHRuci52YWx1ZTtcblxuXHRcdFx0XHRpZiAocHJvZHVjdF9pZCkge1xuXHRcdFx0XHRcdHRoaXMuY2FydC5hZGRfaXRlbShwcm9kdWN0X2lkLCAxKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9nZ2xlX2NvbnRlbnQnKS5mb3JFYWNoKCh0b2dnbGVFbGVtZW50KSA9PiB7XG5cdFx0XHR0b2dnbGVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGNvbnN0IHRhcmdldFNlbGVjdG9yID0gdG9nZ2xlRWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdGFyZ2V0Jyk7XG5cdFx0XHRcdGNvbnN0IHRhcmdldEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRhcmdldFNlbGVjdG9yKTtcblx0XHRcdFx0aWYgKHRhcmdldEVsZW1lbnQpIHtcblx0XHRcdFx0XHR0YXJnZXRFbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoJ2hpZGUnKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRjb25zdCBmYXFDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZmFxJyk7XG5cdFx0aWYgKGZhcUNvbnRhaW5lcikge1xuXHRcdFx0Y29uc3QgZmFxSXRlbXMgPSBmYXFDb250YWluZXIucXVlcnlTZWxlY3RvckFsbCgndWwgbGkuYWNjb3JkaW9uX19pdGVtJyk7XG5cdFx0XHRjb25zdCBmYXFEYXRhID0gW107XG5cdFx0XHRmYXFJdGVtcy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuXHRcdFx0XHRjb25zdCBxdWVzdGlvbiA9IGl0ZW0ucXVlcnlTZWxlY3RvcignLmFjY29yZGlvbl9faXRlbS0tYnRuJykudGV4dENvbnRlbnQudHJpbSgpO1xuXHRcdFx0XHRjb25zdCBhbnN3ZXIgPSBpdGVtLnF1ZXJ5U2VsZWN0b3IoJ3VsJykudGV4dENvbnRlbnQudHJpbSgpO1xuXG5cdFx0XHRcdGZhcURhdGEucHVzaCh7XG5cdFx0XHRcdFx0J0B0eXBlJzogJ1F1ZXN0aW9uJyxcblx0XHRcdFx0XHRuYW1lOiBxdWVzdGlvbixcblx0XHRcdFx0XHRhY2NlcHRlZEFuc3dlcjoge1xuXHRcdFx0XHRcdFx0J0B0eXBlJzogJ0Fuc3dlcicsXG5cdFx0XHRcdFx0XHR0ZXh0OiBhbnN3ZXJcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIENyZWF0ZSBKU09OLUxEIHNjcmlwdCBlbGVtZW50IGZvciBzY2hlbWEgbWFya3VwXG5cdFx0XHRjb25zdCBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcblx0XHRcdHNjcmlwdC50eXBlID0gJ2FwcGxpY2F0aW9uL2xkK2pzb24nO1xuXHRcdFx0c2NyaXB0LmlubmVySFRNTCA9IGBcblx0XHRcdHtcblx0XHRcdFx0XCJAY29udGV4dFwiOiBcImh0dHBzOi8vc2NoZW1hLm9yZ1wiLFxuXHRcdFx0XHRcIkB0eXBlXCI6IFwiRkFRUGFnZVwiLFxuXHRcdFx0XHRcIm1haW5FbnRpdHlcIjogJHtKU09OLnN0cmluZ2lmeShmYXFEYXRhKX1cblx0XHRcdH1cblx0XHRgO1xuXG5cdFx0XHQvLyBBcHBlbmQgdGhlIHNjcmlwdCBlbGVtZW50IHRvIHRoZSBoZWFkIG9mIHRoZSBkb2N1bWVudFxuXHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuXHRcdH1cblxuXHRcdHdpbmRvdy5saXZlRXZlbnQoJyNhaXItY2FydC1tb2R1bGUgLmNsb3NlJywgJ2NsaWNrJywgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYmFja2Ryb3AnKS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhaXItY2FydC1tb2R1bGUnKS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWlyLWNhcnQtbW9kdWxlJykuY2xhc3NMaXN0LmNvbnRhaW5zKCdlcnJvcicpKSB7XG5cdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhaXItY2FydC1tb2R1bGUnKS5jbGFzc0xpc3QucmVtb3ZlKCdlcnJvcicpO1xuXHRcdFx0fVxuXHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdjYXJ0LW9wZW4nKTtcblx0XHRcdGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnJztcblx0XHR9KTtcblxuXHRcdHdpbmRvdy5saXZlRXZlbnQoJy5iYWNrZHJvcCcsICdjbGljaycsIChldmVudCwgZWxlbWVudCkgPT4ge1xuXHRcdFx0aWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5iYWNrZHJvcCcpLmNsYXNzTGlzdC5jb250YWlucygnYWN0aXZlJykpIHtcblx0XHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmJhY2tkcm9wJykuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhaXItY2FydC1tb2R1bGUnKS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0dmFyIHNpemVhbmRmaXRjb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjc2l6ZWFuZGZpdCcpO1xuXHRcdFx0XHRpZiAoc2l6ZWFuZGZpdGNvbnRhaW5lcikge1xuXHRcdFx0XHRcdHNpemVhbmRmaXRjb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0d2luZG93LnNpemVORml0SW5pdGlhbGl6ZWQgPSBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcja3VuZHJhZGdpdm5pbmcnKS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3N0eWxlYWR2aXNvcicpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjbW9kYWxfYXJlYScpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXG5cdFx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWlyLWNhcnQtbW9kdWxlJykuY2xhc3NMaXN0LmNvbnRhaW5zKCdlcnJvcicpKSB7XG5cdFx0XHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2Fpci1jYXJ0LW1vZHVsZScpLmNsYXNzTGlzdC5yZW1vdmUoJ2Vycm9yJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdjYXJ0LW9wZW4nLCAnc2l6ZWFuZGZpdC1vcGVuJywgJ3N0eWxlYWR2aXNvcicsICdrdW5kcmFkZ2l2bmluZycpO1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR3aW5kb3cubGl2ZUV2ZW50KCcubmF2aWdhdGUnLCAnY2xpY2snLCBhc3luYyhldmVudCwgZWxlbWVudCkgPT4ge1xuXHRcdFx0aWYgKGVsZW1lbnQuaHJlZikge1xuXHRcdFx0XHR0aGlzLmhhc2ggPSB3aW5kb3cubG9jYXRpb24uaGFzaDtcblx0XHRcdFx0dGhpcy5lbGVtZW50ID0gZWxlbWVudDtcblx0XHRcdFx0bGV0IGxpc3RMb2FkaW5nID0gZmFsc2U7XG5cdFx0XHRcdHZhciBsaXN0U3Bpbm5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5saXN0c3Bpbm5lcicpO1xuXG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHRcdFx0bGlzdExvYWRpbmcgPSB0cnVlO1xuXHRcdFx0XHRpZiAoKGxpc3RMb2FkaW5nID0gdHJ1ZSkpIHtcblx0XHRcdFx0XHQvLyBTZXQgYSB0aW1lb3V0IHRvIHNob3cgdGhlIHNwaW5uZXIgYWZ0ZXIgMTAwbXNcblx0XHRcdFx0XHR2YXIgbGlzdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0bGlzdFNwaW5uZXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cdFx0XHRcdFx0fSwgMTAwKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGF3YWl0IHRoaXMubmF2aWdhdGVQYWdlKGVsZW1lbnQuaHJlZiwgJ2xpc3QnKTtcblxuXHRcdFx0XHRjbGVhclRpbWVvdXQobGlzdFRpbWVvdXQpO1xuXHRcdFx0XHRsaXN0U3Bpbm5lci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdFx0XHRsaXN0TG9hZGluZyA9IGZhbHNlO1xuXHRcdFx0XHRpZiAoZWxlbWVudC5jbG9zZXN0KCcuaGFzX19jaGlsZHJlbicpKSB7XG5cdFx0XHRcdFx0ZWxlbWVudC5jbG9zZXN0KCcuaGFzX19jaGlsZHJlbicpLmNsYXNzTGlzdC5hZGQoJ3JlbG9hZCcpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR3aW5kb3cubGl2ZUV2ZW50KCcucHJvZHVjdHBhZ2UtYmFjaycsICdjbGljaycsIChldmVudCwgZWxlbWVudCkgPT4ge1xuXHRcdFx0aGlzdG9yeS5iYWNrKCk7XG5cdFx0fSk7XG5cblx0XHR3aW5kb3cub25wb3BzdGF0ZSA9IChldmVudCkgPT4ge1xuXHRcdFx0aWYgKHRoaXMucHJvZHVjdExvYWRlZCkge1xuXHRcdFx0XHR0aGlzLmhpZGVQcm9kdWN0KCk7XG5cdFx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuYmFja2Ryb3AnKS5jbGFzc0xpc3QuY29udGFpbnMoJ2FjdGl2ZScpKSB7XG5cdFx0XHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmJhY2tkcm9wJykuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2Fpci1jYXJ0LW1vZHVsZScpLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWlyLWNhcnQtbW9kdWxlJykuY2xhc3NMaXN0LmNvbnRhaW5zKCdlcnJvcicpKSB7XG5cdFx0XHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjYWlyLWNhcnQtbW9kdWxlJykuY2xhc3NMaXN0LnJlbW92ZSgnZXJyb3InKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdjYXJ0LW9wZW4nKTtcblx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmIChldmVudC5zdGF0ZSAmJiBldmVudC5zdGF0ZS5hamF4X25hdikge1xuXHRcdFx0XHRcdHdpbmRvdy5sb2NhdGlvbiA9IGxvY2F0aW9uLmhyZWY7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG5cblx0c2hvd1Rvb2x0aXAoZWxlbWVudFdyYXBwZXIsIHRvb2x0aXApIHtcblx0XHRlbGVtZW50V3JhcHBlci5vbm1vdXNlbW92ZSA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdHZhciB4ID0gZS5jbGllbnRYXG5cdFx0XHQgICwgeSA9IGUuY2xpZW50WTtcblx0XHRcdHRvb2x0aXAuc3R5bGUudG9wID0geSArIDE1ICsgJ3B4JztcblxuXHRcdFx0aWYgKHRvb2x0aXAuY2xhc3NMaXN0LmNvbnRhaW5zKCdwb3NpdGlvbi1yaWdodCcpKSB7XG5cdFx0XHRcdHRvb2x0aXAuc3R5bGUubGVmdCA9IHggLSAxMjAgKyAncHgnO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dG9vbHRpcC5zdHlsZS5sZWZ0ID0geCArIDE1ICsgJ3B4Jztcblx0XHRcdH1cblx0XHRcdGlmICgvQW5kcm9pZHx3ZWJPU3xpUGhvbmV8aVBhZHxpUG9kfEJsYWNrQmVycnkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG5cdFx0XHRcdHRvb2x0aXAuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdHRvb2x0aXAuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdH0sIDMwMDApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dG9vbHRpcC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0ZWxlbWVudFdyYXBwZXIub25tb3VzZW91dCA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdHRvb2x0aXAuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0fTtcblx0fVxuXG5cdGZyb21MaXN0KGVsZW1lbnQpIHtcblx0XHRsZXQgcmVxdWVzdFR5cGUgPSAnJztcblxuXHRcdGlmICh0aGlzLnByb2R1Y3RMb2FkZWQpXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblxuXHRcdGlmICh3aW5kb3cuc2hvcF9zZXR0aW5ncykge1xuXHRcdFx0cmVxdWVzdFR5cGUgPSB3aW5kb3cuc2hvcF9zZXR0aW5nc1sncmVxdWVzdF90eXBlJ107XG5cdFx0fVxuXG5cdFx0aWYgKHJlcXVlc3RUeXBlID09PSAncHJvZHVjdCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9IGVsc2UgaWYgKHJlcXVlc3RUeXBlID09PSAncHJvZHVjdF9ncm91cCcgfHwgcmVxdWVzdFR5cGUgPT09ICdicmFuZCcgfHwgcmVxdWVzdFR5cGUgPT09ICdicmFuZF9pbl9ncm91cCcgfHwgcmVxdWVzdFR5cGUgPT09ICdzZWFyY2gnKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gY2hlY2sgZm9yIHNsaWRlcnNcblx0XHRcdGlmIChlbGVtZW50LnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc0xpc3QuY29udGFpbnMoJ3NuYXBwaW5nJykgfHwgZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc0xpc3QuY29udGFpbnMoJ3Byb2R1Y3QtLWxpc3QnKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRzZXR1cCgpIHtcblx0XHR0aGlzLm1haW5Db250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdtYWluJylbMF07XG5cdFx0dGhpcy5wcm9kdWN0Q29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbWFpbicpO1xuXHRcdHRoaXMucHJvZHVjdENvbnRhaW5lci5pZCA9ICdtYWluLXNlY29uZCc7XG5cdFx0dGhpcy5tYWluQ29udGFpbmVyLmFmdGVyKHRoaXMucHJvZHVjdENvbnRhaW5lcik7XG5cdFx0dGhpcy5pc1NldHVwID0gdHJ1ZTtcblx0fVxuXG5cdGFzeW5jIGdldFByb2R1Y3QodXJsLCBlbGVtZW50KSB7XG5cdFx0Ly8gR2V0IHRoZSBzcGlubmVyIGVsZW1lbnRcblx0XHR2YXIgc3Bpbm5lciA9IGVsZW1lbnQucXVlcnlTZWxlY3RvcignLnNwaW5uZXInKTtcblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGUgc3Bpbm5lciBlbGVtZW50IGV4aXN0c1xuXHRcdGlmICghc3Bpbm5lcikge1xuXHRcdFx0Ly8gSWYgdGhlIHNwaW5uZXIgZWxlbWVudCBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGEgbmV3IGVsZW1lbnRcblx0XHRcdHNwaW5uZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblx0XHRcdHNwaW5uZXIuY2xhc3NMaXN0LmFkZCgnc3Bpbm5lcicpO1xuXHRcdFx0Ly8gQXBwZW5kIHRoZSBzcGlubmVyIGVsZW1lbnQgdG8gdGhlIGNsaWNrZWQgZWxlbWVudFxuXHRcdFx0ZWxlbWVudC5hcHBlbmRDaGlsZChzcGlubmVyKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgYSB0aW1lb3V0IHRvIHNob3cgdGhlIHNwaW5uZXIgYWZ0ZXIgMTAwbXNcblx0XHR2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRzcGlubmVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXHRcdH0sIDEwMCk7XG5cdFx0aWYgKCF0aGlzLmlzU2V0dXApXG5cdFx0XHR0aGlzLnNldHVwKCk7XG5cdFx0aWYgKHRoaXMucHJvZHVjdExvYWRpbmcpXG5cdFx0XHRyZXR1cm47XG5cblx0XHRpZiAoIXRoaXMub2Zmc2V0KSB7XG5cdFx0XHR0aGlzLm9mZnNldCA9IHdpbmRvdy5wYWdlWU9mZnNldDtcblx0XHR9XG5cblx0XHR0aGlzLnByb2R1Y3RMb2FkaW5nID0gdHJ1ZTtcblx0XHRsZXQgc2VwYXJhdG9yID0gdXJsLmluY2x1ZGVzKCc/JykgPyAnJicgOiAnPyc7XG5cdFx0bGV0IHByb2R1Y3RVcmwgPSB1cmwgKyBzZXBhcmF0b3IgKyAnc3c9MSc7XG5cblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHByb2R1Y3RVcmwpO1xuXHRcdGNvbnN0IGh0bWwgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG5cblx0XHR0aGlzLnNhdmVNZXRhKCk7XG5cblx0XHRpZiAod2luZG93LnNob3Bfc2V0dGluZ3MpIHtcblx0XHRcdHRoaXMuZnJvbVJlcWVzdFR5cGUgPSB3aW5kb3cuc2hvcF9zZXR0aW5nc1sncmVxdWVzdF90eXBlJ107XG5cdFx0fVxuXG5cdFx0dGhpcy5zaG93UHJvZHVjdChodG1sKTtcblxuXHRcdHRoaXMuc2hvd1Byb2R1Y3RCYWNrKCk7XG5cblx0XHRpZiAodGhpcy5wcm9kdWN0TG9hZGVkKSB7XG5cdFx0XHRjbGVhclRpbWVvdXQodGltZW91dCk7XG5cdFx0XHRzcGlubmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0XHR3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUoe30sIG51bGwsIHVybCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSh7XG5cdFx0XHRcdGFqYXhfbmF2OiB0cnVlXG5cdFx0XHR9LCBudWxsLCB1cmwpO1xuXHRcdH1cblx0XHRjbGVhclRpbWVvdXQodGltZW91dCk7XG5cdFx0c3Bpbm5lci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdHRoaXMucHJvZHVjdExvYWRpbmcgPSBmYWxzZTtcblx0XHR0aGlzLnByb2R1Y3RMb2FkZWQgPSB0cnVlO1xuXHRcdHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcInBkcF9hamF4X2xvYWRlZFwiKSlcblxuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX2FydG5yJywgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QtaWQtaW5mbycpLnRleHRDb250ZW50KTtcblx0XHR9LCA1MDApO1xuXG5cdFx0Y29uc3Qgc2l6ZUFuZEZpdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaXplYW5kZml0Jyk7XG5cdFx0aWYgKHNpemVBbmRGaXQpIHtcblx0XHRcdGNvbnN0IGJhY2tkcm9wQmx1ciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5iYWNrZHJvcCcpO1xuXHRcdFx0Y29uc3Qgc2l6ZU5GaXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2l6ZWFuZGZpdCcpO1xuXHRcdFx0Y29uc3Qgc2l6ZU5GaXRTdGVwID0gc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbSgnc25mX3N0ZXAnKTtcblxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnNpemVBbmRGaXRUcmlnZ2VyJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcblx0XHRcdFx0XHRjb25zdCBwcm9kdWN0UGFnZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaW5nbGUtcHJvZHVjdCcpO1xuXHRcdFx0XHRcdGNvbnN0IHNpemVBbmRGaXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2l6ZWFuZGZpdCcpO1xuXHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcInNpemVhbmRmaXQtb3BlblwiKTtcblx0XHRcdFx0XHRpZiAocHJvZHVjdFBhZ2UpIHtcblx0XHRcdFx0XHRcdGNvbnN0IGltYWdlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wcm9kdWN0SW1nLS13cmFwcGVyIGltZycpO1xuXHRcdFx0XHRcdFx0Y29uc3QgcHJvZHVjdEFydE5yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QtaWQtaW5mbycpO1xuXHRcdFx0XHRcdFx0c2l6ZUFuZEZpdC5jbGFzc0xpc3QuYWRkKCdmcm9tLXBkcCcpO1xuXG5cdFx0XHRcdFx0XHRjb25zdCBpbWFnZVNvdXJjZSA9IGltYWdlc1swXS5nZXRBdHRyaWJ1dGUoJ3NyYycpO1xuXHRcdFx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX2ltYWdlJywgaW1hZ2VTb3VyY2UpO1xuXHRcdFx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX2FydG5yJywgcHJvZHVjdEFydE5yLnRleHRDb250ZW50KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRiYWNrZHJvcEJsdXIuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0c2l6ZU5GaXQuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0dGhpcy5hY3RpdmVTdGVwKCk7XG5cblx0XHRcdFx0XHRpZiAoc2l6ZU5GaXRTdGVwID4gJzEnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnNuZkJhY2tCdG4oKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0c2hvd1Byb2R1Y3RCYWNrKCkge1xuXHRcdHRoaXMucHJvZHVjdENvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcucHJvZHVjdHBhZ2UtYmFjaycpLmZvckVhY2goZnVuY3Rpb24oZWxlbSkge1xuXHRcdFx0ZWxlbS5jbGFzc0xpc3QucmVtb3ZlKCdoaWRkZW4nKTtcblx0XHR9KTtcblx0fVxuXG5cdGFzeW5jIG5hdmlnYXRlUGFnZSh1cmwsIHR5cGUpIHtcblx0XHRpZiAoIXVybClcblx0XHRcdHJldHVybjtcblx0XHRpZiAoIXRoaXMuaXNTZXR1cClcblx0XHRcdHRoaXMuc2V0dXAoKTtcblxuXHRcdGxldCBzZXBhcmF0b3IgPSB1cmwuaW5jbHVkZXMoJz8nKSA/ICcmJyA6ICc/Jztcblx0XHRsZXQgcGFnZVVSTCA9IHVybCArIHNlcGFyYXRvciArICdzdz0xJztcblxuXHRcdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocGFnZVVSTCk7XG5cdFx0Y29uc3QgaHRtbCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcblxuXHRcdGlmICh0aGlzLnByb2R1Y3RMb2FkZWQpIHtcblx0XHRcdHRoaXMuaGlkZVByb2R1Y3QoKTtcblx0XHR9XG5cblx0XHR0aGlzLm5hdk1lbnUuaGlkZU1haW5OYXYodGhpcy5uYXZNZW51KTtcblxuXHRcdHRoaXMubWFpbkNvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG5cdFx0d2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKHtcblx0XHRcdGFqYXhfbmF2OiB0cnVlXG5cdFx0fSwgbnVsbCwgdXJsKTtcblxuXHRcdGV4ZWN1dGVKcyh0aGlzLm1haW5Db250YWluZXIpO1xuXG5cdFx0aWYgKHR5cGUgPT09ICdwcm9kdWN0Jykge1xuXHRcdFx0dGhpcy5wcm9kdWN0UGFnZS5yZWluaXQoKTtcblx0XHRcdHRoaXMubWFpbkNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcucHJvZHVjdHBhZ2UtYmFjaycpLmZvckVhY2goZnVuY3Rpb24oZWxlbSkge1xuXHRcdFx0XHRlbGVtLmNsYXNzTGlzdC5yZW1vdmUoJ2hpZGRlbicpO1xuXHRcdFx0fSk7XG5cdFx0XHR3aW5kb3cuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJwZHBfYWpheF9sb2FkZWRcIikpO1xuXG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnc25mX2FydG5yJywgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QtaWQtaW5mbycpLnRleHRDb250ZW50KTtcblx0XHRcdH0sIDUwMCk7XG5cdFx0fSBlbHNlIGlmICh0eXBlID09PSAnbGlzdCcpIHtcblx0XHRcdGlmICh0aGlzLmVsZW1lbnQgJiYgdGhpcy5lbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygncGFnZV9fY2F0ZWdvcnktLWl0ZW0nKSkge1xuXHRcdFx0XHRpZiAodGhpcy5oYXNoKSB7XG5cdFx0XHRcdFx0d2luZG93LmxvY2F0aW9uLmhhc2ggPSB0aGlzLmhhc2g7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcInBscF9hamF4X2xvYWRlZFwiKSk7XG5cdFx0XHRpbml0aWFsaXplUGFnZSgpO1xuXHRcdFx0dGhpcy5maWx0ZXIucmVpbml0KCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5pbml0SnMoZG9jdW1lbnQpO1xuXHRcdHRoaXMuYWpheF9nYV9wYWdldmlldygpO1xuXG5cdFx0dGhpcy5hdG1fcGl4ZWxzX2FmdGVyKCk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9vbHRpcC1zcGFuJykuZm9yRWFjaCgodG9vbHRpcCkgPT4ge1xuXHRcdFx0Y29uc3QgcGFyZW50ID0gdG9vbHRpcC5wYXJlbnROb2RlO1xuXHRcdFx0dGhpcy5zaG93VG9vbHRpcChwYXJlbnQsIHRvb2x0aXApO1xuXHRcdH0pO1xuXG5cdFx0aWYgKHR5cGUgPT09IFwibGlzdFwiKSB7XG5cdFx0XHQvLyBDcmVhdGUgYW5kIGRpc3BhdGNoIHRoZSBjdXN0b20gZXZlbnRcblx0XHRcdHdpbmRvdy5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcInBscF9hamF4X2xvYWRlZFwiKSlcblx0XHR9XG5cblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcblx0XHR9LCAxMCk7XG5cdH1cblxuXHRzaG93UHJvZHVjdChodG1sKSB7XG5cdFx0dGhpcy5wcm9kdWN0Q29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7XG5cdFx0dGhpcy5wcm9kdWN0Q29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXHRcdHRoaXMubWFpbkNvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcblx0XHRleGVjdXRlSnModGhpcy5wcm9kdWN0Q29udGFpbmVyKTtcblx0XHR0aGlzLnByb2R1Y3RQYWdlLnJlaW5pdCgpO1xuXHRcdHRoaXMuaW5pdEpzKHRoaXMucHJvZHVjdENvbnRhaW5lcik7XG5cdFx0dGhpcy5hamF4X2dhX3BhZ2V2aWV3KCk7XG5cdFx0dGhpcy5hdG1fcGl4ZWxzX2FmdGVyKCk7XG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2hlYWRlcicpLmNsYXNzTGlzdC5yZW1vdmUoJ2hlYWRlcl9fbm90U2Nyb2xsZWQnKTtcblx0fVxuXG5cdGhpZGVQcm9kdWN0KCkge1xuXHRcdGlmICgnc2Nyb2xsUmVzdG9yYXRpb24nIGluIGhpc3RvcnkpIHtcblx0XHRcdGhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSAnbWFudWFsJztcblx0XHR9XG5cblx0XHR0aGlzLm1haW5Db250YWluZXIuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cdFx0dGhpcy5wcm9kdWN0Q29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0dGhpcy5wcm9kdWN0Q29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xuXHRcdHRoaXMucHJvZHVjdExvYWRlZCA9IGZhbHNlO1xuXG5cdFx0dGhpcy5yZXNldE1ldGEoKTtcblxuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0d2luZG93LnNjcm9sbFRvKDAsIHRoaXMub2Zmc2V0KTtcblx0XHRcdHRoaXMub2Zmc2V0ID0gMDtcblx0XHR9LCAxMCk7XG5cdH1cblxuXHRzYXZlTWV0YSgpIHtcblx0XHRjb25zdCB0aXRsZUVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGl0bGUnKVswXTtcblx0XHRjb25zdCByZWxFbGVtID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImxpbmtbcmVsPSdjYW5vbmljYWwnXVwiKTtcblxuXHRcdGlmICghdGl0bGVFbGVtLmRhdGFzZXQucmVzZXQpIHtcblx0XHRcdHRpdGxlRWxlbS5kYXRhc2V0LnJlc2V0ID0gZG9jdW1lbnQudGl0bGU7XG5cdFx0fVxuXG5cdFx0aWYgKHJlbEVsZW0gJiYgIXJlbEVsZW0uZGF0YXNldC5yZXNldCkge1xuXHRcdFx0cmVsRWxlbS5kYXRhc2V0LnJlc2V0ID0gcmVsRWxlbS5ocmVmO1xuXHRcdH1cblx0fVxuXG5cdHJlc2V0TWV0YSgpIHtcblx0XHRjb25zdCB0aXRsZUVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGl0bGUnKVswXTtcblx0XHRjb25zdCByZWxFbGVtID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImxpbmtbcmVsPSdjYW5vbmljYWwnXVwiKTtcblxuXHRcdGlmICh3aW5kb3cuc2hvcF9zZXR0aW5ncykge1xuXHRcdFx0d2luZG93LnNob3Bfc2V0dGluZ3NbJ3JlcXVlc3RfdHlwZSddID0gdGhpcy5mcm9tUmVxZXN0VHlwZTtcblx0XHR9XG5cblx0XHRpZiAodGl0bGVFbGVtLmRhdGFzZXQucmVzZXQpIHtcblx0XHRcdGRvY3VtZW50LnRpdGxlID0gdGl0bGVFbGVtLmRhdGFzZXQucmVzZXQ7XG5cdFx0XHR0aXRsZUVsZW0uZGF0YXNldC5yZXNldCA9ICcnO1xuXHRcdH1cblxuXHRcdGlmIChyZWxFbGVtICYmIHJlbEVsZW0uZGF0YXNldC5yZXNldCkge1xuXHRcdFx0cmVsRWxlbS5ocmVmID0gcmVsRWxlbS5kYXRhc2V0LnJlc2V0O1xuXHRcdFx0cmVsRWxlbS5kYXRhc2V0LnJlc2V0ID0gJyc7XG5cdFx0fVxuXHR9XG5cblx0aW5pdEpzKGNvbnRhaW5lcikge1xuXHRcdGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuc25hcHBpbmctLXdyYXBwZXInKS5mb3JFYWNoKGZ1bmN0aW9uKGVsZW0pIHtcblx0XHRcdG5ldyBTaW1wbGVTbGlkZXIoZWxlbSk7XG5cdFx0fSk7XG5cblx0XHR3aW5kb3cubGF6eUxvYWRJbnN0YW5jZS51cGRhdGUoKTtcblxuXHRcdC8qIFByb2R1a3QgZ3JpZCBicmVkZCB0b2dnbGUgLSBtb2JpbCAqL1xuXHRcdGxldCB0YWJMaW5rID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnRhYi1saW5rJyk7XG5cblx0XHRsZXQgdmlkZW9XcmFwcGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnZpZGVvJyk7XG5cdFx0bGV0IHZpZGVvRWxlbSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3ZpZGVvJyk7XG5cdFx0Ly8gSW5pdCB2aWRlb3MgaWYgbmVlZGVkLlxuXHRcdGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCd2aWRlbywgLnZpZGVvSW5mb1dyYXBwZXInKS5mb3JFYWNoKGZ1bmN0aW9uKGVsZW0pIHtcblx0XHRcdGVsZW0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKHZpZGVvRWxlbS5wYXVzZWQpIHtcblx0XHRcdFx0XHR2aWRlb0VsZW0ucGxheSgpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHZpZGVvRWxlbS5wYXVzZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHZpZGVvV3JhcHBlci5jbGFzc0xpc3QudG9nZ2xlKCdwbGF5aW5nJyk7XG5cdFx0XHRcdHZpZGVvV3JhcHBlci5jbGFzc0xpc3QuYWRkKCdzdGFydGVkJyk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXHRhamF4X2dhX3BhZ2V2aWV3KCkge1xuXHRcdGlmICh0eXBlb2YgZ2EgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0Y29uc3QgcGFnZSA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2g7XG5cdFx0XHRcdGdhKCdzZXQnLCAncGFnZScsIHBhZ2UpO1xuXHRcdFx0XHRnYSgnc2VuZCcsICdwYWdldmlldycpO1xuXHRcdFx0fSwgMSk7XG5cdFx0fVxuXHR9XG5cdGF0bV9waXhlbHNfYWZ0ZXIoKSB7XG5cdFx0aWYgKHR5cGVvZiBhdG1fcGl4ZWxzX2FmdGVyX2Z1bmN0aW9uICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgYXRtX3BpeGVsc19hZnRlcl9mdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0YXRtX3BpeGVsc19hZnRlcl9mdW5jdGlvbigpO1xuXHRcdH1cblx0fVxufVxuIiwiaW1wb3J0IHsgZm9ybWF0UHJpY2VIdG1sIH0gZnJvbSBcIi4uLy4uL3NjcmlwdHMvdXRpbHMuanNcIjtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnVuZGxlUHJvZHVjdCB7XG5cbiAgICBjb25zdHJ1Y3RvcihidW5kbGVEYXRhLCBidXlCdXR0b24pIHtcbiAgICAgICAgdGhpcy5idW5kbGVEYXRhID0gYnVuZGxlRGF0YTtcbiAgICAgICAgdGhpcy5maWVsZHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdidXlib3hfX2J1bmRsZXMtLWl0ZW1zJyk7XG4gICAgICAgIHRoaXMuZmllbGRJdGVtcyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2J1eWJveF9fYnVuZGxlcy0taXRlbScpO1xuICAgICAgICB0aGlzLmJ1eUJ1dHRvbiA9IGJ1eUJ1dHRvbjtcblxuICAgICAgICB0aGlzLmluaXQoKTtcbiAgICB9XG5cbiAgICBpbml0KCkge1xuICAgICAgICB0aGlzLmluaXRFdmVudHMoKTtcbiAgICB9XG5cbiAgICBpbml0RXZlbnRzKCkge1xuICAgICAgICAvLyBpZiBidW5kbGUgZmllbGRzIGFyZSBzZWxlY3RzLlxuICAgICAgICAvLyBmb3IgKGNvbnN0IGYgb2YgdGhpcy5maWVsZHMpIHtcbiAgICAgICAgLy8gICAgZi5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB0aGlzLnVwZGF0ZUZpZWxkKCkpO1xuICAgICAgICAvLyB9XG5cbiAgICAgICAgZm9yIChjb25zdCBmIG9mIHRoaXMuZmllbGRJdGVtcykge1xuICAgICAgICAgICAgZi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB0aGlzLnVwZGF0ZUZpZWxkRXZlbnQoZSkpO1xuICAgICAgICB9ICAgICAgICBcbiAgICB9XG5cbiAgICB1cGRhdGVGaWVsZEV2ZW50KGUpIHtcbiAgICAgICAgbGV0IGJ1dHRvbiA9IGUudGFyZ2V0O1xuICAgICAgICBjb25zdCBmaWVsZCA9IGJ1dHRvbi5wYXJlbnROb2RlO1xuICAgIFxuICAgICAgICB0aGlzLmJ1eUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdhbGVydC1kaXNhYmxlZCcpO1xuICAgICAgICBjb25zdCBhbGVydCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdhbGVydC1wb3B1cCcpO1xuXG4gICAgICAgIGlmIChhbGVydCkge1xuICAgICAgICAgICAgYWxlcnQucmVtb3ZlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGNvbnN0IGMgb2YgZmllbGQuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGlmIChjID09IGJ1dHRvbikge1xuICAgICAgICAgICAgICAgIGMuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICAgZmllbGQuZGF0YXNldC52YWx1ZSA9IGMuZGF0YXNldC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYy5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXBkYXRlRmllbGQoKTtcbiAgICB9XG5cbiAgICB1cGRhdGVGaWVsZCgpIHtcbiAgICAgICAgdGhpcy51cGRhdGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICB1cGRhdGVGaWVsZHMoKSB7XG4gICAgICAgIGxldCBpZHMgPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHRoaXMuZmllbGRzKSB7XG4gICAgICAgICAgICBpZHMucHVzaChmaWVsZC5kYXRhc2V0LnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwcmljZSA9IDA7XG4gICAgICAgIGxldCBwcmljZVJlZ3VsYXIgPSAwO1xuICAgICAgICBsZXQgY2FtcGFpZ24gPSBmYWxzZTtcblxuICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwgZmllbGRdIG9mIHRoaXMuYnVuZGxlRGF0YS5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIGlkcy5zb3J0KCk7XG4gICAgICAgICAgICBmaWVsZC5pdGVtcy5zb3J0KCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBmaWVsZC5pdGVtcykge1xuICAgICAgICAgICAgICAgIGlmIChpZHNbaW5kZXhdID09IGl0ZW0uaWQpIHtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIWl0ZW0ucHJpY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLmNhbXBhaWduKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYW1wYWlnbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmljZVJlZ3VsYXIgKz0gTnVtYmVyKGl0ZW0ucHJpY2VfcmVndWxhcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmljZVJlZ3VsYXIgKz0gTnVtYmVyKGl0ZW0ucHJpY2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcHJpY2UgKz0gTnVtYmVyKGl0ZW0ucHJpY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVsZW1zID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgncHJpY2UtaW5mbycpO1xuXG4gICAgICAgIGZvciAodmFyIGVsZW0gb2YgZWxlbXMpIHtcbiAgICAgICAgICAgIGVsZW0uaW5uZXJIVE1MID0gZm9ybWF0UHJpY2VIdG1sKHByaWNlLCBwcmljZVJlZ3VsYXIsIGNhbXBhaWduKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImltcG9ydCB7IHNldFN0b3JhZ2UsIHJlbW92ZVN0b3JhZ2UsIGdldFN0b3JhZ2UgfSBmcm9tIFwiLi4vLi4vc2NyaXB0cy91dGlscy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmlsdGVyIHtcblxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHR0aGlzLmluaXQoKTtcblx0fVxuXG5cdHJlaW5pdCgpIHtcblx0XHR0aGlzLmluaXQoKTtcblx0XHRkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImFmdGVyX2ZpbHRlclwiKSk7XG5cdH1cblxuXHRpbml0KCkge1xuXHRcdGlmIChkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdwYWdlX19maWx0ZXInKS5sZW5ndGggPT0gMCkgcmV0dXJuO1xuXHRcdGlmICh3aW5kb3cubG9jYXRpb24uaGFzaCkgdGhpcy5zZXRGaWx0ZXJGcm9tSGFzaCgpO1xuXG5cdFx0bGV0IG1haW4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwibWFpblwiKVxuXHRcdGxldCBncmlkID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5wcm9kdWN0LS1ncm91cFwiKVxuXHRcdGxldCBncmlkVG9nZ2xlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuZ3JpZC1pY29uXCIpXG5cblx0XHRpZiAoc2NyZWVuLndpZHRoIDwgNzY4ICYmIGdldFN0b3JhZ2UoJ2Fpcl92aWV3XycgKyBmaWx0ZXJTZXR0aW5ncy5nZXQoJ2lkJykpID09ICdzaW5nbGUnKSB7XG5cdFx0XHRtYWluLmNsYXNzTGlzdC5hZGQoXCJzaW5nbGVcIilcblx0XHRcdGdyaWQuY2xhc3NMaXN0LmFkZChcInNpbmdsZVwiKVxuXG5cdFx0XHRncmlkVG9nZ2xlcy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG5cdFx0XHRcdGlmIChlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnc2luZ2xlJykpIHtcblx0XHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIilcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHR9XG5cblx0XHRncmlkVG9nZ2xlcy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG5cdFx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGdyaWRUb2dnbGVzLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0pIHtcblx0XHRcdFx0XHRpdGVtLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIilcblx0XHRcdFx0fSlcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpXG5cblx0XHRcdFx0aWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKFwic2luZ2xlXCIpKSB7XG5cdFx0XHRcdFx0bWFpbi5jbGFzc0xpc3QuYWRkKFwic2luZ2xlXCIpXG5cdFx0XHRcdFx0Z3JpZC5jbGFzc0xpc3QuYWRkKFwic2luZ2xlXCIpXG5cdFx0XHRcdFx0c2V0U3RvcmFnZSgnYWlyX3ZpZXdfJyArIGZpbHRlclNldHRpbmdzLmdldCgnaWQnKSwgJ3NpbmdsZScpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG1haW4uY2xhc3NMaXN0LnJlbW92ZShcInNpbmdsZVwiKVxuXHRcdFx0XHRcdGdyaWQuY2xhc3NMaXN0LnJlbW92ZShcInNpbmdsZVwiKVxuXHRcdFx0XHRcdHJlbW92ZVN0b3JhZ2UoJ2Fpcl92aWV3XycgKyBmaWx0ZXJTZXR0aW5ncy5nZXQoJ2lkJykpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdH0pXG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmZpbHRlcl9saW5rXCIpLmZvckVhY2goKGVsZW1lbnQpID0+IHtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcblx0XHRcdFx0dGhpcy5jbGVhckZpbHRlcigpO1xuXHRcdFx0XHRjb25zdCBpZHMgPSBlbGVtZW50LmRhdGFzZXQuaWQuc3BsaXQoJywnKTtcblx0XHRcdFx0Y29uc3QgdmFsdWVzID0gZWxlbWVudC5kYXRhc2V0LnZhbHVlLnRvTG93ZXJDYXNlKCkuc3BsaXQoJywnKTtcblxuXHRcdFx0XHRpZHMuZm9yRWFjaCgoaWQpID0+IHtcblx0XHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmZpbHRlcl9fY29udGFpbmVyXCIpLmZvckVhY2goKHcpID0+IHtcblx0XHRcdFx0XHRcdGlmICh3LmRhdGFzZXQuaWQgPT0gaWQpIHtcblx0XHRcdFx0XHRcdFx0dy5xdWVyeVNlbGVjdG9yQWxsKFwiLmZpbHRlcl9fY29udGFpbmVyLS1pdGVtc1wiKS5mb3JFYWNoKChpbnB1dCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHZhbHVlcy5pbmNsdWRlcyhpbnB1dC5kYXRhc2V0LmZpbHRlci50b0xvd2VyQ2FzZSgpKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlucHV0LmNsaWNrKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cblx0XHR0aGlzLm1vcmVCdXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmlsdGVyX21vcmUnKTtcblx0XHR0aGlzLnNvcnRTZWxlY3QgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInNvcnQtb3JkZXJcIik7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyX190aXRsZScpLmZvckVhY2goZmlsdGVyID0+IHtcblx0XHRcdGZpbHRlci5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuXG5cdFx0XHRcdHZhciBhY3RpdmVfZmlsdGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmZpbHRlci4tLWFjdGl2ZScpO1xuXHRcdFx0XHRpZiAoYWN0aXZlX2ZpbHRlcikge1xuXHRcdFx0XHRcdGlmIChhY3RpdmVfZmlsdGVyICE9IGZpbHRlci5wYXJlbnROb2RlKSB7XG5cdFx0XHRcdFx0XHRhY3RpdmVfZmlsdGVyLmNsYXNzTGlzdC5yZW1vdmUoXCItLWFjdGl2ZVwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0ZmlsdGVyLnBhcmVudE5vZGUuY2xhc3NMaXN0LnRvZ2dsZSgnLS1hY3RpdmUnKTtcblx0XHRcdH0pXG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudWwtbGktbGlzdCBzcGFuJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiBlbGVtZW50LnBhcmVudE5vZGUuY2xhc3NMaXN0LnRvZ2dsZSgnLS1hY3RpdmUnKSk7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYnRuLS1maWx0ZXIsIC5wYWdlLS1zZXR0aW5ncy0taGVhZCcpLmZvckVhY2goYnV0dG9uID0+IHtcblx0XHRcdGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0XHRkb2N1bWVudFxuXHRcdFx0XHRcdC5xdWVyeVNlbGVjdG9yQWxsKFxuXHRcdFx0XHRcdFx0XCIucGFnZS0tc2V0dGluZ3MtLXdyYXBwZXIsIGRlcGFydG1lbnRzLS1zZXR0aW5ncy0td3JhcHBlclwiXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdC5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG5cdFx0XHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoXCItLWFjdGl2ZVwiKVxuXHRcdFx0XHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5iYWNrZHJvcFwiKS5jbGFzc0xpc3QudG9nZ2xlKFwiZmlsdGVyLW9wZW5cIilcblx0XHRcdFx0XHR9KVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyX19jb250YWluZXItLWl0ZW1zJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiB0aGlzLmhhbmRsZUV2ZW50KGVsZW1lbnQsIGV2ZW50KSk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLnBhZ2luYXRpb25FdmVudHMoKTtcblxuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5maWx0ZXJfY2xlYXInKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXHRcdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGV2ZW50ID0+IHsgdGhpcy5jbGVhckZpbHRlcigpOyB0aGlzLmdldCgpIH0pO1xuXHRcdH0pO1xuXG5cdFx0aWYgKHRoaXMubW9yZUJ1dHRvbikgdGhpcy5tb3JlQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZXZlbnQgPT4ge1xuXHRcdFx0XG5cdFx0XHRpZiAoIXRoaXMubG9hZCkge1xuXHRcdFx0XHR0aGlzLmxvYWQgPSB0cnVlO1xuXHRcdFx0XHR0aGlzLmdldChmaWx0ZXJTZXR0aW5ncy5nZXQoJ2N1cnJlbnRfb2Zmc2V0JykgPyBmaWx0ZXJTZXR0aW5ncy5nZXQoJ2N1cnJlbnRfb2Zmc2V0JykgOiBmaWx0ZXJTZXR0aW5ncy5nZXQoJ3BhZ2Vfc2l6ZScpLCAxKTtcblx0XHRcdFx0dGhpcy5pbmZpbml0X3Njcm9sbCgpO1xuXHRcdFx0XHRoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uID0gXCJtYW51YWxcIjtcblx0XHRcdH07XG5cdFx0fSk7XG5cdFx0aWYgKHRoaXMuc29ydFNlbGVjdCkgdGhpcy5zb3J0U2VsZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGV2ZW50ID0+IHtcblx0XHRcdHRoaXMuZ2V0KCk7XG5cdFx0XHRsZXQgW3NvcnQsIG9yZGVyXSA9IHRoaXMuc29ydFNlbGVjdCA/IHRoaXMuc29ydFNlbGVjdC52YWx1ZS5zcGxpdCgnLScpIDogW1wiXCIsIFwiXCJdO1xuXHRcdFx0dGhpcy5zZXRTdGF0ZSh7XG5cdFx0XHRcdFwic29ydFwiOiBzb3J0LFxuXHRcdFx0XHRcIm9yZGVyXCI6IG9yZGVyLFxuXHRcdFx0XHRcInBhZ2VcIjogJycsXG5cdFx0XHR9KTtcblx0XHR9KTtcblxuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNzb3J0LW9yZGVyLXVsIGxpJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiB7XG5cdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJyNzb3J0LW9yZGVyLXVsIGxpJykuZm9yRWFjaChzb3J0X2xpID0+IHtcblx0XHRcdFx0XHRzb3J0X2xpLmNsYXNzTGlzdC5yZW1vdmUoXCItLWFjdGl2ZVwiKTtcblx0XHRcdFx0fSk7XG5cdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5hY3RpdmVfc29ydF9sYWJlbCcpLmZvckVhY2gobGFiZWwgPT4ge1xuXHRcdFx0XHRcdGxhYmVsLmlubmVySFRNTCA9IGVsZW1lbnQuaW5uZXJIVE1MO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiLS1hY3RpdmVcIik7XG5cblx0XHRcdFx0ZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUuY2xhc3NMaXN0LnJlbW92ZSgnLS1hY3RpdmUnKTtcblxuXHRcdFx0XHR0aGlzLmdldCgpO1xuXHRcdFx0XHRsZXQgW3NvcnQsIG9yZGVyXSA9IGVsZW1lbnQuZGF0YXNldC52YWx1ZS5zcGxpdCgnLScpO1xuXG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUoe1xuXHRcdFx0XHRcdFwic29ydFwiOiBzb3J0LFxuXHRcdFx0XHRcdFwib3JkZXJcIjogb3JkZXIsXG5cdFx0XHRcdFx0XCJwYWdlXCI6ICcnXG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwic29ydF9jaGFuZ2VkXCIsIHtcblx0XHRcdFx0XHQnZGV0YWlsJzoge1xuXHRcdFx0XHRcdFx0J3NvcnQnOiBzb3J0LFxuXHRcdFx0XHRcdFx0J29yZGVyJzogb3JkZXJcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pKTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmJyYW5kX2ZpbHRlcl9pbnB1dCcpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZXZlbnQgPT4geyB0aGlzLmZpbHRlcl9icmFuZHMoZWxlbWVudC52YWx1ZSk7IH0pO1xuXHRcdH0pO1xuXG5cdFx0d2luZG93LmxpdmVFdmVudChcImJvZHlcIiwgXCJjbGlja1wiLCAoZXZlbnQsIGVsZW1lbnQpID0+IHtcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5maWx0ZXIuLS1hY3RpdmUnKS5mb3JFYWNoKGFjdGl2ZV9maWx0ZXIgPT4ge1xuXG5cdFx0XHRcdGlmICghYWN0aXZlX2ZpbHRlci5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG5cdFx0XHRcdFx0YWN0aXZlX2ZpbHRlci5jbGFzc0xpc3QucmVtb3ZlKFwiLS1hY3RpdmVcIik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyLi0tYWN0aXZlLCAudWwtbGktbGlzdC4tLWFjdGl2ZScpLmZvckVhY2goYWN0aXZlX2ZpbHRlciA9PiB7XG5cblx0XHRcdFx0aWYgKCFhY3RpdmVfZmlsdGVyLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcblx0XHRcdFx0XHRhY3RpdmVfZmlsdGVyLmNsYXNzTGlzdC5yZW1vdmUoXCItLWFjdGl2ZVwiKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdyZWZyZXNoX2ZpbHRlcicsICgpID0+IHtcblx0XHRcdHRoaXMuZ2V0KCk7XG5cdFx0fSk7XG5cdH1cblxuXHRoYW5kbGVFdmVudChlbGVtZW50LCBldmVudCkge1xuXHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHRpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJy0tZGlzYWJsZWQnKSkgcmV0dXJuO1xuXG5cdFx0ZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKCctLWFjdGl2ZScpO1xuXHRcdHRoaXMuZ2V0KCk7XG5cblx0XHQvKiBTY3JvbGwgdG8gZmlsdGVyIG9uIGZpbHRlcnNlbGVjdCAqL1xuXHRcdGNvbnN0IFNjcm9sbFRvRmlsdGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ0ZpbHRlckFuY2hvcicpO1xuXHRcdGNvbnN0IGhlYWRlckhlaWdodCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdoZWFkZXInKS5vZmZzZXRIZWlnaHRcblx0XHR3aW5kb3cuc2Nyb2xsVG8oe1xuXHRcdFx0dG9wOiBTY3JvbGxUb0ZpbHRlci5vZmZzZXRUb3AgLSBoZWFkZXJIZWlnaHQsXG5cdFx0XHRsZWZ0OiAwLFxuXHRcdFx0YmVoYXZpb3I6ICdzbW9vdGgnXG5cdFx0fSk7XG5cblx0fVxuXG5cdHVwZGF0ZUZpbHRlckNvdW50KCkge1xuXHRcdC8qIEZpbHRlciBjaG9pY2UgY291bnRlciovXG5cdFx0bGV0IGZpbHRlcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnBhZ2VfX2ZpbHRlciAuZmlsdGVyXCIpXG5cdFx0ZmlsdGVycy5mb3JFYWNoKChmaWx0ZXIpID0+IHtcblx0XHRcdGxldCBhY3RpdmVGaWx0ZXIgPSBmaWx0ZXIucXVlcnlTZWxlY3RvckFsbChcblx0XHRcdFx0XCIuZmlsdGVyX19jb250YWluZXItLWl0ZW1zLi0tYWN0aXZlXCJcblx0XHRcdClcblx0XHRcdGlmIChhY3RpdmVGaWx0ZXIubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRmaWx0ZXIucXVlcnlTZWxlY3RvcihcIi5hY3RpdmVfbmJyXCIpLmlubmVySFRNTCA9XG5cdFx0XHRcdFx0XCI8c3BhbiBjbGFzcz0nZmlsdGVyQ291bnQnPihcIiArIGFjdGl2ZUZpbHRlci5sZW5ndGggKyBcIik8L3NwYW4+XCJcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZpbHRlci5xdWVyeVNlbGVjdG9yKFwiLmFjdGl2ZV9uYnJcIikuaW5uZXJIVE1MID0gJydcblx0XHRcdH1cblx0XHR9KVxuXHR9XG5cblx0YXN5bmMgZ2V0KG9mZnNldCwgYXBwZW5kKSB7XG5cdFx0dGhpcy51cGRhdGVGaWx0ZXJDb3VudCgpO1xuXG5cdFx0Y29uc3QgZGF0YSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcblx0XHRsZXQgZmlsdGVyUGFyYW1zID0gXCJcIjtcblxuXHRcdG9mZnNldCA9IG9mZnNldCA/IG9mZnNldCA6IDA7XG5cblx0XHRjb25zdCBzZWxlY3RlZEZpbHRlcnMgPSB0aGlzLmdldFNlbGVjdGVkRmlsdGVycygpO1xuXHRcdHRoaXMuc2V0U2VsZWN0ZWRGaWx0ZXJCb3hlcyhzZWxlY3RlZEZpbHRlcnMpO1xuXG5cdFx0T2JqZWN0LmtleXMoc2VsZWN0ZWRGaWx0ZXJzKS5mb3JFYWNoKGlkID0+IHtcblx0XHRcdGlmIChmaWx0ZXJQYXJhbXMpIGZpbHRlclBhcmFtcyArPSBcIjtcIjtcblx0XHRcdGZpbHRlclBhcmFtcyArPSBpZCArIFwiOlwiO1xuXG5cdFx0XHRsZXQgdmFsdWVzID0gXCJcIjtcblx0XHRcdHNlbGVjdGVkRmlsdGVyc1tpZF0uZm9yRWFjaCh2YWx1ZSA9PiB7XG5cdFx0XHRcdGlmICh2YWx1ZXMpIHZhbHVlcyArPSBcIixcIjtcblx0XHRcdFx0dmFsdWVzICs9IHZhbHVlO1xuXHRcdFx0fSk7XG5cdFx0XHRmaWx0ZXJQYXJhbXMgKz0gdmFsdWVzO1xuXHRcdH0pO1xuXG5cdFx0Y29uc3QganNvbl9maWx0ZXIgPSBKU09OLnN0cmluZ2lmeShzZWxlY3RlZEZpbHRlcnMpO1xuXHRcdGlmICh3aW5kb3cubG9jYXRpb24uaGFzaCB8fCBqc29uX2ZpbHRlciAhPT0gXCJ7fVwiKSB7XG5cdFx0XHR3aW5kb3cubG9jYXRpb24uaGFzaCA9IGpzb25fZmlsdGVyXG5cdFx0fVxuXG5cdFx0bGV0IFtzb3J0LCBvcmRlcl0gPSB0aGlzLnNvcnRTZWxlY3QgPyB0aGlzLnNvcnRTZWxlY3QudmFsdWUuc3BsaXQoJy0nKSA6IFtcIlwiLCBcIlwiXTtcblxuXHRcdGxldCBzb3J0X3VsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnI3NvcnQtb3JkZXItdWwgbGkuLS1hY3RpdmUnKVswXTtcblx0XHRbc29ydCwgb3JkZXJdID0gc29ydF91bCA/IHNvcnRfdWwuZGF0YXNldC52YWx1ZS5zcGxpdCgnLScpIDogW1wiXCIsIFwiXCJdO1xuXG5cdFx0ZGF0YS5hcHBlbmQoJ2Z1bmsnLCAnZ2V0X2ZpbHRlcicpO1xuXHRcdGZpbHRlclNldHRpbmdzLmdldCgncmVxdWVzdF90eXBlJykgPT09ICdzZWFyY2gnID8gZGF0YS5hcHBlbmQoJ3EnLCBmaWx0ZXJTZXR0aW5ncy5nZXQoJ3EnKSkgOiBkYXRhLmFwcGVuZCgnaWQnLCBmaWx0ZXJTZXR0aW5ncy5nZXQoJ2lkJykpO1xuXHRcdGRhdGEuYXBwZW5kKCd0eXBlJywgZmlsdGVyU2V0dGluZ3MuZ2V0KCdyZXF1ZXN0X3R5cGUnKSk7XG5cdFx0ZGF0YS5hcHBlbmQoJ2ZpbHRlcl9wYXJhbXMnLCBqc29uX2ZpbHRlcik7XG5cdFx0ZGF0YS5hcHBlbmQoJ2pzb24nLCAxKTtcblx0XHRkYXRhLmFwcGVuZCgnc29ydCcsIHNvcnQpO1xuXHRcdGRhdGEuYXBwZW5kKCdvcmRlcicsIG9yZGVyKTtcblx0XHRkYXRhLmFwcGVuZCgnb2Zmc2V0Jywgb2Zmc2V0ID8gb2Zmc2V0IDogMCk7XG5cblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcCcsIHtcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0Ym9keTogZGF0YVxuXHRcdH0pO1xuXG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXHRcdGlmIChyZXN1bHQucmVxdWVzdF9kYXRhKSB7XG5cdFx0XHRsZXQgY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5yb3cucHJvZHVjdC0tZ3JvdXBcIik7XG5cdFx0XHRpZiAoIWNvbnRhaW5lcikgcmV0dXJuO1xuXG5cdFx0XHRpZiAocmVzdWx0LnJlcXVlc3RfZGF0YS5maWx0ZXJzKSB0aGlzLnNldEluYWN0aXZlKHJlc3VsdC5yZXF1ZXN0X2RhdGEuZmlsdGVycyk7XG5cblx0XHRcdGlmIChhcHBlbmQpIHtcblx0XHRcdFx0Y29udGFpbmVyLmluc2VydEFkamFjZW50SFRNTChcImJlZm9yZWVuZFwiLCByZXN1bHQucmVxdWVzdF9kYXRhLmh0bWwpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdGNvbnRhaW5lci5pbm5lckhUTUwgPSByZXN1bHQucmVxdWVzdF9kYXRhLmh0bWw7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0aGlzLm1vcmVCdXR0b24pIHtcblx0XHRcdFx0aWYgKG9mZnNldCArIHJlc3VsdC5yZXF1ZXN0X2RhdGEuY291bnQgPj0gcmVzdWx0LnJlcXVlc3RfZGF0YS50b3RhbF9jb3VudCkge1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nKClcblx0XHRcdFx0XHR0aGlzLm1vcmVCdXR0b24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdFx0XHR0aGlzLm1vcmVCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnaW5maW5pdGUnKTtcblxuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMubW9yZUJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJyc7XG5cdFx0XHRcdFx0bGV0IGN1cnJlbnRVcmwgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWVcblxuXHRcdFx0XHRcdGlmICh0eXBlb2YgZ2EgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0XHRnYShcInNldFwiLCBcInBhZ2VcIiwgY3VycmVudFVybCArIFwiI1wiICsgb2Zmc2V0ICsgcmVzdWx0LnJlcXVlc3RfZGF0YS5jb3VudClcbiAgICAgICAgICBcdFx0XHRcdGdhKFwic2VuZFwiLCBcInBhZ2V2aWV3XCIpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XHRcblx0XHRcdH1cblxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmZpbHRlcl9jb3VudF9zaG93aW5nJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5pbm5lckhUTUwgPSBvZmZzZXQgKyByZXN1bHQucmVxdWVzdF9kYXRhLmNvdW50O1xuXHRcdFx0fSk7XG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyX2NvdW50X3RvdGFsJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5pbm5lckhUTUwgPSByZXN1bHQucmVxdWVzdF9kYXRhLnRvdGFsX2NvdW50O1xuXHRcdFx0fSk7XG5cblx0XHRcdHdpbmRvdy5sYXp5TG9hZEluc3RhbmNlLnVwZGF0ZSgpO1xuXG5cdFx0XHRmaWx0ZXJTZXR0aW5ncy5zZXQoJ3RvdGFsX2NvdW50JywgcmVzdWx0LnJlcXVlc3RfZGF0YS50b3RhbF9jb3VudCk7XG5cdFx0XHRmaWx0ZXJTZXR0aW5ncy5zZXQoJ2N1cnJlbnRfb2Zmc2V0Jywgb2Zmc2V0ICsgcmVzdWx0LnJlcXVlc3RfZGF0YS5jb3VudCk7XG5cblx0XHRcdGlmICghb2Zmc2V0KSB7XG5cdFx0XHRcdHRoaXMuc2V0U3RhdGUoeyBcInBhZ2VcIjogJycgfSk7XG5cdFx0XHRcdHRoaXMudXBkYXRlUGFnaW5hdGlvbigxKTtcblx0XHRcdH1cblxuXHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJhZnRlcl9maWx0ZXJcIikpO1xuXHRcdFx0aWYgKHRoaXMubW9yZUJ1dHRvbikgdGhpcy5tb3JlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoJ2xvYWRpbmcnKTtcblx0XHRcdHRoaXMubG9hZCA9IGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdGdldFNlbGVjdGVkRmlsdGVycygpIHtcblx0XHRsZXQgc2VsZWN0ZWRGaWx0ZXJzID0ge307XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyX19jb250YWluZXInKS5mb3JFYWNoKGZpbHRlcl90eXBlID0+IHtcblx0XHRcdGZpbHRlcl90eXBlLnF1ZXJ5U2VsZWN0b3JBbGwoJy5maWx0ZXJfX2NvbnRhaW5lci0taXRlbXMuLS1hY3RpdmUnKS5mb3JFYWNoKG9wdGlvbiA9PiB7XG5cdFx0XHRcdGlmICghc2VsZWN0ZWRGaWx0ZXJzW2ZpbHRlcl90eXBlLmRhdGFzZXQuaWRdKSB7XG5cdFx0XHRcdFx0c2VsZWN0ZWRGaWx0ZXJzW2ZpbHRlcl90eXBlLmRhdGFzZXQuaWRdID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0c2VsZWN0ZWRGaWx0ZXJzW2ZpbHRlcl90eXBlLmRhdGFzZXQuaWRdLnB1c2gob3B0aW9uLmRhdGFzZXQudmFsdWUpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gc2VsZWN0ZWRGaWx0ZXJzO1xuXHR9XG5cblx0Y2xlYXJGaWx0ZXIoKSB7XG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmZpbHRlcl9fY29udGFpbmVyIC4tLWFjdGl2ZScpLmZvckVhY2goaXRlbSA9PiB7XG5cdFx0XHRpdGVtLmNsYXNzTGlzdC5yZW1vdmUoJy0tYWN0aXZlJyk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXRTZWxlY3RlZEZpbHRlckJveGVzKHNlbGVjdGVkRmlsdGVycykge1xuXHRcdGxldCBzZWxlY3RlZEZpbHRlckJveGVzID0gXCJcIjtcblx0XHRjb25zdCBwYXJlbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsZWN0ZWRfZmlsdGVycycpO1xuXHRcdGlmICghcGFyZW50KSByZXR1cm47XG5cblx0XHRPYmplY3Qua2V5cyhzZWxlY3RlZEZpbHRlcnMpLmZvckVhY2goaWQgPT4ge1xuXG5cdFx0XHRzZWxlY3RlZEZpbHRlcnNbaWRdLmZvckVhY2godmFsdWUgPT4ge1xuXHRcdFx0XHRzZWxlY3RlZEZpbHRlckJveGVzICs9ICc8c3BhbiBjbGFzcz1cInNlbGVjdGVkX2ZpbHRlciBsaWdodC1iZWlnZS1iZy0yMCB0ZXh0LS11cHBlcmNhc2VcIiBkYXRhLWlkPVwiJyArIGlkICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgdmFsdWUgKyAnXCI+JyArIHZhbHVlICsgJzxzdmcgd2lkdGg9XCI5XCIgaGVpZ2h0PVwiMTBcIiB2aWV3Qm94PVwiMCAwIDkgMTBcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cHM6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIk04LjUgMUw0LjUgNU00LjUgNUwwLjUgOU00LjUgNUw4LjUgOU00LjUgNUwwLjUgMVwiIHN0cm9rZT1cImJsYWNrXCIvPjwvc3ZnPjwvc3Bhbj4nO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cGFyZW50LmlubmVySFRNTCA9IHNlbGVjdGVkRmlsdGVyQm94ZXM7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuc2VsZWN0ZWRfZmlsdGVyJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiB7IHRoaXMudG9nZ2xlRmlsdGVyVmFsdWUoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSwgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKSk7IHRoaXMuZ2V0KCk7IH0pO1xuXHRcdH0pO1xuXG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmZpbHRlcl9jbGVhcicpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRzZWxlY3RlZEZpbHRlckJveGVzID8gZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZVwiKSA6IGVsZW1lbnQuY2xhc3NMaXN0LmFkZChcImhpZGVcIik7XG5cdFx0XHRzZWxlY3RlZEZpbHRlckJveGVzID8gZWxlbWVudC5wYXJlbnROb2RlLmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRlXCIpIDogZWxlbWVudC5wYXJlbnROb2RlLmNsYXNzTGlzdC5hZGQoXCJoaWRlXCIpXG5cdFx0fSk7XG5cdH1cblxuXHRzZXRJbmFjdGl2ZShmaWx0ZXJzKSB7XG5cdFx0ZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiB7XG5cdFx0XHRpZiAoZmlsdGVyLnR5cGUgPT09IFwiVHJlZVwiKSB7XG5cdFx0XHRcdHRoaXMuc2V0SW5hY3RpdmVUcmVlKGZpbHRlci5pZCwgZmlsdGVyLnZhbHVlcyk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIGlmIChmaWx0ZXIudHlwZSA9PT0gXCJTbGlkZXJfUmFuZ2VcIikge1xuXHRcdFx0XHR0aGlzLnNldEluYWN0aXZlU2xpZGVyKGZpbHRlci5pZCwgZmlsdGVyLnZhbHVlcyk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlIHtcblx0XHRcdFx0dGhpcy5zZXRJbmFjdGl2ZUxpc3QoZmlsdGVyKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdHNldEluYWN0aXZlTGlzdChmaWx0ZXIpIHtcblx0XHRsZXQgaWQgPSBmaWx0ZXIuaWQ7XG5cdFx0bGV0IHZhbHVlcyA9IGZpbHRlci52YWx1ZXM7XG5cdFx0bGV0IHR5cGUgPSBmaWx0ZXIudHlwZTtcblxuXHRcdGlmICh0eXBlID09PSAncmFuZ2UnKSByZXR1cm47XG5cblx0XHRsZXQgZW5hYmxlZF9vcHRpb25zID0ge307XG5cdFx0dmFsdWVzLmZvckVhY2godmFsdWUgPT4ge1xuXHRcdFx0ZW5hYmxlZF9vcHRpb25zW3ZhbHVlLnZhbHVlXSA9IDE7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyX19jb250YWluZXJbZGF0YS1pZD0nICsgaWQgKyAnXSAuZmlsdGVyX19jb250YWluZXItLWl0ZW1zJykuZm9yRWFjaChvcHRpb24gPT4ge1xuXHRcdFx0ZW5hYmxlZF9vcHRpb25zW29wdGlvbi5kYXRhc2V0LnZhbHVlXSA/IG9wdGlvbi5jbGFzc0xpc3QucmVtb3ZlKFwiLS1kaXNhYmxlZFwiKSA6IG9wdGlvbi5jbGFzc0xpc3QuYWRkKFwiLS1kaXNhYmxlZFwiKTtcblx0XHR9KTtcblx0fVxuXG5cdHRvZ2dsZUZpbHRlclZhbHVlKGlkLCB2YWx1ZSkge1xuXHRcdGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZmlsdGVyX19jb250YWluZXJbZGF0YS1pZD1cIicgKyBpZCArICdcIl0gLmZpbHRlcl9fY29udGFpbmVyLS1pdGVtc1tkYXRhLXZhbHVlPVwiJyArIHZhbHVlICsgJ1wiXScpO1xuXHRcdGlmIChlbGVtZW50KSBlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoJy0tYWN0aXZlJylcblxuXHR9XG5cblx0c2V0RmlsdGVyRnJvbUhhc2goKSB7XG5cdFx0Y29uc3Qgc2VsZWN0ZWRGaWx0ZXJzID0gSlNPTi5wYXJzZShkZWNvZGVVUkkod2luZG93LmxvY2F0aW9uLmhhc2guc2xpY2UoMSkpKTtcblxuXHRcdE9iamVjdC5rZXlzKHNlbGVjdGVkRmlsdGVycykuZm9yRWFjaChpZCA9PiB7XG5cdFx0XHRzZWxlY3RlZEZpbHRlcnNbaWRdLmZvckVhY2godmFsdWUgPT4ge1xuXHRcdFx0XHR0aGlzLnRvZ2dsZUZpbHRlclZhbHVlKGlkLCB2YWx1ZSk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblxuXHRcdGlmIChPYmplY3Qua2V5cyhzZWxlY3RlZEZpbHRlcnMpLmxlbmd0aCkgdGhpcy5nZXQoKTtcblx0fVxuXG5cdHNldFN0YXRlKGluUGFyYW1zKSB7XG5cdFx0Y29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcblxuXHRcdE9iamVjdC5rZXlzKGluUGFyYW1zKS5mb3JFYWNoKG5hbWUgPT4ge1xuXHRcdFx0aW5QYXJhbXNbbmFtZV0gPyBwYXJhbXMuc2V0KG5hbWUsIGluUGFyYW1zW25hbWVdKSA6IHBhcmFtcy5kZWxldGUobmFtZSk7XG5cdFx0fSk7XG5cblx0XHRsZXQgbmV3VXJsID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lO1xuXHRcdGxldCBzZWFyY2ggPSBwYXJhbXMudG9TdHJpbmcoKTtcblx0XHRpZiAoc2VhcmNoKSB7XG5cdFx0XHRuZXdVcmwgKz0gXCI/XCIgKyBwYXJhbXMudG9TdHJpbmcoKTtcblx0XHR9XG5cblx0XHRpZiAod2luZG93LmxvY2F0aW9uLmhhc2ggJiYgd2luZG93LmxvY2F0aW9uLmhhc2ggIT09IFwiI3t9XCIpIHsgbmV3VXJsICs9IHdpbmRvdy5sb2NhdGlvbi5oYXNoIH07XG5cdFx0d2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsIFwiXCIsIGRlY29kZVVSSUNvbXBvbmVudChuZXdVcmwpKTtcblxuXHRcdGlmICh0eXBlb2YgZ2EgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRnYSgnc2V0JywgJ3BhZ2UnLCBuZXdVcmwpXG5cdFx0XHRnYSgnc2VuZCcsICdwYWdldmlldycpXG5cdFx0fVxuXHR9XG5cblx0cGFnaW5hdGlvbkV2ZW50cygpIHtcblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcucGFnaW5hdGlvbi1wYWdlOm5vdCgtLWRvdHMpJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBldmVudCA9PiB7XG5cdFx0XHRcdHRoaXMuZ2V0KChwYXJzZUludChlbGVtZW50LnRleHRDb250ZW50KSAtIDEpICogZmlsdGVyU2V0dGluZ3MuZ2V0KCdwYWdlX3NpemUnKSlcblx0XHRcdFx0dGhpcy5zZXRTdGF0ZSh7IFwicGFnZVwiOiBlbGVtZW50LnRleHRDb250ZW50IH0pO1xuXHRcdFx0XHR0aGlzLnVwZGF0ZVBhZ2luYXRpb24ocGFyc2VJbnQoZWxlbWVudC50ZXh0Q29udGVudCkpO1xuXHRcdFx0XHR3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiBcInNtb290aFwiIH0pO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHR1cGRhdGVQYWdpbmF0aW9uKGFjdGl2ZV9wYWdlKSB7XG5cdFx0bGV0IG51bWJlcl9vZl9wYWdlcyA9IE1hdGguY2VpbChmaWx0ZXJTZXR0aW5ncy5nZXQoJ3RvdGFsX2NvdW50JykgLyBmaWx0ZXJTZXR0aW5ncy5nZXQoJ3BhZ2Vfc2l6ZScpKTtcblxuXHRcdGlmIChhY3RpdmVfcGFnZSA+IG51bWJlcl9vZl9wYWdlcykgeyBhY3RpdmVfcGFnZSA9IG51bWJlcl9vZl9wYWdlczsgfVxuXG5cdFx0bGV0IHBhZ2luYXRpb24gPSBhY3RpdmVfcGFnZSA9PSAxID8gJzxzcGFuIGNsYXNzPVwicGFnaW5hdGlvbi1wYWdlIC0tYWN0aXZlXCI+MTwvc3Bhbj4nIDogJzxzcGFuIGNsYXNzPVwicGFnaW5hdGlvbi1wYWdlIGRhcmstZ3JleS10ZXh0XCI+MTwvc3Bhbj4nO1xuXHRcdGlmIChhY3RpdmVfcGFnZSAtIDIgPiAyKSB7XG5cdFx0XHRwYWdpbmF0aW9uICs9ICc8c3BhbiBjbGFzcz1cInBhZ2luYXRpb24tcGFnZSAtLWRvdHMgZGFyay1ncmV5LXRleHRcIj4uLi48L3NwYW4+Jztcblx0XHR9XG5cblx0XHRsZXQgbnVtYmVyID0gYWN0aXZlX3BhZ2UgLSAyID4gMiA/IGFjdGl2ZV9wYWdlIC0gMiA6IDI7XG5cdFx0bGV0IHBhZ2VfY291bnQgPSAxO1xuXHRcdGxldCBsb29wcyA9IGFjdGl2ZV9wYWdlIDwgNCA/IDQgOiA1O1xuXG5cdFx0d2hpbGUgKG51bWJlciA+IDEgJiYgbnVtYmVyIDwgbnVtYmVyX29mX3BhZ2VzICYmIHBhZ2VfY291bnQgPD0gbG9vcHMpIHtcblx0XHRcdGlmIChudW1iZXIgPj0gbnVtYmVyX29mX3BhZ2VzKSBicmVhaztcblx0XHRcdHBhZ2luYXRpb24gKz0gYWN0aXZlX3BhZ2UgPT0gbnVtYmVyID8gJzxzcGFuIGNsYXNzPVwicGFnaW5hdGlvbi1wYWdlIC0tYWN0aXZlXCI+JyArIG51bWJlciArICc8L3NwYW4+JyA6ICc8c3BhbiBjbGFzcz1cInBhZ2luYXRpb24tcGFnZSBkYXJrLWdyZXktdGV4dFwiPicgKyBudW1iZXIgKyAnPC9zcGFuPic7XG5cblx0XHRcdHBhZ2VfY291bnQgKz0gMTtcblx0XHRcdG51bWJlciArPSAxO1xuXHRcdH1cblxuXHRcdGlmIChhY3RpdmVfcGFnZSArIDMgPCBudW1iZXJfb2ZfcGFnZXMpIHtcblx0XHRcdHBhZ2luYXRpb24gKz0gJzxzcGFuIGNsYXNzPVwicGFnaW5hdGlvbi1wYWdlIC0tZG90cyBkYXJrLWdyZXktdGV4dFwiPi4uLjwvc3Bhbj4nO1xuXHRcdH1cblxuXHRcdGlmIChudW1iZXJfb2ZfcGFnZXMgPiAxKSB7XG5cdFx0XHRwYWdpbmF0aW9uICs9IGFjdGl2ZV9wYWdlID09IG51bWJlcl9vZl9wYWdlcyA/ICc8c3BhbiBjbGFzcz1cInBhZ2luYXRpb24tcGFnZSAtLWFjdGl2ZVwiPicgKyBudW1iZXJfb2ZfcGFnZXMgKyAnPC9zcGFuPicgOiAnPHNwYW4gY2xhc3M9XCJwYWdpbmF0aW9uLXBhZ2UgZGFyay1ncmV5LXRleHRcIj4nICsgbnVtYmVyX29mX3BhZ2VzICsgJzwvc3Bhbj4nO1xuXHRcdH1cblxuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5wYWdlX25hdmlnYXRpb24nKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXHRcdFx0ZWxlbWVudC5pbm5lckhUTUwgPSBwYWdpbmF0aW9uO1xuXHRcdH0pO1xuXG5cdFx0dGhpcy5wYWdpbmF0aW9uRXZlbnRzKCk7XG5cdH1cblxuXHRmaWx0ZXJfYnJhbmRzKHZhbHVlKSB7XG5cdFx0aWYgKCF2YWx1ZSkge1xuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmZpbHRlcl9fY29udGFpbmVyW2RhdGEtaWQ9YnJhbmRdIC5maWx0ZXJfX2l0ZW0nKS5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuXHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWhpZGRlblwiKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5maWx0ZXJfX2NvbnRhaW5lcltkYXRhLWlkPWJyYW5kXSAuZmlsdGVyX19pdGVtJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QuYWRkKFwiLS1oaWRkZW5cIik7XG5cdFx0XHR9KTtcblxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmZpbHRlcl9fY29udGFpbmVyW2RhdGEtaWQ9YnJhbmRdIC5maWx0ZXJfX2l0ZW1bZGF0YS1maWx0ZXIqPVwiJyArIHZhbHVlLnRvTG93ZXJDYXNlKCkgKyAnXCJdJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdFx0ZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKFwiLS1oaWRkZW5cIik7XG5cdFx0XHR9KTtcblxuXHRcdH1cblx0fVxuXG5cdGluZmluaXRfc2Nyb2xsKCkge1xuXHRcdGlmICh0aGlzLm1vcmVCdXR0b24uY2xhc3NMaXN0LmNvbnRhaW5zKCdpbmZpbml0ZScpKSB7XG5cdFx0XHRsZXQgY291bnQgPSBwYXJzZUludCh0aGlzLm1vcmVCdXR0b24uZGF0YXNldC5jb3VudCk7XG5cdFx0XHRjb3VudCA9PSAzID8gdGhpcy5tb3JlQnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUoXCJpbmZpbml0ZVwiKSA6IHRoaXMubW9yZUJ1dHRvbi5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNvdW50XCIsIGNvdW50ICsgMSk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0dGhpcy5tb3JlQnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2luZmluaXRlJyk7XG5cdFx0XHR0aGlzLm1vcmVCdXR0b24uc2V0QXR0cmlidXRlKCdkYXRhLWNvdW50JywgMSk7XG5cblx0XHRcdGlmICghdGhpcy5tb3JlQnV0dG9uLmNsYXNzTGlzdC5jb250YWlucygnaW5maW5pdGVfaW5pdGlhdGVkJykpIHtcblx0XHRcdFx0Y29uc3QgYnRuID0gdGhpcy5tb3JlQnV0dG9uO1xuXG5cdFx0XHRcdHdpbmRvdy5vbnNjcm9sbCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRpZiAoYnRuKSB7XG5cdFx0XHRcdFx0XHRjb25zdCB0b190b3AgPSBidG4ub2Zmc2V0VG9wIC0gd2luZG93LnNjcm9sbFk7XG5cdFx0XHRcdFx0XHRpZiAodG9fdG9wIDw9IDIwMDApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCFidG4uY2xhc3NMaXN0LmNvbnRhaW5zKCdsb2FkaW5nJykgJiYgYnRuLmNsYXNzTGlzdC5jb250YWlucygnaW5maW5pdGUnKSkge1xuXHRcdFx0XHRcdFx0XHRcdGJ0bi5jbGljaygpO1xuXHRcdFx0XHRcdFx0XHRcdGJ0bi5jbGFzc0xpc3QuYWRkKCdsb2FkaW5nJyk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHRcdHRoaXMubW9yZUJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdpbmZpbml0ZV9pbml0aWF0ZWQnKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0iLCJpbXBvcnQgVmFyaWF0aW9uIGZyb20gXCIuL3ZhcmlhdGlvbi92YXJpYXRpb25cIlxuaW1wb3J0IEJ1bmRsZVByb2R1Y3QgZnJvbSBcIi4vYnVuZGxlX3Byb2R1Y3RcIlxuaW1wb3J0IEltYWdlWm9vbSBmcm9tIFwiLi96b29tXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUHJvZHVjdFBhZ2Uge1xuICBjb25zdHJ1Y3RvcihjYXJ0LCBidXlfYnV0dG9uX2lkID0gXCJhaXItYnV5XCIsIHF0eV9pbnB1dF9pZCA9IFwiYWlyLXF0eVwiKSB7XG4gICAgdGhpcy5jYXJ0ID0gY2FydFxuICAgIHRoaXMuYnV5X2J1dHRvbl9pZCA9IGJ1eV9idXR0b25faWRcbiAgICB0aGlzLnF0eV9pbnB1dF9pZCA9IHF0eV9pbnB1dF9pZFxuICAgIHRoaXMuYWxlcnRfcG9wdXAgPSB1bmRlZmluZWRcbiAgICB0aGlzLmNsb3NlQWxlcnQgPSB1bmRlZmluZWRcbiAgICBpZiAod2luZG93LnNob3Bfc2V0dGluZ3MucmVxdWVzdF90eXBlID09IFwicHJvZHVjdFwiKSB7XG4gICAgICB0aGlzLmluaXQoKVxuICAgIH1cbiAgfVxuXG4gIHJlaW5pdCgpIHtcbiAgICBpZiAodHlwZW9mKGxpcHNjb3JlKSAhPT0gXCJ1bmRlZmluZWRcIilcbiAgICB7XG4gICAgICBsaXBzY29yZS5pbml0V2lkZ2V0cygpXG4gICAgfVxuICAgIHRoaXMuaW5pdCgpXG4gICAgZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJwcm9kdWN0X2NlbGxfdXBkYXRlXCIpKVxuICB9XG5cbiAgaW5pdChzdGF0dXMpIHtcbiAgICB0aGlzLmJ1eV9idXR0b24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmJ1eV9idXR0b25faWQpXG4gICAgdGhpcy5xdHlfaW5wdXQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLnF0eV9pbnB1dF9pZClcblxuICAgIGRvY3VtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwicHJvZHVjdF9wYWdlX3ZpZXdlZFwiKSlcbiAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcInByb2R1Y3RfcGFnZV9zdHlsZXZpZXdcIikpXG5cbiAgICBpZiAod2luZG93LnZhcmlhbnRzKSB7XG4gICAgICB0aGlzLnZhcmlhdGlvbnMgPSBuZXcgVmFyaWF0aW9uKHdpbmRvdy52YXJpYW50cywgdGhpcy5idXlfYnV0dG9uKVxuICAgIH0gZWxzZSBpZiAod2luZG93LmJ1bmRsZV9maWVsZHMpIHtcbiAgICAgIHRoaXMuYnVuZGxlID0gbmV3IEJ1bmRsZVByb2R1Y3Qod2luZG93LmJ1bmRsZV9maWVsZHMsIHRoaXMuYnV5X2J1dHRvbilcbiAgICB9XG5cbiAgICBpZiAodGhpcy5idXlfYnV0dG9uKSB7XG4gICAgICB0aGlzLmJ1eV9idXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIHRoaXMuYWRkX2NhcnQoZSwgdGhpcy5idXlfYnV0dG9uKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyBpbml0IHNpbXBsZSBidXkgYnV0dG9ucy5cbiAgICBjb25zdCBidG5zID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImJ1eS1idG5cIilcblxuICAgIGZvciAoY29uc3QgYnRuIG9mIGJ0bnMpIHtcbiAgICAgIGJ0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHRoaXMuYWRkX2NhcnQoZSwgYnRuKSlcbiAgICB9XG5cbiAgICB0aGlzLmluaXRMaXBzY29yZSgpXG5cbiAgICB0aGlzLnRhYlByb3BzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ0YWItcHJvcGVydGllc1wiKVxuXG4gICAgaWYgKHRoaXMudGFiUHJvcHMpIHtcbiAgICAgIHRoaXMudGFiUHJvcHMucGFyZW50Tm9kZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4ge1xuICAgICAgICB0aGlzLmluaXRUYWJQcm9wcygpXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8qIFNjcm9sbFRvIG1vcmUgaW5mbyBhYm91dCBzaXplICovXG5cbiAgICBjb25zdCByZWFkTW9yZVNpemUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnRydWVTaXplTGlua1wiKVxuICAgIGNvbnN0IHJlYWRNb3JlU2Nyb2xsVG8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmFib3V0LS1saXN0XCIpXG5cbiAgICBpZiAocmVhZE1vcmVTaXplKSB7XG4gICAgICByZWFkTW9yZVNpemUub25jbGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2Nyb2xsVG9Nb3JlKClcbiAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gc2Nyb2xsVG9Nb3JlKCkge1xuICAgICAgd2luZG93LnNjcm9sbFRvKHtcbiAgICAgICAgdG9wOiByZWFkTW9yZVNjcm9sbFRvLm9mZnNldFRvcCxcbiAgICAgICAgbGVmdDogMCxcbiAgICAgICAgYmVoYXZpb3I6IFwic21vb3RoXCIsXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8qIFNjcm9sbFRvIG1vcmUgaW5mbyBhYm91dCBzaXplICovXG4gICAgY29uc3QgcmVhZE1vcmVSZXZpZXcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLmJ1eWJveF9fcmF0aW5nXCIpXG4gICAgY29uc3QgcmVhZFJldmlld1Njcm9sbFRvID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNyZXZpZXdzQWNjb3JkaW9uXCIpXG4gICAgY29uc3QgdHJpZ2dlclJldmlldyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjcmV2aWV3c0FjY29yZGlvbiA+IHNwYW5cIilcbiAgICBpZiAocmVhZE1vcmVSZXZpZXcpIHtcbiAgICAgIHJlYWRNb3JlUmV2aWV3Lm9uY2xpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNjcm9sbFRvUmV2aWV3KClcbiAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gc2Nyb2xsVG9SZXZpZXcoKSB7XG4gICAgICB3aW5kb3cuc2Nyb2xsVG8oe1xuICAgICAgICB0b3A6IHJlYWRSZXZpZXdTY3JvbGxUby5vZmZzZXRUb3AsXG4gICAgICAgIGxlZnQ6IDAsXG4gICAgICAgIGJlaGF2aW9yOiBcInNtb290aFwiLFxuICAgICAgfSlcbiAgICAgIGlmIChyZWFkUmV2aWV3U2Nyb2xsVG8uY2xhc3NMaXN0LmNvbnRhaW5zKFwiYWN0aXZlXCIpKSB7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmlnZ2VyUmV2aWV3LmNsaWNrKClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuem9vbUluaXQpIHtcbiAgICAgIHRoaXMuaW5pdFpvb20oKVxuICAgIH1cblxuICAgIHRoaXMuaW5pdFRvb2x0aXAoKVxuXG4gICAgLy8gSGFuZGxlIGFkZCB0byBjYXJ0IGZvciBvbGQgZ2lmdCBjYXJkIHBhZ2UuXG4gICAgdGhpcy5oYW5kbGVHaWZ0Y2FyZHMoKVxuICB9XG5cbiAgYWRkX2NhcnQoZSwgZWxlbSkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKClcblxuICAgIGlmIChlbGVtLmNsYXNzTGlzdC5jb250YWlucyhcImFsZXJ0YWJsZVwiKSkge1xuICAgICAgdGhpcy5zaG93X2FsZXJ0X3BvcHVwKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHByb2R1Y3RfaWQgPSBlbGVtLmRhdGFzZXQuaWRcbiAgICBjb25zdCBxdHkgPSB0aGlzLnF0eV9pbnB1dC52YWx1ZSB8fCAxXG4gICAgbGV0IGV4dHJhX2RhdGEgPSB7fVxuXG4gICAgaWYgKGVsZW0uZGF0YXNldC50eXBlID09PSBcImJ1bmRsZVwiKSB7XG4gICAgICBjb25zdCBmaWVsZHMgPSB0aGlzLmJ1bmRsZS5maWVsZHNcblxuICAgICAgbGV0IGZpZWxkc19kYXRhID0gW11cblxuICAgICAgZm9yIChjb25zdCBmIG9mIGZpZWxkcykge1xuICAgICAgICBmaWVsZHNfZGF0YS5wdXNoKHsgZmllbGRfaWQ6IGYuZGF0YXNldC5pZCwgYnVuZGxlX2lkOiBmLmRhdGFzZXQudmFsdWUgfSlcbiAgICAgIH1cblxuICAgICAgZXh0cmFfZGF0YVtcImJ1bmRsZV9maWVsZHNcIl0gPSBmaWVsZHNfZGF0YVxuICAgIH1cblxuICAgIGVsZW0uZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJhZGRUb0NhcnRcIikpXG5cbiAgICBpZiAoIXByb2R1Y3RfaWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuY2FydC5hZGRfaXRlbShwcm9kdWN0X2lkLCBxdHksIGV4dHJhX2RhdGEpXG4gIH1cblxuICBhc3luYyBzaG93X2FsZXJ0X3BvcHVwKCkge1xuICAgIGlmIChcbiAgICAgIHRoaXMuYnV5X2J1dHRvbi5jbGFzc0xpc3QuY29udGFpbnMoXCJkaXNhYmxlZFwiKSB8fFxuICAgICAgdGhpcy5idXlfYnV0dG9uLmNsYXNzTGlzdC5jb250YWlucyhcImFsZXJ0LWRpc2FibGVkXCIpXG4gICAgKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvKiBoaWRlIGJldmFrYSAqL1xuXG4gICAgY29uc3QgcHJvZHVjdF9pZCA9IHRoaXMuYnV5X2J1dHRvbi5kYXRhc2V0LmlkXG4gICAgY29uc3Qgc3RvY2tfaWQgPSB0aGlzLmJ1eV9idXR0b24uZGF0YXNldC5zdG9ja19pZFxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcbiAgICAgIFwiL3Nob3A/ZnVuaz1nZXRfYWxlcnRfcG9wdXAmcHJvZHVjdF9pZD1cIiArXG4gICAgICAgIHByb2R1Y3RfaWQgK1xuICAgICAgICBcIiZzdG9ja19pZD1cIiArXG4gICAgICAgIHN0b2NrX2lkXG4gICAgKVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuXG4gICAgaWYgKHJlc3VsdC5zdGF0dXMgPT0gMjAwKSB7XG4gICAgICBjb25zdCBkYXRhID0gcmVzdWx0LmRhdGFcblxuICAgICAgbGV0IG5ld3NsZXR0ZXJfaHRtbCA9IFwiXCJcblxuICAgICAgaWYgKGRhdGEubmV3c2xldHRlcikge1xuICAgICAgICBuZXdzbGV0dGVyX2h0bWwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZzLTEyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD1cImFsZXJ0LW5ld3NsZXR0ZXJcIiB0eXBlPVwiY2hlY2tib3hcIiAvPlxuICAgICAgICAgICAgICAgICAgICAke2RhdGEubmV3c2xldHRlcl9waHJhc2V9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgYFxuICAgICAgfVxuXG4gICAgICBsZXQgaHRtbCA9IGBcbiAgICAgICAgICAgIDxkaXYgaWQ9XCJhbGVydC1wb3B1cFwiIGNsYXNzPVwiZC1mbGV4IGxpZ2h0LWdyZXktYiBmbGV4LWNvbHVtbiBwLTE2IGJlaWdlLXRpbnQtMi1iZyBmcy0xNFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJjbG9zZS1hbGVydFwiIGNsYXNzPVwiY2xvc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE3XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE3IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMi45OTYwOSAxMy4zMzMzTDEzLjY2MjggMi42ODUxMVwiIHN0cm9rZT1cImJsYWNrXCIvPlxuICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIuOTk2MDkgMi42NjY3NUwxMy42NTM1IDEzLjMyNDJcIiBzdHJva2U9XCJibGFja1wiLz5cbiAgICAgICAgICAgICAgICAgICAgPC9zdmc+ICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYi04XCI+JHtkYXRhLmhlYWRpbmd9PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBiLThcIj4ke2RhdGEucGhyYXNlfTwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYi04IGFsZXJ0LWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGlkPVwiYWxlcnQtZW1haWxcIiBwbGFjZWhvbGRlcj1cIiR7ZGF0YS5wbGFjZWhvbGRlcn1cIiB2YWx1ZT1cIiR7ZGF0YS5lbWFpbH1cIiAvPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGlkPVwiYWxlcnQtc2F2ZVwiIGNsYXNzPVwiXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTdcIiBoZWlnaHQ9XCI4XCIgdmlld0JveD1cIjAgMCAxNyA4XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xNi42ODE3IDQuMzUzNTVDMTYuODc2OSA0LjE1ODI5IDE2Ljg3NjkgMy44NDE3MSAxNi42ODE3IDMuNjQ2NDVMMTMuNDk5NyAwLjQ2NDQ2NkMxMy4zMDQ0IDAuMjY5MjA0IDEyLjk4NzkgMC4yNjkyMDQgMTIuNzkyNiAwLjQ2NDQ2NkMxMi41OTczIDAuNjU5NzI4IDEyLjU5NzMgMC45NzYzMTEgMTIuNzkyNiAxLjE3MTU3TDE1LjYyMSA0TDEyLjc5MjYgNi44Mjg0M0MxMi41OTczIDcuMDIzNjkgMTIuNTk3MyA3LjM0MDI3IDEyLjc5MjYgNy41MzU1M0MxMi45ODc5IDcuNzMwOCAxMy4zMDQ0IDcuNzMwOCAxMy40OTk3IDcuNTM1NTNMMTYuNjgxNyA0LjM1MzU1Wk0wLjMyODEyNSA0LjVIMTYuMzI4MVYzLjVIMC4zMjgxMjVWNC41WlwiIGZpbGw9XCIjMDgyOTM5XCIvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICR7bmV3c2xldHRlcl9odG1sfVxuICAgICAgICAgICAgPC9kaXY+YFxuXG4gICAgICBpZiAoIXRoaXMuYWxlcnRfcG9wdXApIHtcbiAgICAgICAgdGhpcy5hbGVydF9wb3B1cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIilcbiAgICAgICAgdGhpcy5idXlfYnV0dG9uLmFmdGVyKHRoaXMuYWxlcnRfcG9wdXApXG4gICAgICB9XG5cbiAgICAgIHRoaXMuYWxlcnRfcG9wdXAuaW5uZXJIVE1MID0gaHRtbFxuXG4gICAgICBjb25zdCBjbG9zZUFsZXJ0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJjbG9zZS1hbGVydFwiKVxuICAgICAgY29uc3QgYWxlclBvcHVwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJhbGVydC1wb3B1cFwiKVxuXG4gICAgICBpZiAoY2xvc2VBbGVydCkge1xuICAgICAgICBjbG9zZUFsZXJ0LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYWxlclBvcHVwLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoYWxlclBvcHVwKVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFsZXJ0LXNhdmVcIikuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIHRoaXMuc2F2ZV9hbGVydCgpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNhdmVfYWxlcnQoKSB7XG4gICAgdGhpcy5idXlfYnV0dG9uLmNsYXNzTGlzdC5hZGQoXCJhbGVydC1kaXNhYmxlZFwiKVxuXG4gICAgY29uc3QgcHJvZHVjdF9pZCA9IHRoaXMuYnV5X2J1dHRvbi5kYXRhc2V0LmlkXG4gICAgY29uc3QgZW1haWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFsZXJ0LWVtYWlsXCIpLnZhbHVlXG4gICAgY29uc3QgbmV3c2xldHRlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYWxlcnQtbmV3c2xldHRlclwiKS5jaGVja2VkXG5cbiAgICBpZiAocHJvZHVjdF9pZCAmJiBlbWFpbCkge1xuICAgICAgY29uc3QgZGF0YSA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKVxuXG4gICAgICBkYXRhLmFwcGVuZChcImZ1bmtcIiwgXCJzYXZlX2FsZXJ0XCIpXG4gICAgICBkYXRhLmFwcGVuZChcInByb2R1Y3RfaWRcIiwgcHJvZHVjdF9pZClcbiAgICAgIGRhdGEuYXBwZW5kKFwiZW1haWxcIiwgZW1haWwpXG4gICAgICBkYXRhLmFwcGVuZChcIm5ld3NsZXR0ZXJcIiwgbmV3c2xldHRlcilcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcIi9zaG9wXCIsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYm9keTogZGF0YSxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuXG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PSAyMDApIHtcbiAgICAgICAgdGhpcy5hbGVydF9wb3B1cC5yZW1vdmUoKVxuXG4gICAgICAgIGlmIChyZXN1bHQuZGF0YS5waHJhc2UpIHtcbiAgICAgICAgICBjb25zdCBidG5MYWJlbCA9XG4gICAgICAgICAgICB0aGlzLmJ1eV9idXR0b24uZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImFpci1idXktbGFiZWxcIilbMF1cbiAgICAgICAgICBidG5MYWJlbC5pbm5lckhUTUwgPSByZXN1bHQuZGF0YS5waHJhc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGluaXRMaXBzY29yZSgpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGxpcHNjb3JlV3JhcHBlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibGlwc2NvcmUtcmV2aWV3LWxpc3RcIilcbiAgICAgIGlmIChsaXBzY29yZVdyYXBwZXIgJiYgbGlwc2NvcmVXcmFwcGVyLmRhdGFzZXRbXCJsc1Byb2R1Y3RWb3Rlc1wiXSA9PSAwKSB7XG4gICAgICAgIGRvY3VtZW50XG4gICAgICAgICAgLmdldEVsZW1lbnRCeUlkKFwibGlwc2NvcmUtcmV2aWV3LWxpc3RcIilcbiAgICAgICAgICAucGFyZW50Tm9kZS5wYXJlbnROb2RlLnJlbW92ZSgpXG4gICAgICB9XG4gICAgfSwgNDAwKVxuICB9XG5cbiAgYXN5bmMgaW5pdFRhYlByb3BzKCkge1xuICAgIGlmICh0aGlzLnRhYlByb3BzTG9hZGVkKSByZXR1cm5cblxuICAgIHRoaXMudGFiUHJvcHNMb2FkZWQgPSB0cnVlXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcbiAgICAgIFwiL2NnaS1iaW4vaWJ1dGlrL0FQSS5mY2dpP2Z1bms9Z2V0X3RhYl9wcm9wZXJ0aWVzJmFydG5yPVwiICtcbiAgICAgICAgd2luZG93LnByb2R1Y3RfaWRcbiAgICApXG4gICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKVxuICAgIHRoaXMudGFiUHJvcHMuaW5uZXJIVE1MID0gaHRtbFxuICB9XG5cbiAgaGFuZGxlR2lmdGNhcmRzKCkge1xuICAgIGNvbnN0IGRpZ2l0YWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcIkFJUl9pYnV0aWtfbGFnZ3RpbGxfZFwiKVxuICAgIGNvbnN0IGlybEdpZnRjYXJkID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJBSVJfaWJ1dGlrX2xhZ2d0aWxsX2ZcIilcblxuICAgIGlmIChkaWdpdGFsKSB7XG4gICAgICBjb25zdCBkaWdpdGFsQnRuID0gZGlnaXRhbC5xdWVyeVNlbGVjdG9yKFwiYVwiKVxuXG4gICAgICBkaWdpdGFsQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCAoZSkgPT4ge1xuICAgICAgICB0aGlzLmFkZFRvQ2FydEdpZnRjYXJkKGUsIGRpZ2l0YWwpXG4gICAgICB9KVxuICAgIH1cbiAgICBpZiAoaXJsR2lmdGNhcmQpIHtcbiAgICAgIGNvbnN0IGlybEdpZnRjYXJkQnRuID0gaXJsR2lmdGNhcmQucXVlcnlTZWxlY3RvcihcImFcIilcblxuICAgICAgaXJsR2lmdGNhcmRCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIChlKSA9PiB7XG4gICAgICAgIHRoaXMuYWRkVG9DYXJ0R2lmdGNhcmQoZSwgaXJsR2lmdGNhcmQpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGFkZFRvQ2FydEdpZnRjYXJkKGUsIGZvcm0pIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KClcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXCIvc2hvcFwiLCB7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgYm9keTogbmV3IEZvcm1EYXRhKGZvcm0pLFxuICAgIH0pXG5cbiAgICB0aGlzLmNhcnQuc2hvdyhcImFkZFwiLCB7IG9yZGVyOiBcInVwZGF0ZV90aW1lXCIgfSlcbiAgfVxuXG4gIGluaXRab29tKCkge1xuICAgIHRoaXMuem9vbUluaXQgPSB0cnVlXG4gICAgdGhpcy56b29tQWN0aXZlID0gZmFsc2VcblxuICAgIHRoaXMuY2hhbmdlRXZlbnQgPSAoZSkgPT4ge1xuICAgICAgbGV0IHRvb2x0aXBTcGFuID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgXCIuc25hcHBpbmctLXdyYXBwZXIgLnRvb2x0aXAtc3BhblwiXG4gICAgICApXG4gICAgICBpZiAodGhpcy56b29tQWN0aXZlKSB7XG4gICAgICAgIHRvb2x0aXBTcGFuLmNsYXNzTGlzdC5yZW1vdmUoXCJub3RBY3RpdmVcIilcbiAgICAgICAgdGhpcy5yZW1vdmVab29tKGUsIHRoaXMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNob3dab29tKGUsIHRoaXMpXG4gICAgICAgIHRvb2x0aXBTcGFuLmNsYXNzTGlzdC5hZGQoXCJub3RBY3RpdmVcIilcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW1vdmVFdmVudCA9IChlKSA9PiB7XG4gICAgICB0aGlzLnJlbW92ZVpvb20oZSwgdGhpcylcbiAgICB9XG4gICAgdGhpcy5ob3ZlckV2ZW50ID0gKGUpID0+IHtcbiAgICAgIHRoaXMuc2hvd1pvb21Ib3ZlcihlLCB0aGlzKVxuICAgIH1cbiAgICB0aGlzLmhvdmVyUmVtb3ZlRXZlbnQgPSAoZSkgPT4ge1xuICAgICAgdGhpcy5oaWRlWm9vbUhvdmVyKGUsIHRoaXMpXG4gICAgfVxuXG4gICAgdGhpcy5pbWdXcmFwcGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5zaW5nbGUtLXByb2R1Y3RfX2ltZ1wiKVxuICAgIHRoaXMuaW1nV3JhcHBlci5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdmVyXCIsIHRoaXMuaG92ZXJFdmVudClcbiAgICB0aGlzLmltZ1dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlb3V0XCIsIHRoaXMuaG92ZXJSZW1vdmVFdmVudClcblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzbGlkZXJfY2xpY2tlZFwiLCB0aGlzLmNoYW5nZUV2ZW50KVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzbGlkZXJfY2hhbmdlZFwiLCB0aGlzLnJlbW92ZUV2ZW50KVxuICB9XG5cbiAgc2hvd1pvb21Ib3ZlcihlLCBfc2VsZikge1xuICAgIC8vIFByZWxvYWQgc3VwZXJ6b29tIG9uIGhvdmVyLlxuICAgIGlmICghZS50YXJnZXQucGFyZW50Tm9kZS5jbGFzc0xpc3QuY29udGFpbnMoXCJzdXBlcnpvb20tbG9hZGVkXCIpKSB7XG4gICAgICBlLnRhcmdldC5wYXJlbnROb2RlLmNsYXNzTGlzdC5hZGQoXCJzdXBlcnpvb20tbG9hZGVkXCIpXG5cbiAgICAgIGlmIChlLnRhcmdldC5wYXJlbnROb2RlLmRhdGFzZXQuc3VwZXJ6b29tKSB7XG4gICAgICAgIGxldCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpXG4gICAgICAgIGltZy5zcmMgPSBlLnRhcmdldC5wYXJlbnROb2RlLmRhdGFzZXQuc3VwZXJ6b29tXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaW5pdFRvb2x0aXAoKSB7XG4gICAgLy8gbGV0IHRvb2x0aXBTcGFuID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJ0b29sdGlwLXNwYW5cIilcbiAgICAvLyBsZXQgdG9vbHRpcENvbG9yID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcInRvb2x0aXAtY29sb3JcIilcbiAgICAvLyBjb25zdCBpbWFnZVdyYXBwZXIgPVxuICAgIC8vICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIuc25hcHBpbmctLXdyYXBwZXJcIilcbiAgICAvLyBjb25zdCBjb2xvcldyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnJvdy52YXJpdXNDb2xvcnNcIilcblxuICAgIC8vIGxldCBpbWFnZVdyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuc2luZ2xlLS1wcm9kdWN0X19pbWcnKS5wYXJlbnROb2RlO1xuXG4gICAgLy8gdGhpcy5zaG93VG9vbHRpcChpbWFnZVdyYXBwZXIsIHRvb2x0aXBTcGFuKVxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIudG9vbHRpcC1zcGFuXCIpLmZvckVhY2goKHRvb2x0aXApID0+IHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRvb2x0aXAucGFyZW50Tm9kZVxuXG4gICAgICB0aGlzLnNob3dUb29sdGlwKHBhcmVudCwgdG9vbHRpcClcbiAgICB9KVxuICB9XG5cbiAgaGlkZVpvb21Ib3ZlcihlLCBfc2VsZikge31cblxuICBzaG93Wm9vbShlLCBfc2VsZikge1xuICAgIC8vIGlmIChlLnBvaW50ZXJUeXBlICE9PSAnbW91c2UnKSByZXR1cm47XG4gICAgX3NlbGYuem9vbUFjdGl2ZSA9IHRydWVcbiAgICBfc2VsZi56b29tcyA9IFtdXG5cbiAgICBfc2VsZi5pbWdXcmFwcGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW92ZXJcIiwgX3NlbGYuaG92ZXJFdmVudClcblxuICAgIGxldCB6b29tV3JhcHBlciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiem9vbVdyYXBwZXJcIilcbiAgICBsZXQgcHJvZHVjdERlc2MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiLnByb2R1Y3REZXNjXCIpXG5cbiAgICBjb25zdCB3aWR0aCA9IHByb2R1Y3REZXNjLm9mZnNldFdpZHRoIC0gMTBcblxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIucHJvZHVjdEltZy0td3JhcHBlciBpbWdcIikuZm9yRWFjaCgoaW1nKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gaW1nLnBhcmVudE5vZGVcbiAgICAgIGxldCBpbWFnZSA9IGltZy5zcmNcblxuICAgICAgaWYgKGVsZW1lbnQuZGF0YXNldC5zdXBlcnpvb20pIHtcbiAgICAgICAgaW1hZ2UgPSBlbGVtZW50LmRhdGFzZXQuc3VwZXJ6b29tXG4gICAgICB9XG5cbiAgICAgIF9zZWxmLnpvb21zLnB1c2goXG4gICAgICAgIG5ldyBJbWFnZVpvb20oZWxlbWVudCwge1xuICAgICAgICAgIHpvb21Db250YWluZXI6IHpvb21XcmFwcGVyLFxuICAgICAgICAgIHpvb21XaWR0aDogd2lkdGgsXG4gICAgICAgICAgem9vbUltYWdlOiBpbWFnZSxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICB9KVxuXG4gICAgaWYgKGUuZGV0YWlsKSB7XG4gICAgICBjb25zdCBldnQgPSBlLmRldGFpbC5ldnRcblxuICAgICAgaWYgKGV2dCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBsZXQgd3JhcHBlciA9IGV2dC50YXJnZXQucGFyZW50Tm9kZVxuICAgICAgICAgIHdyYXBwZXIuZGlzcGF0Y2hFdmVudChcbiAgICAgICAgICAgIG5ldyBNb3VzZUV2ZW50KFwibW91c2Vtb3ZlXCIsIHtcbiAgICAgICAgICAgICAgY2xpZW50WDogZXZ0LmNsaWVudFgsXG4gICAgICAgICAgICAgIGNsaWVudFk6IGV2dC5jbGllbnRZLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICAgIH0sIDEwKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZVpvb20oZSwgX3NlbGYpIHtcbiAgICBpZiAoIV9zZWxmLnpvb21BY3RpdmUpIHJldHVyblxuXG4gICAgX3NlbGYuem9vbUFjdGl2ZSA9IGZhbHNlXG4gICAgbGV0IGVsZW1lbnQgPSBfc2VsZi5pbWdXcmFwcGVyXG5cbiAgICBfc2VsZi56b29tcy5mb3JFYWNoKCh6b29tKSA9PiB7XG4gICAgICB6b29tLmtpbGwoKVxuICAgIH0pXG5cbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBfc2VsZi5yZW1vdmVFdmVudClcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBfc2VsZi5zaG93RXZlbnQpXG4gICAgX3NlbGYuaW1nV3JhcHBlci5hZGRFdmVudExpc3RlbmVyKFwibW91c2VvdmVyXCIsIF9zZWxmLmhvdmVyRXZlbnQpXG4gIH1cblxuICBzaG93VG9vbHRpcChlbGVtZW50V3JhcHBlciwgdG9vbHRpcCkge1xuICAgIGVsZW1lbnRXcmFwcGVyLm9ubW91c2Vtb3ZlID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgIHZhciB4ID0gZS5jbGllbnRYLFxuICAgICAgICB5ID0gZS5jbGllbnRZXG4gICAgICB0b29sdGlwLnN0eWxlLnRvcCA9IHkgKyAxNSArIFwicHhcIlxuICAgICAgdG9vbHRpcC5zdHlsZS5sZWZ0ID0geCArIDE1ICsgXCJweFwiXG4gICAgICB0b29sdGlwLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIilcbiAgICB9XG4gICAgZWxlbWVudFdyYXBwZXIub25tb3VzZW91dCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICB0b29sdGlwLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIilcbiAgICB9XG4gIH1cbn1cbiIsIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTaW1wbGVTbGlkZXIge1xuXG5cdGNvbnN0cnVjdG9yKHNsaWRlcikge1xuXHRcdHRoaXMuc2xpZGVyID0gc2xpZGVyO1xuXHRcdHRoaXMuc2xpZGVzV3JhcHBlciA9IHNsaWRlci5xdWVyeVNlbGVjdG9yKCcuc25hcHBpbmcnKTtcblx0XHR0aGlzLnNsaWRlcyA9IHRoaXMuc2xpZGVzV3JhcHBlci5jaGlsZHJlbjtcblx0XHRjb25zdCBwYXJlbnQgPSB0aGlzLnNsaWRlci5wYXJlbnRFbGVtZW50O1xuXHRcdHRoaXMucHJldiA9IHNsaWRlci5xdWVyeVNlbGVjdG9yKCcubmF2LXByZXYnKTtcblx0XHR0aGlzLm5leHQgPSBzbGlkZXIucXVlcnlTZWxlY3RvcignLm5hdi1uZXh0Jyk7XG5cblx0XHRpZiAoIXRoaXMucHJldikge1xuXHRcdFx0aWYgKHBhcmVudC5xdWVyeVNlbGVjdG9yKCcubmF2LXByZXYnKSkge1xuXHRcdFx0XHR0aGlzLnByZXYgPSBwYXJlbnQucXVlcnlTZWxlY3RvcignLm5hdi1wcmV2Jyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCF0aGlzLm5leHQpIHtcblx0XHRcdGlmIChwYXJlbnQucXVlcnlTZWxlY3RvcignLm5hdi1uZXh0JykpIHtcblx0XHRcdFx0dGhpcy5uZXh0ID0gcGFyZW50LnF1ZXJ5U2VsZWN0b3IoJy5uYXYtbmV4dCcpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuc2xpZGVzTGVuZ3RoID0gdGhpcy5zbGlkZXMubGVuZ3RoO1xuXG5cdFx0aWYgKCF0aGlzLnNsaWRlc0xlbmd0aCkgcmV0dXJuO1xuXG5cdFx0dGhpcy5zbGlkZVNpemUgPSB0aGlzLnNsaWRlc1swXS5vZmZzZXRXaWR0aDtcblx0XHR0aGlzLmluZGV4ID0gMTtcblx0XHR0aGlzLnBvc1gxID0gMDtcblx0XHR0aGlzLnBvc1gyID0gMDtcblx0XHR0aGlzLnBvc0luaXRpYWwgPSAwO1xuXHRcdHRoaXMudG91Y2hFbmRQb3NpdGlvbiA9IDA7XG5cdFx0dGhpcy50b3VjaEV2ZW50VGltZXI7XG5cdFx0dGhpcy5oYXNBdXRvc2xpZGUgPSBmYWxzZTtcblxuXHRcdHRoaXMuaW5pdFBhZ2luYXRpb24oKTtcblx0XHRpZiAoL0FuZHJvaWR8d2ViT1N8aVBob25lfGlQYWR8aVBvZHxCbGFja0JlcnJ5L2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSkge1xuXHRcdH1cblx0XHRlbHNle1xuXHRcdFx0dGhpcy5pbml0QXV0b3NsaWRlKCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5pbml0RXZlbnRzKCk7XG5cblx0XHR0aGlzLnNsaWRlci5jbGFzc0xpc3QuYWRkKCdsb2FkZWQnKTtcblx0fVxuXG5cdGluaXRFdmVudHMoKSB7XG5cdFx0dGhpcy5tb3VzZVVwRXZlbnQgPSAoZSkgPT4geyB0aGlzLmRyYWdFbmQoZSwgdGhpcyk7IH07XG5cdFx0dGhpcy5tb3VzZU1vdmVFdmVudCA9IChlKSA9PiB7IHRoaXMuZHJhZ0FjdGlvbihlLCB0aGlzKTsgfTtcblxuXHRcdHRoaXMuZGlzYWJsZVBhZ2luYXRpb24gPSBmYWxzZTtcblxuXHRcdGlmICh0aGlzLnNsaWRlc1dyYXBwZXIuc2Nyb2xsV2lkdGggPD0gdGhpcy5zbGlkZXNXcmFwcGVyLmNsaWVudFdpZHRoKSB7XG5cdFx0XHR0aGlzLmRpc2FibGVQYWdpbmF0aW9uID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5wcmV2KSB7XG5cdFx0XHRpZiAodGhpcy5kaXNhYmxlUGFnaW5hdGlvbikge1xuXHRcdFx0XHR0aGlzLnByZXYuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMucHJldi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHsgdGhpcy5zaGlmdFNsaWRlKHRoaXMsIC0xKSB9KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKHRoaXMubmV4dCkge1xuXHRcdFx0aWYgKHRoaXMuZGlzYWJsZVBhZ2luYXRpb24pIHtcblx0XHRcdFx0dGhpcy5uZXh0LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLm5leHQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7IHRoaXMuc2hpZnRTbGlkZSh0aGlzLCAxKSB9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLnNsaWRlc1dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgKGUpID0+IHsgXG5cdFx0XHRpZiAoZS5idXR0b25zID09IDEgJiYgIWUudGFyZ2V0LmNsb3Nlc3QoXCIucHJvZHVjdF9fd2lzaGxpc3RcIikpIHtcblx0XHRcdFx0dGhpcy5kcmFnU3RhcnQoZSwgdGhpcyk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR0aGlzLnNsaWRlc1dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCAoZSkgPT4geyB0aGlzLnRvdWNoRXZlbnQodGhpcykgfSk7XG5cdFx0dGhpcy5zbGlkZXNXcmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNld2hlZWwnLCAoZSkgPT4geyB0aGlzLnRvdWNoRXZlbnQodGhpcykgfSk7XG5cdH1cblxuXHRpbml0QXV0b3NsaWRlKCkge1xuXHRcdGlmICh0aGlzLnNsaWRlc1dyYXBwZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdhdXRvc2xpZGUnKSkge1xuXHRcdFx0dGhpcy5oYXNBdXRvc2xpZGUgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmhhc0F1dG9zbGlkZSkge1xuXHRcdFx0dGhpcy5tYXhTY3JvbGwgPSB0aGlzLnNsaWRlc1dyYXBwZXIuc2Nyb2xsV2lkdGggLSB0aGlzLnNsaWRlc1dyYXBwZXIuY2xpZW50V2lkdGg7XG5cdFx0XHR0aGlzLmF1dG9zbGlkZVRpbWVyID0gc2V0SW50ZXJ2YWwodGhpcy5hdXRvc2xpZGVIYW5kbGVyLCA1MCwgdGhpcyk7XG5cblx0XHRcdHRoaXMuc2xpZGVzV3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCAoKSA9PiB7IHRoaXMuc2xpZGVzV3JhcHBlci5jbGFzc0xpc3QuYWRkKCdwYXVzZScpOyB9KTtcblx0XHRcdHRoaXMuc2xpZGVzV3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsICgpID0+IHsgdGhpcy5zbGlkZXNXcmFwcGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3BhdXNlJyk7IH0pO1xuXHRcdFx0dGhpcy5zbGlkZXNXcmFwcGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCAoKSA9PiB7IHRoaXMuc2xpZGVzV3JhcHBlci5jbGFzc0xpc3QuYWRkKCdwYXVzZScpOyB9KTtcblx0XHRcdHRoaXMuc2xpZGVzV3JhcHBlci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsICgpID0+IHsgdGhpcy5zbGlkZXNXcmFwcGVyLmNsYXNzTGlzdC5yZW1vdmUoJ3BhdXNlJyk7IH0pO1xuXHRcdH1cblx0fVxuXG5cdGF1dG9zbGlkZUhhbmRsZXIoX3NlbGYpIHtcblx0XHRpZiAoX3NlbGYuc2xpZGVzV3JhcHBlci5jbGFzc0xpc3QuY29udGFpbnMoXCJzbGlkaW5nXCIpKSByZXR1cm47XG5cdFx0aWYgKF9zZWxmLnNsaWRlc1dyYXBwZXIuY2xhc3NMaXN0LmNvbnRhaW5zKFwicGF1c2VcIikpIHJldHVybjtcblxuXHRcdF9zZWxmLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdCArPSAxO1xuXHRcdGlmIChfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbExlZnQgPj0gX3NlbGYubWF4U2Nyb2xsKSB7XG5cdFx0XHRjbGVhckludGVydmFsKF9zZWxmLmF1dG9zbGlkZVRpbWVyKTtcblx0XHR9XG5cdH1cblxuXHRpbml0UGFnaW5hdGlvbigpIHtcblx0XHR0aGlzLnBhZ2luYXRpb25XcmFwcGVyID0gdGhpcy5zbGlkZXIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnc2xpZGVyX19wYWdpbmF0aW9uJyk7XG5cdFx0dGhpcy5oYXNQYWdpbmF0aW9uID0gdGhpcy5wYWdpbmF0aW9uV3JhcHBlci5sZW5ndGggPyB0cnVlIDogZmFsc2U7XG5cblx0XHRpZiAodGhpcy5oYXNQYWdpbmF0aW9uKSB7XG5cdFx0XHR0aGlzLnBhZ2luYXRpb25XcmFwcGVyID0gdGhpcy5zbGlkZXIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnc2xpZGVyX19wYWdpbmF0aW9uJylbMF07XG5cdFx0XHR0aGlzLnBhZ2luYXRpb25XcmFwcGVyLmZpcnN0RWxlbWVudENoaWxkLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuXG5cdFx0XHRcblx0XHRcdGNvbnN0IHBhZ2luYXRpb25fZG90cyA9IHRoaXMucGFnaW5hdGlvbldyYXBwZXIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnc2xpZGVyX19wYWdpbmF0aW9uLS1kb3QnKTtcblxuXHRcdFx0Zm9yIChjb25zdCBkb3Qgb2YgcGFnaW5hdGlvbl9kb3RzKSB7XG5cdFx0XHRcdGRvdC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChlKSA9PiB0aGlzLnBhZ2luYXRpb25DbGljayhlLCB0aGlzKSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cGFnaW5hdGlvbkNsaWNrKGUsIF9zZWxmKSB7XG5cdFx0Y29uc3QgZWxlbWVudCA9IGUudGFyZ2V0O1xuXHRcdGNvbnN0IHBhcmVudCA9IGVsZW1lbnQucGFyZW50RWxlbWVudDtcblx0XHRcblx0XHRfc2VsZi5pbmRleCA9IEFycmF5LmZyb20ocGFyZW50LmNoaWxkcmVuKS5pbmRleE9mKGVsZW1lbnQpICsgMTtcblxuXHRcdF9zZWxmLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdCA9IF9zZWxmLnNsaWRlU2l6ZSAqIChfc2VsZi5pbmRleCAtIDEpO1xuXG5cdFx0X3NlbGYudXBkYXRlUGFnaW5hdGlvbigpO1xuXHR9XG5cblx0dG91Y2hFdmVudChfc2VsZikge1xuXHRcdF9zZWxmLnRvdWNoRW5kUG9zaXRpb24gPSBfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbExlZnQ7XG5cdFx0X3NlbGYudG91Y2hFdmVudFRpbWVyID0gc2V0SW50ZXJ2YWwoX3NlbGYudG91Y2hFdmVudEhhbmRsZXIsIDUwLCBfc2VsZik7XG5cdH1cblxuXHR0b3VjaEV2ZW50SGFuZGxlcihvYmopIHtcblx0XHRpZiAob2JqLnRvdWNoRW5kUG9zaXRpb24gPT0gb2JqLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdCkge1xuXHRcdFx0Y2xlYXJJbnRlcnZhbChvYmoudG91Y2hFdmVudFRpbWVyKTtcblxuXHRcdFx0b2JqLmluZGV4ID0gTWF0aC5yb3VuZChvYmoudG91Y2hFbmRQb3NpdGlvbiAvIG9iai5zbGlkZVNpemUpICsgMTtcblx0XHRcdG9iai51cGRhdGVQYWdpbmF0aW9uKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG9iai50b3VjaEVuZFBvc2l0aW9uID0gb2JqLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdDtcblx0XHR9XG5cdH1cblxuXHRkcmFnU3RhcnQoZSwgX3NlbGYpIHtcblx0XHRfc2VsZi5wb3NJbml0aWFsID0gX3NlbGYuc2xpZGVzV3JhcHBlci5zY3JvbGxMZWZ0O1xuXHRcdF9zZWxmLmluaXRpYWxYID0gZS5jbGllbnRYO1xuXHRcdF9zZWxmLnBvc1gxID0gZS5jbGllbnRYO1xuXG5cdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIF9zZWxmLm1vdXNlVXBFdmVudCk7XG5cdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgX3NlbGYubW91c2VNb3ZlRXZlbnQpO1xuXHR9XG5cblx0ZHJhZ0FjdGlvbihlLCBfc2VsZikge1xuXHRcdF9zZWxmLnNsaWRlc1dyYXBwZXIuY2xhc3NMaXN0LmFkZChcInNsaWRpbmdcIik7XG5cdFx0X3NlbGYucG9zWDIgPSBfc2VsZi5wb3NYMSAtIGUuY2xpZW50WDtcblx0XHRfc2VsZi5wb3NYMSA9IGUuY2xpZW50WDtcblx0XHRfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbExlZnQgPSBfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbExlZnQgKyBfc2VsZi5wb3NYMjtcblx0fVxuXG5cdGRyYWdFbmQoZSwgX3NlbGYpIHtcblx0XHRfc2VsZi5pbmRleCA9IE1hdGgucm91bmQoX3NlbGYuc2xpZGVzV3JhcHBlci5zY3JvbGxMZWZ0IC8gX3NlbGYuc2xpZGVTaXplKSArIDE7XG5cblx0XHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgX3NlbGYubW91c2VVcEV2ZW50KTtcblx0XHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBfc2VsZi5tb3VzZU1vdmVFdmVudCk7XG5cblx0XHRfc2VsZi5zbGlkZXNXcmFwcGVyLmNsYXNzTGlzdC5yZW1vdmUoXCJzbGlkaW5nXCIpO1xuXG5cdFx0aWYgKF9zZWxmLmluaXRpYWxYID09IGUuY2xpZW50WCkge1xuXHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJzbGlkZXJfY2xpY2tlZFwiLCB7ZGV0YWlsOiB7ZXZ0OiBlfX0pKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJzbGlkZXJfY2hhbmdlZFwiLCB7ZGV0YWlsOiB7ZXZ0OiBlfX0pKTtcblx0XHR9XG5cblx0XHRfc2VsZi51cGRhdGVQYWdpbmF0aW9uKCk7XG5cdH1cblxuXHRzaGlmdFNsaWRlKF9zZWxmLCBkaXIpIHtcblx0XHRfc2VsZi5wb3NJbml0aWFsID0gX3NlbGYuc2xpZGVzV3JhcHBlci5zY3JvbGxMZWZ0O1xuXG5cdFx0aWYgKGRpciA9PSAxKSB7XG5cdFx0XHRpZiAoX3NlbGYuaW5kZXggPiBfc2VsZi5zbGlkZXNMZW5ndGggfHwgKF9zZWxmLnNsaWRlc1dyYXBwZXIuc2Nyb2xsV2lkdGggPj0gKF9zZWxmLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdCArIF9zZWxmLnNsaWRlc1dyYXBwZXIuY2xpZW50V2lkdGggLSAxKSAmJiBfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbFdpZHRoIDw9IChfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbExlZnQgKyBfc2VsZi5zbGlkZXNXcmFwcGVyLmNsaWVudFdpZHRoICsgMSkpKSB7XG5cdFx0XHRcdF9zZWxmLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdCA9IDA7XG5cdFx0XHRcdF9zZWxmLmluZGV4ID0gMTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdF9zZWxmLnNsaWRlc1dyYXBwZXIuc2Nyb2xsTGVmdCA9IF9zZWxmLnBvc0luaXRpYWwgKyBfc2VsZi5zbGlkZVNpemU7XG5cdFx0XHRcdF9zZWxmLmluZGV4Kys7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChkaXIgPT0gLTEgJiYgX3NlbGYuaW5kZXggPiAxKSB7XG5cdFx0XHRfc2VsZi5zbGlkZXNXcmFwcGVyLnNjcm9sbExlZnQgPSBfc2VsZi5wb3NJbml0aWFsIC0gX3NlbGYuc2xpZGVTaXplO1xuXHRcdFx0X3NlbGYuaW5kZXgtLTtcblx0XHR9XG5cblx0XHRkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcInNsaWRlcl9jaGFuZ2VkXCIpKTtcblxuXHRcdHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xuXHR9XG5cblx0dXBkYXRlUGFnaW5hdGlvbigpIHtcblx0XHRpZiAoIXRoaXMuaGFzUGFnaW5hdGlvbikgeyByZXR1cm47IH07XG5cblx0XHR0aGlzLnBhZ2luYXRpb25XcmFwcGVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5hY3RpdmUnKS5mb3JFYWNoKGUgPT5cblx0XHRcdGUuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKVxuXHRcdCk7XG5cblx0XHR0aGlzLnBhZ2luYXRpb25XcmFwcGVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5zbGlkZXJfX3BhZ2luYXRpb24tLWRvdDpudGgtY2hpbGQoJyArIHRoaXMuaW5kZXggKyAnKScpWzBdLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuXHR9XG59XG4iLCJpbXBvcnQge2Zvcm1hdFByaWNlSHRtbH0gZnJvbSBcIi4uLy4uLy4uL3NjcmlwdHMvdXRpbHMuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZhcmlhdGlvbiB7XG5cbiAgICBjb25zdHJ1Y3Rvcih2YXJpYW50c0RhdGEsIGJ1eUJ1dHRvbikge1xuICAgICAgICB0aGlzLnByb2R1Y3RfaWQgPSB2YXJpYW50c0RhdGEucHJvZHVjdF9pZDtcbiAgICAgICAgdGhpcy52YXJpYW50c0RhdGEgPSB2YXJpYW50c0RhdGEudmFyaWFudHM7XG4gICAgICAgIHRoaXMuZmllbGRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZhcmlhdGlvbi0xJyk7XG4gICAgICAgIHRoaXMucG9pX3NpemVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnBvaS5idXlib3hfX3ZhcmlhbnQtLWl0ZW0nKTtcbiAgICAgICAgdGhpcy52YXJpYW50cyA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2J1eWJveF9fdmFyaWFudC0taXRlbScpO1xuICAgICAgICB0aGlzLmJ1eUJ1dHRvbiA9IGJ1eUJ1dHRvbjtcbiAgICAgICAgdGhpcy5hdXRvQWRkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IGZhbHNlOyAgLy8gQWRkZWQgdG8gY29udHJvbCByZS1pbml0aWFsaXphdGlvblxuXG4gICAgICAgIHRoaXMuaW5pdCh0aGlzLnZhcmlhbnRzKTtcbiAgICB9XG5cbiAgICBpbml0KHZhcmlhbnRzKSB7XG4gICAgICAgIHRoaXMuaW5pdEV2ZW50cygpO1xuICAgICAgICB0aGlzLmluaXRQT0lfdG9nZ2xlKCk7XG4gICAgfVxuXG4gICAgaW5pdEV2ZW50cygpIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmJ1eWJveF9fdmFyaWFudC0taXRlbXMnKTtcbiAgICAgICAgaWYgKCFjb250YWluZXIpIHJldHVybjtcblxuICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBjbGlja2VkIGVsZW1lbnQgaXMgYSAuYnV5Ym94X192YXJpYW50LS1pdGVtXG4gICAgICAgICAgICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0LmNsb3Nlc3QoJy5idXlib3hfX3ZhcmlhbnQtLWl0ZW0nKTtcbiAgICAgICAgICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG5cbiAgICAgICAgICAgIC8vIEhpZGUgYWxsIG92ZXJsYXkgdGV4dHNcbiAgICAgICAgICAgIHZhciBvdmVybGF5cyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcub3ZlcmxheS10ZXh0Jyk7XG5cbiAgICAgICAgICAgIG92ZXJsYXlzLmZvckVhY2goKG92ZXJsYXkpID0+IHtcbiAgICAgICAgICAgICAgICBvdmVybGF5LmNsYXNzTGlzdC5hZGQoJ2hpZGUnKTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBTaG93IHRoZSBvdmVybGF5IHRleHQgZm9yIHRoZSBjbGlja2VkIGl0ZW1cbiAgICAgICAgICAgIHZhciBvdmVybGF5VGV4dCA9IHRhcmdldC5xdWVyeVNlbGVjdG9yKCcub3ZlcmxheS10ZXh0Jyk7XG4gICAgICAgICAgICBpZiAob3ZlcmxheVRleHQpIHtcbiAgICAgICAgICAgICAgICBvdmVybGF5VGV4dC5jbGFzc0xpc3QucmVtb3ZlKCdoaWRlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFsc28gaGFuZGxlIHRoZSBmaWVsZCB1cGRhdGUgZXZlbnRcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRmllbGRFdmVudChldmVudCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuYnV5QnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2FkZFRvQ2FydCcsIGUgPT4geyB0aGlzLnNob3dDYXJ0RXJyb3IoZSk7IH0pO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgbGFiZWxzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnYnV5Ym94X192YXJpYW50LS10aXRsZScpO1xuICAgICAgICBmb3IgKGNvbnN0IGxhYmVsIG9mIGxhYmVscykge1xuICAgICAgICAgICAgbGFiZWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBlID0+IHsgdGhpcy50b2dnbGVWYXJpYW50V3JhcHBlcihsYWJlbCk7IH0pO1xuICAgICAgICB9XG4gICAgfVxuXG5cbiAgICB0b2dnbGVWYXJpYW50V3JhcHBlcihsYWJlbCkge1xuICAgICAgICBjb25zdCB3cmFwcGVyID0gbGFiZWwucGFyZW50Tm9kZTtcbiAgICAgICAgaWYgKHdyYXBwZXIuY2xhc3NMaXN0LmNvbnRhaW5zKCdvcGVuJykpIHtcbiAgICAgICAgICAgIHdyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZSgnb3BlbicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3JhcHBlci5jbGFzc0xpc3QuYWRkKCdvcGVuJyk7XG4gICAgICAgICAgICBsYWJlbC5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVGaWVsZEV2ZW50KGUpIHtcbiAgICAgICAgbGV0IGJ1dHRvbiA9IGUudGFyZ2V0LmNsb3Nlc3QoJy5idXlib3hfX3ZhcmlhbnQtLWl0ZW0nKTtcbiAgICAgICAgaWYgKCFidXR0b24gfHwgIWJ1dHRvbi5kYXRhc2V0LmlkKSByZXR1cm47ICBcblxuICAgICAgICBjb25zdCB2YXJpYW50SWQgPSBidXR0b24uZGF0YXNldC5pZDtcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnByb2R1Y3QtaWQtaW5mbycpLmlubmVySFRNTD12YXJpYW50SWQ7XG4gICAgICAgIGNvbnN0IGZpZWxkID0gdGhpcy5maWVsZHM7Ly9idXR0b24ucGFyZW50Tm9kZTtcbiAgICAgICAgQXJyYXkuZnJvbSh0aGlzLnBvaV9zaXplcykuZm9yRWFjaChlbGVtPT4gZWxlbS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKSk7XG4gICAgICAgIEFycmF5LmZyb20oZmllbGQuY2hpbGRyZW4pLmZvckVhY2goY2hpbGQgPT4gY2hpbGQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJykpO1xuICAgICAgICBidXR0b24uY2xhc3NMaXN0LnRvZ2dsZSgnYWN0aXZlJyk7XG4gICAgICAgIHRoaXMuYnV5QnV0dG9uLmNsYXNzTGlzdC50b2dnbGUoXCJkaXNhYmxlZFwiLCAhYnV0dG9uLmNsYXNzTGlzdC5jb250YWlucygnYWN0aXZlJykpO1xuICAgICAgICBmaWVsZC5kYXRhc2V0LnZhbHVlID0gYnV0dG9uLmNsYXNzTGlzdC5jb250YWlucygnYWN0aXZlJykgPyB2YXJpYW50SWQgOiAnJztcblxuICAgICAgICB0aGlzLnVwZGF0ZUxhYmVsKGZpZWxkLCBidXR0b24uY2xhc3NMaXN0LmNvbnRhaW5zKCdhY3RpdmUnKSA/IHZhcmlhbnRJZCA6ICcnKTtcbiAgICAgICAgdGhpcy51cGRhdGVGaWVsZHMoKTtcbiAgICB9XG5cbiAgICB1cGRhdGVMYWJlbChmaWVsZCwgdmFyaWFudElkKSB7XG4gICAgICAgIGNvbnN0IGxhYmVscyA9IGZpZWxkLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvckFsbCgnLmxhYmVsJyk7IC8vIEFzc3VtaW5nIG11bHRpcGxlIGxhYmVsc1xuICAgICAgICBsYWJlbHMuZm9yRWFjaChsYWJlbCA9PiB7XG4gICAgICAgICAgICBjb25zdCBkYXRhRm9yID0gbGFiZWwuZ2V0QXR0cmlidXRlKCdkYXRhLWZvcicpO1xuICAgICAgICAgICAgaWYgKGRhdGFGb3IgPT09IHZhcmlhbnRJZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhcmlhbnQgPSB0aGlzLnZhcmlhbnRzRGF0YS5maW5kKHYgPT4gdi5pZCA9PT0gdmFyaWFudElkKTtcbiAgICAgICAgICAgICAgICBpZiAodmFyaWFudCkge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbC50ZXh0Q29udGVudCA9IHZhcmlhbnQubGFiZWwgfHwgJyc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1cGRhdGVGaWVsZHMoKSB7XG4gICAgICAgIGxldCB2YWx1ZXMgPSBbXTtcbiAgICAgICAgbGV0IGFsbEZpZWxkc1NlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICBcblxuICAgICAgICAgICAgaWYgKHRoaXMuZmllbGRzLmRhdGFzZXQudmFsdWUpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaCh0aGlzLmZpZWxkcy5kYXRhc2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWxsRmllbGRzU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgIFxuICAgICAgICBhbGxGaWVsZHNTZWxlY3RlZCA/IHRoaXMuc2V0VmFyaWFudCh2YWx1ZXMpIDogdGhpcy5jbGVhclZhcmlhbnQoKTtcbiAgICB9XG5cbiAgICBhc3luYyBzZXRWYXJpYW50KHZhbHVlcykge1xuICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykge1xuICAgICAgICAgICAgY29uc3QgdmFyaWFudCA9IHRoaXMudmFyaWFudHNEYXRhLmZpbmQodiA9PiB2LmlkID09PSB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAodmFyaWFudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYC9zaG9wP2Z1bms9Z2V0X3ZhcmlhbnQmcHJvZHVjdF9pZD0ke3RoaXMucHJvZHVjdF9pZH0mdmFyaWFudF9pZD0ke3ZhcmlhbnQuaWR9YCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIFxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzLmNvZGUgPT09IDIwMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gcmVzdWx0LmRhdGE7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlVmFyaWFudEluZm8odmFyaWFudCwgZGF0YSk7ICAvLyBDb3JyZWN0bHkgY2FsbCB1cGRhdGVWYXJpYW50SW5mbyBoZXJlXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGZldGNoIHZhcmlhbnQgZGF0YTonLCByZXN1bHQuc3RhdHVzLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignVmFyaWFudCBub3QgZm91bmQgZm9yIElEOicsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGluaXRQT0lfdG9nZ2xlKCkge1xuICAgICAgICBjb25zdCB0b2dnbGVUcmlnZ2VyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5wb2lfdG9nZ2xlXCIpO1xuICAgICAgICBjb25zdCB2YXJpYW50Q29udGFpbmVycyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuYnV5Ym94X192YXJpYW50LS1pdGVtc1wiKTtcbiAgICBcbiAgICAgICAgaWYgKHRvZ2dsZVRyaWdnZXIpIHtcbiAgICAgICAgICAgIHRvZ2dsZVRyaWdnZXIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVuc2VsZWN0VmFyaWFudHMoKTtcbiAgICAgICAgICAgICAgICB2YXJpYW50Q29udGFpbmVycy5mb3JFYWNoKGNvbnRhaW5lciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIEFycmF5LmZyb20oY29udGFpbmVyLmNoaWxkcmVuKS5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGQuY2xhc3NMaXN0LmNvbnRhaW5zKFwicG9pX3RvZ2dsZVwiKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmNsYXNzTGlzdC50b2dnbGUoXCJoaWRlXCIpOyAvLyBUb2dnbGUgdmlzaWJpbGl0eSBmb3IgZWFjaCBub24tdG9nZ2xlIGNoaWxkXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgIFxuICAgICAgICAgICAgICAgIC8vIERldGVybWluZSB0aGUgdG9nZ2xlIHRleHQgYmFzZWQgb24gdGhlIHZpc2liaWxpdHkgb2YgdGhlIGZpcnN0IGl0ZW0gYWNyb3NzIGFsbCBjb250YWluZXJzXG4gICAgICAgICAgICAgICAgY29uc3Qgc29tZVZpc2libGUgPSBBcnJheS5mcm9tKHZhcmlhbnRDb250YWluZXJzKS5zb21lKGNvbnRhaW5lciA9PiBcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5wb2kuYnV5Ym94X192YXJpYW50LS1pdGVtJykgJiYgIWNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcucG9pLmJ1eWJveF9fdmFyaWFudC0taXRlbScpLmNsYXNzTGlzdC5jb250YWlucyhcImhpZGVcIilcbiAgICAgICAgICAgICAgICApO1xuICAgIFxuICAgICAgICAgICAgICAgIHRvZ2dsZVRyaWdnZXIudGV4dENvbnRlbnQgPSBzb21lVmlzaWJsZSA/IFwiVmlzYSBlbmRhc3QgbnlhXCIgOiBcIlZpc2EgZW5kYXN0IFByZS1vd25lZFwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1bnNlbGVjdFZhcmlhbnRzKCkge1xuICAgICAgICBBcnJheS5mcm9tKHRoaXMudmFyaWFudHMpLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgICBpdGVtLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgQXJyYXkuZnJvbShpdGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzcGFuJykpLmZvckVhY2goc3BhbiA9PiB7XG4gICAgICAgICAgICAgICAgc3Bhbi5jbGFzc0xpc3QuYWRkKCdoaWRlJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYWlyQnV5RWxlbWVudCA9IHRoaXMuYnV5QnV0dG9uO1xuICAgICAgICBpZiAoYWlyQnV5RWxlbWVudCkge1xuICAgICAgICAgICAgYWlyQnV5RWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkaXNhYmxlZCcpO1xuICAgICAgICAgICAgYWlyQnV5RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdlcnJvcicpO1xuICAgICAgICAgICAgYWlyQnV5RWxlbWVudC5kYXRhc2V0LmlkID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jbGVhclZhcmlhbnQoKTtcbiAgICAgICAgdGhpcy5jbGVhckZpZWxkcygpO1xuICAgICAgICB0aGlzLmJ1eUJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdhZGRUb0NhcnQnLCBlID0+IHsgdGhpcy5zaG93Q2FydEVycm9yKGUpOyB9KTtcbiAgICB9XG5cbiAgICB1cGRhdGVWYXJpYW50SW5mbyh2YXJpYW50LCBkYXRhKSB7XG4gICAgICAgIC8vIFVwZGF0ZSBidXkgYnV0dG9uIGxhYmVsIGFuZCBjbGFzc2VzIGJhc2VkIG9uIHZhcmlhbnQgcHJvcGVydGllc1xuICAgICAgICBjb25zdCBidG5MYWJlbCA9IHRoaXMuYnV5QnV0dG9uLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2Fpci1idXktbGFiZWwnKVswXTtcbiAgICBcbiAgICAgICAgaWYgKHZhcmlhbnQuYnV5YWJsZSkge1xuICAgICAgICAgICAgYnRuTGFiZWwudGV4dENvbnRlbnQgPSBidG5MYWJlbC5kYXRhc2V0LmJ1eWFibGU7XG4gICAgICAgICAgICB0aGlzLmJ1eUJ1dHRvbi5jbGFzc0xpc3QuYWRkKCdidXlhYmxlJyk7XG4gICAgICAgICAgICB0aGlzLmJ1eUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdhbGVydGFibGUnKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YXJpYW50LndhdGNoYWJsZSkge1xuICAgICAgICAgICAgYnRuTGFiZWwudGV4dENvbnRlbnQgPSBidG5MYWJlbC5kYXRhc2V0LmFsZXJ0YWJsZTtcbiAgICAgICAgICAgIHRoaXMuYnV5QnV0dG9uLmNsYXNzTGlzdC5hZGQoJ2FsZXJ0YWJsZScpO1xuICAgICAgICAgICAgdGhpcy5idXlCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgnYnV5YWJsZScpO1xuICAgICAgICB9XG4gICAgXG4gICAgICAgIC8vIFNldCBidXkgYnV0dG9uIGRhdGEgYXR0cmlidXRlcyBmb3IgdmFyaWFudCB0cmFja2luZ1xuICAgICAgICB0aGlzLmJ1eUJ1dHRvbi5kYXRhc2V0LmlkID0gdmFyaWFudC5pZDtcbiAgICAgICAgdGhpcy5idXlCdXR0b24uZGF0YXNldC5zdG9ja19pZCA9IHZhcmlhbnQuYXZhaWxhYmlsaXR5X2lkO1xuICAgICAgICB0aGlzLmJ1eUJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKCdlcnJvcicpO1xuICAgICAgICAvLyBVcGRhdGUgdmFyaW91cyBlbGVtZW50cyBhY3Jvc3MgdGhlIHBhZ2Ugd2l0aCB2YXJpYW50LXNwZWNpZmljIGRhdGFcbiAgICAgICAgdGhpcy51cGRhdGVWYXJpYW50RWxlbWVudHModmFyaWFudC5pZCxkYXRhKTtcbiAgICAgICAgaWYgKHRoaXMuYXV0b0FkZCkge1xuICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhaXItYnV5XCIpLmNsaWNrKCk7XG4gICAgICAgICAgICB0aGlzLmF1dG9BZGQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZVZhcmlhbnRFbGVtZW50cyh2YXJpYW50SWQsIGRhdGEpIHtcblxuICAgICAgICAvLyBBc3N1bWUgZGF0YSBjb250YWlucyB0aGUgcHJpY2luZyBhbmQgb3RoZXIgdmFyaWFudC1zcGVjaWZpYyBpbmZvcm1hdGlvblxuICAgICAgICBjb25zdCBwcmljZUVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucHJpY2UtaW5mbyAnKTtcbiAgICAgICAgaWYgKCFwcmljZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIFxuICAgICAgICAvLyBBc3N1bWluZyBmb3JtYXRQcmljZUh0bWwgaXMgYSBmdW5jdGlvbiBkZWZpbmVkIGVsc2V3aGVyZSB0aGF0IGZvcm1hdHMgdGhlIHByaWNlIEhUTUxcbiAgICAgICAgcHJpY2VFbGVtZW50LmlubmVySFRNTCA9ICgwLF9zY3JpcHRzX3V0aWxzX2pzX19XRUJQQUNLX0lNUE9SVEVEX01PRFVMRV8wX18uZm9ybWF0UHJpY2VIdG1sKShkYXRhLnByaWNlLCBkYXRhLnByaWNlX3JlZ3VsYXIsIGRhdGEuY2FtcGFpZ24sIGRhdGEucHJpY2VfcHJlZml4KTtcbiAgICB9XG5cbiAgICBjbGVhclZhcmlhbnQoKSB7XG4gICAgICAgIHRoaXMuYnV5QnV0dG9uLmRhdGFzZXQuaWQgPSAnJztcbiAgICB9XG5cbiAgICBjbGVhckZpZWxkcygpIHtcbiAgICAgICAgLy8gSXRlcmF0ZSBvdmVyIGVhY2ggZmllbGQgYW5kIHJlc2V0IGl0cyBkYXRhc2V0IHZhbHVlXG4gICAgICAgIFxuICAgICAgICAgICAgaWYgKHRoaXMuZmllbGRzLmRhdGFzZXQudmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpZWxkcy5kYXRhc2V0LnZhbHVlID0gJyc7IC8vIFJlc2V0IHRoZSBkYXRhc2V0IHZhbHVlXG4gICAgICAgICAgICB9IFxuICAgICAgICBcbiAgICB9XG5cbiAgICBzaG93Q2FydEVycm9yKCkge1xuICAgICAgICBsZXQgZXJyb3IgPSBmYWxzZTtcbiAgICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiB0aGlzLnZhcmlhbnRzKSB7XG4gICAgICAgICAgICBpZiAoIWZpZWxkLmRhdGFzZXQuaWQpIHtcblxuXG4gICAgICAgICAgICAgICAgZmllbGQuY2xhc3NMaXN0LmFkZCgnZXJyb3InKTtcbiAgICAgICAgICAgICAgICBmaWVsZC5wYXJlbnRFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Vycm9yJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNhaXItYnV5XCIpLmNsYXNzTGlzdC5hZGQoXCJlcnJvclwiKTtcbiAgICAgICAgICAgICAgICBlcnJvciA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpZWxkLmNsYXNzTGlzdC5yZW1vdmUoJ2Vycm9yJyk7XG4gICAgICAgICAgICAgICAgZmllbGQucGFyZW50RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdlcnJvcicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yRXZlbnQgPSAoKSA9PiB0aGlzLmhpZGVFcnJvckV2ZW50KCk7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuZXJyb3JFdmVudCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoaWRlRXJyb3JFdmVudCgpIHtcbiAgICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiB0aGlzLmZpZWxkcykge1xuICAgICAgICAgICAgZmllbGQuY2xhc3NMaXN0LnJlbW92ZSgnZXJyb3InKTtcbiAgICAgICAgICAgIGZpZWxkLnBhcmVudEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZXJyb3InKTtcbiAgICAgICAgfVxuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuZXJyb3JFdmVudCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHtnZXRDb29raWV9IGZyb20gXCIuLi8uLi9zY3JpcHRzL3V0aWxzLmpzXCI7XG5cbmNvbnN0IHN0b3JhZ2VfbmFtZSA9ICdhaXJfd2lzaGxpc3QnO1xuY29uc3QgZXhwaXJlX3RpbWUgPSA2MDsgLy8gSW4gbWludXRlcy5cbmxldCB3aXNobGlzdDtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgV2lzaGxpc3Qge1xuXG5cdGNvbnN0cnVjdG9yKGNhcnQpIHtcblx0XHR0aGlzLmNhcnQgPSBjYXJ0O1xuXHRcdHRoaXMuaW5pdCgpO1xuXHRcdHRoaXMuaW5pdF9ldmVudHMoKTtcblx0fVxuXG5cdGluaXQoKSB7XG5cdFx0aWYgKCFnZXRDb29raWUoJ1NFU1MnKSkgcmV0dXJuO1xuXHRcdGlmICghZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImhlYWRlcl9fd2lzaGxpc3RcIikubGVuZ3RoKSByZXR1cm47XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuRGluX1NpZGFfT25za2VsaXN0YV9XcmFwcGVyIC5LbmFwcF9Lb3AgYScpLmZvckVhY2goZWxlbWVudCA9PiB7XG5cdFx0XHRjb25zb2xlLmxvZyhlbGVtZW50KTtcblx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSkgPT4ge1xuXHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGNvbnNvbGUubG9nKGVsZW1lbnQucGFyZW50Tm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUpO1xuXG5cdFx0XHRcdGxldCBmb3JtID0gZWxlbWVudC5wYXJlbnROb2RlLnBhcmVudE5vZGUucGFyZW50Tm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGU7XG5cdFx0XHRcdGxldCBwcm9kdWN0X2lkID0gZm9ybS5hbHRuci52YWx1ZTtcblxuXHRcdFx0XHRpZiAocHJvZHVjdF9pZCkge1xuXHRcdFx0XHRcdHRoaXMuY2FydC5hZGRfaXRlbShwcm9kdWN0X2lkLCAxKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHR3aXNobGlzdCA9IHRoaXMuZ2V0X3N0b3JhZ2UoKTtcblxuXHRcdGlmICh3aXNobGlzdCkge1xuXHRcdFx0dGhpcy5yZW5kZXIoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5nZXQoKTtcblx0XHR9XG5cdH1cblxuXHRpbml0X2V2ZW50cygpIHtcblx0XHR3aW5kb3cubGl2ZUV2ZW50KFwiLnByb2R1Y3RfX3dpc2hsaXN0XCIsIFwiY2xpY2tcIiwgKGV2ZW50LCBlbGVtZW50KSA9PiB7IFxuXHRcdFx0dGhpcy5oYW5kbGVfZXZlbnQoZWxlbWVudCwgZXZlbnQpO1xuXHRcdH0pO1xuXG5cdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignYWZ0ZXJfZmlsdGVyJywgKCkgPT4ge1xuXHRcdFx0dGhpcy5pbml0KCk7XG5cdFx0fSk7XG5cblx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdwcm9kdWN0X2NlbGxfdXBkYXRlJywgKCkgPT4ge1xuXHRcdFx0dGhpcy5pbml0KCk7XG5cdFx0fSk7XG5cdH1cblxuXHRhc3luYyBnZXQoKSB7XG5cdFx0Y29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnL3Nob3A/ZnVuaz1nZXRfd2lzaGxpc3QnKTtcblx0XHRjb25zdCByZXN1bHQgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cblx0XHRpZiAocmVzdWx0LnN0YXR1cy5jb2RlID09IDIwMCkge1xuXHRcdFx0d2lzaGxpc3QgPSByZXN1bHQuZGF0YTtcblxuXHRcdFx0dGhpcy5zYXZlX3N0b3JhZ2UoKTtcblx0XHRcdHRoaXMucmVuZGVyKCk7XG5cdFx0fVxuXHR9XG5cblx0Z2V0X3N0b3JhZ2UoKSB7XG5cdFx0aWYgKHR5cGVvZiAoU3RvcmFnZSkgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcblxuXHRcdGxldCBzdHIgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oc3RvcmFnZV9uYW1lKTtcblxuXHRcdGlmIChzdHIgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuXHRcdGxldCBkYXRhO1xuXG5cdFx0dHJ5IHtcblx0XHRcdGRhdGEgPSBKU09OLnBhcnNlKHN0cik7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHRpZiAoZGF0YS5leHBpcmVzIDwgRGF0ZS5ub3coKSkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YTtcblx0fVxuXG5cdHNhdmVfc3RvcmFnZSgpIHtcblx0XHRpZiAodHlwZW9mIChTdG9yYWdlKSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBudWxsO1xuXG5cdFx0d2lzaGxpc3QuZXhwaXJlcyA9IERhdGUubm93KCkgKyBleHBpcmVfdGltZSAqIDYwMDAwO1xuXHRcdHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShzdG9yYWdlX25hbWUsIEpTT04uc3RyaW5naWZ5KHdpc2hsaXN0KSk7XG5cdH1cblxuXHRoYW5kbGVfZXZlbnQoZWxlbWVudCwgZXZlbnQpIHtcblx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0aWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCctLWZpbGxlZCcpKSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoXCItLWZpbGxlZFwiKTtcblx0XHRcdHRoaXMucmVtb3ZlX2l0ZW0oZWxlbWVudC5kYXRhc2V0LmlkKTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoXCItLWZpbGxlZFwiKTtcblx0XHRcdHRoaXMuYWRkX2l0ZW0oZWxlbWVudC5kYXRhc2V0LmlkKTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBhZGRfaXRlbShpZCkge1xuXHRcdGNvbnN0IGRhdGEgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG5cblx0XHRkYXRhLmFwcGVuZCgnZnVuaycsICdhZGRfd2lzaGxpc3RfaXRlbScpO1xuXHRcdGRhdGEuYXBwZW5kKCdpZCcsIGlkKTtcblx0XHRcblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcCcsIHtcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0Ym9keTogZGF0YVxuXHRcdH0pO1xuXG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXHRcdGlmIChyZXN1bHQuc3RhdHVzLmNvZGUgPT0gMjAwKSB7XG5cdFx0XHR3aXNobGlzdCA9IHJlc3VsdC5kYXRhLndpc2hsaXN0O1xuXG5cdFx0XHR0aGlzLnNhdmVfc3RvcmFnZSgpO1xuXHRcdFx0dGhpcy5yZW5kZXIoKTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyByZW1vdmVfaXRlbShpZCkge1xuXHRcdGNvbnN0IGRhdGEgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG5cblx0XHRkYXRhLmFwcGVuZCgnZnVuaycsICdyZW1vdmVfd2lzaGxpc3RfaXRlbScpO1xuXHRcdGRhdGEuYXBwZW5kKCdpZCcsIGlkKTtcblx0XHRcblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCcvc2hvcCcsIHtcblx0XHRcdG1ldGhvZDogJ1BPU1QnLFxuXHRcdFx0Ym9keTogZGF0YVxuXHRcdH0pO1xuXG5cdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuXHRcdGlmIChyZXN1bHQuc3RhdHVzLmNvZGUgPT0gMjAwKSB7XG5cdFx0XHR3aXNobGlzdCA9IHJlc3VsdC5kYXRhLndpc2hsaXN0O1xuXG5cdFx0XHR0aGlzLnNhdmVfc3RvcmFnZSgpO1xuXHRcdFx0dGhpcy5yZW5kZXIoKTtcblx0XHR9XG5cdH1cblxuXHRyZW5kZXIoKSB7XG5cdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnByb2R1Y3RfX3dpc2hsaXN0Li0tZmlsbGVkJykuZm9yRWFjaChlbGVtZW50ID0+IHtcblx0XHRcdGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShcIi0tZmlsbGVkXCIpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gTGlnaHRzIHVwIHN0YXJzIGZvciBwcm9kdWN0cyBpbiB3aXNobGlzdFxuXHRcdGxldCBpID0gMDtcblx0XHR3aGlsZSAoaSA8IHdpc2hsaXN0Lmxlbmd0aCkge1xuXHRcdFx0Y29uc3QgZWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbZGF0YS1pZD1cIicgKyB3aXNobGlzdFtpXS5pZCArICdcIl0nKTtcblx0XHRcdGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xuXHRcdFx0XHRlbGVtZW50LmNsYXNzTGlzdC5hZGQoJy0tZmlsbGVkJyk7XG5cdFx0XHR9KTtcblxuXHRcdFx0aSsrO1xuXHRcdH1cblxuXHRcdC8vIExpZ2h0cyB1cCBzdGFyIGluIGhlYWRlclxuXHRcdHZhciBoZWFkZXJfZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJoZWFkZXJfX3dpc2hsaXN0XCIpO1xuXHRcdGlmICghaGVhZGVyX2VsZW1lbnQpIHJldHVybjtcblxuXHRcdGlmICh3aXNobGlzdC5sZW5ndGgpIHtcblx0XHRcdGhlYWRlcl9lbGVtZW50WzBdLmNsYXNzTGlzdC5hZGQoJy0tZmlsbGVkJyk7XG5cdFx0fVxuXHRcdGVsc2Uge1xuXHRcdFx0aGVhZGVyX2VsZW1lbnRbMF0uY2xhc3NMaXN0LnJlbW92ZShcIi0tZmlsbGVkXCIpO1xuXHRcdH1cblx0fVxufVxuIiwiKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJvb3QuSW1hZ2Vab29tID0gZmFjdG9yeSgpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250YWluZXIgRE9NIGVsZW1lbnQsIHdoaWNoIGNvbnRhaW5zIGFuIGltYWdlIHRvIGJlIHpvb21lZCAocmVxdWlyZWQpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMganMtaW1hZ2Utem9vbSBvcHRpb25zIChyZXF1aXJlZClcbiAgICAgKiAqKndpZHRoKiogKG51bWJlcikgLSB3aWR0aCBvZiB0aGUgc291cmNlIGltYWdlIChvcHRpb25hbClcbiAgICAgKiAqKmhlaWdodCoqIChudW1iZXIpIC0gaGVpZ2h0IG9mIHRoZSBzb3VyY2UgaW1hZ2UgKG9wdGlvbmFsKS5cbiAgICAgKiAqKnpvb21XaWR0aCoqIChudW1iZXIpIC0gd2lkdGggb2YgdGhlIHpvb21lZCBpbWFnZS4gWm9vbWVkIGltYWdlIGhlaWdodCBlcXVhbHMgc291cmNlIGltYWdlIGhlaWdodCAob3B0aW9uYWwpXG4gICAgICogKippbWcqKiAoc3RyaW5nKSAtIHVybCBvZiB0aGUgc291cmNlIGltYWdlLiBQcm92aWRlZCBpZiBjb250YWluZXIgZG9lcyBub3QgY29udGFpbiBpbWcgZWxlbWVudCBhcyBhIHRhZyAob3B0aW9uYWwpXG4gICAgICogKipzY2FsZSoqIChudW1iZXIpIC0gem9vbSBzY2FsZS4gaWYgbm90IHByb3ZpZGVkLCBzY2FsZSBpcyBjYWxjdWxhdGVkIGFzIG5hdHVyYWwgaW1hZ2Ugc2l6ZSAvIGltYWdlIHNpemUsIHByb3ZpZGVkIGluIHBhcmFtcyAob3B0aW9uYWwgaWYgem9vbVdpZHRoIHBhcmFtIGlzIHByb3ZpZGVkKVxuICAgICAqICoqb2Zmc2V0KiogKG9iamVjdCkgLSB7dmVydGljYWw6IG51bWJlciwgaG9yaXpvbnRhbDogbnVtYmVyfS4gWm9vbWVkIGltYWdlIG9mZnNldCAob3B0aW9uYWwpXG4gICAgICogKip6b29tQ29udGFpbmVyKiogKG5vZGUpIC0gRE9NIG5vZGUgcmVmZXJlbmNlIHdoZXJlIHpvb21lZEltYWdlIHdpbGwgYmUgYXBwZW5kZWQgdG8gKGRlZmF1bHQgdG8gdGhlIGNvbnRhaW5lciBlbGVtZW50IG9mIGltYWdlKVxuICAgICAqICoqem9vbVN0eWxlKiogKHN0cmluZykgLSBjdXN0b20gc3R5bGUgYXBwbGllZCB0byB0aGUgem9vbWVkIGltYWdlIChpLmUuICdvcGFjaXR5OiAwLjE7YmFja2dyb3VuZC1jb2xvcjogd2hpdGU7JylcbiAgICAgKiAqKnpvb21Qb3NpdGlvbioqIChzdHJpbmcpIC0gcG9zaXRpb24gb2Ygem9vbWVkIGltYWdlLiBJdCBjYW4gYmU6ICBgdG9wYCwgYGxlZnRgLCBgYm90dG9tYCwgYG9yaWdpbmFsYCBvciB0aGUgZGVmYXVsdCBgcmlnaHRgLlxuICAgICAqICoqem9vbUxlbnNTdHlsZSoqIChzdHJpbmcpIGN1c3RvbSBzdHlsZSBhcHBsaWVkIHRvIHRvIHpvb20gbGVudHMgKGkuZS4gJ29wYWNpdHk6IDAuMTtiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsnKVxuICAgICAqL1xuICAgIHJldHVybiBmdW5jdGlvbiBJbWFnZVpvb20oY29udGFpbmVyLCBvcHRzKSB7XG4gICAgICAgIFwidXNlIHN0cmljdFwiO1xuICAgICAgICB2YXIgb3B0aW9ucyA9IG9wdHM7XG4gICAgICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGRhdGEgPSB7XG4gICAgICAgICAgICBzb3VyY2VJbWc6IHtcbiAgICAgICAgICAgICAgICBlbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgICAgICAgIGhlaWdodDogMCxcbiAgICAgICAgICAgICAgICBuYXR1cmFsV2lkdGg6IDAsXG4gICAgICAgICAgICAgICAgbmF0dXJhbEhlaWdodDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGltZzoge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAwLFxuICAgICAgICAgICAgICAgIG5hdHVyYWxXaWR0aDogMCxcbiAgICAgICAgICAgICAgICBuYXR1cmFsSGVpZ2h0OiAwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgem9vbWVkSW1nT2Zmc2V0OiB7XG4gICAgICAgICAgICAgICAgdmVydGljYWw6IDAsXG4gICAgICAgICAgICAgICAgaG9yaXpvbnRhbDogMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHpvb21lZEltZzoge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgem9vbUxlbnM6IHtcbiAgICAgICAgICAgICAgICBlbGVtZW50OiBudWxsLFxuICAgICAgICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgICAgICAgIGhlaWdodDogMFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdmFyIGxlbnNEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdmFyIHNjYWxlWDtcbiAgICAgICAgdmFyIHNjYWxlWTtcbiAgICAgICAgdmFyIG9mZnNldDtcbiAgICAgICAgdmFyIHpvb21TY2FsZVg7XG4gICAgICAgIHZhciB6b29tU2NhbGVZO1xuICAgICAgICB2YXIgem9vbU9mZnNldDtcbiAgICAgICAgZGF0YS56b29tZWRJbWdPZmZzZXQgPSB7XG4gICAgICAgICAgICB2ZXJ0aWNhbDogb3B0aW9ucy5vZmZzZXQgJiYgb3B0aW9ucy5vZmZzZXQudmVydGljYWwgPyBvcHRpb25zLm9mZnNldC52ZXJ0aWNhbCA6IDAsXG4gICAgICAgICAgICBob3Jpem9udGFsOiBvcHRpb25zLm9mZnNldCAmJiBvcHRpb25zLm9mZnNldC5ob3Jpem9udGFsID8gb3B0aW9ucy5vZmZzZXQuaG9yaXpvbnRhbCA6IDBcbiAgICAgICAgfTtcbiAgICAgICAgZGF0YS56b29tUG9zaXRpb24gPSBvcHRpb25zLnpvb21Qb3NpdGlvbiB8fCAncmlnaHQnO1xuICAgICAgICBkYXRhLnpvb21Db250YWluZXIgPSAob3B0aW9ucy56b29tQ29udGFpbmVyKSA/IG9wdGlvbnMuem9vbUNvbnRhaW5lciA6IGNvbnRhaW5lcjtcbiAgICAgICAgZnVuY3Rpb24gZ2V0T2Zmc2V0KGVsKSB7XG4gICAgICAgICAgICBpZiAoZWwpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWxSZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtsZWZ0OiBlbFJlY3QubGVmdCwgdG9wOiBlbFJlY3QudG9wfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7bGVmdDogMCwgdG9wOiAwfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGxlZnRMaW1pdChtaW4pIHtcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25zLndpZHRoIC0gbWluO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gdG9wTGltaXQobWluKSB7XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5oZWlnaHQgLSBtaW47XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBnZXRWYWx1ZSh2YWwsIG1pbiwgbWF4KSB7XG4gICAgICAgICAgICBpZiAodmFsIDwgbWluKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh2YWwgPiBtYXgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGdldFBvc2l0aW9uKHYsIG1pbiwgbWF4KSB7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBnZXRWYWx1ZSh2LCBtaW4sIG1heCk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgLSBtaW47XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiB6b29tTGVuc0xlZnQobGVmdCkge1xuICAgICAgICAgICAgdmFyIGxlZnRNaW4gPSBkYXRhLnpvb21MZW5zLndpZHRoIC8gMjtcbiAgICAgICAgICAgIHJldHVybiBnZXRQb3NpdGlvbihsZWZ0LCBsZWZ0TWluLCBsZWZ0TGltaXQobGVmdE1pbikpO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gem9vbUxlbnNUb3AodG9wKSB7XG4gICAgICAgICAgICB2YXIgdG9wTWluID0gZGF0YS56b29tTGVucy5oZWlnaHQgLyAyO1xuICAgICAgICAgICAgcmV0dXJuIGdldFBvc2l0aW9uKHRvcCwgdG9wTWluLCB0b3BMaW1pdCh0b3BNaW4pKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHNldFpvb21lZEltZ1NpemUob3B0aW9ucywgZGF0YSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2NhbGUpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLndpZHRoID0gb3B0aW9ucy53aWR0aCAqIG9wdGlvbnMuc2NhbGUgKyAncHgnO1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gb3B0aW9ucy5oZWlnaHQgKiBvcHRpb25zLnNjYWxlICsgJ3B4JztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy56b29tV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLndpZHRoID0gb3B0aW9ucy56b29tV2lkdGggKyAncHgnO1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gZGF0YS5zb3VyY2VJbWcuZWxlbWVudC5zdHlsZS5oZWlnaHQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBvblNvdXJjZUltZ0xvYWQoKSB7XG4gICAgICAgICAgICAvLyB1c2UgaGVpZ2h0IGRldGVybWluZWQgYnkgYnJvd3NlciBpZiBoZWlnaHQgaXMgbm90IHNldCBpbiBvcHRpb25zXG4gICAgICAgICAgICBvcHRpb25zLmhlaWdodCA9IG9wdGlvbnMuaGVpZ2h0IHx8IGRhdGEuc291cmNlSW1nLmVsZW1lbnQuaGVpZ2h0O1xuICAgICAgICAgICAgLy8gZGF0YS5zb3VyY2VJbWcuZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBvcHRpb25zLmhlaWdodCArICdweCc7XG4gICAgICAgICAgICBkYXRhLnNvdXJjZUltZy5lbGVtZW50LnN0eWxlLmhlaWdodCA9ICcxMDAlJztcblxuICAgICAgICAgICAgLy8gdXNlIHdpZHRoIGRldGVybWluZWQgYnkgYnJvd3NlciBpZiB3aWR0aCBpcyBub3Qgc2V0IGluIG9wdGlvbnNcbiAgICAgICAgICAgIG9wdGlvbnMud2lkdGggPSBvcHRpb25zLndpZHRoIHx8IGRhdGEuc291cmNlSW1nLmVsZW1lbnQud2lkdGg7XG4gICAgICAgICAgICBkYXRhLnNvdXJjZUltZy5lbGVtZW50LnN0eWxlLndpZHRoID0gb3B0aW9ucy53aWR0aCArICdweCc7XG5cbiAgICAgICAgICAgIHNldFpvb21lZEltZ1NpemUob3B0aW9ucywgZGF0YSk7XG5cbiAgICAgICAgICAgIGRhdGEuc291cmNlSW1nLm5hdHVyYWxXaWR0aCA9IGRhdGEuc291cmNlSW1nLmVsZW1lbnQubmF0dXJhbFdpZHRoO1xuICAgICAgICAgICAgZGF0YS5zb3VyY2VJbWcubmF0dXJhbEhlaWdodCA9IGRhdGEuc291cmNlSW1nLmVsZW1lbnQubmF0dXJhbEhlaWdodDtcbiAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZFNpemUgPSBkYXRhLmltZy5lbGVtZW50Lm5hdHVyYWxXaWR0aCArICdweCAnICsgZGF0YS5pbWcuZWxlbWVudC5uYXR1cmFsSGVpZ2h0ICsgJ3B4JztcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuem9vbVN0eWxlKSB7XG4gICAgICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5zdHlsZS5jc3NUZXh0ICs9IG9wdGlvbnMuem9vbVN0eWxlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuem9vbUxlbnNTdHlsZSkge1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbUxlbnMuZWxlbWVudC5zdHlsZS5jc3NUZXh0ICs9IG9wdGlvbnMuem9vbUxlbnNTdHlsZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmQgPSAnd2hpdGUnO1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbUxlbnMuZWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gJzAuNCc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHpvb21TY2FsZVggPSBkYXRhLmltZy5lbGVtZW50Lm5hdHVyYWxXaWR0aCAvIG9wdGlvbnMud2lkdGg7XG4gICAgICAgICAgICB6b29tU2NhbGVZID0gZGF0YS5pbWcuZWxlbWVudC5uYXR1cmFsSGVpZ2h0IC8gb3B0aW9ucy5oZWlnaHQ7XG4gICAgICAgICAgICB6b29tT2Zmc2V0ID0gZ2V0T2Zmc2V0KGRhdGEuaW1nLmVsZW1lbnQpO1xuXG4gICAgICAgICAgICBzY2FsZVggPSBkYXRhLnNvdXJjZUltZy5uYXR1cmFsV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICAgICAgICAgICAgc2NhbGVZID0gZGF0YS5zb3VyY2VJbWcubmF0dXJhbEhlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICAgICAgICAgICAgb2Zmc2V0ID0gZ2V0T2Zmc2V0KGRhdGEuc291cmNlSW1nLmVsZW1lbnQpO1xuXG4gICAgICAgICAgICAvLyBzZXQgem9vbUxlbnMgZGltZW5zaW9uc1xuICAgICAgICAgICAgLy8gaWYgY3VzdG9tIHNjYWxlIGlzIHNldFxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2NhbGUpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21MZW5zLndpZHRoID0gb3B0aW9ucy53aWR0aCAvIChkYXRhLnNvdXJjZUltZy5uYXR1cmFsV2lkdGggLyAob3B0aW9ucy53aWR0aCAqIG9wdGlvbnMuc2NhbGUpKTtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21MZW5zLmhlaWdodCA9IG9wdGlvbnMuaGVpZ2h0IC8gKGRhdGEuc291cmNlSW1nLm5hdHVyYWxIZWlnaHQgLyAob3B0aW9ucy5oZWlnaHQgKiBvcHRpb25zLnNjYWxlKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGVsc2UgaWYgem9vbVdpZHRoIGlzIHNldFxuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy56b29tV2lkdGgpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21MZW5zLndpZHRoID0gb3B0aW9ucy56b29tV2lkdGggLyB6b29tU2NhbGVYO1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbUxlbnMuaGVpZ2h0ID0gb3B0aW9ucy5oZWlnaHQgLyB6b29tU2NhbGVZO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBlbHNlIHJlYWQgZnJvbSB0aGUgem9vbWVkSW1nXG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbUxlbnMud2lkdGggPSBkYXRhLnpvb21lZEltZy5lbGVtZW50LmNsaWVudFdpZHRoIC8gc2NhbGVYO1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbUxlbnMuaGVpZ2h0ID0gZGF0YS56b29tZWRJbWcuZWxlbWVudC5jbGllbnRIZWlnaHQgLyBzY2FsZVk7XG4gICAgICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkYXRhLnpvb21MZW5zLmVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LnN0eWxlLndpZHRoID0gZGF0YS56b29tTGVucy53aWR0aCArICdweCc7XG4gICAgICAgICAgICBkYXRhLnpvb21MZW5zLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gZGF0YS56b29tTGVucy5oZWlnaHQgKyAncHgnO1xuICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBzZXR1cCgpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBzb3VyY2VJbWcgZWxlbWVudFxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuaW1nKSB7XG4gICAgICAgICAgICAgICAgdmFyIGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgICAgICAgICAgIGltZy5zcmMgPSBvcHRpb25zLmltZztcbiAgICAgICAgICAgICAgICBkYXRhLnNvdXJjZUltZy5lbGVtZW50ID0gY29udGFpbmVyLmFwcGVuZENoaWxkKGltZyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRhdGEuc291cmNlSW1nLmVsZW1lbnQgPSBjb250YWluZXIuY2hpbGRyZW5bMF07XG5cbiAgICAgICAgICAgICAgICAvLyBpZiBzb3VyY2VJbWcgaXMgbm90IGFuIGltZyAobWlnaHQgYmUgYSBwaWN0dXJlIGVsZW1lbnQpLCB0cnkgdG8gZmluZCBvbmVcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5zb3VyY2VJbWcuZWxlbWVudC5ub2RlTmFtZSAhPT0gXCJJTUdcIikge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLnNvdXJjZUltZy5lbGVtZW50ID0gZGF0YS5zb3VyY2VJbWcuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCdpbWcnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuem9vbUltYWdlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgICAgICAgICAgIGltZy5zcmMgPSBvcHRpb25zLnpvb21JbWFnZTtcbiAgICAgICAgICAgICAgICBkYXRhLmltZy5lbGVtZW50ID0gaW1nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhLmltZy5lbGVtZW50ID0gZGF0YS5zb3VyY2VJbWcuZWxlbWVudDtcbiAgICAgICAgICAgIH1cblxuXG5cbiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgY29udGFpbmVyLnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcbiAgICAgICAgICAgIC8vIGRhdGEuc291cmNlSW1nLmVsZW1lbnQuc3R5bGUud2lkdGggPSBvcHRpb25zLndpZHRoID8gb3B0aW9ucy53aWR0aCArICdweCcgOiAnYXV0byc7XG4gICAgICAgICAgICAvLyBkYXRhLnNvdXJjZUltZy5lbGVtZW50LnN0eWxlLmhlaWdodCA9IG9wdGlvbnMuaGVpZ2h0ID8gb3B0aW9ucy5oZWlnaHQgKyAncHgnIDogJ2F1dG8nO1xuXG4gICAgICAgICAgICBcblxuICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50ID0gY29udGFpbmVyLmFwcGVuZENoaWxkKGxlbnNEaXYpO1xuICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBkYXRhLnpvb21MZW5zLmVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnanMtaW1hZ2Utem9vbV9fem9vbWVkLWFyZWEnKTtcblxuICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudCA9IGRhdGEuem9vbUNvbnRhaW5lci5hcHBlbmRDaGlsZChkaXYpO1xuICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdqcy1pbWFnZS16b29tX196b29tZWQtaW1hZ2UnKTtcbiAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gXCJ1cmwoJ1wiICsgZGF0YS5pbWcuZWxlbWVudC5zcmMgKyBcIicpXCI7XG4gICAgICAgICAgICAvLyBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IFwidXJsKCdcIiArIGRhdGEuc291cmNlSW1nLmVsZW1lbnQuc3JjICsgXCInKVwiO1xuICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kUmVwZWF0ID0gJ25vLXJlcGVhdCc7XG4gICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLnpJbmRleCA9ICcyJztcblxuICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLnRvcCA9IGRhdGEuem9vbWVkSW1nT2Zmc2V0LnZlcnRpY2FsICsgJ3B4JztcbiAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUucmlnaHQgPSBkYXRhLnpvb21lZEltZ09mZnNldC5ob3Jpem9udGFsIC0gKGRhdGEuem9vbWVkSW1nT2Zmc2V0Lmhvcml6b250YWwgKiAyKSArICdweCc7XG4gICAgICAgICAgICBkYXRhLnpvb21lZEltZy5lbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGVYKDEwMCUpJztcblxuXG4gICAgICAgICAgICAvLyBzZXR1cCBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBldmVudHMsIGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgZXZlbnRzLCBmYWxzZSk7XG4gICAgICAgICAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIGV2ZW50cywgZmFsc2UpO1xuICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBldmVudHMsIGZhbHNlKTtcbiAgICAgICAgICAgIGRhdGEuem9vbUxlbnMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgZXZlbnRzLCBmYWxzZSk7XG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgZXZlbnRzLCBmYWxzZSk7XG5cbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24ga2lsbCgpIHtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGV2ZW50cywgZmFsc2UpO1xuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBldmVudHMsIGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgZXZlbnRzLCBmYWxzZSk7XG4gICAgICAgICAgICBkYXRhLnpvb21MZW5zLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsIGV2ZW50cywgZmFsc2UpO1xuICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCBldmVudHMsIGZhbHNlKTtcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBldmVudHMsIGZhbHNlKTtcblxuICAgICAgICAgICAgLy8gcmVtb3ZlIGRvbSBub2Rlc1xuICAgICAgICAgICAgaWYgKGRhdGEuem9vbUxlbnMgJiYgZGF0YS56b29tZWRJbWcpIHtcbiAgICAgICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoZGF0YS56b29tTGVucy5lbGVtZW50KTtcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21Db250YWluZXIucmVtb3ZlQ2hpbGQoZGF0YS56b29tZWRJbWcuZWxlbWVudCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLmltZykge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChkYXRhLnNvdXJjZUltZy5lbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0YS5zb3VyY2VJbWcuZWxlbWVudC5zdHlsZS53aWR0aCA9ICcnO1xuICAgICAgICAgICAgICAgIGRhdGEuc291cmNlSW1nLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gJyc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGV2ZW50cyA9IHtcbiAgICAgICAgICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbW91c2Vtb3ZlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZU1vdXNlTW92ZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ21vdXNlZW50ZXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTW91c2VFbnRlcihldmVudCk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ21vdXNlbGVhdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTW91c2VMZWF2ZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Njcm9sbCc6XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVTY3JvbGwoZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoYW5kbGVNb3VzZU1vdmU6IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBvZmZzZXRYO1xuICAgICAgICAgICAgICAgIHZhciBvZmZzZXRZO1xuICAgICAgICAgICAgICAgIHZhciBiYWNrZ3JvdW5kVG9wO1xuICAgICAgICAgICAgICAgIHZhciBiYWNrZ3JvdW5kUmlnaHQ7XG4gICAgICAgICAgICAgICAgdmFyIGJhY2tncm91bmRQb3NpdGlvbjtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldFggPSB6b29tTGVuc0xlZnQoZXZlbnQuY2xpZW50WCAtIG9mZnNldC5sZWZ0KTtcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0WSA9IHpvb21MZW5zVG9wKGV2ZW50LmNsaWVudFkgLSBvZmZzZXQudG9wKTtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZFRvcCA9IG9mZnNldFggKiB6b29tU2NhbGVYO1xuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kUmlnaHQgPSBvZmZzZXRZICogem9vbVNjYWxlWTtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZFBvc2l0aW9uID0gJy0nICsgYmFja2dyb3VuZFRvcCArICdweCAnICsgJy0nICsgYmFja2dyb3VuZFJpZ2h0ICsgJ3B4JztcbiAgICAgICAgICAgICAgICAgICAgZGF0YS56b29tZWRJbWcuZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kUG9zaXRpb24gPSBiYWNrZ3JvdW5kUG9zaXRpb247XG4gICAgICAgICAgICAgICAgICAgIGRhdGEuem9vbUxlbnMuZWxlbWVudC5zdHlsZS5jc3NUZXh0ICs9ICd0b3A6JyArIG9mZnNldFkgKyAncHg7JyArICdsZWZ0OicgKyBvZmZzZXRYICsgJ3B4O2Rpc3BsYXk6IGJsb2NrOyc7XG5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGFuZGxlTW91c2VFbnRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgICAgICAgICAgZGF0YS56b29tTGVucy5lbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGFuZGxlTW91c2VMZWF2ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGRhdGEuem9vbWVkSW1nLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICBkYXRhLnpvb21MZW5zLmVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoYW5kbGVTY3JvbGw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBnZXRPZmZzZXQoZGF0YS5zb3VyY2VJbWcuZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0dXAvSW5pdGlhbGl6ZSBsaWJyYXJ5XG4gICAgICAgIHNldHVwKCk7XG5cbiAgICAgICAgLy8gaWYgKGRhdGEuc291cmNlSW1nLmVsZW1lbnQuY29tcGxldGUpIHtcbiAgICAgICAgaWYgKGRhdGEuaW1nLmVsZW1lbnQuY29tcGxldGUpIHtcbiAgICAgICAgICAgIG9uU291cmNlSW1nTG9hZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0YS5pbWcuZWxlbWVudC5vbmxvYWQgPSBvblNvdXJjZUltZ0xvYWQ7XG4gICAgICAgICAgICAvLyBkYXRhLnNvdXJjZUltZy5lbGVtZW50Lm9ubG9hZCA9IG9uU291cmNlSW1nTG9hZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXR1cDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldHVwKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2lsbDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGtpbGwoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBfZ2V0SW5zdGFuY2VJbmZvOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0dXA6IHNldHVwLFxuICAgICAgICAgICAgICAgICAgICBraWxsOiBraWxsLFxuICAgICAgICAgICAgICAgICAgICBvblNvdXJjZUltZ0xvYWQ6IG9uU291cmNlSW1nTG9hZCxcbiAgICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn0pKTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIhZnVuY3Rpb24obix0KXtcIm9iamVjdFwiPT10eXBlb2YgZXhwb3J0cyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIG1vZHVsZT9tb2R1bGUuZXhwb3J0cz10KCk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZSh0KToobj1cInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsVGhpcz9nbG9iYWxUaGlzOm58fHNlbGYpLkxhenlMb2FkPXQoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBuKCl7cmV0dXJuIG49T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24obil7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIGU9YXJndW1lbnRzW3RdO2Zvcih2YXIgaSBpbiBlKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChlLGkpJiYobltpXT1lW2ldKX1yZXR1cm4gbn0sbi5hcHBseSh0aGlzLGFyZ3VtZW50cyl9dmFyIHQ9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyxlPXQmJiEoXCJvbnNjcm9sbFwiaW4gd2luZG93KXx8XCJ1bmRlZmluZWRcIiE9dHlwZW9mIG5hdmlnYXRvciYmLyhnbGV8aW5nfHJvKWJvdHxjcmF3bHxzcGlkZXIvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpLGk9dCYmXCJJbnRlcnNlY3Rpb25PYnNlcnZlclwiaW4gd2luZG93LG89dCYmXCJjbGFzc0xpc3RcImluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwXCIpLGE9dCYmd2luZG93LmRldmljZVBpeGVsUmF0aW8+MSxyPXtlbGVtZW50c19zZWxlY3RvcjpcIi5sYXp5XCIsY29udGFpbmVyOmV8fHQ/ZG9jdW1lbnQ6bnVsbCx0aHJlc2hvbGQ6MzAwLHRocmVzaG9sZHM6bnVsbCxkYXRhX3NyYzpcInNyY1wiLGRhdGFfc3Jjc2V0Olwic3Jjc2V0XCIsZGF0YV9zaXplczpcInNpemVzXCIsZGF0YV9iZzpcImJnXCIsZGF0YV9iZ19oaWRwaTpcImJnLWhpZHBpXCIsZGF0YV9iZ19tdWx0aTpcImJnLW11bHRpXCIsZGF0YV9iZ19tdWx0aV9oaWRwaTpcImJnLW11bHRpLWhpZHBpXCIsZGF0YV9iZ19zZXQ6XCJiZy1zZXRcIixkYXRhX3Bvc3RlcjpcInBvc3RlclwiLGNsYXNzX2FwcGxpZWQ6XCJhcHBsaWVkXCIsY2xhc3NfbG9hZGluZzpcImxvYWRpbmdcIixjbGFzc19sb2FkZWQ6XCJsb2FkZWRcIixjbGFzc19lcnJvcjpcImVycm9yXCIsY2xhc3NfZW50ZXJlZDpcImVudGVyZWRcIixjbGFzc19leGl0ZWQ6XCJleGl0ZWRcIix1bm9ic2VydmVfY29tcGxldGVkOiEwLHVub2JzZXJ2ZV9lbnRlcmVkOiExLGNhbmNlbF9vbl9leGl0OiEwLGNhbGxiYWNrX2VudGVyOm51bGwsY2FsbGJhY2tfZXhpdDpudWxsLGNhbGxiYWNrX2FwcGxpZWQ6bnVsbCxjYWxsYmFja19sb2FkaW5nOm51bGwsY2FsbGJhY2tfbG9hZGVkOm51bGwsY2FsbGJhY2tfZXJyb3I6bnVsbCxjYWxsYmFja19maW5pc2g6bnVsbCxjYWxsYmFja19jYW5jZWw6bnVsbCx1c2VfbmF0aXZlOiExLHJlc3RvcmVfb25fZXJyb3I6ITF9LGM9ZnVuY3Rpb24odCl7cmV0dXJuIG4oe30scix0KX0sbD1mdW5jdGlvbihuLHQpe3ZhciBlLGk9XCJMYXp5TG9hZDo6SW5pdGlhbGl6ZWRcIixvPW5ldyBuKHQpO3RyeXtlPW5ldyBDdXN0b21FdmVudChpLHtkZXRhaWw6e2luc3RhbmNlOm99fSl9Y2F0Y2gobil7KGU9ZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJDdXN0b21FdmVudFwiKSkuaW5pdEN1c3RvbUV2ZW50KGksITEsITEse2luc3RhbmNlOm99KX13aW5kb3cuZGlzcGF0Y2hFdmVudChlKX0sdT1cInNyY1wiLHM9XCJzcmNzZXRcIixkPVwic2l6ZXNcIixmPVwicG9zdGVyXCIsXz1cImxsT3JpZ2luYWxBdHRyc1wiLGc9XCJkYXRhXCIsdj1cImxvYWRpbmdcIixiPVwibG9hZGVkXCIsbT1cImFwcGxpZWRcIixwPVwiZXJyb3JcIixoPVwibmF0aXZlXCIsRT1cImRhdGEtXCIsST1cImxsLXN0YXR1c1wiLHk9ZnVuY3Rpb24obix0KXtyZXR1cm4gbi5nZXRBdHRyaWJ1dGUoRSt0KX0saz1mdW5jdGlvbihuKXtyZXR1cm4geShuLEkpfSx3PWZ1bmN0aW9uKG4sdCl7cmV0dXJuIGZ1bmN0aW9uKG4sdCxlKXt2YXIgaT1cImRhdGEtbGwtc3RhdHVzXCI7bnVsbCE9PWU/bi5zZXRBdHRyaWJ1dGUoaSxlKTpuLnJlbW92ZUF0dHJpYnV0ZShpKX0obiwwLHQpfSxBPWZ1bmN0aW9uKG4pe3JldHVybiB3KG4sbnVsbCl9LEw9ZnVuY3Rpb24obil7cmV0dXJuIG51bGw9PT1rKG4pfSxPPWZ1bmN0aW9uKG4pe3JldHVybiBrKG4pPT09aH0seD1bdixiLG0scF0sQz1mdW5jdGlvbihuLHQsZSxpKXtuJiYodm9pZCAwPT09aT92b2lkIDA9PT1lP24odCk6bih0LGUpOm4odCxlLGkpKX0sTj1mdW5jdGlvbihuLHQpe28/bi5jbGFzc0xpc3QuYWRkKHQpOm4uY2xhc3NOYW1lKz0obi5jbGFzc05hbWU/XCIgXCI6XCJcIikrdH0sTT1mdW5jdGlvbihuLHQpe28/bi5jbGFzc0xpc3QucmVtb3ZlKHQpOm4uY2xhc3NOYW1lPW4uY2xhc3NOYW1lLnJlcGxhY2UobmV3IFJlZ0V4cChcIihefFxcXFxzKylcIit0K1wiKFxcXFxzK3wkKVwiKSxcIiBcIikucmVwbGFjZSgvXlxccysvLFwiXCIpLnJlcGxhY2UoL1xccyskLyxcIlwiKX0sej1mdW5jdGlvbihuKXtyZXR1cm4gbi5sbFRlbXBJbWFnZX0sVD1mdW5jdGlvbihuLHQpe2lmKHQpe3ZhciBlPXQuX29ic2VydmVyO2UmJmUudW5vYnNlcnZlKG4pfX0sUj1mdW5jdGlvbihuLHQpe24mJihuLmxvYWRpbmdDb3VudCs9dCl9LEc9ZnVuY3Rpb24obix0KXtuJiYobi50b0xvYWRDb3VudD10KX0saj1mdW5jdGlvbihuKXtmb3IodmFyIHQsZT1bXSxpPTA7dD1uLmNoaWxkcmVuW2ldO2krPTEpXCJTT1VSQ0VcIj09PXQudGFnTmFtZSYmZS5wdXNoKHQpO3JldHVybiBlfSxEPWZ1bmN0aW9uKG4sdCl7dmFyIGU9bi5wYXJlbnROb2RlO2UmJlwiUElDVFVSRVwiPT09ZS50YWdOYW1lJiZqKGUpLmZvckVhY2godCl9LEg9ZnVuY3Rpb24obix0KXtqKG4pLmZvckVhY2godCl9LFY9W3VdLEY9W3UsZl0sQj1bdSxzLGRdLEo9W2ddLFA9ZnVuY3Rpb24obil7cmV0dXJuISFuW19dfSxTPWZ1bmN0aW9uKG4pe3JldHVybiBuW19dfSxVPWZ1bmN0aW9uKG4pe3JldHVybiBkZWxldGUgbltfXX0sJD1mdW5jdGlvbihuLHQpe2lmKCFQKG4pKXt2YXIgZT17fTt0LmZvckVhY2goKGZ1bmN0aW9uKHQpe2VbdF09bi5nZXRBdHRyaWJ1dGUodCl9KSksbltfXT1lfX0scT1mdW5jdGlvbihuLHQpe2lmKFAobikpe3ZhciBlPVMobik7dC5mb3JFYWNoKChmdW5jdGlvbih0KXshZnVuY3Rpb24obix0LGUpe2U/bi5zZXRBdHRyaWJ1dGUodCxlKTpuLnJlbW92ZUF0dHJpYnV0ZSh0KX0obix0LGVbdF0pfSkpfX0sSz1mdW5jdGlvbihuLHQsZSl7TihuLHQuY2xhc3NfYXBwbGllZCksdyhuLG0pLGUmJih0LnVub2JzZXJ2ZV9jb21wbGV0ZWQmJlQobix0KSxDKHQuY2FsbGJhY2tfYXBwbGllZCxuLGUpKX0sUT1mdW5jdGlvbihuLHQsZSl7TihuLHQuY2xhc3NfbG9hZGluZyksdyhuLHYpLGUmJihSKGUsMSksQyh0LmNhbGxiYWNrX2xvYWRpbmcsbixlKSl9LFc9ZnVuY3Rpb24obix0LGUpe2UmJm4uc2V0QXR0cmlidXRlKHQsZSl9LFg9ZnVuY3Rpb24obix0KXtXKG4sZCx5KG4sdC5kYXRhX3NpemVzKSksVyhuLHMseShuLHQuZGF0YV9zcmNzZXQpKSxXKG4sdSx5KG4sdC5kYXRhX3NyYykpfSxZPXtJTUc6ZnVuY3Rpb24obix0KXtEKG4sKGZ1bmN0aW9uKG4peyQobixCKSxYKG4sdCl9KSksJChuLEIpLFgobix0KX0sSUZSQU1FOmZ1bmN0aW9uKG4sdCl7JChuLFYpLFcobix1LHkobix0LmRhdGFfc3JjKSl9LFZJREVPOmZ1bmN0aW9uKG4sdCl7SChuLChmdW5jdGlvbihuKXskKG4sViksVyhuLHUseShuLHQuZGF0YV9zcmMpKX0pKSwkKG4sRiksVyhuLGYseShuLHQuZGF0YV9wb3N0ZXIpKSxXKG4sdSx5KG4sdC5kYXRhX3NyYykpLG4ubG9hZCgpfSxPQkpFQ1Q6ZnVuY3Rpb24obix0KXskKG4sSiksVyhuLGcseShuLHQuZGF0YV9zcmMpKX19LFo9W1wiSU1HXCIsXCJJRlJBTUVcIixcIlZJREVPXCIsXCJPQkpFQ1RcIl0sbm49ZnVuY3Rpb24obix0KXshdHx8ZnVuY3Rpb24obil7cmV0dXJuIG4ubG9hZGluZ0NvdW50PjB9KHQpfHxmdW5jdGlvbihuKXtyZXR1cm4gbi50b0xvYWRDb3VudD4wfSh0KXx8QyhuLmNhbGxiYWNrX2ZpbmlzaCx0KX0sdG49ZnVuY3Rpb24obix0LGUpe24uYWRkRXZlbnRMaXN0ZW5lcih0LGUpLG4ubGxFdkxpc25yc1t0XT1lfSxlbj1mdW5jdGlvbihuLHQsZSl7bi5yZW1vdmVFdmVudExpc3RlbmVyKHQsZSl9LG9uPWZ1bmN0aW9uKG4pe3JldHVybiEhbi5sbEV2TGlzbnJzfSxhbj1mdW5jdGlvbihuKXtpZihvbihuKSl7dmFyIHQ9bi5sbEV2TGlzbnJzO2Zvcih2YXIgZSBpbiB0KXt2YXIgaT10W2VdO2VuKG4sZSxpKX1kZWxldGUgbi5sbEV2TGlzbnJzfX0scm49ZnVuY3Rpb24obix0LGUpeyFmdW5jdGlvbihuKXtkZWxldGUgbi5sbFRlbXBJbWFnZX0obiksUihlLC0xKSxmdW5jdGlvbihuKXtuJiYobi50b0xvYWRDb3VudC09MSl9KGUpLE0obix0LmNsYXNzX2xvYWRpbmcpLHQudW5vYnNlcnZlX2NvbXBsZXRlZCYmVChuLGUpfSxjbj1mdW5jdGlvbihuLHQsZSl7dmFyIGk9eihuKXx8bjtvbihpKXx8ZnVuY3Rpb24obix0LGUpe29uKG4pfHwobi5sbEV2TGlzbnJzPXt9KTt2YXIgaT1cIlZJREVPXCI9PT1uLnRhZ05hbWU/XCJsb2FkZWRkYXRhXCI6XCJsb2FkXCI7dG4obixpLHQpLHRuKG4sXCJlcnJvclwiLGUpfShpLChmdW5jdGlvbihvKXshZnVuY3Rpb24obix0LGUsaSl7dmFyIG89Tyh0KTtybih0LGUsaSksTih0LGUuY2xhc3NfbG9hZGVkKSx3KHQsYiksQyhlLmNhbGxiYWNrX2xvYWRlZCx0LGkpLG98fG5uKGUsaSl9KDAsbix0LGUpLGFuKGkpfSksKGZ1bmN0aW9uKG8peyFmdW5jdGlvbihuLHQsZSxpKXt2YXIgbz1PKHQpO3JuKHQsZSxpKSxOKHQsZS5jbGFzc19lcnJvciksdyh0LHApLEMoZS5jYWxsYmFja19lcnJvcix0LGkpLGUucmVzdG9yZV9vbl9lcnJvciYmcSh0LEIpLG98fG5uKGUsaSl9KDAsbix0LGUpLGFuKGkpfSkpfSxsbj1mdW5jdGlvbihuLHQsZSl7IWZ1bmN0aW9uKG4pe3JldHVybiBaLmluZGV4T2Yobi50YWdOYW1lKT4tMX0obik/ZnVuY3Rpb24obix0LGUpeyFmdW5jdGlvbihuKXtuLmxsVGVtcEltYWdlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJJTUdcIil9KG4pLGNuKG4sdCxlKSxmdW5jdGlvbihuKXtQKG4pfHwobltfXT17YmFja2dyb3VuZEltYWdlOm4uc3R5bGUuYmFja2dyb3VuZEltYWdlfSl9KG4pLGZ1bmN0aW9uKG4sdCxlKXt2YXIgaT15KG4sdC5kYXRhX2JnKSxvPXkobix0LmRhdGFfYmdfaGlkcGkpLHI9YSYmbz9vOmk7ciYmKG4uc3R5bGUuYmFja2dyb3VuZEltYWdlPSd1cmwoXCInLmNvbmNhdChyLCdcIiknKSx6KG4pLnNldEF0dHJpYnV0ZSh1LHIpLFEobix0LGUpKX0obix0LGUpLGZ1bmN0aW9uKG4sdCxlKXt2YXIgaT15KG4sdC5kYXRhX2JnX211bHRpKSxvPXkobix0LmRhdGFfYmdfbXVsdGlfaGlkcGkpLHI9YSYmbz9vOmk7ciYmKG4uc3R5bGUuYmFja2dyb3VuZEltYWdlPXIsSyhuLHQsZSkpfShuLHQsZSksZnVuY3Rpb24obix0LGUpe3ZhciBpPXkobix0LmRhdGFfYmdfc2V0KTtpZihpKXt2YXIgbz1pLnNwbGl0KFwifFwiKSxhPW8ubWFwKChmdW5jdGlvbihuKXtyZXR1cm5cImltYWdlLXNldChcIi5jb25jYXQobixcIilcIil9KSk7bi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2U9YS5qb2luKCksXCJcIj09PW4uc3R5bGUuYmFja2dyb3VuZEltYWdlJiYoYT1vLm1hcCgoZnVuY3Rpb24obil7cmV0dXJuXCItd2Via2l0LWltYWdlLXNldChcIi5jb25jYXQobixcIilcIil9KSksbi5zdHlsZS5iYWNrZ3JvdW5kSW1hZ2U9YS5qb2luKCkpLEsobix0LGUpfX0obix0LGUpfShuLHQsZSk6ZnVuY3Rpb24obix0LGUpe2NuKG4sdCxlKSxmdW5jdGlvbihuLHQsZSl7dmFyIGk9WVtuLnRhZ05hbWVdO2kmJihpKG4sdCksUShuLHQsZSkpfShuLHQsZSl9KG4sdCxlKX0sdW49ZnVuY3Rpb24obil7bi5yZW1vdmVBdHRyaWJ1dGUodSksbi5yZW1vdmVBdHRyaWJ1dGUocyksbi5yZW1vdmVBdHRyaWJ1dGUoZCl9LHNuPWZ1bmN0aW9uKG4pe0QobiwoZnVuY3Rpb24obil7cShuLEIpfSkpLHEobixCKX0sZG49e0lNRzpzbixJRlJBTUU6ZnVuY3Rpb24obil7cShuLFYpfSxWSURFTzpmdW5jdGlvbihuKXtIKG4sKGZ1bmN0aW9uKG4pe3EobixWKX0pKSxxKG4sRiksbi5sb2FkKCl9LE9CSkVDVDpmdW5jdGlvbihuKXtxKG4sSil9fSxmbj1mdW5jdGlvbihuLHQpeyhmdW5jdGlvbihuKXt2YXIgdD1kbltuLnRhZ05hbWVdO3Q/dChuKTpmdW5jdGlvbihuKXtpZihQKG4pKXt2YXIgdD1TKG4pO24uc3R5bGUuYmFja2dyb3VuZEltYWdlPXQuYmFja2dyb3VuZEltYWdlfX0obil9KShuKSxmdW5jdGlvbihuLHQpe0wobil8fE8obil8fChNKG4sdC5jbGFzc19lbnRlcmVkKSxNKG4sdC5jbGFzc19leGl0ZWQpLE0obix0LmNsYXNzX2FwcGxpZWQpLE0obix0LmNsYXNzX2xvYWRpbmcpLE0obix0LmNsYXNzX2xvYWRlZCksTShuLHQuY2xhc3NfZXJyb3IpKX0obix0KSxBKG4pLFUobil9LF9uPVtcIklNR1wiLFwiSUZSQU1FXCIsXCJWSURFT1wiXSxnbj1mdW5jdGlvbihuKXtyZXR1cm4gbi51c2VfbmF0aXZlJiZcImxvYWRpbmdcImluIEhUTUxJbWFnZUVsZW1lbnQucHJvdG90eXBlfSx2bj1mdW5jdGlvbihuLHQsZSl7bi5mb3JFYWNoKChmdW5jdGlvbihuKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4uaXNJbnRlcnNlY3Rpbmd8fG4uaW50ZXJzZWN0aW9uUmF0aW8+MH0obik/ZnVuY3Rpb24obix0LGUsaSl7dmFyIG89ZnVuY3Rpb24obil7cmV0dXJuIHguaW5kZXhPZihrKG4pKT49MH0obik7dyhuLFwiZW50ZXJlZFwiKSxOKG4sZS5jbGFzc19lbnRlcmVkKSxNKG4sZS5jbGFzc19leGl0ZWQpLGZ1bmN0aW9uKG4sdCxlKXt0LnVub2JzZXJ2ZV9lbnRlcmVkJiZUKG4sZSl9KG4sZSxpKSxDKGUuY2FsbGJhY2tfZW50ZXIsbix0LGkpLG98fGxuKG4sZSxpKX0obi50YXJnZXQsbix0LGUpOmZ1bmN0aW9uKG4sdCxlLGkpe0wobil8fChOKG4sZS5jbGFzc19leGl0ZWQpLGZ1bmN0aW9uKG4sdCxlLGkpe2UuY2FuY2VsX29uX2V4aXQmJmZ1bmN0aW9uKG4pe3JldHVybiBrKG4pPT09dn0obikmJlwiSU1HXCI9PT1uLnRhZ05hbWUmJihhbihuKSxmdW5jdGlvbihuKXtEKG4sKGZ1bmN0aW9uKG4pe3VuKG4pfSkpLHVuKG4pfShuKSxzbihuKSxNKG4sZS5jbGFzc19sb2FkaW5nKSxSKGksLTEpLEEobiksQyhlLmNhbGxiYWNrX2NhbmNlbCxuLHQsaSkpfShuLHQsZSxpKSxDKGUuY2FsbGJhY2tfZXhpdCxuLHQsaSkpfShuLnRhcmdldCxuLHQsZSl9KSl9LGJuPWZ1bmN0aW9uKG4pe3JldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChuKX0sbW49ZnVuY3Rpb24obil7cmV0dXJuIG4uY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwobi5lbGVtZW50c19zZWxlY3Rvcil9LHBuPWZ1bmN0aW9uKG4pe3JldHVybiBmdW5jdGlvbihuKXtyZXR1cm4gayhuKT09PXB9KG4pfSxobj1mdW5jdGlvbihuLHQpe3JldHVybiBmdW5jdGlvbihuKXtyZXR1cm4gYm4obikuZmlsdGVyKEwpfShufHxtbih0KSl9LEVuPWZ1bmN0aW9uKG4sZSl7dmFyIG89YyhuKTt0aGlzLl9zZXR0aW5ncz1vLHRoaXMubG9hZGluZ0NvdW50PTAsZnVuY3Rpb24obix0KXtpJiYhZ24obikmJih0Ll9vYnNlcnZlcj1uZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoKGZ1bmN0aW9uKGUpe3ZuKGUsbix0KX0pLGZ1bmN0aW9uKG4pe3JldHVybntyb290Om4uY29udGFpbmVyPT09ZG9jdW1lbnQ/bnVsbDpuLmNvbnRhaW5lcixyb290TWFyZ2luOm4udGhyZXNob2xkc3x8bi50aHJlc2hvbGQrXCJweFwifX0obikpKX0obyx0aGlzKSxmdW5jdGlvbihuLGUpe3QmJihlLl9vbmxpbmVIYW5kbGVyPWZ1bmN0aW9uKCl7IWZ1bmN0aW9uKG4sdCl7dmFyIGU7KGU9bW4obiksYm4oZSkuZmlsdGVyKHBuKSkuZm9yRWFjaCgoZnVuY3Rpb24odCl7TSh0LG4uY2xhc3NfZXJyb3IpLEEodCl9KSksdC51cGRhdGUoKX0obixlKX0sd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJvbmxpbmVcIixlLl9vbmxpbmVIYW5kbGVyKSl9KG8sdGhpcyksdGhpcy51cGRhdGUoZSl9O3JldHVybiBFbi5wcm90b3R5cGU9e3VwZGF0ZTpmdW5jdGlvbihuKXt2YXIgdCxvLGE9dGhpcy5fc2V0dGluZ3Mscj1obihuLGEpO0codGhpcyxyLmxlbmd0aCksIWUmJmk/Z24oYSk/ZnVuY3Rpb24obix0LGUpe24uZm9yRWFjaCgoZnVuY3Rpb24obil7LTEhPT1fbi5pbmRleE9mKG4udGFnTmFtZSkmJmZ1bmN0aW9uKG4sdCxlKXtuLnNldEF0dHJpYnV0ZShcImxvYWRpbmdcIixcImxhenlcIiksY24obix0LGUpLGZ1bmN0aW9uKG4sdCl7dmFyIGU9WVtuLnRhZ05hbWVdO2UmJmUobix0KX0obix0KSx3KG4saCl9KG4sdCxlKX0pKSxHKGUsMCl9KHIsYSx0aGlzKToobz1yLGZ1bmN0aW9uKG4pe24uZGlzY29ubmVjdCgpfSh0PXRoaXMuX29ic2VydmVyKSxmdW5jdGlvbihuLHQpe3QuZm9yRWFjaCgoZnVuY3Rpb24odCl7bi5vYnNlcnZlKHQpfSkpfSh0LG8pKTp0aGlzLmxvYWRBbGwocil9LGRlc3Ryb3k6ZnVuY3Rpb24oKXt0aGlzLl9vYnNlcnZlciYmdGhpcy5fb2JzZXJ2ZXIuZGlzY29ubmVjdCgpLHQmJndpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwib25saW5lXCIsdGhpcy5fb25saW5lSGFuZGxlciksbW4odGhpcy5fc2V0dGluZ3MpLmZvckVhY2goKGZ1bmN0aW9uKG4pe1Uobil9KSksZGVsZXRlIHRoaXMuX29ic2VydmVyLGRlbGV0ZSB0aGlzLl9zZXR0aW5ncyxkZWxldGUgdGhpcy5fb25saW5lSGFuZGxlcixkZWxldGUgdGhpcy5sb2FkaW5nQ291bnQsZGVsZXRlIHRoaXMudG9Mb2FkQ291bnR9LGxvYWRBbGw6ZnVuY3Rpb24obil7dmFyIHQ9dGhpcyxlPXRoaXMuX3NldHRpbmdzO2huKG4sZSkuZm9yRWFjaCgoZnVuY3Rpb24obil7VChuLHQpLGxuKG4sZSx0KX0pKX0scmVzdG9yZUFsbDpmdW5jdGlvbigpe3ZhciBuPXRoaXMuX3NldHRpbmdzO21uKG4pLmZvckVhY2goKGZ1bmN0aW9uKHQpe2ZuKHQsbil9KSl9fSxFbi5sb2FkPWZ1bmN0aW9uKG4sdCl7dmFyIGU9Yyh0KTtsbihuLGUpfSxFbi5yZXNldFN0YXR1cz1mdW5jdGlvbihuKXtBKG4pfSx0JiZmdW5jdGlvbihuLHQpe2lmKHQpaWYodC5sZW5ndGgpZm9yKHZhciBlLGk9MDtlPXRbaV07aSs9MSlsKG4sZSk7ZWxzZSBsKG4sdCl9KEVuLHdpbmRvdy5sYXp5TG9hZE9wdGlvbnMpLEVufSkpO1xuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsImltcG9ydCBBamF4aWZ5IGZyb20gJy4vZGVmYXVsdC92aWV3cy9wcm9kdWN0L2FqYXhpZnknO1xuaW1wb3J0IGFjY29yZGlvbiBmcm9tICcuL2RlZmF1bHQvY29tcG9uZW50cy9vcmdhbmlzbXMvYWNjb3JkaW9uJztcbmltcG9ydCBIZWFkZXIgZnJvbSAnLi9kZWZhdWx0L2NvbXBvbmVudHMvb3JnYW5pc21zL2hlYWRlci9oZWFkZXInO1xuaW1wb3J0IENhcnQgZnJvbSAnLi9kZWZhdWx0L2NvbXBvbmVudHMvbW9sZWN1bGVzL2NhcnQvY2FydCc7XG5pbXBvcnQgR3JpZCBmcm9tICcuL2RlZmF1bHQvYWJzdHJhY3RzL2dyaWQvZ3JpZCc7XG5pbXBvcnQgTG9naW4gZnJvbSAnLi9kZWZhdWx0L2NvbXBvbmVudHMvbW9sZWN1bGVzL2xvZ2luL2xvZ2luJztcbmltcG9ydCBOYXYgZnJvbSAnLi9kZWZhdWx0L2NvbXBvbmVudHMvYXRvbXMvTmF2aWdhdGlvbi9tYWluLW5hdmlnYXRpb24nO1xuaW1wb3J0IFNlYXJjaCBmcm9tICcuL2RlZmF1bHQvYmxvY2tzL3NlYXJjaC9zZWFyY2gnO1xuaW1wb3J0IENvdW50cnlQaWNrZXIgZnJvbSAnLi9kZWZhdWx0L2Jsb2Nrcy9jb3VudHJ5LXBpY2tlci9jb3VudHJ5LXBpY2tlcic7XG5pbXBvcnQgVG9wbGlzdCBmcm9tICcuL2RlZmF1bHQvY29tcG9uZW50cy9tb2xlY3VsZXMvdG9wbGlzdC90b3BsaXN0JztcbmltcG9ydCBBY2UgZnJvbSAnLi9kZWZhdWx0L2NvbXBvbmVudHMvYWNlL0FjZSc7XG5pbXBvcnQgUHJvZHVjdFBhZ2UgZnJvbSAnLi9kZWZhdWx0L3ZpZXdzL3Byb2R1Y3QvcHJvZHVjdF9wYWdlJztcbmltcG9ydCBOZXdzbGV0dGVyIGZyb20gJy4vZGVmYXVsdC9ibG9ja3MvbmV3c2xldHRlcnMvbmV3c2xldHRlcic7XG5pbXBvcnQgRmlsdGVyIGZyb20gJy4vZGVmYXVsdC92aWV3cy9wcm9kdWN0L2ZpbHRlcic7XG5pbXBvcnQgU3R5bGVBZHZpc29yIGZyb20gJy4vZGVmYXVsdC9jb21wb25lbnRzL3N0eWxlX2Fkdmlzb3Ivc3R5bGVhZHZpc29yJztcbmltcG9ydCBCcmFuZFNlYXJjaCBmcm9tICcuL2RlZmF1bHQvdmlld3MvYnJhbmQvYnJhbmRzZWFyY2gnO1xuaW1wb3J0IFdpc2hsaXN0IGZyb20gJy4vZGVmYXVsdC92aWV3cy9wcm9kdWN0L3dpc2hsaXN0JztcbmltcG9ydCBSZXNlcnZhdGlvbiBmcm9tICcuL2RlZmF1bHQvdmlld3MvbXlwYWdlcy9yZXNlcnZhdGlvbic7XG5pbXBvcnQgTGF6eUxvYWQgZnJvbSAndmFuaWxsYS1sYXp5bG9hZCc7XG5pbXBvcnQgTXlTdHlsZSBmcm9tICcuL2RlZmF1bHQvY29tcG9uZW50cy9teXN0eWxlJztcbmltcG9ydCBTaW1wbGVTbGlkZXIgZnJvbSAnLi9kZWZhdWx0L3ZpZXdzL3Byb2R1Y3Qvc2ltcGxlX3NsaWRlcic7XG5pbXBvcnQgUmVjZW50bHlWaWV3ZWQgZnJvbSAnLi9kZWZhdWx0L2Jsb2Nrcy9wcm9kdWN0bGlzdHMvcmVjZW50bHl2aWV3ZWQuanMnO1xuaW1wb3J0IFN0eWxlVmlldyBmcm9tICcuL2RlZmF1bHQvYmxvY2tzL3Byb2R1Y3RsaXN0cy9zdHlsZXZpZXcuanMnO1xuaW1wb3J0IENoZWNrb3V0IGZyb20gJy4vZGVmYXVsdC92aWV3cy9jaGVja291dC9jaGVja291dCc7XG5pbXBvcnQgU2l6ZUFuZEZpdCBmcm9tICcuL2RlZmF1bHQvY29tcG9uZW50cy9zaXplX2FuZF9maXQvc2l6ZUFuZEZpdCc7XG5cbi8vIGhhbmRsZSBzY3NzXG5pbXBvcnQgJy4vZGVmYXVsdC9hcHAuc2Nzcyc7XG5cbmNsYXNzIEFwcCB7XG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMubGl2ZUV2ZW50KCk7XG5cdFx0dGhpcy5pbml0KCk7XG5cblx0XHR0aGlzLmhlYWRlciA9IG5ldyBIZWFkZXIoKTtcblx0XHR0aGlzLmNoZWNrb3V0ID0gbmV3IENoZWNrb3V0KCk7XG5cdFx0dGhpcy5hY2NvcmRpb24gPSBuZXcgYWNjb3JkaW9uKCk7XG5cdFx0dGhpcy5jYXJ0ID0gbmV3IENhcnQoKTtcblx0XHR0aGlzLmxvZ2luID0gbmV3IExvZ2luKCk7XG5cdFx0dGhpcy5ncmlkID0gbmV3IEdyaWQoKTtcblx0XHR0aGlzLm5hdiA9IG5ldyBOYXYoKTtcblx0XHR0aGlzLnNlYXJjaCA9IG5ldyBTZWFyY2goKTtcblx0XHR0aGlzLnRvcGxpc3QgPSBuZXcgVG9wbGlzdCgpO1xuXHRcdHRoaXMuY291bnRyeVBpY2tlciA9IG5ldyBDb3VudHJ5UGlja2VyKCk7XG5cdFx0dGhpcy5yZWNlbnRseV92aWV3ZWQgPSBuZXcgUmVjZW50bHlWaWV3ZWQoKTtcblx0XHR0aGlzLnN0eWxldmlldyA9IG5ldyBTdHlsZVZpZXcoKTtcblx0XHR0aGlzLnByb2R1Y3RfcGFnZSA9IG5ldyBQcm9kdWN0UGFnZSh0aGlzLmNhcnQpO1xuXHRcdHRoaXMud2lzaGxpc3QgPSBuZXcgV2lzaGxpc3QodGhpcy5jYXJ0KTtcblx0XHR0aGlzLnJlc2VydmF0aW9uID0gbmV3IFJlc2VydmF0aW9uKHRoaXMuY2FydCk7XG5cdFx0dGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKCk7XG5cdFx0dGhpcy5hamF4aWZ5ID0gbmV3IEFqYXhpZnkodGhpcy5wcm9kdWN0X3BhZ2UsIHRoaXMubmF2LCB0aGlzLmZpbHRlcik7XG5cdFx0dGhpcy5zdHlsZV9hZHZpc29yID0gbmV3IFN0eWxlQWR2aXNvcigpO1xuXHRcdHRoaXMuYnJhbmRfc2VhcmNoID0gbmV3IEJyYW5kU2VhcmNoKCk7XG5cdFx0dGhpcy5hY2UgPSBuZXcgQWNlKCk7XG5cdFx0dGhpcy5teXN0eWxlID0gbmV3IE15U3R5bGUoKTtcblx0XHR0aGlzLm5ld3NsZXR0ZXIgPSBuZXcgTmV3c2xldHRlcigpO1xuXHRcdHRoaXMuc2l6ZV9hbmRfZml0ID0gbmV3IFNpemVBbmRGaXQoKTtcblxuXHRcdGNvbnN0IHNtb290aFNjcm9sbFRvQW5jaG9yID0gKGFuY2hvcikgPT4ge1xuXHRcdFx0Y29uc3QgeyB0b3AgfSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYW5jaG9yKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRcdGNvbnN0IHN0YXJ0UG9zaXRpb24gPSB3aW5kb3cucGFnZVlPZmZzZXQ7XG5cdFx0XHRjb25zdCBkaXN0YW5jZSA9IHRvcCAtIHN0YXJ0UG9zaXRpb247XG5cdFx0XHRjb25zdCBkdXJhdGlvbiA9IDEwMDA7XG5cdFx0XHRsZXQgc3RhcnQgPSBudWxsO1xuXHRcdFx0Y29uc3Qgc3RlcCA9ICh0aW1lc3RhbXApID0+IHtcblx0XHRcdFx0aWYgKCFzdGFydCkgc3RhcnQgPSB0aW1lc3RhbXA7XG5cdFx0XHRcdGNvbnN0IHByb2dyZXNzID0gdGltZXN0YW1wIC0gc3RhcnQ7XG5cdFx0XHRcdHdpbmRvdy5zY3JvbGxUbygwLCBlYXNlSW5PdXRDdWJpYyhwcm9ncmVzcywgc3RhcnRQb3NpdGlvbiwgZGlzdGFuY2UsIGR1cmF0aW9uKSk7XG5cdFx0XHRcdGlmIChwcm9ncmVzcyA8IGR1cmF0aW9uKSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHN0ZXApO1xuXHRcdFx0fTtcblxuXHRcdFx0d2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShzdGVwKTtcblx0XHR9O1xuXG5cdFx0Y29uc3QgZWFzZUluT3V0Q3ViaWMgPSAodCwgYiwgYywgZCkgPT4ge1xuXHRcdFx0dCAvPSBkIC8gMjtcblx0XHRcdHJldHVybiB0IDwgMSA/IChjIC8gMikgKiB0ICogdCAqIHQgKyBiIDogKGMgLyAyKSAqICgodCAtPSAyKSAqIHQgKiB0ICsgMikgKyBiO1xuXHRcdH07XG5cblx0XHR3aW5kb3cubGl2ZUV2ZW50KCcuc21vb3RoQW5jaG9yJywgJ2NsaWNrJywgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0Y29uc3QgdGFyZ2V0ID0gZWxlbWVudC5kYXRhc2V0LnNjcm9sbHRhcmdldDtcblx0XHRcdHNtb290aFNjcm9sbFRvQW5jaG9yKHRhcmdldCk7XG5cdFx0fSk7XG5cblx0XHRmdW5jdGlvbiBzaG93VG9vbHRpcChlbGVtZW50V3JhcHBlciwgdG9vbHRpcCkge1xuXHRcdFx0ZWxlbWVudFdyYXBwZXIub25tb3VzZW1vdmUgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHR2YXIgeCA9IGUuY2xpZW50WCxcblx0XHRcdFx0XHR5ID0gZS5jbGllbnRZO1xuXHRcdFx0XHR0b29sdGlwLnN0eWxlLnRvcCA9IHkgKyAxNSArICdweCc7XG5cblx0XHRcdFx0aWYgKHRvb2x0aXAuY2xhc3NMaXN0LmNvbnRhaW5zKCdwb3NpdGlvbi1yaWdodCcpKSB7XG5cdFx0XHRcdFx0dG9vbHRpcC5zdHlsZS5sZWZ0ID0geCAtIDEyMCArICdweCc7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dG9vbHRpcC5zdHlsZS5sZWZ0ID0geCArIDE1ICsgJ3B4Jztcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoL0FuZHJvaWR8d2ViT1N8aVBob25lfGlQYWR8aVBvZHxCbGFja0JlcnJ5L2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSkge1xuXHRcdFx0XHRcdHRvb2x0aXAuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0XHR0b29sdGlwLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRcdH0sIDMwMDApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRvb2x0aXAuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRcdGVsZW1lbnRXcmFwcGVyLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHR0b29sdGlwLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcudG9vbHRpcC1zcGFuJykuZm9yRWFjaCgodG9vbHRpcCkgPT4ge1xuXHRcdFx0Y29uc3QgcGFyZW50ID0gdG9vbHRpcC5wYXJlbnROb2RlO1xuXHRcdFx0c2hvd1Rvb2x0aXAocGFyZW50LCB0b29sdGlwKTtcblx0XHR9KTtcblxuXHRcdGNvbnN0IGJhY2tkcm9wID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmJhY2tkcm9wJyk7XG5cblx0XHQvLyBQcmVvd25lZCBpbmZvIHRvZ2dsZVxuXHRcdGxldCBwcmVvd25lZEluZm8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjdGVzdEpKJyk7XG5cdFx0bGV0IHByZW93bmVkSW5mb0J0biA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbCBhJyk7XG5cblx0XHRpZiAocHJlb3duZWRJbmZvQnRuKSB7XG5cdFx0XHRwcmVvd25lZEluZm9CdG4uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHByZW93bmVkSW5mby5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdFx0YmFja2Ryb3AuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRsZXQgdmlkZW8gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCd2aWRlbycpO1xuXHRcdGxldCB2aWRlb0VsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgndmlkZW8sIC52aWRlb0luZm9XcmFwcGVyJyk7XG5cdFx0bGV0IHZpZGVvV3JhcHBlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy52aWRlbycpO1xuXHRcdGlmICh2aWRlb0VsZW1lbnRzKSB7XG5cdFx0XHR2aWRlb0VsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcblx0XHRcdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRpZiAodmlkZW8ucGF1c2VkKSB7XG5cdFx0XHRcdFx0XHR2aWRlby5wbGF5KCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHZpZGVvLnBhdXNlKCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHZpZGVvV3JhcHBlci5jbGFzc0xpc3QudG9nZ2xlKCdwbGF5aW5nJyk7XG5cdFx0XHRcdFx0dmlkZW9XcmFwcGVyLmNsYXNzTGlzdC5hZGQoJ3N0YXJ0ZWQnKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvKiBGcmVkcmlrIHNwZWNpYWwgZsO2ciBlZ2Vuc2thcGVyICovXG5cdFx0dmFyIHByb2R1Y3RzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLnByb2R1Y3QtLWdyb3VwIC5iaWcgaW1nOm5vdCgucHJvZHVjdF9faW1nLS1ob3ZlciknKTtcblxuXHRcdHByb2R1Y3RzLmZvckVhY2gobXlGdW5jdGlvbik7XG5cblx0XHRmdW5jdGlvbiBteUZ1bmN0aW9uKGl0ZW0sIGluZGV4LCBhcnIpIHtcblx0XHRcdGl0ZW0uc3JjID0gaXRlbS5zcmMucmVwbGFjZSgnLmpwZycsICdfMi5qcGcnKS5yZXBsYWNlKCdhcnRpa2xhci8nLCAnYXJ0aWtsYXIvem9vbS8nKTtcblx0XHR9XG5cblx0XHRjb25zdCB0YXJnZXQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubWVudV9fY2F0ZWdvcmllcycpO1xuXHRcdGNvbnN0IGNsb3NlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmNsb3NlJyk7XG5cblx0XHRpZiAodGFyZ2V0KSB7XG5cdFx0XHR0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgbU92ZXIsIGZhbHNlKTtcblx0XHRcdHRhcmdldC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsIG1PdXQsIGZhbHNlKTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBtT3ZlcihldmVudCkge1xuXHRcdFx0aWYgKGV2ZW50LnRhcmdldC5jbG9zZXN0KCcuaGFzX19jaGlsZHJlbiwgLmJyYW5kc0xpbmsnKSkge1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZU5hdicpO1xuXHRcdFx0XHRiYWNrZHJvcC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRmdW5jdGlvbiBtT3V0KCkge1xuXHRcdFx0Y29uc3QgY2xpY2tlZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5yZWxvYWQnKTtcblx0XHRcdGlmIChjbGlja2VkKSB7XG5cdFx0XHRcdGNsaWNrZWQuY2xhc3NMaXN0LnJlbW92ZSgncmVsb2FkJyk7XG5cdFx0XHR9XG5cblx0XHRcdGJhY2tkcm9wLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmVOYXYnKTtcblx0XHR9XG5cblx0XHRjb25zdCBrdW5kcmFkZ2l2bmluZyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5rdW5kcmFkZ2l2bmluZycpO1xuXHRcdGlmIChrdW5kcmFkZ2l2bmluZykge1xuXHRcdFx0d2luZG93LmxpdmVFdmVudCgnLmhlYWRlcl9fY3VzdG9tZXJzZXJ2aWNlJywgJ2NsaWNrJywgKGV2ZW50LCBlbGVtZW50KSA9PiB7XG5cdFx0XHRcdGt1bmRyYWRnaXZuaW5nLmNsYXNzTGlzdC5hZGQoJ2FjdGl2ZScpO1xuXHRcdFx0XHRiYWNrZHJvcC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmdWxsYmFja2Ryb3AnKTtcblx0XHRcdH0pO1xuXG5cdFx0XHRjb25zdCBrdW5kcmFkZ2l2bmluZ0Nsb3NlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmt1bmRyYWRnaXZuaW5nIC5jbG9zZScpO1xuXHRcdFx0aWYgKGt1bmRyYWRnaXZuaW5nQ2xvc2UpIHtcblx0XHRcdFx0a3VuZHJhZGdpdm5pbmdDbG9zZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsICgpID0+IHtcblx0XHRcdFx0XHRrdW5kcmFkZ2l2bmluZy5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0XHRiYWNrZHJvcC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2Z1bGxiYWNrZHJvcCcpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRjb25zdCBtb2RhbFNsaWRlT3V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI21vZGFsX2FyZWEnKTtcblx0XHRpZiAobW9kYWxTbGlkZU91dCkge1xuXHRcdFx0d2luZG93LmxpdmVFdmVudCgnLm1vZGFsVHJpZ2dlcicsICdjbGljaycsIChldmVudCwgZWxlbWVudCkgPT4ge1xuXHRcdFx0XHQvLyBHZXQgdGhlIGRhdGEtaGVhZGVyIGFuZCBkYXRhLWNvbnRlbnQgYXR0cmlidXRlcyBmcm9tIHRoZSBjbGlja2VkIGVsZW1lbnRcblx0XHRcdFx0Y29uc3QgaGVhZGVyVGV4dCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWhlYWRlcicpO1xuXHRcdFx0XHRjb25zdCBjb250ZW50VGV4dCA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWNvbnRlbnQnKTtcblxuXHRcdFx0XHQvLyBGaW5kIHRoZSBtb2RhbCBoZWFkZXIgYW5kIGNvbnRlbnQgZWxlbWVudHNcblx0XHRcdFx0Y29uc3QgbW9kYWxIZWFkZXIgPSBtb2RhbFNsaWRlT3V0LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbF9faGVhZGVyIGgyJyk7XG5cdFx0XHRcdGNvbnN0IG1vZGFsQ29udGVudCA9IG1vZGFsU2xpZGVPdXQucXVlcnlTZWxlY3RvcignLm1vZGFsX19jb250ZW50Jyk7XG5cblx0XHRcdFx0Ly8gVXBkYXRlIHRoZSBtb2RhbCBoZWFkZXIgYW5kIGNvbnRlbnQgd2l0aCB0aGUgbmV3IHRleHRcblx0XHRcdFx0aWYgKG1vZGFsSGVhZGVyKSB7XG5cdFx0XHRcdFx0bW9kYWxIZWFkZXIudGV4dENvbnRlbnQgPSBoZWFkZXJUZXh0O1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChtb2RhbENvbnRlbnQpIHtcblx0XHRcdFx0XHRtb2RhbENvbnRlbnQuaW5uZXJIVE1MID0gY29udGVudFRleHQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGNvbnRlbnRUZXh0ICYmIGNvbnRlbnRUZXh0LmluY2x1ZGVzKCdsaXBzY29yZScpKSB7XG5cdFx0XHRcdFx0bGlwc2NvcmUuaW5pdFdpZGdldHMoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFkZCB0aGUgYWN0aXZlIGNsYXNzIHRvIHRoZSBtb2RhbCBhbmQgYmFja2Ryb3Bcblx0XHRcdFx0bW9kYWxTbGlkZU91dC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcblx0XHRcdFx0aWYgKGJhY2tkcm9wKSB7XG5cdFx0XHRcdFx0YmFja2Ryb3AuY2xhc3NMaXN0LmFkZCgnYWN0aXZlJyk7XG5cdFx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCdmdWxsYmFja2Ryb3AnKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGNvbnN0IG1vZGFsU2xpZGVPdXRDbG9zZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNtb2RhbF9hcmVhIC5jbG9zZScpO1xuXHRcdFx0aWYgKG1vZGFsU2xpZGVPdXRDbG9zZSkge1xuXHRcdFx0XHRtb2RhbFNsaWRlT3V0Q2xvc2UuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XG5cdFx0XHRcdFx0bW9kYWxTbGlkZU91dC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0XHRiYWNrZHJvcC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2Z1bGxiYWNrZHJvcCcpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRjb25zdCBzaXplTkZpdCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaXplYW5kZml0Jyk7XG5cdFx0Y29uc3Qgc3R5bGVhZHZpc29yID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0eWxlYWR2aXNvcicpO1xuXHRcdGNvbnN0IGxvZ2luX2Zvcm09IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdsb2dpbi13cmFwcGVyJyk7XG5cdFx0Y29uc3QgY2FydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNhaXItY2FydCcpO1xuXHRcdGJhY2tkcm9wLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0ZG9jdW1lbnQuYm9keS5zdHlsZS5vdmVyZmxvdyA9ICcnO1xuXHRcdFx0Y2FydC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnY2FydC1vcGVuJyk7XG5cdFx0XHRiYWNrZHJvcC5jbGFzc0xpc3QucmVtb3ZlKCdhY3RpdmUnKTtcblx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGFnZS0tc2V0dGluZ3MtLXdyYXBwZXInKSkge1xuXHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcucGFnZS0tc2V0dGluZ3MtLXdyYXBwZXInKS5jbGFzc0xpc3QucmVtb3ZlKCctLWFjdGl2ZScpO1xuXHRcdFx0fVxuXHRcdFx0YmFja2Ryb3AuY2xhc3NMaXN0LnJlbW92ZSgnZmlsdGVyLW9wZW4nKTtcblx0XHRcdGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjaGVhZGVyIC5oZWFkZXJfX3NlYXJjaCAjc3VnZ2VzdC1hcmVhLmFjdGl2ZScpKSB7XG5cdFx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNoZWFkZXIgLmhlYWRlcl9fc2VhcmNoICNzdWdnZXN0LWFyZWEuYWN0aXZlJykuc3R5bGUubWF4SGVpZ2h0ID0gJzBweCc7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzdHlsZWFkdmlzb3IuY2xhc3NMaXN0LmNvbnRhaW5zKCdhY3RpdmUnKSAmJiB0eXBlb2YgX2ltYm94ICE9PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRfaW1ib3gucHVzaChbJ3Nob3dMYXVuY2hlciddKTtcblx0XHRcdH1cblx0XHRcdGlmIChzaXplTkZpdCAmJiBzaXplTkZpdC5jbGFzc0xpc3QuY29udGFpbnMoJ2FjdGl2ZScpKSB7XG5cdFx0XHRcdHNlc3Npb25TdG9yYWdlLmNsZWFyKCk7XG5cdFx0XHRcdHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ3NuZl9zdGVwJywgJzEnKTtcblx0XHRcdFx0c2l6ZU5GaXQuY2xhc3NMaXN0LnJlbW92ZSgnZnJvbS1wZHAnKTtcblx0XHRcdFx0c2l6ZU5GaXQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnc2l6ZWFuZGZpdC1vcGVuJyk7XG5cdFx0XHR9XG5cdFx0XHRsb2dpbl9mb3JtLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0a3VuZHJhZGdpdm5pbmcuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRzdHlsZWFkdmlzb3IuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ3N0eWxlYWR2aXNvcicpO1xuXHRcdFx0ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N1Z2dlc3QtcmVzdWx0Jykuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdWdnZXN0LWluaXQnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG5cdFx0XHRpZiAoc2Vzc2lvblN0b3JhZ2UpIHtcblx0XHRcdFx0dGhpcy50ZXN0X2NvbXBsZXRlZCA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ3Rlc3RfY29tcGxldGVkJyk7XG5cdFx0XHRcdGlmICh0aGlzLnRlc3RfY29tcGxldGVkICYmIHRoaXMudGVzdF9jb21wbGV0ZWQgIT09ICcnKSB7XG5cdFx0XHRcdFx0bG9jYXRpb24ucmVsb2FkKCk7XG5cdFx0XHRcdFx0c2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgndGVzdF9jb21wbGV0ZWQnLCAnJyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0XHRjbG9zZS5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG5cdFx0XHRlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7XG5cdFx0XHRcdGJhY2tkcm9wLmNsYXNzTGlzdC5yZW1vdmUoJ2FjdGl2ZScpO1xuXHRcdFx0XHRpZiAoY2FydCkge1xuXHRcdFx0XHRcdGNhcnQuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoJ2NhcnQtb3BlbicpO1xuXHRcdFx0XHRzdHlsZWFkdmlzb3IuY2xhc3NMaXN0LnJlbW92ZSgnYWN0aXZlJyk7XG5cdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnc3R5bGVhZHZpc29yJyk7XG5cdFx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdWdnZXN0LXJlc3VsdCcpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0XHRcdGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzdWdnZXN0LWluaXQnKS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRpbml0KCkge1xuXHRcdHRoaXMubGF6eWxvYWQoKTtcblxuXHRcdC8vIGluaXQgc2xpZGVyc1xuXHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zbmFwcGluZy0td3JhcHBlcicpLmZvckVhY2goZnVuY3Rpb24gKGVsZW0pIHtcblx0XHRcdG5ldyBTaW1wbGVTbGlkZXIoZWxlbSk7XG5cdFx0fSk7XG5cdH1cblxuXHRsYXp5bG9hZCgpIHtcblx0XHR3aW5kb3cubGF6eUxvYWRJbnN0YW5jZSA9IG5ldyBMYXp5TG9hZCh7XG5cdFx0XHR1bm9ic2VydmVfZW50ZXJlZDogdHJ1ZSwgLy8gPC0gQXZvaWQgZXhlY3V0aW5nIHRoZSBmdW5jdGlvbiBtdWx0aXBsZSB0aW1lc1xuXHRcdFx0Y2FsbGJhY2tfZW50ZXI6IHRoaXMuZXhlY3V0ZUxhenlGdW5jdGlvbiAvLyBBc3NpZ25pbmcgdGhlIGZ1bmN0aW9uIGRlZmluZWQgYWJvdmVcblx0XHR9KTtcblx0XHR3aW5kb3cubGF6eUZ1bmN0aW9ucyA9IHt9O1xuXHR9XG5cblx0ZXhlY3V0ZUxhenlGdW5jdGlvbihlbGVtZW50KSB7XG5cdFx0dmFyIGxhenlGdW5jdGlvbk5hbWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1sYXp5LWZ1bmN0aW9uJyk7XG5cdFx0dmFyIGxhenlGdW5jdGlvbiA9IHdpbmRvdy5sYXp5RnVuY3Rpb25zW2xhenlGdW5jdGlvbk5hbWVdO1xuXHRcdGlmICghbGF6eUZ1bmN0aW9uKSByZXR1cm47XG5cdFx0bGF6eUZ1bmN0aW9uKGVsZW1lbnQpO1xuXHR9XG5cblx0bGl2ZUV2ZW50KCkge1xuXHRcdHdpbmRvdy5saXZlRXZlbnQgPSAoc2VsZWN0b3IsIGV2ZW50LCBoYW5kbGVyKSA9PiB7XG5cdFx0XHRkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoXG5cdFx0XHRcdGV2ZW50LFxuXHRcdFx0XHRmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdHZhciB0YXJnZXQgPSBlLnRhcmdldDtcblx0XHRcdFx0XHR3aGlsZSAodGFyZ2V0ICE9IG51bGwpIHtcblx0XHRcdFx0XHRcdHZhciBpc01hdGNoID0gdGFyZ2V0Lm1hdGNoZXMoc2VsZWN0b3IpO1xuXHRcdFx0XHRcdFx0aWYgKGlzTWF0Y2gpIHtcblx0XHRcdFx0XHRcdFx0aGFuZGxlcihlLCB0YXJnZXQpO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR0YXJnZXQgPSB0YXJnZXQucGFyZW50RWxlbWVudDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRydWVcblx0XHRcdCk7XG5cdFx0fTtcblx0fVxufVxuXG5jb25zdCBhcHAgPSBuZXcgQXBwKCk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=